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

5.7. Decoding Custom Operands

For operands that required custom encoding methods in the instruction encoding, similar functions are also required to decode them.

Firstly in the operand's TableGen definition, the variable DecoderMethod needs to be defined as the name of the function in the Disassembler class that will handle them.

This function is then defined, taking the bits for each part of the operand, parsing them and then adding them to the operand in a similar way as was done in the decoding register class example.

For OpenRISC 1000 , the only operand which requires a custom decoder is the memory operand, which combines a 5-bit register value with a signed 16-bit offset.

Firstly the bit values of the two operands are obtained from the given operand. These are in turn converted to MCOperands and added to the instruction.

The register operand is handled in the same way as the register decoder, with the offset being sign extended to a 32-bit value before the immediate operand type is created.

static DecodeStatus DecodeMemoryValue(MCInst &Inst,
                                      unsigned Insn,
                                      uint64_t Address,
                                      const void *Decoder) {
  unsigned Register = (Insn >> 16) & 0b11111;
  Inst.addOperand(MCOperand::CreateReg(Register+1));
  unsigned Offset = (Insn & 0xffff);
  Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Offset)));
  return MCDisassembler::Success;
}
        
Embecosm divider strip