mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-29 22:30:33 +00:00
[ARM] Warn on deprecated IT blocks in v8 AArch32 assembly.
Patch by Artyom Skrobov. llvm-svn: 191885
This commit is contained in:
parent
78295ae841
commit
ece8c5f612
@ -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.
|
||||
|
91
lib/Target/ARM/ARMFeatures.h
Normal file
91
lib/Target/ARM/ARMFeatures.h
Normal 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
|
@ -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">;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
9715
test/MC/ARM/v8_IT_manual.s
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user