I started writing an LLVM Backend for 16-bit PIC microcontrollers (PIC24, dsPIC30/33). After copying and renaming stuff from Lanai, removing much, adding some and making the backend known to clang I can translate
short foo(void) { return 6*7; }
to
mov #0x2A, W0
ret
which is precisely what I wanted.
The DataLayout is set to "e-m:e-p:16:16-i16:16-a:0:16-n16-S16" and the registers are defined as
def GPR : RegisterClass<"PIC", [i16], 16, (sequence "W%u", 0, 15)>;
and added as
addRegisterClass(MVT::i16, &PIC::GPRRegClass);
However when I change the above return type to 'int', I get "Return operand #1 has unhandled type i16" which is strange because i16 is the only type currently handled:
def RetCC_PIC16 : CallingConv<[
// Use W0 to return 16-bit value.
CCIfType<[i16], CCAssignToReg<[W0]>>
]>;
Compilation aborts in LowerReturn() at
CCInfo.AnalyzeReturn(Outs, RetCC_PIC16);
What am I missing? What else do I have to do to tell clang / llvm which int size to use and how to return it?
Where does the identifier GPRRegClass come from and is it actually correct?