Hello LLVM, My target has a complex relaxation hierarchy. Perhaps a modest TableGen extension would help consolidate most of the work involved in choosing a relaxed opcode. I also notice the x86 relaxation code with a comment wondering if TableGen could improve life. Does the following outline sound interesting? 1) Add a new field of type 'Instruction' to the Instruction class called "RelaxedInstr" 2) Target instructions optionally set RelaxedInstr, as in: def JMP32 : Instruction<stuff>; // no relaxation from here def JMP8 : Instruction<stuff> { let RelaxedInstr = JMP32; // relax to 32-bit jmp } 3) The tblgen -gen-instr-info processor uses RelaxedInstruction to create the RelaxedOpcode field for the corresponding MCInst. The RelaxedOpcode field contains the target specific opcode (an enumeration value) of the specified RelaxedInstr. 4) From C++, targets access the RelaxedOpcode field as needed, akin to TSFlags. This eliminates the headaches of massive opcode switch statements in targets like mine. It's unclear to me how to handle the default value of an 'Instruction' when no relaxation exists. Regards, -steve
On Thu, Nov 13, 2014 at 1:00 PM, Steve King <steve at metrokings.com> wrote:> Hello LLVM, > > My target has a complex relaxation hierarchy. Perhaps a modest > TableGen extension would help consolidate most of the work involved in > choosing a relaxed opcode. I also notice the x86 relaxation code with > a comment wondering if TableGen could improve life. > > Does the following outline sound interesting? > > 1) Add a new field of type 'Instruction' to the Instruction class > called "RelaxedInstr" > > 2) Target instructions optionally set RelaxedInstr, as in: > > def JMP32 : Instruction<stuff>; // no relaxation from here > def JMP8 : Instruction<stuff> { > let RelaxedInstr = JMP32; // relax to 32-bit jmp > } > > 3) The tblgen -gen-instr-info processor uses RelaxedInstruction to > create the RelaxedOpcode field for the corresponding MCInst. The > RelaxedOpcode field contains the target specific opcode (an > enumeration value) of the specified RelaxedInstr. > > 4) From C++, targets access the RelaxedOpcode field as needed, akin to > TSFlags. This eliminates the headaches of massive opcode switch > statements in targets like mine. > > It's unclear to me how to handle the default value of an 'Instruction' > when no relaxation exists. > >It is possible to get the same result using tablegen instruction mappings. http://llvm.org/docs/HowToUseInstrMappings.html For Octasic's Opus architecture, we use instruction mappings extensively to describe relation between instructions, including relaxed vs non-relaxed jump opcode. Tablegen will generate the huge switch case automatically. Francois Pichet Octasic. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20141113/3199b425/attachment.html>
Hi Francois, Thanks for the pointer. Unfortunately, I'm having trouble with this idea. To implement getRelaxedOpcode InstrMapping, I need to search for some specific property of the relaxed opcode. I'm not sure how to create this searchable property without something grossly artificial. For example, SystemZ does this: // Return the memory form of a register instruction. def getMemOpcode : InstrMapping { let FilterClass = "InstSystemZ"; let RowFields = ["OpKey"]; let ColFields = ["OpType"]; let KeyCol = ["reg"]; let ValueCols = [["mem"]]; } in which they look for instructions with property OpType to be exactly "mem" or "reg" with both instruction having the same OpKey. My relaxation problem is a much more arbitrary progression from one instruction to its relaxation. The underlying instructions don't match nor do field sizes grow dependably. Cheers, -steve On Thu, Nov 13, 2014 at 10:32 AM, Francois Pichet <pichet2000 at gmail.com> wrote:> > On Thu, Nov 13, 2014 at 1:00 PM, Steve King <steve at metrokings.com> wrote: >> >> Hello LLVM, >> >> My target has a complex relaxation hierarchy. Perhaps a modest >> TableGen extension would help consolidate most of the work involved in >> choosing a relaxed opcode. I also notice the x86 relaxation code with >> a comment wondering if TableGen could improve life. >> >> Does the following outline sound interesting? >> >> 1) Add a new field of type 'Instruction' to the Instruction class >> called "RelaxedInstr" >> >> 2) Target instructions optionally set RelaxedInstr, as in: >> >> def JMP32 : Instruction<stuff>; // no relaxation from here >> def JMP8 : Instruction<stuff> { >> let RelaxedInstr = JMP32; // relax to 32-bit jmp >> } >> >> 3) The tblgen -gen-instr-info processor uses RelaxedInstruction to >> create the RelaxedOpcode field for the corresponding MCInst. The >> RelaxedOpcode field contains the target specific opcode (an >> enumeration value) of the specified RelaxedInstr. >> >> 4) From C++, targets access the RelaxedOpcode field as needed, akin to >> TSFlags. This eliminates the headaches of massive opcode switch >> statements in targets like mine. >> >> It's unclear to me how to handle the default value of an 'Instruction' >> when no relaxation exists. >> > > It is possible to get the same result using tablegen instruction mappings. > http://llvm.org/docs/HowToUseInstrMappings.html > > For Octasic's Opus architecture, we use instruction mappings extensively to > describe relation between instructions, including relaxed vs non-relaxed > jump opcode. Tablegen will generate the huge switch case automatically. > > Francois Pichet > Octasic. > >