[LLVMdev] Instruction with variable number of outputs

Jakob Stoklund Olesen stoklund at 2pi.dk
Fri Mar 19 11:04:04 PDT 2010


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






More information about the llvm-dev mailing list