cortex-m{3,4} special registers

I was attempting to compile some code with a recent (r138716)
version of llvm/clang, targeting a cortex-m4 processor.

And I get an error like this:

In file included from sched_garbage.c:43:
In file included from ./os_internal.h:48:
In file included from /p/nuttx/trunk/nuttx/include/sched.h:47:
In file included from /p/nuttx/trunk/nuttx/include/nuttx/sched.h:54:
In file included from /p/nuttx/trunk/nuttx/include/nuttx/irq.h:67:
In file included from /p/nuttx/trunk/nuttx/include/arch/irq.h:60:
/p/nuttx/trunk/nuttx/include/arch/armv7-m/irq.h:186:6: error: invalid operand
      for instruction
     "\tmrs %0, primask\n"
     ^
<inline asm>:1:14: note: instantiated into assembly here
                mrs r5, primask
                           ^

This appears to be due to llvm lacking support for the various
cortex-m{3,4} special registers. ("primask", "faultmask", etc)

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/ch05s13s01.html

Can someone tell me how I would go about adding support for these
special registers?

-Kurt

Hi Kurt,

The assembly parser doesn't (yet) handle these, you're right. Currently, the MRS instruction is split into two variants in the ARMInstrThumb2.td file, t2MRS and t2MRSsys, one for the user mode version reading cpsr and one for the system mode version reading spsr. MSR, by contrast, has a custom parse method for the mask operand since it's a bit more complex than an either/or.

You'll likely want to merge the two MRS variants into one and add an operand for the system register, mapping that to the proper encoding bits in the instruction, and use a custom parse method to map the register names to the appropriate bit values. The current MSR parse method should give a basic idea of how to do that.

Once you have something, post a proposed patch to llvm-commits and we'll have a look and work through any implementation details.

Regards,
-Jim

Hi Kurt, Jim,

I took the liberty of working on this today.

The patch has become a bit of a frankenpatch, for the reasons listed out below
and so I won't be able to submit it until tomorrow.

The actual fix itself was very straightforward, but exposed a failing in the
FixedLenInstructionDecoder in that it does not support instruction predicates
such as "IsThumb2".

Generally this is fine, however MRS has different encodings in v{6,7}m and
v{6,7}{a,r} - the encodings are not sufficiently different to deterministically
tell them apart without subtarget specific information.

I can encode that as instruction predicates (, Requires<[IsMClass]>, assuming
I've added a new predicate 'IsMClass'), but getting the generated decoder to be
subtarget-dependent was quite an invasive change. I also had to do the same with
the MCInstPrinter - it can't know whether to print mask names for the M-series
or the AR-series without a SubtargetInfo.

I'd like to know if yourself or perhaps Owen/Eric has any input on the track I'm
going down. From my (possibly tunnel-visioned) perspective it's the only logical
solution, and I'm surprised that having the parser/printer operate without
subtarget specific knowledge hasn't caused issues before.

Cheers,

James

I can see that I'm totally out of my depth on these changes.
While I understand what both Jim Grosbach and James Molloy said,
I do not believe I'm capable of producing code that fits into
the LLVM ecosystem nicely.

-Kurt

Hi Kurt,

That's fine, I have a 3-part patch that I'm finalising now and putting through
internal code review. Will be out onto the list hopefully tomorrow.

It was quite a complex change in the end.

Cheers,

James