Jaroslav Sýkora
2012-Nov-02 16:44 UTC
[LLVMdev] Alternate instruction encoding for subtargets - SOLVED
>> Can I tell tablegen to have two encodings and switch between them >> using a predicate?After some deliberations, I modified tablegen to generate several versions of the GenCodeEmitter file. My tablegen now accepts a new command line parameter called "emitter-instfld". This specifies the name of the field in Instruction that holds the encoded bytes. In my target's td files I simply specify both encodings at the same time. This is my target's Instruction base class. It defines the traditional field Inst and also an additional field Inst6 that holds the alternate encodings for the KCPSM6 sub-target. /// base class - a picoblaze instruction class InstPB<Format form, dag outs, dag ins, string asmstr, list<dag> pattern> : Instruction { field bits<18> Inst; // for KCPSM3 field bits<18> Inst6; // for KCPSM6 Format Form = form; bits<4> FormBits = Form.Value; // TSFlags layout should be kept in sync with PBlazeInstrInfo.h. let TSFlags{3-0} = FormBits; let Namespace = "PB"; dag OutOperandList = outs; dag InOperandList = ins; let AsmString = asmstr; let Pattern = pattern; } My instruction formats classes encode the same instruction twice: into the Inst and Inst6 fields. The operation subcode which is different between the sub-targets is also specified twice in the class parameters as the op13 (KCPSM3) and op16 (KCPSM6) argument. class AJumpCC<bits<6> op13, bits<6> op16, dag outs, dag ins, string asmstr, list<dag> pattern> : InstPB<FCCAA, outs, ins, asmstr, pattern> { bits<2> cc; // condition codes bits<12> dst; // address field // encode KCPSM3 let Inst{17-12} = op13; let Inst{11-10} = cc; let Inst{9-0} = dst{9-0}; // encode KCPSM6 let Inst6{17-16} = op16{5-4}; let Inst6{15-14} = cc; let Inst6{13-12} = op16{1-0}; let Inst6{11-0} = dst; } Each instruction def in the td file was augmented to specify the new op16 opcode for the new sub-target. Hence, no instructions are duplicated and this change has no effect on the custom lowering passes that can continue to hand-insert specific target instructions. def JUMP_cond : AJumpCC<0b110101, 0b110010, (outs), (ins i8imm:$cc, brtarget:$dst), "jump \t$cc, $dst", [(PBjumpcc simm8:$cc, bb:$dst)]>; Finally, I modified the build system to call "tablegen -gen-emitter" twice, first with "-emitter-instfld=Inst" to generate the encoder for KCPSM3 and then with "-emitter-instfld=Inst6" to generate the encoder for KCPSM6. This creates two *GenCodeEmitter.inc files that are included in the MCCodeEmitter (conflicting function names taken care of by the preprocessor...), and henceforth the encoder implementation can be dynamically switched in runtime according to the current -mcpu. Curious readers may find the hacked tablegen attached. Cheers, Jara -- Space--the final frontier! http://linkedin.com/in/jaroslavsykora -------------- next part -------------- A non-text attachment was scrubbed... Name: tablegen-hack.patch Type: application/octet-stream Size: 3052 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20121102/5f0d8d9d/attachment.obj>