[llvm-dev] Stuck with instruction in tablegen

Michael Stellmann via llvm-dev llvm-dev at lists.llvm.org
Mon Jul 9 21:32:36 PDT 2018


Hi,

I'm trying to revive jacobly0's Z80 back-end (from 
https://github.com/jacobly0/llvm-z80) and build it with a current 
version of LLVM.

Apart from some interface changes, I'm stuck at building the tables. 
Specifically, the generation of the DAG instruction selector causes an 
assertion in the table generator:

     Assertion failed: Ops.size() >= NumSrcResults && "Didn't provide 
enough results"

I tried to fix the problem by searched in the documentation and in other 
table sources, but to no avail. Even stepping through that code in the 
debugger (MatcherGen::EmitResultCode()) didn't help me to find the cause 
of the problem. The instruction tables description are quite unique in 
all the officially supported CPU models, I couldn't find any similar 
code that could help me figuring out what is going wrong.

So I isolated the table sources to a minimum of two simple 
base-instructions and attached these for reproduction of the problem 
(not sure if the attachment gets through).

The table generation is done with:

     llvm-tblgen -gen-dag-isel -I=<path-to-llvm-include> -o=out.inc Z80.td

The first instruction in Z80InstrInfo.td is a unary instruction, that 
does a rotate left of a byte in memory, resulting in the leftmost bit 
being placed in the Carry flag - and changing the memory contents at the 
pointer's address (in Z80: "RLC (HL)", I expect).
The table generation completes without errors with just this instruction 
(by commenting the last line in Z80InstrInfo.td).

The second one is a binary instruction, adding the contents of a pointer 
and a register, with results in register A and F (Z80: "ADD A,(HL)").

A is an 8-bit register. The Z80 ALU can only do 8 bit arithmetic with 
that register and another param. The two instructions don't seem to 
require a specific register for the address in the table class, so the 
RegisterInfo table is not defined so far in the minimized version

The problem is in Z80InstrInfo.td, in the following section of 
"BinOp8RF", which is used by the "defm" line that generates the "add" 
instruction pattern:

     multiclass BinOp8RF<Prefix prefix, bits<3> opcode, string mnemonic,
                         bit compare = 0> {
       let isCompare = compare, Defs = [A, F], Uses = [A] in {
         def 8ap : I8 <prefix, {0b10, opcode, 0b110}, mnemonic, "\ta, 
$src", "",
                       (outs), (ins   ptr:$src),
                       [(set A, F,
                            (Z80add_flag
                                 A, (i8 (load   iPTR:$src))))]>;
       }
     }

and the parameters:

     def SDTBinOpRF  : SDTypeProfile<2, 2, [SDTCisInt<0>,
                                            SDTCisFlag<1>,
                                            SDTCisSameAs<2, 0>,
                                            SDTCisSameAs<3, 0>]>;

     def Z80add_flag      : SDNode<"Z80ISD::ADD",     SDTBinOpRF, 
[SDNPCommutative]>;


The unary instruction builds fine, which can be checked by commenting 
out the generation of the binary instruction in the last line of the 
attached Z80InstrInfo.td.

The log in Github indicates that this section was present for over a 
year, so I assume that it did work at some time in the past.

My attempts to fixing the instruction failed with other errors, pointing 
specifically to the specific problems I introduced with the change, e.g. 
parameter number mismatch or wrong type, so above (and attached) is the 
unmodified version.

Any help is appreciated!

Michael


-------------- next part --------------
A non-text attachment was scrubbed...
Name: Z80-min-instruction-table-assertion.zip
Type: application/octet-stream
Size: 3014 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180710/5990a313/attachment.obj>


More information about the llvm-dev mailing list