mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
ARM: diagnose ARM/Thumb assembly switches on CPUs only supporting one.
Some ARM CPUs only support ARM mode (ancient v4 ones, for example) and some only support Thumb mode (M-class ones currently). This makes sure such CPUs default to the correct mode and makes the AsmParser diagnose an attempt to switch modes incorrectly. rdar://14024354 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183710 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
45dec48dc3
commit
9bdd785014
@ -38,7 +38,8 @@ def FeatureNEON : SubtargetFeature<"neon", "HasNEON", "true",
|
|||||||
def FeatureThumb2 : SubtargetFeature<"thumb2", "HasThumb2", "true",
|
def FeatureThumb2 : SubtargetFeature<"thumb2", "HasThumb2", "true",
|
||||||
"Enable Thumb2 instructions">;
|
"Enable Thumb2 instructions">;
|
||||||
def FeatureNoARM : SubtargetFeature<"noarm", "NoARM", "true",
|
def FeatureNoARM : SubtargetFeature<"noarm", "NoARM", "true",
|
||||||
"Does not support ARM mode execution">;
|
"Does not support ARM mode execution",
|
||||||
|
[ModeThumb]>;
|
||||||
def FeatureFP16 : SubtargetFeature<"fp16", "HasFP16", "true",
|
def FeatureFP16 : SubtargetFeature<"fp16", "HasFP16", "true",
|
||||||
"Enable half-precision floating point">;
|
"Enable half-precision floating point">;
|
||||||
def FeatureVFP4 : SubtargetFeature<"vfp4", "HasVFPv4", "true",
|
def FeatureVFP4 : SubtargetFeature<"vfp4", "HasVFPv4", "true",
|
||||||
|
@ -152,12 +152,19 @@ class ARMAsmParser : public MCTargetAsmParser {
|
|||||||
bool isThumbTwo() const {
|
bool isThumbTwo() const {
|
||||||
return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
|
return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
|
||||||
}
|
}
|
||||||
|
bool hasThumb() const {
|
||||||
|
return STI.getFeatureBits() & ARM::HasV4TOps;
|
||||||
|
}
|
||||||
bool hasV6Ops() const {
|
bool hasV6Ops() const {
|
||||||
return STI.getFeatureBits() & ARM::HasV6Ops;
|
return STI.getFeatureBits() & ARM::HasV6Ops;
|
||||||
}
|
}
|
||||||
bool hasV7Ops() const {
|
bool hasV7Ops() const {
|
||||||
return STI.getFeatureBits() & ARM::HasV7Ops;
|
return STI.getFeatureBits() & ARM::HasV7Ops;
|
||||||
}
|
}
|
||||||
|
bool hasARM() const {
|
||||||
|
return !(STI.getFeatureBits() & ARM::FeatureNoARM);
|
||||||
|
}
|
||||||
|
|
||||||
void SwitchMode() {
|
void SwitchMode() {
|
||||||
unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
|
unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
|
||||||
setAvailableFeatures(FB);
|
setAvailableFeatures(FB);
|
||||||
@ -7816,6 +7823,9 @@ bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
|
|||||||
return Error(L, "unexpected token in directive");
|
return Error(L, "unexpected token in directive");
|
||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
|
|
||||||
|
if (!hasThumb())
|
||||||
|
return Error(L, "target does not support Thumb mode");
|
||||||
|
|
||||||
if (!isThumb())
|
if (!isThumb())
|
||||||
SwitchMode();
|
SwitchMode();
|
||||||
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
|
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
|
||||||
@ -7829,6 +7839,9 @@ bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
|
|||||||
return Error(L, "unexpected token in directive");
|
return Error(L, "unexpected token in directive");
|
||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
|
|
||||||
|
if (!hasARM())
|
||||||
|
return Error(L, "target does not support ARM mode");
|
||||||
|
|
||||||
if (isThumb())
|
if (isThumb())
|
||||||
SwitchMode();
|
SwitchMode();
|
||||||
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
|
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
|
||||||
@ -7918,10 +7931,16 @@ bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
|
|||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
|
|
||||||
if (Val == 16) {
|
if (Val == 16) {
|
||||||
|
if (!hasThumb())
|
||||||
|
return Error(L, "target does not support Thumb mode");
|
||||||
|
|
||||||
if (!isThumb())
|
if (!isThumb())
|
||||||
SwitchMode();
|
SwitchMode();
|
||||||
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
|
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
|
||||||
} else {
|
} else {
|
||||||
|
if (!hasARM())
|
||||||
|
return Error(L, "target does not support ARM mode");
|
||||||
|
|
||||||
if (isThumb())
|
if (isThumb())
|
||||||
SwitchMode();
|
SwitchMode();
|
||||||
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
|
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
|
||||||
|
@ -61,6 +61,7 @@ std::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) {
|
|||||||
unsigned SubVer = TT[Idx];
|
unsigned SubVer = TT[Idx];
|
||||||
if (SubVer >= '7' && SubVer <= '9') {
|
if (SubVer >= '7' && SubVer <= '9') {
|
||||||
if (Len >= Idx+2 && TT[Idx+1] == 'm') {
|
if (Len >= Idx+2 && TT[Idx+1] == 'm') {
|
||||||
|
isThumb = true;
|
||||||
if (NoCPU)
|
if (NoCPU)
|
||||||
// v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass
|
// v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass
|
||||||
ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass";
|
ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass";
|
||||||
@ -99,6 +100,7 @@ std::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) {
|
|||||||
if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
|
if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
|
||||||
ARMArchFeature = "+v6t2";
|
ARMArchFeature = "+v6t2";
|
||||||
else if (Len >= Idx+2 && TT[Idx+1] == 'm') {
|
else if (Len >= Idx+2 && TT[Idx+1] == 'm') {
|
||||||
|
isThumb = true;
|
||||||
if (NoCPU)
|
if (NoCPU)
|
||||||
// v6m: FeatureNoARM, FeatureMClass
|
// v6m: FeatureNoARM, FeatureMClass
|
||||||
ARMArchFeature = "+v6,+noarm,+mclass";
|
ARMArchFeature = "+v6,+noarm,+mclass";
|
||||||
|
13
test/MC/ARM/arm-thumb-cpus-default.s
Normal file
13
test/MC/ARM/arm-thumb-cpus-default.s
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
@ RUN: llvm-mc -show-encoding -arch=arm < %s | FileCheck %s --check-prefix=CHECK-ARM-ONLY
|
||||||
|
@ RUN: llvm-mc -show-encoding -triple=armv4t < %s | FileCheck %s --check-prefix=CHECK-ARM-THUMB
|
||||||
|
@ RUN: llvm-mc -show-encoding -arch=arm -mcpu=cortex-a15 < %s| FileCheck %s --check-prefix=CHECK-ARM-THUMB
|
||||||
|
@ RUN: llvm-mc -show-encoding -arch=arm -mcpu=cortex-m3 < %s | FileCheck %s --check-prefix=CHECK-THUMB-ONLY
|
||||||
|
@ RUN: llvm-mc -show-encoding -triple=armv7m < %s | FileCheck %s --check-prefix=CHECK-THUMB-ONLY
|
||||||
|
@ RUN: llvm-mc -show-encoding -triple=armv6m < %s | FileCheck %s --check-prefix=CHECK-THUMB-ONLY
|
||||||
|
|
||||||
|
@ Make sure the architecture chosen by LLVM defaults to a compatible
|
||||||
|
@ ARM/Thumb mode.
|
||||||
|
movs r0, r0
|
||||||
|
@ CHECK-ARM-THUMB: movs r0, r0 @ encoding: [0x00,0x00,0xb0,0xe1]
|
||||||
|
@ CHECK-ARM-ONLY: movs r0, r0 @ encoding: [0x00,0x00,0xb0,0xe1]
|
||||||
|
@ CHECK-THUMB-ONLY: movs r0, r0 @ encoding: [0x00,0x00]
|
20
test/MC/ARM/arm-thumb-cpus.s
Normal file
20
test/MC/ARM/arm-thumb-cpus.s
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
@ RUN: llvm-mc -show-encoding -arch=arm < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ARM-ONLY
|
||||||
|
@ RUN: llvm-mc -show-encoding -triple=armv4t < %s 2>&1| FileCheck %s --check-prefix=CHECK-ARM-THUMB
|
||||||
|
@ RUN: llvm-mc -show-encoding -arch=arm -mcpu=cortex-a15 < %s 2>&1| FileCheck %s --check-prefix=CHECK-ARM-THUMB
|
||||||
|
@ RUN: llvm-mc -show-encoding -arch=arm -mcpu=cortex-m3 < %s 2>&1 | FileCheck %s --check-prefix=CHECK-THUMB-ONLY
|
||||||
|
@ RUN: llvm-mc -show-encoding -triple=armv7m < %s 2>&1 | FileCheck %s --check-prefix=CHECK-THUMB-ONLY
|
||||||
|
@ RUN: llvm-mc -show-encoding -triple=armv6m < %s 2>&1 | FileCheck %s --check-prefix=CHECK-THUMB-ONLY
|
||||||
|
|
||||||
|
@ Make sure correct diagnostics are given for CPUs without support for
|
||||||
|
@ one or other of the execution states.
|
||||||
|
.thumb
|
||||||
|
.arm
|
||||||
|
.code 16
|
||||||
|
.code 32
|
||||||
|
@ CHECK-ARM-THUMB-NOT: target does not support
|
||||||
|
|
||||||
|
@ CHECK-ARM-ONLY: target does not support Thumb mode
|
||||||
|
@ CHECK-ARM-ONLY: target does not support Thumb mode
|
||||||
|
|
||||||
|
@ CHECK-THUMB-ONLY: target does not support ARM mode
|
||||||
|
@ CHECK-THUMB-ONLY: target does not support ARM mode
|
@ -1,5 +1,5 @@
|
|||||||
@@ test st_value bit 0 of thumb function
|
@@ test st_value bit 0 of thumb function
|
||||||
@ RUN: llvm-mc %s -triple=arm-freebsd-eabi -filetype=obj -o - | \
|
@ RUN: llvm-mc %s -triple=armv4t-freebsd-eabi -filetype=obj -o - | \
|
||||||
@ RUN: llvm-readobj -r | FileCheck %s
|
@ RUN: llvm-readobj -r | FileCheck %s
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@ RUN: llvm-mc -triple=arm-linux-gnueabi -filetype=obj < %s | llvm-objdump -t - | FileCheck %s
|
@ RUN: llvm-mc -triple=armv7-linux-gnueabi -filetype=obj < %s | llvm-objdump -t - | FileCheck %s
|
||||||
|
|
||||||
.text
|
.text
|
||||||
@ $a at 0x0000
|
@ $a at 0x0000
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@ RUN: llvm-mc -triple=arm-linux-gnueabi -filetype=obj < %s | llvm-objdump -t - | FileCheck %s
|
@ RUN: llvm-mc -triple=armv7-linux-gnueabi -filetype=obj < %s | llvm-objdump -t - | FileCheck %s
|
||||||
|
|
||||||
.text
|
.text
|
||||||
add r0, r0, r0
|
add r0, r0, r0
|
||||||
|
Loading…
Reference in New Issue
Block a user