This is an archive of the discontinued LLVM Phabricator instance.

[ARM/AArch64] Add ACLE special register intrinsics (10.1)
AbandonedPublic

Authored by bsmith on Nov 13 2014, 4:14 AM.

Details

Reviewers
None
Summary

This patch implements support for the ACLE special register intrinsics in section 10.1, __arm_{w,r}sr{,p,64}.

This includes arm_acle.h definitions, new builtins to support these definitions and codegen for them, as well as SemaChecking support to fault invalid parameters (as far as is reasonable, the backend will further validate this). This unfortunately adds a bit of instruction detail stuff into the frontend that perhaps shouldn't be there, however given that these intrinsics take a string parameter I couldn't see how to reasonably pass this string straight to the backend and have that interpret what it should be (which I would have rathered do). So instead the builtin codegen interprets the string and emits the appropriate inline asm.

Diff Detail

Event Timeline

bsmith updated this revision to Diff 16144.Nov 13 2014, 4:14 AM
bsmith retitled this revision from to [ARM/AArch64] Add ACLE special register intrinsics (10.1).
bsmith updated this object.
bsmith edited the test plan for this revision. (Show Details)
bsmith set the repository for this revision to rL LLVM.
bsmith added a subscriber: Unknown Object (MLST).

Hi Bradley,

We usually try to avoid using inline assembly for intrinsics, even if it does mean an extra LLVM patch. In this case, it would be better to do more thorough analysis anyway to avoid rather dodgy diagnostics like:

$ cat tmp.c
unsigned rsr() {
  return __builtin_arm_rsr("21:2:3:4:5");
}
$ clang -c tmp.c -arch arm64
<inline asm>:1:10: error: expected readable system register
        mrs x8, S21_2_C3_C4_5

(Or possibly worse if someone is using -fno-integrated-as).

Cheers.

Tim.

I agree with Tim. I believe you can reuse the named register builtins to read/write to/from it and let the lowering to the ARM back-end.

Hm, I hadn't seen read_register and write_register, it almost looks like what I want, however it seems that it's used specifically for named registers that map to a backend register (and uses CopyFromReg on them). The issue with this is that none of these special registers are real registers in the backend, they just get encoded to immediate field(s).

I however hadn't considered that use of metadata to pass strings through the IR (like read/write_register do) was an acceptable way of doing things. So I might be able to create my own similar intrinsics that use this method of passing the special register string straight through.

Tim, I avoided doing more analysis than I did in the frontend simply because you'd need to get the the point of using the backend SysRegMappers in the frontend, which seemed like the wrong thing to do. That said, if I take the above approach I could easily do this analysis at the lowering stage, which would allow for proper diagnostics. (Assuming emitting these diagnostics in the backend rather than frontend is acceptable?)

Bradley,

read/write register are only lowered to movs in the backend, so you could, in theory lower your special register naming to mrs/msr or whatever else you need. You'd only need to allow Clang to recognise that syntax as register names, as for now, it only recognise what's in some tablegen files, I believe.

If that doesn't work, a new builtin with similar syntax and usage would be ok, and you cna use the clang/llvm patches for the named registers as a guide. I've split the warning/error messages on Clang and LLVM, so that we could help the user as much as possible as soon as possible. It should be ok to do the same in your case.

cheers,
--renato

bsmith abandoned this revision.May 12 2015, 9:36 AM