diff options
author | Amara Emerson <amara.emerson@arm.com> | 2013-10-03 09:31:51 +0000 |
---|---|---|
committer | Amara Emerson <amara.emerson@arm.com> | 2013-10-03 09:31:51 +0000 |
commit | 6eef361b73b457896b310d411251aedd5e72476a (patch) | |
tree | dfc0acbe041f65d4048244b45475bceefb97b8d9 /lib | |
parent | 9d08d69fd4562a4433cf19eb4b96c17b34f6da2e (diff) | |
download | llvm-6eef361b73b457896b310d411251aedd5e72476a.tar.gz llvm-6eef361b73b457896b310d411251aedd5e72476a.tar.bz2 llvm-6eef361b73b457896b310d411251aedd5e72476a.tar.xz |
[ARM] Warn on deprecated IT blocks in v8 AArch32 assembly.
Patch by Artyom Skrobov.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191885 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/ARMBaseInstrInfo.cpp | 71 | ||||
-rw-r--r-- | lib/Target/ARM/ARMFeatures.h | 91 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 3 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb.td | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb2.td | 3 | ||||
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 23 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp | 11 |
7 files changed, 126 insertions, 78 deletions
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 4076e3b1b1..b4266693c1 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -11,10 +11,11 @@ // //===----------------------------------------------------------------------===// -#include "ARMBaseInstrInfo.h" #include "ARM.h" +#include "ARMBaseInstrInfo.h" #include "ARMBaseRegisterInfo.h" #include "ARMConstantPoolValue.h" +#include "ARMFeatures.h" #include "ARMHazardRecognizer.h" #include "ARMMachineFunctionInfo.h" #include "MCTargetDesc/ARMAddressingModes.h" @@ -513,74 +514,6 @@ bool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI, return Found; } -static bool isV8EligibleForIT(MachineInstr *MI) { - switch (MI->getOpcode()) { - default: - return false; - case ARM::tADC: - case ARM::tADDi3: - case ARM::tADDi8: - case ARM::tADDrSPi: - case ARM::tADDrr: - case ARM::tAND: - case ARM::tASRri: - case ARM::tASRrr: - case ARM::tBIC: - case ARM::tCMNz: - case ARM::tCMPi8: - case ARM::tCMPr: - case ARM::tEOR: - case ARM::tLDRBi: - case ARM::tLDRBr: - case ARM::tLDRHi: - case ARM::tLDRHr: - case ARM::tLDRSB: - case ARM::tLDRSH: - case ARM::tLDRi: - case ARM::tLDRr: - case ARM::tLDRspi: - case ARM::tLSLri: - case ARM::tLSLrr: - case ARM::tLSRri: - case ARM::tLSRrr: - case ARM::tMOVi8: - case ARM::tMUL: - case ARM::tMVN: - case ARM::tORR: - case ARM::tROR: - case ARM::tRSB: - case ARM::tSBC: - case ARM::tSTRBi: - case ARM::tSTRBr: - case ARM::tSTRHi: - case ARM::tSTRHr: - case ARM::tSTRi: - case ARM::tSTRr: - case ARM::tSTRspi: - case ARM::tSUBi3: - case ARM::tSUBi8: - case ARM::tSUBrr: - case ARM::tTST: - return true; -// there are some "conditionally deprecated" opcodes - case ARM::tADDspr: - return MI->getOperand(2).getReg() != ARM::PC; - case ARM::tADDrSP: - case ARM::tBX: - case ARM::tBLXr: - // ADD PC, SP and BLX PC were always unpredictable, - // now on top of it they're deprecated - return MI->getOperand(0).getReg() != ARM::PC; - case ARM::tADDhirr: - return MI->getOperand(0).getReg() != ARM::PC && - MI->getOperand(2).getReg() != ARM::PC; - case ARM::tCMPhir: - case ARM::tMOVr: - return MI->getOperand(0).getReg() != ARM::PC && - MI->getOperand(1).getReg() != ARM::PC; - } -} - /// isPredicable - Return true if the specified instruction can be predicated. /// By default, this returns true for every instruction with a /// PredicateOperand. diff --git a/lib/Target/ARM/ARMFeatures.h b/lib/Target/ARM/ARMFeatures.h new file mode 100644 index 0000000000..eaec050741 --- /dev/null +++ b/lib/Target/ARM/ARMFeatures.h @@ -0,0 +1,91 @@ +//===-- ARMFeatures.h - Checks for ARM instruction features ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the code shared between ARM CodeGen and ARM MC +// +//===----------------------------------------------------------------------===// + +#ifndef TARGET_ARM_FEATURES_H +#define TARGET_ARM_FEATURES_H + +#include "ARM.h" + +using namespace llvm; + +template<typename InstrType> // could be MachineInstr or MCInst +bool isV8EligibleForIT(InstrType *Instr, int BLXOperandIndex=0) { + switch (Instr->getOpcode()) { + default: + return false; + case ARM::tADC: + case ARM::tADDi3: + case ARM::tADDi8: + case ARM::tADDrSPi: + case ARM::tADDrr: + case ARM::tAND: + case ARM::tASRri: + case ARM::tASRrr: + case ARM::tBIC: + case ARM::tCMNz: + case ARM::tCMPi8: + case ARM::tCMPr: + case ARM::tEOR: + case ARM::tLDRBi: + case ARM::tLDRBr: + case ARM::tLDRHi: + case ARM::tLDRHr: + case ARM::tLDRSB: + case ARM::tLDRSH: + case ARM::tLDRi: + case ARM::tLDRr: + case ARM::tLDRspi: + case ARM::tLSLri: + case ARM::tLSLrr: + case ARM::tLSRri: + case ARM::tLSRrr: + case ARM::tMOVi8: + case ARM::tMUL: + case ARM::tMVN: + case ARM::tORR: + case ARM::tROR: + case ARM::tRSB: + case ARM::tSBC: + case ARM::tSTRBi: + case ARM::tSTRBr: + case ARM::tSTRHi: + case ARM::tSTRHr: + case ARM::tSTRi: + case ARM::tSTRr: + case ARM::tSTRspi: + case ARM::tSUBi3: + case ARM::tSUBi8: + case ARM::tSUBrr: + case ARM::tTST: + return true; +// there are some "conditionally deprecated" opcodes + case ARM::tADDspr: + return Instr->getOperand(2).getReg() != ARM::PC; + // ADD PC, SP and BLX PC were always unpredictable, + // now on top of it they're deprecated + case ARM::tADDrSP: + case ARM::tBX: + return Instr->getOperand(0).getReg() != ARM::PC; + case ARM::tBLXr: + return Instr->getOperand(BLXOperandIndex).getReg() != ARM::PC; + case ARM::tADDhirr: + return Instr->getOperand(0).getReg() != ARM::PC && + Instr->getOperand(2).getReg() != ARM::PC; + case ARM::tCMPhir: + case ARM::tMOVr: + return Instr->getOperand(0).getReg() != ARM::PC && + Instr->getOperand(1).getReg() != ARM::PC; + } +} + +#endif diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index eddd9d176e..d92b47729b 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -5533,4 +5533,5 @@ def : InstAlias<"umull${s}${p} $RdLo, $RdHi, $Rn, $Rm", // 'it' blocks in ARM mode just validate the predicates. The IT itself // is discarded. -def ITasm : ARMAsmPseudo<"it$mask $cc", (ins it_pred:$cc, it_mask:$mask)>; +def ITasm : ARMAsmPseudo<"it$mask $cc", (ins it_pred:$cc, it_mask:$mask)>, + ComplexDeprecationPredicate<"IT">; diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 2c547910be..458254ee62 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -313,7 +313,7 @@ def tHLT : T1I<(outs), (ins imm0_63:$val), NoItinerary, "hlt\t$val", } def tSETEND : T1I<(outs), (ins setend_op:$end), NoItinerary, "setend\t$end", - []>, T1Encoding<0b101101> { + []>, T1Encoding<0b101101>, Deprecated<HasV8Ops> { bits<1> end; // A8.6.156 let Inst{9-5} = 0b10010; diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 63f527e775..636b96dde7 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -3565,7 +3565,8 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in { let Defs = [ITSTATE] in def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask), AddrModeNone, 2, IIC_iALUx, - "it$mask\t$cc", "", []> { + "it$mask\t$cc", "", []>, + ComplexDeprecationPredicate<"IT"> { // 16-bit instruction. let Inst{31-16} = 0x0000; let Inst{15-8} = 0b10111111; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index ebc382cef4..71f98abe1d 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "ARMFeatures.h" #include "llvm/MC/MCTargetAsmParser.h" #include "MCTargetDesc/ARMAddressingModes.h" #include "MCTargetDesc/ARMBaseInfo.h" @@ -7622,12 +7623,22 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return true; } - // Some instructions need post-processing to, for example, tweak which - // encoding is selected. Loop on it while changes happen so the - // individual transformations can chain off each other. E.g., - // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8) - while (processInstruction(Inst, Operands)) - ; + { // processInstruction() updates inITBlock state, we need to save it away + bool wasInITBlock = inITBlock(); + + // Some instructions need post-processing to, for example, tweak which + // encoding is selected. Loop on it while changes happen so the + // individual transformations can chain off each other. E.g., + // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8) + while (processInstruction(Inst, Operands)) + ; + + // Only after the instruction is fully processed, we can validate it + if (wasInITBlock && hasV8Ops() && isThumb() && + !isV8EligibleForIT(&Inst, 2)) { + Warning(IDLoc, "deprecated instruction in IT block"); + } + } // Only move forward at the very end so that everything in validate // and process gets a consistent answer about whether we're in an IT diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index 94069cd001..28d921213c 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -63,6 +63,17 @@ static bool getMCRDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, return false; } +static bool getITDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, + std::string &Info) { + if (STI.getFeatureBits() & llvm::ARM::HasV8Ops && + MI.getOperand(1).isImm() && MI.getOperand(1).getImm() != 8) { + Info = "applying IT instruction to more than one subsequent instruction is deprecated"; + return true; + } + + return false; +} + #define GET_INSTRINFO_MC_DESC #include "ARMGenInstrInfo.inc" |