summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
diff options
context:
space:
mode:
authorScott Douglass <sdouglass@arm.com>2015-07-09 14:13:55 +0000
committerScott Douglass <sdouglass@arm.com>2015-07-09 14:13:55 +0000
commit8143bc25ee576eb4b1cc923ede42281f1140bfb3 (patch)
treebbf8345b25ea81b9698b87cd5129e540f8ed1c32 /llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
parent2740a6372514329605d0d43ddbb4a8399d48ed29 (diff)
downloadbcm5719-llvm-8143bc25ee576eb4b1cc923ede42281f1140bfb3.tar.gz
bcm5719-llvm-8143bc25ee576eb4b1cc923ede42281f1140bfb3.zip
[ARM] Thumb1 3 to 2 operand convertion for commutative operations
Differential Revision: http://reviews.llvm.org/D11057 llvm-svn: 241802
Diffstat (limited to 'llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp')
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp24
1 files changed, 21 insertions, 3 deletions
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 0ae6925c28b..88b06f7b938 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -5504,23 +5504,41 @@ void ARMAsmParser::tryConvertingToTwoOperandForm(StringRef Mnemonic,
// 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();
+
+ // For communtative operations, we might be able to transform if we swap
+ // Op4 and Op5. The 'ADD Rdm, SP, Rdm' form is already handled specially
+ // as tADDrsp.
+ const ARMOperand *LastOp = &Op5;
+ bool Swap = false;
+ if (!Transform && Op5.isReg() && Op3.getReg() == Op5.getReg() &&
+ ((Mnemonic == "add" && Op4.getReg() != ARM::SP) ||
+ Mnemonic == "and" || Mnemonic == "eor" ||
+ Mnemonic == "adc" || Mnemonic == "orr")) {
+ Swap = true;
+ LastOp = &Op4;
+ Transform = true;
+ }
+
// 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())
+ LastOp->isReg())
Transform = false;
// Don't transform 'add/sub{s} Rd, Rd, #imm' if the immediate fits into
// 3-bits because the ARMARM says not to.
- if ((Mnemonic == "add" || Mnemonic == "sub") && Op5.isImm0_7())
+ if ((Mnemonic == "add" || Mnemonic == "sub") && LastOp->isImm0_7())
Transform = false;
}
- if (Transform)
+ if (Transform) {
+ if (Swap)
+ std::swap(Op4, Op5);
Operands.erase(Operands.begin() + 3);
+ }
}
bool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
OpenPOWER on IntegriCloud