Services and Modeling for Embedded Software Development
Embecosm divider strip
Prev  Next

5.6. Decoding Register Classes

As with encoding register values when building the instruction encoder, when decoding instructions support for taking an encoded register value and creating an Operand object which appropriately describes it is required.

The names of these functions are defined by TableGen when building the decoding tables, but follow the form DecodeRegClassRegisterClass. These functions are given the instruction to add an operand to, the encoded register value as well as the address in memory where the instruction can be found at.

In the case of the OpenRISC 1000  architecture, the only register class which can be in an instruction is the a general register, meaning only one function needs defining, DecodeGPRRegisterClass. When called, this function checks that the given register number is within the valid range (0-31). If it is, a new register operand is added to the instruction.

DecodeStatus DecodeGPRRegisterClass(MCInst &Inst,
                                    unsigned RegNo,
                                    uint64_t Address,
                                    const void *Decoder) {

  if (RegNo > 31)
    return MCDisassembler::Fail;

  // The internal representation of the registers counts r0: 1, r1: 2, etc.
  Inst.addOperand(MCOperand::CreateReg(RegNo+1));
  return MCDisassembler::Success;
}        
        

Setting the register value in this case is a case of incrementing the given number by 1 as the internal representation of registers is r0 is 1, r1 is 2, etc.

For targets with a more complex register definition, it is better to use a switch statement similar to the getOR1KRegisterNumbering function used in the instruction encoder, but checking the encoding and returning a register object if valid.

Embecosm divider strip