aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2011-07-08 22:36:29 +0000
committerEvan Cheng <evan.cheng@apple.com>2011-07-08 22:36:29 +0000
commit32869205052430f45d598fba25ab878d8b29da2d (patch)
tree49a7040cd53cda26dff8888b4aba41d629fc2a30 /lib/Target/ARM/AsmParser/ARMAsmParser.cpp
parent7c3a5cac02d6676c6e9c55bf8d60bdfa38e3e00a (diff)
Add support for ARM / Thumb mode switching with .code 16 and .code 32.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134760 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/AsmParser/ARMAsmParser.cpp')
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp46
1 files changed, 30 insertions, 16 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 9438ee1775..58ffe32333 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -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);
}