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
On Mar 19, 2010, at 11:04 AM, Jakob Stoklund Olesen wrote:>>> 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.Ah, gotcha. LDM is a particularly evil instruction to model. I agree it is best to model them as a variable number of outputs.> 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.Ok.>>> 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 registersI would prefer to spell this as: def LDM : AXI4ld<(outs reglist:$dsts), (ins addrmode4:$addr, pred:$p), Would this work? You could change 'reglist' to have one fixed operand and the rest variable? There is no reason to support the 'no output' form of reglist. -Chris
Jakob Stoklund Olesen
2010-Mar-22 23:46 UTC
[LLVMdev] Instruction with variable number of outputs
On Mar 22, 2010, at 4:28 PM, Chris Lattner wrote:>>>> >>>> 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 > > I would prefer to spell this as: > > def LDM : AXI4ld<(outs reglist:$dsts), (ins addrmode4:$addr, pred:$p), > > Would this work? You could change 'reglist' to have one fixed operand and the rest variable? There is no reason to support the 'no output' form of reglist.That spelling is better, but you probably want to keep all the reglist operands optional. We don't need to support an empty reglist, but since fixed outputs go first on the machine instruction, the reglist would be broken up: reglist[0], addr[0], addr[1], pred[0], pred[1], reglist[1], reglist[2], ... We don't want that. We want this: addr[0], addr[1], pred[0], pred[1], reglist[0], reglist[1], reglist[2], ... So we need to change tablegen to support variable_ops in MIOperandInfo on the last element of either outs or ins. I'll look into it when I get the time. /jakob
Possibly Parallel 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