From ffc51593c8c948076bd692b83f852b89994d55da Mon Sep 17 00:00:00 2001 From: Scott Douglass Date: Mon, 13 Jul 2015 15:31:40 +0000 Subject: [PATCH] [ARM] Add Thumb2 ADD with SP narrowing from 3 operand to 2 Differential Revision: http://reviews.llvm.org/D11131 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242035 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 19 ++++++++++++++----- test/MC/ARM/thumb2-narrow-dp.ll | 17 ++++++++++++++++- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 901627df129..ede7549e187 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -5486,13 +5486,22 @@ void ARMAsmParser::tryConvertingToTwoOperandForm(StringRef Mnemonic, auto Op4Reg = Op4.getReg(); // For most Thumb2 cases we just generate the 3 operand form and reduce - // it in processInstruction(), but for ADD involving PC the the 3 operand - // form won't accept PC so we do the transformation here. + // it in processInstruction(), but the 3 operand form of ADD (t2ADDrr) + // won't accept SP or PC so we do the transformation here taking care + // with immediate range in the 'add sp, sp #imm' case. auto &Op5 = static_cast(*Operands[5]); if (isThumbTwo()) { - if (Mnemonic != "add" || - !(Op3Reg == ARM::PC || Op4Reg == ARM::PC || - (Op5.isReg() && Op5.getReg() == ARM::PC))) + if (Mnemonic != "add") + return; + bool TryTransform = Op3Reg == ARM::PC || Op4Reg == ARM::PC || + (Op5.isReg() && Op5.getReg() == ARM::PC); + if (!TryTransform) { + TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP || + (Op5.isReg() && Op5.getReg() == ARM::SP)) && + !(Op3Reg == ARM::SP && Op4Reg == ARM::SP && + Op5.isImm() && !Op5.isImm0_508s4()); + } + if (!TryTransform) return; } else if (!isThumbOne()) return; diff --git a/test/MC/ARM/thumb2-narrow-dp.ll b/test/MC/ARM/thumb2-narrow-dp.ll index 13bbd1ff754..0c2aae91643 100644 --- a/test/MC/ARM/thumb2-narrow-dp.ll +++ b/test/MC/ARM/thumb2-narrow-dp.ll @@ -73,17 +73,32 @@ // CHECK: add pc, r2 @ encoding: [0x97,0x44] ADD pc, r2, pc // T2 // CHECK: add pc, r2 @ encoding: [0x97,0x44] + ADD pc, pc, sp // T2 +// CHECK: add pc, sp @ encoding: [0xef,0x44] + ADD pc, sp, pc // T2 +// CHECK: add pc, sp, pc @ encoding: [0xef,0x44] // ADD (SP plus immediate) A8.8.9 ADD sp, sp, #20 // T2 // FIXME: ARMARM says 'add sp, sp, #20' -// CHECK: add sp, #20 @ encoding: [0x05,0xb0] +// CHECK: add sp, #20 @ encoding: [0x05,0xb0] + ADD sp, sp, #508 // T2 +// CHECK: add sp, #508 @ encoding: [0x7f,0xb0] + ADD sp, sp, #512 // T3 +// CHECK: add.w sp, sp, #512 @ encoding: [0x0d,0xf5,0x00,0x7d] // ADD (SP plus register) A8.8.10 (commutative) ADD r9, sp, r9 // T1 // CHECK: add r9, sp, r9 @ encoding: [0xe9,0x44] + ADD r9, r9, sp // T1 +// FIXME: ARMARM says 'add r9, sp, r9' +// CHECK: add r9, sp @ encoding: [0xe9,0x44] ADD sp, sp, r10 // T2 // CHECK: add sp, r10 @ encoding: [0xd5,0x44] + ADD sp, r10, sp // T2 +// CHECK: add sp, r10 @ encoding: [0xd5,0x44] + ADD sp, sp, pc // T2 +// CHECK: add sp, pc @ encoding: [0xfd,0x44] // AND (commutative) ANDS r0, r2, r1 // Must be wide - 3 distinct registers -- 2.34.1