Register Number

Dear all,

in my file, I defined a register like this:

class TestReg<bits<6> enc, string name> : Register {
let HWEncoding{5-0} = enc;
let Namespace = “TEST”;

def D0 : TestReg<0x01, “d0”>, DwarfRegNum<[1]>;

but when I compile, the result I have in is this:

case ‘d’: // 7 strings to match.

switch (Name[1]) {
case ‘0’: // 1 string to match.
return 14; // “d0”

I supposed I will get either 1 (because of encoding) or 0 (because of DwarfRegNum). Is this 14 something system generated? How can I assign my own number to the registers?



It seems like d0 is always 14!

I check it with it was the same!

How is it possible? because it should give the same register value that matches the underlying platform not any autogenerated value!?

The returned number is the register id as defined in <YourTarget> These numbers don't have any meaning other than to represent a particular register. The 0x01 would be the encoding used in generating the binary.

The D0 has id 14 on ARM because there are 13 other registers preceding it:
namespace ARM {
enum {
   APSR = 1,
   APSR_NZCV = 2,
   CPSR = 3,
   FPEXC = 4,
   FPINST = 5,
   FPSCR = 6,
   FPSCR_NZCV = 7,
   FPSID = 8,
   ITSTATE = 9,
   LR = 10,
   PC = 11,
   SP = 12,
   SPSR = 13,
   D0 = 14,


Hi Krzysztof,

Thanks for your reply. I wanted to assign the hardware encoding to the Instruction bits like the link below:

but, at the end, what is assigned to the Inst is, I suppose, the register ID not the encoding!

to be more clear, I do the followings:
def D0 : TestReg<0x01, “d0”>, DwarfRegNum<[0]>;

and then in
bits<6> Dr;
let Inst{5-3} = Dr{2-0};

assuming D0 is passed to $Dr, what I get in the encoding is 110, which I think is the bit 0 to 2 of what is the returned value in the

I mean, at the end, Inst{5-3} is getting a value which is not 001.

What am I doing wrong?

I'm assuming that your TestReg definition assigns the 0x01 to the HWEncoding field.

In an instruction definition, the way that tablegen assigns values from the parameters is that it goes over all undefined fields in the instruction class and assigns the values of the first argument to the first undefined field, the value of the second argument to the second undefined field, etc. What may be happening is that the D0 that you pass to the pattern is assigned to a different field that you expect.

You can get all the expanded records from tablegen:

llvm-tblgen -print-records -I [llvm source]/lib/Target/[your target] -I [llvm source]/lib/Target -I [llvm source]/include [llvm source]/lib/Target/Hexagon/[your target].td

You should see the full class corresponding to the instruction definition, and see what fields in it are undefined. One thing that I'm not sure about is how table-gen handles types, for example, what it does if the argument is bits<5>, but there is an undefined field of type bits<1>. I don't know if it will skip it or truncate it to 1 bit.


Editing inadequacy. Obviously not Hexagon...


Thank you :slight_smile:
If you mean this field, it looks everything is ok:
field bits<16> Inst = { 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, Dr{2}, Dr{1}, Dr{0}, At{0}, 0, 0 };

Is possible that the problem might be on the TestAsmParser.cpp side?

Could you post the entire class that contains this field?


Huh, I found the problem!!

I made a silly mistake, instead of having these lines in my TestMCCodeEmitter::getMachineOpValue function

unsigned Reg = MO.getReg();
unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg);
return RegNo;

I was just returning the Reg itself! like this:
unsigned Reg = MO.getReg();
return Reg;

Thanks a lot Krzysztof. Without your help I would have sunk into the TableGen see! :smiley:

You're welcome. :slight_smile: