mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-28 14:46:39 +00:00
[ARM] Add B.W and CBZ instructions to ARMv8-M Baseline
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257881 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2ff1a833df
commit
eab7e23bdd
@ -478,10 +478,18 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) {
|
||||
MadeChange = true;
|
||||
}
|
||||
|
||||
// Shrink 32-bit Thumb2 branch, load, and store instructions.
|
||||
// Shrink 32-bit Thumb2 load and store instructions.
|
||||
if (isThumb2 && !STI->prefers32BitThumb())
|
||||
MadeChange |= optimizeThumb2Instructions();
|
||||
|
||||
// Shrink 32-bit branch instructions.
|
||||
if (isThumb && STI->hasV8MBaselineOps())
|
||||
MadeChange |= optimizeThumb2Branches();
|
||||
|
||||
// Optimize jump tables using TBB / TBH.
|
||||
if (isThumb2)
|
||||
MadeChange |= optimizeThumb2JumpTables();
|
||||
|
||||
// After a while, this might be made debug-only, but it is not expensive.
|
||||
verify();
|
||||
|
||||
@ -1852,8 +1860,6 @@ bool ARMConstantIslands::optimizeThumb2Instructions() {
|
||||
}
|
||||
}
|
||||
|
||||
MadeChange |= optimizeThumb2Branches();
|
||||
MadeChange |= optimizeThumb2JumpTables();
|
||||
return MadeChange;
|
||||
}
|
||||
|
||||
|
@ -3530,7 +3530,8 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
|
||||
let isPredicable = 1 in
|
||||
def t2B : T2I<(outs), (ins uncondbrtarget:$target), IIC_Br,
|
||||
"b", ".w\t$target",
|
||||
[(br bb:$target)]>, Sched<[WriteBr]> {
|
||||
[(br bb:$target)]>, Sched<[WriteBr]>,
|
||||
Requires<[IsThumb, HasV8MBaseline]> {
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{15-14} = 0b10;
|
||||
let Inst{12} = 1;
|
||||
@ -3661,7 +3662,7 @@ let isBranch = 1, isTerminator = 1 in {
|
||||
def tCBZ : T1I<(outs), (ins tGPR:$Rn, t_cbtarget:$target), IIC_Br,
|
||||
"cbz\t$Rn, $target", []>,
|
||||
T1Misc<{0,0,?,1,?,?,?}>,
|
||||
Requires<[IsThumb2]>, Sched<[WriteBr]> {
|
||||
Requires<[IsThumb, HasV8MBaseline]>, Sched<[WriteBr]> {
|
||||
// A8.6.27
|
||||
bits<6> target;
|
||||
bits<3> Rn;
|
||||
@ -3673,7 +3674,7 @@ let isBranch = 1, isTerminator = 1 in {
|
||||
def tCBNZ : T1I<(outs), (ins tGPR:$Rn, t_cbtarget:$target), IIC_Br,
|
||||
"cbnz\t$Rn, $target", []>,
|
||||
T1Misc<{1,0,?,1,?,?,?}>,
|
||||
Requires<[IsThumb2]>, Sched<[WriteBr]> {
|
||||
Requires<[IsThumb, HasV8MBaseline]>, Sched<[WriteBr]> {
|
||||
// A8.6.27
|
||||
bits<6> target;
|
||||
bits<3> Rn;
|
||||
|
@ -234,7 +234,7 @@ void ARMSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
|
||||
// registers are the 4 used for parameters. We don't currently do this
|
||||
// case.
|
||||
|
||||
SupportsTailCall = !isThumb1Only();
|
||||
SupportsTailCall = !isThumb() || hasV8MBaselineOps();
|
||||
|
||||
if (isTargetMachO() && isTargetIOS() && getTargetTriple().isOSVersionLT(5, 0))
|
||||
SupportsTailCall = false;
|
||||
|
@ -269,6 +269,9 @@ class ARMAsmParser : public MCTargetAsmParser {
|
||||
bool hasV8Ops() const {
|
||||
return getSTI().getFeatureBits()[ARM::HasV8Ops];
|
||||
}
|
||||
bool hasV8MBaseline() const {
|
||||
return getSTI().getFeatureBits()[ARM::HasV8MBaselineOps];
|
||||
}
|
||||
bool hasARM() const {
|
||||
return !getSTI().getFeatureBits()[ARM::FeatureNoARM];
|
||||
}
|
||||
@ -4673,14 +4676,14 @@ void ARMAsmParser::cvtThumbBranches(MCInst &Inst,
|
||||
// classify tB as either t2B or t1B based on range of immediate operand
|
||||
case ARM::tB: {
|
||||
ARMOperand &op = static_cast<ARMOperand &>(*Operands[ImmOp]);
|
||||
if (!op.isSignedOffset<11, 1>() && isThumbTwo())
|
||||
if (!op.isSignedOffset<11, 1>() && isThumb() && hasV8MBaseline())
|
||||
Inst.setOpcode(ARM::t2B);
|
||||
break;
|
||||
}
|
||||
// classify tBcc as either t2Bcc or t1Bcc based on range of immediate operand
|
||||
case ARM::tBcc: {
|
||||
ARMOperand &op = static_cast<ARMOperand &>(*Operands[ImmOp]);
|
||||
if (!op.isSignedOffset<8, 1>() && isThumbTwo())
|
||||
if (!op.isSignedOffset<8, 1>() && isThumb() && hasV8MBaseline())
|
||||
Inst.setOpcode(ARM::t2Bcc);
|
||||
break;
|
||||
}
|
||||
|
@ -159,6 +159,7 @@ void ARMAsmBackend::handleAssemblerFlag(MCAssemblerFlag Flag) {
|
||||
|
||||
unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op) const {
|
||||
bool HasThumb2 = STI->getFeatureBits()[ARM::FeatureThumb2];
|
||||
bool HasV8MBaselineOps = STI->getFeatureBits()[ARM::HasV8MBaselineOps];
|
||||
|
||||
switch (Op) {
|
||||
default:
|
||||
@ -170,7 +171,7 @@ unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op) const {
|
||||
case ARM::tADR:
|
||||
return HasThumb2 ? (unsigned)ARM::t2ADR : Op;
|
||||
case ARM::tB:
|
||||
return HasThumb2 ? (unsigned)ARM::t2B : Op;
|
||||
return HasV8MBaselineOps ? (unsigned)ARM::t2B : Op;
|
||||
case ARM::tCBZ:
|
||||
return ARM::tHINT;
|
||||
case ARM::tCBNZ:
|
||||
@ -563,7 +564,8 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
|
||||
}
|
||||
case ARM::fixup_arm_thumb_br:
|
||||
// Offset by 4 and don't encode the lower bit, which is always 0.
|
||||
if (Ctx && !STI->getFeatureBits()[ARM::FeatureThumb2]) {
|
||||
if (Ctx && !STI->getFeatureBits()[ARM::FeatureThumb2] &&
|
||||
!STI->getFeatureBits()[ARM::HasV8MBaselineOps]) {
|
||||
const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
|
||||
if (FixupDiagnostic) {
|
||||
Ctx->reportError(Fixup.getLoc(), FixupDiagnostic);
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -mtriple=thumbv7-linux-gnueabi -O0 < %s | FileCheck %s
|
||||
; RUN: llc -mtriple=thumbv8m.base-arm-none-eabi -filetype=obj < %s
|
||||
|
||||
; Primarily a non-crash test: Thumbv7 Linux does not have FastISel support,
|
||||
; which led (via a convoluted route) to DAG nodes after a TC_RETURN that
|
||||
|
10
test/MC/ARM/thumb1-relax-8m-baseline.s
Normal file
10
test/MC/ARM/thumb1-relax-8m-baseline.s
Normal file
@ -0,0 +1,10 @@
|
||||
@ RUN: not llvm-mc -triple thumbv6m-none-eabi -filetype=obj -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=CHECK-V6M
|
||||
@ RUN: llvm-mc -triple thumbv8m.base-none-eabi -filetype=obj -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=CHECK-V8MBASE --allow-empty
|
||||
|
||||
@ CHECK-V8MBASE-NOT: out of range pc-relative fixup value
|
||||
@ CHECK-V6M: out of range pc-relative fixup value
|
||||
b Lfar2
|
||||
|
||||
.space 2050
|
||||
Lfar2:
|
||||
.word 42
|
@ -23,6 +23,18 @@ isb sy
|
||||
|
||||
// 'Code optimization'
|
||||
|
||||
// CHECK: cbz r3, .Ltmp0 @ encoding: [0x03'A',0xb1'A']
|
||||
// CHECK-NEXT: @ fixup A - offset: 0, value: .Ltmp0, kind: fixup_arm_thumb_cb
|
||||
cbz r3, 1f
|
||||
|
||||
// CHECK: cbnz r3, .Ltmp0 @ encoding: [0x03'A',0xb9'A']
|
||||
// CHECK-NEXT: @ fixup A - offset: 0, value: .Ltmp0, kind: fixup_arm_thumb_cb
|
||||
cbnz r3, 1f
|
||||
|
||||
// CHECK: b.w .Ltmp0 @ encoding: [A,0xf0'A',A,0x90'A']
|
||||
// CHECK-NEXT: @ fixup A - offset: 0, value: .Ltmp0, kind: fixup_t2_uncondbranch
|
||||
b.w 1f
|
||||
|
||||
// CHECK: sdiv r1, r2, r3 @ encoding: [0x92,0xfb,0xf3,0xf1]
|
||||
sdiv r1, r2, r3
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user