tl;dr, I’d like to add my own instruction, but I’m running into problems due to my lack of x86 encoding/decoding understanding.
Hello all. Currently, I’m working on adding my own x86 instruction. I have done this once before; the basic process I used was:
- Find an unused opcode, e.g. 0xF1 in this table: http://ref.x86asm.net/coder32.html
- Insert an instruction into lib/Target/X86/X86InstrInfo.td using this opcode.
In this case, I used 0xF1, and created the following instruction:
def CACHE_OPERAND_B64i : RIi64<0xF1, AddRegFrm, (outs GR64:$unused),
(ins i64imm:$b), “cache_operand_b_i64\t$b”,
[(int_cache_operand_b_i64 i64imm:$b)]>,
Requires<[In64BitMode]>;
However, when I compile, I’m getting errors of the form:
Error: Primary decode conflict: TEST64ri32 would overwrite CACHE_OPERAND_B64i
ModRM 199
Opcode 247
Context IC_64BIT_REXW
When I look at the definition of TEST64ri32, I see:
let Predicates = [In64BitMode] in
def TEST64ri32 : BinOpRI_F<0xF6, “test”, Xi64, X86testpat, MRM0r>;
It looks like TEST64ri32 is using opcode 0xF6 – why is there a conflict with 0xF1?
Even if I comment out TEST64ri32 (which I recognize is not a good idea), I still get a similar error:
Error: Primary decode conflict: NOT64r would overwrite CACHE_OPERAND_B64i
ModRM 215
Opcode 247
Context IC_64BIT_REXW
Which corresponds to the definition:
def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src1),
“not{q}\t$dst”,
[(set GR64:$dst, (not GR64:$src1))], IIC_UNARY_REG>;
Again, why does 0xF7 conflict with 0xF1?
Thanks,
Gus Smith
P.S. If this looks hacky, that’s because it is; I’m not sure what the correct way to add an instruction into x86 is, if there even is one. Pointers along that line are appreciated.