Jakob Stoklund Olesen
2010-Mar-19 14:46 UTC
[LLVMdev] Instruction with variable number of outputs
Hi, After Bob fixed the two-address format of the ARM ldm/stm instructions, a problem remains. The load multiple instruction looks like: // A list of registers separated by comma. Used by load/store multiple. def reglist : Operand<i32> { let PrintMethod = "printRegisterList"; } def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p, reglist:$dsts, variable_ops), IndexModeNone, LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $dsts", "", []>; Tablegen produces an instruction description with 5 input operands: 2 for $addr, 2 for $p, and 1 for $dsts. But $dsts and the following variable_ops are all outputs! The description should only have 4 operands + variable_ops. How can you specify a named, variable list of output operands? Perhaps this could be made to work: def reglist : Operand<i32> { let PrintMethod = "printRegisterList"; let MIOperandInfo = (ops variable_ops); } def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p, reglist:$dsts),
On Mar 19, 2010, at 7:46 AM, Jakob Stoklund Olesen wrote:> Hi, > > After Bob fixed the two-address format of the ARM ldm/stm instructions, a problem remains. The load multiple instruction looks like: > > // A list of registers separated by comma. Used by load/store multiple. > def reglist : Operand<i32> { > let PrintMethod = "printRegisterList"; > } > > def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p, > reglist:$dsts, variable_ops), > IndexModeNone, LdStMulFrm, IIC_iLoadm, > "ldm${addr:submode}${p}\t$addr, $dsts", "", []>; > > Tablegen produces an instruction descriptionOk, you mean TargetInstrDesc, right?> with 5 input operands: 2 for $addr, 2 for $p, and 1 for $dsts. But $dsts and the following variable_ops are all outputs!Right, variable_ops means that it takes a variable number of operands, not that an operand has a variable number of registers.> The description should only have 4 operands + variable_ops. > > How can you specify a named, variable list of output operands?Why do you need to do this? You currently can't do it. -Chris> > Perhaps this could be made to work: > > def reglist : Operand<i32> { > let PrintMethod = "printRegisterList"; > let MIOperandInfo = (ops variable_ops); > } > > def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p, reglist:$dsts), > > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Jakob Stoklund Olesen
2010-Mar-19 18:04 UTC
[LLVMdev] Instruction with variable number of outputs
On Mar 19, 2010, at 10:28 AM, Chris Lattner wrote:> > On Mar 19, 2010, at 7:46 AM, Jakob Stoklund Olesen wrote: > >> Hi, >> >> After Bob fixed the two-address format of the ARM ldm/stm instructions, a problem remains. The load multiple instruction looks like: >> >> // A list of registers separated by comma. Used by load/store multiple. >> def reglist : Operand<i32> { >> let PrintMethod = "printRegisterList"; >> } >> >> def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p, >> reglist:$dsts, variable_ops), >> IndexModeNone, LdStMulFrm, IIC_iLoadm, >> "ldm${addr:submode}${p}\t$addr, $dsts", "", []>; >> >> Tablegen produces an instruction description > > Ok, you mean TargetInstrDesc, right?Yes.>> with 5 input operands: 2 for $addr, 2 for $p, and 1 for $dsts. But $dsts and the following variable_ops are all outputs! > > Right, variable_ops means that it takes a variable number of operands, not that an operand has a variable number of registers. > >> The description should only have 4 operands + variable_ops. >> >> How can you specify a named, variable list of output operands? > > Why do you need to do this? You currently can't do it.Because an instruction like LDM loads a variable number of registers. When it specifies "reglist:$dsts, variable_ops", those are really output registers, the registers being loaded. I am assuming that the operands on a machine instruction are, in order: fixed outs, fixed ins, variable ops, implicit ops. The variable ops can be inputs or outputs. As far as I can tell, this is only a problem with verification. The operand corresponding to $dsts is a <def>, but the TargetInstrDesc says that it is one of the fixed inputs. The following operands are fine as they fall in the variable_ops part of the instruction. I need a way of referring to the variable_ops by name without forcing the first operand to be an input.>> def reglist : Operand<i32> { >> let PrintMethod = "printRegisterList"; >> let MIOperandInfo = (ops variable_ops); >> } >> >> def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p, reglist:$dsts),This syntax is not ideal, because reglist:$dsts is a variable list of output operands. But at least there is no extra input operand. I need a way of describing the LDM instruction with: Fixed outputs: none Fixed inputs: addr and pred Variable ops: list of output registers This produces the right TargetInstrDesc:>> def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p, variable_ops)But now there is no way of referring to the reglist in the asm pattern, and there is no way of specifying that the reglist should be printed with "printRegisterList" The basic problem is that variable_ops require an 'anchor operand' to get a $name and to specify a PrintMethod. The anchor operand is forced to be an input by the current syntax, as far as I can tell. /jakob
Apparently Analagous Threads
- [LLVMdev] Instruction with variable number of outputs
- [LLVMdev] Instruction with variable number of outputs
- [LLVMdev] Instruction with variable number of outputs
- [LLVMdev] Distinguish variadic register defines/uses in MCInstrDesc?
- MC Assembler / tablegen: actually parsing variable_ops