Add support for ARM / Thumb mode switching with .code 16 and .code 32.

llvm-svn: 134760
This commit is contained in:
Evan Cheng 2011-07-08 22:36:29 +00:00
parent d0f0600b49
commit 284b467d9f
2 changed files with 46 additions and 16 deletions

View File

@ -42,7 +42,11 @@ class ARMOperand;
class ARMAsmParser : public TargetAsmParser {
MCAsmParser &Parser;
OwningPtr<const MCSubtargetInfo> STI;
/// STI, ARM_STI, Thumb_STI - Subtarget info for ARM and Thumb modes. STI
/// points to either ARM_STI or Thumb_STI depending on the mode.
const MCSubtargetInfo *STI;
OwningPtr<const MCSubtargetInfo> ARM_STI;
OwningPtr<const MCSubtargetInfo> Thumb_STI;
MCAsmParser &getParser() const { return Parser; }
MCAsmLexer &getLexer() const { return Parser.getLexer(); }
@ -89,10 +93,13 @@ class ARMAsmParser : public TargetAsmParser {
// FIXME: Can tablegen auto-generate this?
return (STI->getFeatureBits() & ARM::ModeThumb) != 0;
}
bool isThumbOne() const {
return isThumb() && (STI->getFeatureBits() & ARM::FeatureThumb2) == 0;
}
void SwitchMode() {
STI = isThumb() ? ARM_STI.get() : Thumb_STI.get();
setAvailableFeatures(ComputeAvailableFeatures(STI->getFeatureBits()));
}
/// @name Auto-generated Match Functions
/// {
@ -129,10 +136,24 @@ class ARMAsmParser : public TargetAsmParser {
public:
ARMAsmParser(StringRef TT, StringRef CPU, StringRef FS, MCAsmParser &_Parser)
: TargetAsmParser(), Parser(_Parser),
STI(ARM_MC::createARMMCSubtargetInfo(TT, CPU, FS)) {
: TargetAsmParser(), Parser(_Parser) {
MCAsmParserExtension::Initialize(_Parser);
STI = ARM_MC::createARMMCSubtargetInfo(TT, CPU, FS);
// FIXME: Design a better way to create two subtargets with only difference
// being a feature change.
if (isThumb()) {
Thumb_STI.reset(STI);
assert(TT.startswith("thumb") && "Unexpected Triple string for Thumb!");
Twine ARM_TT = "arm" + TT.substr(5);
ARM_STI.reset(ARM_MC::createARMMCSubtargetInfo(ARM_TT.str(), CPU, FS));
} else {
ARM_STI.reset(STI);
assert(TT.startswith("arm") && "Unexpected Triple string for ARM!");
Twine Thumb_TT = "thumb" + TT.substr(3);
Thumb_STI.reset(ARM_MC::createARMMCSubtargetInfo(Thumb_TT.str(),CPU, FS));
}
// Initialize the set of available features.
setAvailableFeatures(ComputeAvailableFeatures(STI->getFeatureBits()));
}
@ -2215,18 +2236,11 @@ bool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
return Error(Parser.getTok().getLoc(), "unexpected token in directive");
Parser.Lex();
// FIXME: We need to be able switch subtargets at this point so that
// MatchInstructionImpl() will work when it gets the AvailableFeatures which
// includes Feature_IsThumb or not to match the right instructions. This is
// blocked on the FIXME in llvm-mc.cpp when creating the TargetMachine.
if (Val == 16){
assert(isThumb() &&
"switching between arm/thumb not yet suppported via .code 16)");
if (Val == 16) {
if (!isThumb()) SwitchMode();
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
}
else{
assert(!isThumb() &&
"switching between thumb/arm not yet suppported via .code 32)");
} else {
if (isThumb()) SwitchMode();
getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
}

View File

@ -0,0 +1,16 @@
@ Test ARM / Thumb mode switching with .code
@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding < %s | FileCheck %s
.code 16
@ CHECK: add.w r0, r0, r1 @ encoding: [0x01,0x00,0x00,0xeb]
add.w r0, r0, r1
.code 32
@ CHECK: add r0, r0, r1 @ encoding: [0x01,0x00,0x80,0xe0]
add r0, r0, r1
.code 16
@ CHECK: add r0, r0, r1 @ encoding: [0x40,0x18]
add r0, r0, r1