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 @@ -1022,9 +1022,9 @@ /// 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 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 @@ let Inst{26-25} = 0b01; let Inst{24-21} = opcod; } -} + } + // Shortened forms + def : t2InstAlias(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn, t2_so_imm:$imm, pred:$p, + cc_out:$s)>; + def : t2InstAlias(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p, + cc_out:$s)>; + def : t2InstAlias(NAME#"rs") rGPR:$Rdn, rGPR:$Rdn, t2_so_reg:$ShiftedRm, pred:$p, + cc_out:$s)>; + def : t2InstAlias(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn, t2_so_imm:$imm, pred:$p, + cc_out:$s)>; + def : t2InstAlias(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p, + cc_out:$s)>; + def : t2InstAlias(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 / @@ -2365,15 +2384,17 @@ 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)>; @@ -4847,6 +4868,11 @@ 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", diff --git a/llvm/test/MC/ARM/basic-thumb2-instructions.s b/llvm/test/MC/ARM/basic-thumb2-instructions.s --- a/llvm/test/MC/ARM/basic-thumb2-instructions.s +++ b/llvm/test/MC/ARM/basic-thumb2-instructions.s @@ -27,6 +27,8 @@ adc r5, r3, #0x87000000 adc r4, r2, #0x7f800000 adc r4, r2, #0x00000680 + adc r0, #1 + adc r1, #0x7f800000 @ CHECK: adc r0, r1, #4 @ encoding: [0x41,0xf1,0x04,0x00] @ CHECK: adcs r0, r1, #0 @ encoding: [0x51,0xf1,0x00,0x00] @@ -37,6 +39,8 @@ @ CHECK: adc r5, r3, #2264924160 @ encoding: [0x43,0xf1,0x07,0x45] @ CHECK: adc r4, r2, #2139095040 @ encoding: [0x42,0xf1,0xff,0x44] @ CHECK: adc r4, r2, #1664 @ encoding: [0x42,0xf5,0xd0,0x64] +@ CHECK: adc r0, r0, #1 @ encoding: [0x40,0xf1,0x01,0x00] +@ CHECK: adc r1, r1, #2139095040 @ encoding: [0x41,0xf1,0xff,0x41] @------------------------------------------------------------------------------ @ ADC (register) @@ -49,6 +53,10 @@ adcs r0, r1, r3, lsl #7 adc.w r0, r1, r3, lsr #31 adcs.w r0, r1, r3, asr #32 + adc r4, r5 + adc.w r9, r1 + adc r0, r1, ror #4 + adc.w r0, r1, lsr #31 @ CHECK: adc.w r4, r5, r6 @ encoding: [0x45,0xeb,0x06,0x04] @ CHECK: adcs.w r4, r5, r6 @ encoding: [0x55,0xeb,0x06,0x04] @@ -58,6 +66,10 @@ @ CHECK: adcs.w r0, r1, r3, lsl #7 @ encoding: [0x51,0xeb,0xc3,0x10] @ CHECK: adc.w r0, r1, r3, lsr #31 @ encoding: [0x41,0xeb,0xd3,0x70] @ CHECK: adcs.w r0, r1, r3, asr #32 @ encoding: [0x51,0xeb,0x23,0x00] +@ CHECK: adc.w r4, r4, r5 @ encoding: [0x44,0xeb,0x05,0x04] +@ CHECK: adc.w r9, r9, r1 @ encoding: [0x49,0xeb,0x01,0x09] +@ CHECK: adc.w r0, r0, r1, ror #4 @ encoding: [0x40,0xeb,0x31,0x10] +@ CHECK: adc.w r0, r0, r1, lsr #31 @ encoding: [0x40,0xeb,0xd1,0x70] @------------------------------------------------------------------------------ diff --git a/llvm/test/MC/Disassembler/ARM/thumb2.txt b/llvm/test/MC/Disassembler/ARM/thumb2.txt --- a/llvm/test/MC/Disassembler/ARM/thumb2.txt +++ b/llvm/test/MC/Disassembler/ARM/thumb2.txt @@ -12,6 +12,8 @@ # CHECK: adc r5, r3, #2264924160 # CHECK: adc r4, r2, #2139095040 # CHECK: adc r4, r2, #1664 +# CHECK: adc r0, r0, #1 +# CHECK: adc r1, r1, #2139095040 0x41 0xf1 0x04 0x00 0x51 0xf1 0x00 0x00 @@ -22,6 +24,8 @@ 0x43 0xf1 0x07 0x45 0x42 0xf1 0xff 0x44 0x42 0xf5 0xd0 0x64 +0x40 0xf1 0x01 0x00 +0x41 0xf1 0xff 0x41 #------------------------------------------------------------------------------ # ADC (register) @@ -34,6 +38,10 @@ # CHECK: adcs.w r0, r1, r3, lsl #7 # CHECK: adc.w r0, r1, r3, lsr #31 # CHECK: adcs.w r0, r1, r3, asr #32 +# CHECK: adc.w r4, r4, r5 +# CHECK: adc.w r9, r9, r1 +# CHECK: adc.w r0, r0, r1, ror #4 +# CHECK: adc.w r0, r0, r1, lsr #31 0x45 0xeb 0x06 0x04 0x55 0xeb 0x06 0x04 @@ -43,6 +51,10 @@ 0x51 0xeb 0xc3 0x10 0x41 0xeb 0xd3 0x70 0x51 0xeb 0x23 0x00 +0x44 0xeb 0x05 0x04 +0x49 0xeb 0x01 0x09 +0x40 0xeb 0x31 0x10 +0x40 0xeb 0xd1 0x70 #------------------------------------------------------------------------------