Tablegen Decode Conflict error with no obvious conflict

Hi all, first time poster, short time lurker. I’ve been banging my head trying to add an instruction to a non-official LLVM instruction set, created by Fotis Loukos here GitHub - fotisl/tms320c64x-fwtools: Tools for reverse engineering firmware running on the TMS320C64x DSP for a TMS320C64x DSP for the purpose of creating a Capstone disassembler. I wanted to make some modifications to his instruction set to add an ‘instruction’ added by the TMS320C64x+ DSP, calling an fphead (short for fetch packet head). Basically this instruction is a marker used to support 16-bit instructions in addition to the 32-bit instructions in the TMS320C64x.

However, after adding this error, running the llvm-tblgen -gen-disassembler command results in a decode conflict. The instruction is uniquely identified by the first 4 bits 1110 Inst{31-28} which is a reserved bit pattern in the TMS320C64x and should not be used by any instructions. When I add this new instruction, along with its other variable fields, i get a decode error. There are 5 other instructions which border this bit-range with fixed bit values going up to bit 27 Inst{27-x}. If I either remove those 5 instructions, or change their bit patterns to go up to Inst{26-x} (incorrect, just a test), the disassembler generation runs fine with the new fphead instruction. In addition, if I change the fphead instruction to be defined by only the first 3 bits 111 Inst{31-29} the generation ALSO succeeds.

My work is documented here Added fphead 'instruction' and test scripts with results showing the … · trogdan/tms320c64x-tablegen@4b1caa4 · GitHub and includes the output from the decode-conflict of llvm-tblgen as well as the command I run. The failure also occurs with llvm-14, i just happened to be on a system that couldn’t install llvm-14 at the time.

The instruction set is defined at the below link, but warning, the IS is very complicated.

I’ve also included the conflict output here, for posterity sake.

Removing the instruction defs #1-#5 or #6, results in a successful disassemble table generation

1) BNOP_s10_ri ____00001_____00____0011011000__
2) B_s6_r      ____00000_____00000_0011011000__
3) B_s7_irp    ____00000001100000000000111000__
4) B_s7_nrp    ____00000001110000000000111000__
5) NOP_n       ____00000000000____00000000000__
6) FPHEAD      1110____________________________

Oh yeah, guess I didn’t ask. Does anyone know why I would be getting the decode error?

For instructions 1-5 listed, bits 31-28 are cond and bit 27 is condzero, both of which are operands for the instructions listed and thus are wildcard values in the conflict checker. So as far as TableGen is concerned, any of those five instructions when given cond=111 condzero=0 overlap with FPHEAD.

I think you mean bits 31-29 are cond and bit 28 is condzero, and are the wildcard values in the conflict checker. This was the concern I had, but thought I had ruled that out when I was wrong with this when I was successful by only setting bits 31-29, and leaving bit 28, 1, and 0 as the wildcards.

Is there anyway to not use a wildcard for bits 31-28 in the TMS320C64xInst? like, either an acceptable list of bit patterns, or some kind of “all bits are wildcard, but not 1110”? Can i remove the wildcard from TMS320C64xInst and implement it in each lower subclass? Not sure how to define this mutual exclusive pattern.

@jrtc27 Is there no way to have one instruction have a wildcard, and another instruction to specify a field for that wildcard? I’m at a loss for how to handle this. Basically, this language has conditional instructions, defined by bits 31-29 (creg) and bit 28 (z). You can see in the below table. So any ‘normal’ instruction can use one of the non-reserved bit patterns to define what condition it executes on. A creg value of 111 is reserved by definition for conditional instructions, and although the FPHEAD is technically not an instruction, it uses this reserved bit pattern for the instruction processor to recognize it as such. This is from the Texas Instruments document spru732j.

I don’t believe so. You’ll likely need a separate DecoderNamespace.

Oh I guess this is what hasCompleteDecoder is for; you’re meant to set that for any instruction where some of its wildcard combinations aren’t legal (or at least in ways that collide with other instructions).

Thanks for the tip. I read through hasCompleteDecoder and thought this would solve the problem, but unfortunately it doesn’t. I still get the decode conflict. Even REMOVING the condzero and cond vars (effectively removing the wildcard) didn’t remove the conflict.

I ended up adding another instruction that overlapped the creg field, a CALLP instruction, added by the TMS320C64x+. This has 0001 for it’s first 4 bits. For now, I was able to remove the leading 27th bit from the 5 instructions which seem to be causing the conflict. This allows me to specify the patterns I need for bits 31-28, and, from perusing the bit patterns, shouldn’t cause a decode error. I am still thinking this is possibly a bug in the Tablegen decode error, and will probably submit a bug ticket at some point, and spend some more time stepping through the Decoder to have more information to provide.