Relative addressing

The destination register and each of the source registers can be
relatively addressed by some special "address registers": a0, a1, a2,
a3.

suppose a0 = 4, a1 = 2, the instruction

  add r[a0], r[a1], r7

equals to:
  
  r4 = r2 + r7

How should the instruction be defined in TableGen *.td file? If an
opcode is defined for each variant (like X86InstrInfo.td) there will
be eight opcodes for each binary operation, and 16 opcodes for each
trinary operation!

  { relative, not-relative } * { relative, not-relative } * {
relative, not-relative } = 8

  That is, opcodes:
  
    ADD_x_x_x
    ADD_r_x_x
    ADD_x_r_x
    ADD_x_x_r
    ADD_x_r_r
    ADD_r_x_r
    ADD_r_r_x
    ADD_r_r_r
    
  (x: not relative addressing, r: relative addressing)

Alternatively, the code selector could be designed to generate 'mov'
instruction with relative addressing only. The above 'add' instruction
is translated to:

  mov r1, r[a0]
  mov r2, r[a1]
  add r1, r2, r7

but it makes the register allocation/assignment and instruction
scheduling difficult. For the register allocation, one more register
will be needed. For the instruction scheduling, the 'add' and the
associated 'mov's must be moved altogehter.

The destination register and each of the source registers can be
relatively addressed by some special "address registers": a0, a1, a2,
a3.
suppose a0 = 4, a1 = 2, the instruction
add r[a0], r[a1], r7
equals to:
r4 = r2 + r7

ok

How should the instruction be defined in TableGen *.td file? If an
opcode is defined for each variant (like X86InstrInfo.td) there will
be eight opcodes for each binary operation, and 16 opcodes for each
trinary operation!

{ relative, not-relative } * { relative, not-relative } * {
relative, not-relative } = 8

Yup.

That is, opcodes:

   ADD_x_x_x
   ADD_r_x_x
   ADD_x_r_x
   ADD_x_x_r
   ADD_x_r_r
   ADD_r_x_r
   ADD_r_r_x
   ADD_r_r_r

(x: not relative addressing, r: relative addressing)

I think this (though it is painful) really is the best way to go. The different operations have different semantics that should be reflected by their opcode #.

Having a large number of opcodes should not cause any problem for the code generator (X86 has many as well), it is just a pain to write by hand. I would suggest using a perl script or something to help generate the initial ones. In time we could add some sort of macro expansion support to tblgen to help with this, but we don't currently have anything that will help.

-Chris

Alternatively, the code selector could be designed to generate 'mov'
instruction with relative addressing only. The above 'add' instruction
is translated to:

mov r1, r[a0]
mov r2, r[a1]
add r1, r2, r7

but it makes the register allocation/assignment and instruction
scheduling difficult. For the register allocation, one more register
will be needed. For the instruction scheduling, the 'add' and the
associated 'mov's must be moved altogehter.

-Chris