[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
This commit is contained in:
Amara Emerson 2013-10-03 09:31:51 +00:00
parent 9d08d69fd4
commit 6eef361b73
9 changed files with 9888 additions and 92 deletions

View File

@ -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.

View File

@ -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

View File

@ -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">;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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"

View File

@ -1,18 +1,51 @@
@ RUN: llvm-mc -triple armv8 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-V8
@ RUN: llvm-mc -triple armv7 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-V7
@ RUN: llvm-mc -triple armv6 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-V6
@ RUN: llvm-mc -triple armv8 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ARMV8
@ RUN: llvm-mc -triple thumbv8 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-THUMBV8
@ RUN: llvm-mc -triple armv7 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ARMV7
@ RUN: llvm-mc -triple thumbv7 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-THUMBV7
@ RUN: llvm-mc -triple armv6 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ARMV6
setend be
@ CHECK-V8: warning: deprecated
@ CHECK-V7-NOT: warning: deprecated
@ CHECK-ARMV8: warning: deprecated
@ CHECK-THUMBV8: warning: deprecated
@ CHECK-ARMV7-NOT: warning: deprecated
@ CHECK-THUMBV7-NOT: warning: deprecated
mcr p15, #0, r5, c7, c5, #4
@ CHECK-V8: warning: deprecated since v7, use 'isb'
@ CHECK-V7: warning: deprecated since v7, use 'isb'
@ CHECK-V6-NOT: warning: deprecated since v7, use 'isb'
@ CHECK-ARMV8: warning: deprecated since v7, use 'isb'
@ CHECK-THUMBV8: warning: deprecated since v7, use 'isb'
@ CHECK-ARMV7: warning: deprecated since v7, use 'isb'
@ CHECK-THUMBV7: warning: deprecated since v7, use 'isb'
@ CHECK-ARMV6-NOT: warning: deprecated since v7, use 'isb'
mcr p15, #0, r5, c7, c10, #4
@ CHECK-V8: warning: deprecated since v7, use 'dsb'
@ CHECK-V7: warning: deprecated since v7, use 'dsb'
@ CHECK-V6-NOT: warning: deprecated since v7, use 'dsb'
@ CHECK-ARMV8: warning: deprecated since v7, use 'dsb'
@ CHECK-THUMBV8: warning: deprecated since v7, use 'dsb'
@ CHECK-ARMV7: warning: deprecated since v7, use 'dsb'
@ CHECK-THUMBV7: warning: deprecated since v7, use 'dsb'
@ CHECK-ARMV6-NOT: warning: deprecated since v7, use 'dsb'
mcr p15, #0, r5, c7, c10, #5
@ CHECK-V8: warning: deprecated since v7, use 'dmb'
@ CHECK-V7: warning: deprecated since v7, use 'dmb'
@ CHECK-V6-NOT: warning: deprecated since v7, use 'dmb'
@ CHECK-ARMV8: warning: deprecated since v7, use 'dmb'
@ CHECK-THUMBV8: warning: deprecated since v7, use 'dmb'
@ CHECK-ARMV7: warning: deprecated since v7, use 'dmb'
@ CHECK-THUMBV7: warning: deprecated since v7, use 'dmb'
@ CHECK-ARMV6-NOT: warning: deprecated since v7, use 'dmb'
it ge
movge r0, #4096
@ CHECK-THUMBV8: warning: deprecated instruction in IT block
@ CHECK-THUMBV7-NOT: warning
ite ge
addge r0, r1
addlt r0, r2
@ CHECK-ARMV8: warning: applying IT instruction to more than one subsequent instruction is deprecated
@ CHECK-THUMBV8: warning: applying IT instruction to more than one subsequent instruction is deprecated
@ CHECK-THUMBV7-NOT: warning
it ge
movge r0, pc // invalid operand
@ CHECK-THUMBV8: warning: deprecated instruction in IT block
@ CHECK-THUMBV7-NOT: warning
it ge
revge r0, r0 // invalid instruction
@ CHECK-THUMBV8: warning: deprecated instruction in IT block
@ CHECK-THUMBV7-NOT: warning
it ge
clzge r0, r0 // only has 32-bit form
@ CHECK-THUMBV8: warning: deprecated instruction in IT block
@ CHECK-THUMBV7-NOT: warning

9715
test/MC/ARM/v8_IT_manual.s Normal file

File diff suppressed because it is too large Load Diff