diff options
Diffstat (limited to 'llvm/lib/Target/ARM/ARMInstrThumb2.td')
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb2.td | 116 |
1 files changed, 103 insertions, 13 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index 521cb0695384..610a71d68ec8 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -1022,9 +1022,9 @@ multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, SDNode opnode, /// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns /// for a binary operation that produces a value and use the carry /// bit. It's not predicable. -let Defs = [CPSR], Uses = [CPSR] in { multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, SDNode opnode, - bit Commutable = 0> { + bit Commutable = 0, bit PostISelHook = 0> { + let Defs = [CPSR], Uses = [CPSR], hasPostISelHook = PostISelHook in { // shifted imm def ri : T2sTwoRegImm<(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi, opc, "\t$Rd, $Rn, $imm", @@ -1058,7 +1058,26 @@ multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, SDNode opnode, let Inst{26-25} = 0b01; let Inst{24-21} = opcod; } -} + } + // Shortened forms + def : t2InstAlias<!strconcat(opc, "${s}${p}", ".w $Rdn, $imm"), + (!cast<Instruction>(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn, t2_so_imm:$imm, pred:$p, + cc_out:$s)>; + def : t2InstAlias<!strconcat(opc, "${s}${p}", ".w $Rdn, $Rm"), + (!cast<Instruction>(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p, + cc_out:$s)>; + def : t2InstAlias<!strconcat(opc, "${s}${p}", ".w $Rdn, $ShiftedRm"), + (!cast<Instruction>(NAME#"rs") rGPR:$Rdn, rGPR:$Rdn, t2_so_reg:$ShiftedRm, pred:$p, + cc_out:$s)>; + def : t2InstAlias<!strconcat(opc, "${s}${p}", "$Rdn, $imm"), + (!cast<Instruction>(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn, t2_so_imm:$imm, pred:$p, + cc_out:$s)>; + def : t2InstAlias<!strconcat(opc, "${s}${p}", "$Rdn, $Rm"), + (!cast<Instruction>(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p, + cc_out:$s)>; + def : t2InstAlias<!strconcat(opc, "${s}${p}", "$Rdn, $ShiftedRm"), + (!cast<Instruction>(NAME#"rs") rGPR:$Rdn, rGPR:$Rdn, t2_so_reg:$ShiftedRm, pred:$p, + cc_out:$s)>; } /// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift / @@ -1577,6 +1596,46 @@ def t2LDR_PRE_imm : t2AsmPseudo<"ldr${p}.w $Rt, $addr!", def t2LDR_POST_imm : t2AsmPseudo<"ldr${p}.w $Rt, $Rn, $imm", (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>; +// A7.7.46 LDRB (immediate) T3 +// .w suffixes; Constraints can't be used on t2InstAlias to describe +// "$Rn = $Rn_wb" on POST or "$addr.base = $Rn_wb" on PRE. +def t2LDRB_OFFSET_imm : t2AsmPseudo<"ldrb${p}.w $Rt, $addr", + (ins GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>; +def t2LDRB_PRE_imm : t2AsmPseudo<"ldrb${p}.w $Rt, $addr!", + (ins GPR:$Rt, t2addrmode_imm8_pre:$addr, pred:$p)>; +def t2LDRB_POST_imm : t2AsmPseudo<"ldrb${p}.w $Rt, $Rn, $imm", + (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>; + +// A7.7.55 LDRH (immediate) T3 +// .w suffixes; Constraints can't be used on t2InstAlias to describe +// "$Rn = $Rn_wb" on POST or "$addr.base = $Rn_wb" on PRE. +def t2LDRH_OFFSET_imm : t2AsmPseudo<"ldrh${p}.w $Rt, $addr", + (ins GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>; +def t2LDRH_PRE_imm : t2AsmPseudo<"ldrh${p}.w $Rt, $addr!", + (ins GPR:$Rt, t2addrmode_imm8_pre:$addr, pred:$p)>; +def t2LDRH_POST_imm : t2AsmPseudo<"ldrh${p}.w $Rt, $Rn, $imm", + (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>; + +// A7.7.59 LDRSB (immediate) T2 +// .w suffixes; Constraints can't be used on t2InstAlias to describe +// "$Rn = $Rn_wb" on POST or "$addr.base = $Rn_wb" on PRE. +def t2LDRSB_OFFSET_imm : t2AsmPseudo<"ldrsb${p}.w $Rt, $addr", + (ins GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>; +def t2LDRSB_PRE_imm : t2AsmPseudo<"ldrsb${p}.w $Rt, $addr!", + (ins GPR:$Rt, t2addrmode_imm8_pre:$addr, pred:$p)>; +def t2LDRSB_POST_imm : t2AsmPseudo<"ldrsb${p}.w $Rt, $Rn, $imm", + (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>; + +// A7.7.63 LDRSH (immediate) T2 +// .w suffixes; Constraints can't be used on t2InstAlias to describe +// "$Rn = $Rn_wb" on POST or "$addr.base = $Rn_wb" on PRE. +def t2LDRSH_OFFSET_imm : t2AsmPseudo<"ldrsh${p}.w $Rt, $addr", + (ins GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>; +def t2LDRSH_PRE_imm : t2AsmPseudo<"ldrsh${p}.w $Rt, $addr!", + (ins GPR:$Rt, t2addrmode_imm8_pre:$addr, pred:$p)>; +def t2LDRSH_POST_imm : t2AsmPseudo<"ldrsh${p}.w $Rt, $Rn, $imm", + (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>; + // LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110). // Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4 class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii> @@ -1743,6 +1802,26 @@ def t2STR_PRE_imm : t2AsmPseudo<"str${p}.w $Rt, $addr!", def t2STR_POST_imm : t2AsmPseudo<"str${p}.w $Rt, $Rn, $imm", (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>; +// A7.7.163 STRB (immediate) T3 +// .w suffixes; Constraints can't be used on t2InstAlias to describe +// "$Rn = $Rn_wb" on POST or "$addr.base = $Rn_wb" on PRE. +def t2STRB_OFFSET_imm : t2AsmPseudo<"strb${p}.w $Rt, $addr", + (ins GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>; +def t2STRB_PRE_imm : t2AsmPseudo<"strb${p}.w $Rt, $addr!", + (ins GPR:$Rt, t2addrmode_imm8_pre:$addr, pred:$p)>; +def t2STRB_POST_imm : t2AsmPseudo<"strb${p}.w $Rt, $Rn, $imm", + (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>; + +// A7.7.170 STRH (immediate) T3 +// .w suffixes; Constraints can't be used on t2InstAlias to describe +// "$Rn = $Rn_wb" on POST or "$addr.base = $Rn_wb" on PRE. +def t2STRH_OFFSET_imm : t2AsmPseudo<"strh${p}.w $Rt, $addr", + (ins GPR:$Rt, t2addrmode_negimm8:$addr, pred:$p)>; +def t2STRH_PRE_imm : t2AsmPseudo<"strh${p}.w $Rt, $addr!", + (ins GPR:$Rt, t2addrmode_imm8_pre:$addr, pred:$p)>; +def t2STRH_POST_imm : t2AsmPseudo<"strh${p}.w $Rt, $Rn, $imm", + (ins GPR:$Rt, addr_offset_none:$Rn, t2am_imm8_offset:$imm, pred:$p)>; + // STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly // only. // Ref: A8.6.193 STR (immediate, Thumb) Encoding T4 @@ -2365,15 +2444,17 @@ def : T2Pat<(ARMsubs GPRnopc:$Rn, rGPR:$Rm), (t2SUBSrr $Rn, $Rm)>; def : T2Pat<(ARMsubs GPRnopc:$Rn, t2_so_reg:$ShiftedRm), (t2SUBSrs $Rn, t2_so_reg:$ShiftedRm)>; -let hasPostISelHook = 1 in { -defm t2ADC : T2I_adde_sube_irs<0b1010, "adc", ARMadde, 1>; -defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc", ARMsube>; -} +defm t2ADC : T2I_adde_sube_irs<0b1010, "adc", ARMadde, 1, 1>; +defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc", ARMsube, 0, 1>; def : t2InstSubst<"adc${s}${p} $rd, $rn, $imm", (t2SBCri rGPR:$rd, rGPR:$rn, t2_so_imm_not:$imm, pred:$p, s_cc_out:$s)>; +def : t2InstSubst<"adc${s}${p} $rdn, $imm", + (t2SBCri rGPR:$rdn, rGPR:$rdn, t2_so_imm_not:$imm, pred:$p, s_cc_out:$s)>; def : t2InstSubst<"sbc${s}${p} $rd, $rn, $imm", (t2ADCri rGPR:$rd, rGPR:$rn, t2_so_imm_not:$imm, pred:$p, s_cc_out:$s)>; +def : t2InstSubst<"sbc${s}${p} $rdn, $imm", + (t2ADCri rGPR:$rdn, rGPR:$rdn, t2_so_imm_not:$imm, pred:$p, s_cc_out:$s)>; def : t2InstSubst<"add${s}${p}.w $rd, $rn, $imm", (t2SUBri rGPR:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>; @@ -2726,10 +2807,10 @@ def t2RRX : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi, } let isCodeGenOnly = 1, Defs = [CPSR] in { -def t2MOVsrl_flag : T2TwoRegShiftImm< +def t2MOVsrl_glue : T2TwoRegShiftImm< (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi, "lsrs", ".w\t$Rd, $Rm, #1", - [(set rGPR:$Rd, (ARMsrl_flag rGPR:$Rm))]>, + [(set rGPR:$Rd, (ARMsrl_glue rGPR:$Rm))]>, Sched<[WriteALU]> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; @@ -2741,10 +2822,10 @@ def t2MOVsrl_flag : T2TwoRegShiftImm< let Inst{14-12} = 0b000; let Inst{7-6} = 0b01; } -def t2MOVsra_flag : T2TwoRegShiftImm< +def t2MOVsra_glue : T2TwoRegShiftImm< (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi, "asrs", ".w\t$Rd, $Rm, #1", - [(set rGPR:$Rd, (ARMsra_flag rGPR:$Rm))]>, + [(set rGPR:$Rd, (ARMsra_glue rGPR:$Rm))]>, Sched<[WriteALU]> { let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; @@ -4193,7 +4274,7 @@ def t2RFEIA : T2RFE<0b111010011001, let isReturn = 1, isBarrier = 1, isTerminator = 1, Defs = [PC] in def t2SUBS_PC_LR : T2I <(outs), (ins imm0_255:$imm), NoItinerary, "subs", "\tpc, lr, $imm", - [(ARMintretflag imm0_255:$imm)]>, + [(ARMintretglue imm0_255:$imm)]>, Requires<[IsThumb2,IsNotMClass]> { let Inst{31-8} = 0b111100111101111010001111; @@ -4699,8 +4780,12 @@ def t2CDP2 : T2Cop<0b1111, (outs), (ins p_imm:$cop, imm0_15:$opc1, // Reading thread pointer from coprocessor register +def : T2Pat<(ARMthread_pointer), (t2MRC 15, 0, 13, 0, 2)>, + Requires<[IsThumb2, IsReadTPTPIDRURW]>; def : T2Pat<(ARMthread_pointer), (t2MRC 15, 0, 13, 0, 3)>, - Requires<[IsThumb2, IsReadTPHard]>; + Requires<[IsThumb2, IsReadTPTPIDRURO]>; +def : T2Pat<(ARMthread_pointer), (t2MRC 15, 0, 13, 0, 4)>, + Requires<[IsThumb2, IsReadTPTPIDRPRW]>; //===----------------------------------------------------------------------===// // ARMv8.1 Privilege Access Never extension @@ -4847,6 +4932,11 @@ def : t2InstAlias<"adc${s}${p} $Rd, $Rn, $Rm", def : t2InstAlias<"adc${s}${p} $Rd, $Rn, $ShiftedRm", (t2ADCrs rGPR:$Rd, rGPR:$Rn, t2_so_reg:$ShiftedRm, pred:$p, cc_out:$s)>; +def : t2InstAlias<"adc${s}${p} $Rdn, $Rm", + (t2ADCrr rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>; +def : t2InstAlias<"adc${s}${p} $Rdn, $ShiftedRm", + (t2ADCrs rGPR:$Rdn, rGPR:$Rdn, t2_so_reg:$ShiftedRm, + pred:$p, cc_out:$s)>; // Aliases for SBC without the ".w" optional width specifier. def : t2InstAlias<"sbc${s}${p} $Rd, $Rn, $Rm", |