[llvm] r241799 - [ARM] Refactor converting Thumb1 from 3 to 2 operand (nfc)
Scott Douglass
sdouglass at arm.com
Thu Jul 9 07:13:34 PDT 2015
Author: scott-0
Date: Thu Jul 9 09:13:34 2015
New Revision: 241799
URL: http://llvm.org/viewvc/llvm-project?rev=241799&view=rev
Log:
[ARM] Refactor converting Thumb1 from 3 to 2 operand (nfc)
Also adds some test cases.
Differential Revision: http://reviews.llvm.org/D11054
Modified:
llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
llvm/trunk/test/MC/ARM/thumb_rewrites.s
Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=241799&r1=241798&r2=241799&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Jul 9 09:13:34 2015
@@ -242,6 +242,8 @@ class ARMAsmParser : public MCTargetAsmP
bool &CanAcceptCarrySet,
bool &CanAcceptPredicationCode);
+ void tryConvertingToTwoOperandForm(StringRef Mnemonic, bool CarrySetting,
+ OperandVector &Operands);
bool isThumb() const {
// FIXME: Can tablegen auto-generate this?
return STI.getFeatureBits()[ARM::ModeThumb];
@@ -5465,6 +5467,47 @@ void ARMAsmParser::getMnemonicAcceptInfo
CanAcceptPredicationCode = true;
}
+// \brief Some Thumb1 instructions have two operand forms that are not
+// available as three operand, convert to two operand form if possible.
+//
+// FIXME: We would really like to be able to tablegen'erate this.
+void ARMAsmParser::tryConvertingToTwoOperandForm(StringRef Mnemonic,
+ bool CarrySetting,
+ OperandVector &Operands) {
+ if (Operands.size() != 6 || !isThumbOne())
+ return;
+
+ ARMOperand &Op3 = static_cast<ARMOperand &>(*Operands[3]);
+ ARMOperand &Op4 = static_cast<ARMOperand &>(*Operands[4]);
+ if (!Op3.isReg() || !Op4.isReg())
+ return;
+
+ ARMOperand &Op5 = static_cast<ARMOperand &>(*Operands[5]);
+
+ if (!(Mnemonic == "add" || Mnemonic == "sub" || Mnemonic == "and" ||
+ Mnemonic == "eor" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
+ Mnemonic == "asr" || Mnemonic == "adc" || Mnemonic == "sbc" ||
+ Mnemonic == "ror" || Mnemonic == "orr" || Mnemonic == "bic"))
+ return;
+
+ // If first 2 operands of a 3 operand instruction are the same
+ // then transform to 2 operand version of the same instruction
+ // e.g. 'adds r0, r0, #1' transforms to 'adds r0, #1'
+ bool Transform = Op3.getReg() == Op4.getReg();
+ // If both registers are the same then remove one of them from
+ // the operand list, with certain exceptions.
+ if (Transform) {
+ // Don't transform 'adds Rd, Rd, Rm' or 'sub{s} Rd, Rd, Rm' because the
+ // 2 operand forms don't exist.
+ if (((Mnemonic == "add" && CarrySetting) || Mnemonic == "sub") &&
+ Op5.isReg())
+ Transform = false;
+ }
+
+ if (Transform)
+ Operands.erase(Operands.begin() + 3);
+}
+
bool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
OperandVector &Operands) {
// FIXME: This is all horribly hacky. We really need a better way to deal
@@ -5838,6 +5881,8 @@ bool ARMAsmParser::ParseInstruction(Pars
"VFP/Neon double precision register expected");
}
+ tryConvertingToTwoOperandForm(Mnemonic, CarrySetting, Operands);
+
// Some instructions, mostly Thumb, have forms for the same mnemonic that
// do and don't have a cc_out optional-def operand. With some spot-checks
// of the operand list, we can figure out which variant we're trying to
@@ -5901,48 +5946,6 @@ bool ARMAsmParser::ParseInstruction(Pars
}
}
- // If first 2 operands of a 3 operand instruction are the same
- // then transform to 2 operand version of the same instruction
- // e.g. 'adds r0, r0, #1' transforms to 'adds r0, #1'
- // FIXME: We would really like to be able to tablegen'erate this.
- if (isThumbOne() && Operands.size() == 6 &&
- (Mnemonic == "add" || Mnemonic == "sub" || Mnemonic == "and" ||
- Mnemonic == "eor" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
- Mnemonic == "asr" || Mnemonic == "adc" || Mnemonic == "sbc" ||
- Mnemonic == "ror" || Mnemonic == "orr" || Mnemonic == "bic")) {
- ARMOperand &Op3 = static_cast<ARMOperand &>(*Operands[3]);
- ARMOperand &Op4 = static_cast<ARMOperand &>(*Operands[4]);
- ARMOperand &Op5 = static_cast<ARMOperand &>(*Operands[5]);
-
- // If both registers are the same then remove one of them from
- // the operand list.
- if (Op3.isReg() && Op4.isReg() && Op3.getReg() == Op4.getReg()) {
- // If 3rd operand (variable Op5) is a register and the instruction is adds/sub
- // then do not transform as the backend already handles this instruction
- // correctly.
- if (!Op5.isReg() || !((Mnemonic == "add" && CarrySetting) || Mnemonic == "sub")) {
- Operands.erase(Operands.begin() + 3);
- if (Mnemonic == "add" && !CarrySetting) {
- // Special case for 'add' (not 'adds') instruction must
- // remove the CCOut operand as well.
- Operands.erase(Operands.begin() + 1);
- }
- }
- }
- }
-
- // If instruction is 'add' and first two register operands
- // use SP register, then remove one of the SP registers from
- // the instruction.
- // FIXME: We would really like to be able to tablegen'erate this.
- if (isThumbOne() && Operands.size() == 5 && Mnemonic == "add" && !CarrySetting) {
- ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[2]);
- ARMOperand &Op3 = static_cast<ARMOperand &>(*Operands[3]);
- if (Op2.isReg() && Op3.isReg() && Op2.getReg() == ARM::SP && Op3.getReg() == ARM::SP) {
- Operands.erase(Operands.begin() + 2);
- }
- }
-
// GNU Assembler extension (compatibility)
if ((Mnemonic == "ldrd" || Mnemonic == "strd")) {
ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[2]);
Modified: llvm/trunk/test/MC/ARM/thumb_rewrites.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb_rewrites.s?rev=241799&r1=241798&r2=241799&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/thumb_rewrites.s (original)
+++ llvm/trunk/test/MC/ARM/thumb_rewrites.s Thu Jul 9 09:13:34 2015
@@ -12,6 +12,19 @@
add sp, sp, r0
@ CHECK: add sp, r0 @ encoding: [0x85,0x44]
+ add r4, sp, r4
+@ CHECK: add r4, sp, r4 @ encoding: [0x6c,0x44]
+
+ add r4, r4, sp
+@ CHECK: add r4, sp @ encoding: [0x6c,0x44]
+
+ add sp, sp, #32
+@ FIXME: ARMARM says 'add sp, sp, #32'
+@ CHECK: add sp, #32 @ encoding: [0x08,0xb0]
+
+ add r5, sp, #1016
+@ CHECK: add r5, sp, #1016 @ encoding: [0xfe,0xad]
+
add r0, r0, r1
@ CHECK: add r0, r1 @ encoding: [0x08,0x44]
@@ -21,6 +34,12 @@
subs r0, r0, r0
@ CHECK: subs r0, r0, r0 @ encoding: [0x00,0x1a]
+ subs r2, r2, #8
+@ CHECK: subs r2, #8 @ encoding: [0x08,0x3a]
+
+ sub sp, sp, #16
+@ CHECK: sub sp, #16 @ encoding: [0x84,0xb0]
+
ands r0, r0, r1
@ CHECK: ands r0, r1 @ encoding: [0x08,0x40]
More information about the llvm-commits
mailing list