diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 3fd27b0e305..d87b526739e 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -950,9 +950,9 @@ multiclass AI_exta_rrot_np opcod, string opc> { } /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube. -let Uses = [CPSR] in { multiclass AI1_adde_sube_irs opcod, string opc, PatFrag opnode, - bit Commutable = 0> { + string baseOpc, bit Commutable = 0> { + let Uses = [CPSR] in { def ri : AsI1, @@ -991,7 +991,24 @@ multiclass AI1_adde_sube_irs opcod, string opc, PatFrag opnode, let Inst{15-12} = Rd; let Inst{19-16} = Rn; } -} + } + // Assembly aliases for optional destination operand when it's the same + // as the source operand. + def : InstAlias(!strconcat(baseOpc, "ri")) GPR:$Rdn, GPR:$Rdn, + so_imm:$imm, pred:$p, + cc_out:$s)>, + Requires<[IsARM]>; + def : InstAlias(!strconcat(baseOpc, "rr")) GPR:$Rdn, GPR:$Rdn, + GPR:$Rm, pred:$p, + cc_out:$s)>, + Requires<[IsARM]>; + def : InstAlias(!strconcat(baseOpc, "rs")) GPR:$Rdn, GPR:$Rdn, + so_reg:$shift, pred:$p, + cc_out:$s)>, + Requires<[IsARM]>; } // Carry setting variants @@ -2252,9 +2269,11 @@ defm SUBS : AI1_bin_s_irs<0b0010, "subs", BinOpFrag<(subc node:$LHS, node:$RHS)>>; defm ADC : AI1_adde_sube_irs<0b0101, "adc", - BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>; + BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, + "ADC", 1>; defm SBC : AI1_adde_sube_irs<0b0110, "sbc", - BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>; + BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>, + "SBC">; // ADC and SUBC with 's' bit set. let usesCustomInserter = 1 in { diff --git a/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s index 756b59f10ec..66a3a4ee24f 100644 --- a/test/MC/ARM/basic-arm-instructions.s +++ b/test/MC/ARM/basic-arm-instructions.s @@ -60,6 +60,25 @@ _func: adc r6, r7, r8, ror r9 adc r4, r5, r6, rrx + @ Destination register is optional + adc r5, r6 + adc r4, r5, lsl #1 + adc r4, r5, lsl #31 + adc r4, r5, lsr #1 + adc r4, r5, lsr #31 + adc r4, r5, lsr #32 + adc r4, r5, asr #1 + adc r4, r5, asr #31 + adc r4, r5, asr #32 + adc r4, r5, ror #1 + adc r4, r5, ror #31 + adc r4, r5, rrx + adc r6, r7, lsl r9 + adc r6, r7, lsr r9 + adc r6, r7, asr r9 + adc r6, r7, ror r9 + adc r4, r5, rrx + @ CHECK: adc r4, r5, r6 @ encoding: [0x06,0x40,0xa5,0xe0] @ CHECK: adc r4, r5, r6, lsl #1 @ encoding: [0x86,0x40,0xa5,0xe0] @@ -79,3 +98,20 @@ _func: @ CHECK: adc r6, r7, r8, ror r9 @ encoding: [0x78,0x69,0xa7,0xe0] @ CHECK: adc r4, r5, r6, rrx @ encoding: [0x66,0x40,0xa5,0xe0] +@ CHECK: adc r5, r5, r6 @ encoding: [0x06,0x50,0xa5,0xe0] +@ CHECK: adc r4, r4, r5, lsl #1 @ encoding: [0x85,0x40,0xa4,0xe0] +@ CHECK: adc r4, r4, r5, lsl #31 @ encoding: [0x85,0x4f,0xa4,0xe0] +@ CHECK: adc r4, r4, r5, lsr #1 @ encoding: [0xa5,0x40,0xa4,0xe0] +@ CHECK: adc r4, r4, r5, lsr #31 @ encoding: [0xa5,0x4f,0xa4,0xe0] +@ CHECK: adc r4, r4, r5, lsr #32 @ encoding: [0x25,0x40,0xa4,0xe0] +@ CHECK: adc r4, r4, r5, asr #1 @ encoding: [0xc5,0x40,0xa4,0xe0] +@ CHECK: adc r4, r4, r5, asr #31 @ encoding: [0xc5,0x4f,0xa4,0xe0] +@ CHECK: adc r4, r4, r5, asr #32 @ encoding: [0x45,0x40,0xa4,0xe0] +@ CHECK: adc r4, r4, r5, ror #1 @ encoding: [0xe5,0x40,0xa4,0xe0] +@ CHECK: adc r4, r4, r5, ror #31 @ encoding: [0xe5,0x4f,0xa4,0xe0] +@ CHECK: adc r4, r4, r5, rrx @ encoding: [0x65,0x40,0xa4,0xe0] +@ CHECK: adc r6, r6, r7, lsl r9 @ encoding: [0x17,0x69,0xa6,0xe0] +@ CHECK: adc r6, r6, r7, lsr r9 @ encoding: [0x37,0x69,0xa6,0xe0] +@ CHECK: adc r6, r6, r7, asr r9 @ encoding: [0x57,0x69,0xa6,0xe0] +@ CHECK: adc r6, r6, r7, ror r9 @ encoding: [0x77,0x69,0xa6,0xe0] +@ CHECK: adc r4, r4, r5, rrx @ encoding: [0x65,0x40,0xa4,0xe0]