diff options
author | Scott Douglass <sdouglass@arm.com> | 2015-07-09 14:13:55 +0000 |
---|---|---|
committer | Scott Douglass <sdouglass@arm.com> | 2015-07-09 14:13:55 +0000 |
commit | 8143bc25ee576eb4b1cc923ede42281f1140bfb3 (patch) | |
tree | bbf8345b25ea81b9698b87cd5129e540f8ed1c32 /llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | |
parent | 2740a6372514329605d0d43ddbb4a8399d48ed29 (diff) | |
download | bcm5719-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.cpp | 24 |
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, |