diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -990,7 +990,7 @@ : Operand, ComplexPattern { let PrintMethod = "printShiftedRegister"; - let MIOperandInfo = (ops regclass, !cast("arith_shift" # width)); + let MIOperandInfo = (ops regclass:$rc, !cast("arith_shift" # width):$shift); } def arith_shifted_reg32 : arith_shifted_reg; @@ -1020,7 +1020,7 @@ : Operand, ComplexPattern { let PrintMethod = "printShiftedRegister"; - let MIOperandInfo = (ops regclass, shiftop); + let MIOperandInfo = (ops regclass:$rc, shiftop:$shift); } def logical_shifted_reg32 : logical_shifted_reg; @@ -1144,13 +1144,13 @@ class arith_extended_reg32 : Operand, ComplexPattern { let PrintMethod = "printExtendedRegister"; - let MIOperandInfo = (ops GPR32, arith_extend); + let MIOperandInfo = (ops GPR32:$rc, arith_extend:$extend); } class arith_extended_reg32to64 : Operand, ComplexPattern { let PrintMethod = "printExtendedRegister"; - let MIOperandInfo = (ops GPR32, arith_extend64); + let MIOperandInfo = (ops GPR32:$rc, arith_extend64:$extend); } def arith_extended_reg32_i32 : arith_extended_reg32; @@ -2485,23 +2485,19 @@ asm, "\t$Rd, $Rn, $Rm", "", [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>, Sched<[WriteISReg, ReadI, ReadISReg]> { - // The operands are in order to match the 'addr' MI operands, so we - // don't need an encoder method and by-name matching. Just use the default - // in-order handling. Since we're using by-order, make sure the names - // do not match. - bits<5> dst; - bits<5> src1; - bits<5> src2; - bits<8> shift; + bits<5> Rd; + bits<5> Rn; + bits<5> Rm__rc; + bits<8> Rm__shift; let Inst{30} = isSub; let Inst{29} = setFlags; let Inst{28-24} = 0b01011; - let Inst{23-22} = shift{7-6}; + let Inst{23-22} = Rm__shift{7-6}; let Inst{21} = 0; - let Inst{20-16} = src2; - let Inst{15-10} = shift{5-0}; - let Inst{9-5} = src1; - let Inst{4-0} = dst; + let Inst{20-16} = Rm__rc; + let Inst{15-10} = Rm__shift{5-0}; + let Inst{9-5} = Rn; + let Inst{4-0} = Rd; let DecoderMethod = "DecodeThreeAddrSRegInstruction"; } @@ -2509,22 +2505,22 @@ class BaseAddSubEReg - : I<(outs dstRegtype:$R1), - (ins src1Regtype:$R2, src2Regtype:$R3), - asm, "\t$R1, $R2, $R3", "", - [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>, + : I<(outs dstRegtype:$Rd), + (ins src1Regtype:$Rn, src2Regtype:$Rm), + asm, "\t$Rd, $Rn, $Rm", "", + [(set dstRegtype:$Rd, (OpNode src1Regtype:$Rn, src2Regtype:$Rm))]>, Sched<[WriteIEReg, ReadI, ReadIEReg]> { bits<5> Rd; bits<5> Rn; bits<5> Rm; - bits<6> ext; + bits<6> Rm__extend; let Inst{30} = isSub; let Inst{29} = setFlags; let Inst{28-24} = 0b01011; let Inst{23-21} = 0b001; let Inst{20-16} = Rm; - let Inst{15-13} = ext{5-3}; - let Inst{12-10} = ext{2-0}; + let Inst{15-13} = Rm__extend{5-3}; + let Inst{12-10} = Rm__extend{2-0}; let Inst{9-5} = Rn; let Inst{4-0} = Rd; @@ -2914,22 +2910,18 @@ : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm), asm, "\t$Rd, $Rn, $Rm", "", pattern>, Sched<[WriteISReg, ReadI, ReadISReg]> { - // The operands are in order to match the 'addr' MI operands, so we - // don't need an encoder method and by-name matching. Just use the default - // in-order handling. Since we're using by-order, make sure the names - // do not match. - bits<5> dst; - bits<5> src1; - bits<5> src2; - bits<8> shift; + bits<5> Rd; + bits<5> Rn; + bits<5> Rm__rc; + bits<8> Rm__shift; let Inst{30-29} = opc; let Inst{28-24} = 0b01010; - let Inst{23-22} = shift{7-6}; + let Inst{23-22} = Rm__shift{7-6}; let Inst{21} = N; - let Inst{20-16} = src2; - let Inst{15-10} = shift{5-0}; - let Inst{9-5} = src1; - let Inst{4-0} = dst; + let Inst{20-16} = Rm__rc; + let Inst{15-10} = Rm__shift{5-0}; + let Inst{9-5} = Rn; + let Inst{4-0} = Rd; let DecoderMethod = "DecodeThreeAddrSRegInstruction"; } diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -3898,26 +3898,26 @@ def t2TBB : T2I<(outs), (ins addrmode_tbb:$addr), IIC_Br, "tbb", "\t$addr", []>, Sched<[WriteBrTbl]> { - bits<4> Rn; - bits<4> Rm; + bits<4> addr__Rn; + bits<4> addr__Rm; let Inst{31-20} = 0b111010001101; - let Inst{19-16} = Rn; + let Inst{19-16} = addr__Rn; let Inst{15-5} = 0b11110000000; let Inst{4} = 0; // B form - let Inst{3-0} = Rm; + let Inst{3-0} = addr__Rm; let DecoderMethod = "DecodeThumbTableBranch"; } def t2TBH : T2I<(outs), (ins addrmode_tbh:$addr), IIC_Br, "tbh", "\t$addr", []>, Sched<[WriteBrTbl]> { - bits<4> Rn; - bits<4> Rm; + bits<4> addr__Rn; + bits<4> addr__Rm; let Inst{31-20} = 0b111010001101; - let Inst{19-16} = Rn; + let Inst{19-16} = addr__Rn; let Inst{15-5} = 0b11110000000; let Inst{4} = 1; // H form - let Inst{3-0} = Rm; + let Inst{3-0} = addr__Rm; let DecoderMethod = "DecodeThumbTableBranch"; } diff --git a/llvm/utils/TableGen/CodeEmitterGen.cpp b/llvm/utils/TableGen/CodeEmitterGen.cpp --- a/llvm/utils/TableGen/CodeEmitterGen.cpp +++ b/llvm/utils/TableGen/CodeEmitterGen.cpp @@ -105,7 +105,14 @@ // operand number. Non-matching operands are assumed to be in // order. unsigned OpIdx; - if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) { + if (VarName.find("__") != std::string::npos) { + // If there's __ in the name, we'll assume it MUST match by name to a suboperand. + std::string OpName = "$"; + OpName += VarName; + OpName.replace(OpName.find("__"), 2, "."); + std::pair SubOp = CGI.Operands.ParseOperandName(OpName, true); + OpIdx = CGI.Operands[SubOp.first].MIOperandNo + SubOp.second; + } else if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) { // Get the machine operand number for the indicated operand. OpIdx = CGI.Operands[OpIdx].MIOperandNo; assert(!CGI.Operands.isFlatOperandNotEmitted(OpIdx) &&