Add an "msasm" flag to inline asm as suggested in PR 5125.
authorDale Johannesen <dalej@apple.com>
Tue, 13 Oct 2009 20:46:56 +0000 (20:46 +0000)
committerDale Johannesen <dalej@apple.com>
Tue, 13 Oct 2009 20:46:56 +0000 (20:46 +0000)
A little ugliness is accepted to keep the binary file format
compatible.  No functional change yet.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84020 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/InlineAsm.h
lib/AsmParser/LLLexer.cpp
lib/AsmParser/LLParser.cpp
lib/AsmParser/LLToken.h
lib/Bitcode/Reader/BitcodeReader.cpp
lib/Bitcode/Writer/BitcodeWriter.cpp
lib/VMCore/AsmWriter.cpp
lib/VMCore/Core.cpp
lib/VMCore/InlineAsm.cpp
test/Assembler/msasm.ll [new file with mode: 0644]

index e0d992be7eddc8e0f9232f07ffff90460b08b77e..bc55031b0d42e40cee5ae8ae8adc69f95ec35342 100644 (file)
@@ -31,18 +31,22 @@ class InlineAsm : public Value {
 
   std::string AsmString, Constraints;
   bool HasSideEffects;
+  bool IsMsAsm;
   
   InlineAsm(const FunctionType *Ty, const StringRef &AsmString,
-            const StringRef &Constraints, bool hasSideEffects);
+            const StringRef &Constraints, bool hasSideEffects,
+            bool isMsAsm = false);
   virtual ~InlineAsm();
 public:
 
   /// InlineAsm::get - Return the the specified uniqued inline asm string.
   ///
   static InlineAsm *get(const FunctionType *Ty, const StringRef &AsmString,
-                        const StringRef &Constraints, bool hasSideEffects);
+                        const StringRef &Constraints, bool hasSideEffects,
+                        bool isMsAsm = false);
   
   bool hasSideEffects() const { return HasSideEffects; }
+  bool isMsAsm() const { return IsMsAsm; }
   
   /// getType - InlineAsm's are always pointers.
   ///
index 16e0bd78c906a18e3eda29fdaba28fc35f2c5936..0e9f1a05fe3ebe8a7babeb1657e28b6fd144f84b 100644 (file)
@@ -529,6 +529,7 @@ lltok::Kind LLLexer::LexIdentifier() {
   KEYWORD(module);
   KEYWORD(asm);
   KEYWORD(sideeffect);
+  KEYWORD(msasm);
   KEYWORD(gc);
 
   KEYWORD(ccc);
index a1186ac9c7bceb8533a5bbdbbe3b7b61601e24f8..09bc5f736fc610d895dd74ad1f21c269508c8876 100644 (file)
@@ -1959,16 +1959,17 @@ bool LLParser::ParseValID(ValID &ID) {
     return false;
 
   case lltok::kw_asm: {
-    // ValID ::= 'asm' SideEffect? STRINGCONSTANT ',' STRINGCONSTANT
-    bool HasSideEffect;
+    // ValID ::= 'asm' SideEffect? MsAsm? STRINGCONSTANT ',' STRINGCONSTANT
+    bool HasSideEffect, MsAsm;
     Lex.Lex();
     if (ParseOptionalToken(lltok::kw_sideeffect, HasSideEffect) ||
+        ParseOptionalToken(lltok::kw_msasm, MsAsm) ||
         ParseStringConstant(ID.StrVal) ||
         ParseToken(lltok::comma, "expected comma in inline asm expression") ||
         ParseToken(lltok::StringConstant, "expected constraint string"))
       return true;
     ID.StrVal2 = Lex.getStrVal();
-    ID.UIntVal = HasSideEffect;
+    ID.UIntVal = HasSideEffect | ((unsigned)MsAsm<<1);
     ID.Kind = ValID::t_InlineAsm;
     return false;
   }
@@ -2368,7 +2369,7 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
       PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
     if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2))
       return Error(ID.Loc, "invalid type for inline asm constraint string");
-    V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal);
+    V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal&1, ID.UIntVal>>1);
     return false;
   } else if (ID.Kind == ValID::t_Metadata) {
     V = ID.MetadataVal;
index bfcb58e721433cb441091eab1d1d0ca92474015f..b3c59ee9d3604a7c38e8f71c93f54e1dd39a70b5 100644 (file)
@@ -62,6 +62,7 @@ namespace lltok {
     kw_module,
     kw_asm,
     kw_sideeffect,
+    kw_msasm,
     kw_gc,
     kw_dbg,
     kw_c,
index 50b99ae383b33cd93952f7a506b048b0e6fda83f..4eb12c69eb6ec58409a52c8aa3ab316498dfc9e9 100644 (file)
@@ -1164,7 +1164,8 @@ bool BitcodeReader::ParseConstants() {
     case bitc::CST_CODE_INLINEASM: {
       if (Record.size() < 2) return Error("Invalid INLINEASM record");
       std::string AsmStr, ConstrStr;
-      bool HasSideEffects = Record[0];
+      bool HasSideEffects = Record[0] & 1;
+      bool IsMsAsm = Record[0] >> 1;
       unsigned AsmStrSize = Record[1];
       if (2+AsmStrSize >= Record.size())
         return Error("Invalid INLINEASM record");
@@ -1178,7 +1179,7 @@ bool BitcodeReader::ParseConstants() {
         ConstrStr += (char)Record[3+AsmStrSize+i];
       const PointerType *PTy = cast<PointerType>(CurTy);
       V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()),
-                         AsmStr, ConstrStr, HasSideEffects);
+                         AsmStr, ConstrStr, HasSideEffects, IsMsAsm);
       break;
     }
     }
index 2c45b342e54a1c76ff0340e7a4cf1218a47bc966..12a1f5ea5dc2edc00277cfb73aa18f5eee728c2a 100644 (file)
@@ -679,7 +679,8 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
     }
 
     if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
-      Record.push_back(unsigned(IA->hasSideEffects()));
+      Record.push_back(unsigned(IA->hasSideEffects()) |
+                       unsigned(IA->isMsAsm()) << 1);
 
       // Add the asm string.
       const std::string &AsmStr = IA->getAsmString();
index 3e628ae0d08b9dad7c796a13fce4f10837040e18..b5ae81b50f979b141c52d6cdedaa72cbf92c2957 100644 (file)
@@ -1206,6 +1206,8 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
     Out << "asm ";
     if (IA->hasSideEffects())
       Out << "sideeffect ";
+    if (IA->isMsAsm())
+      Out << "msasm ";
     Out << '"';
     PrintEscapedString(IA->getAsmString(), Out);
     Out << "\", \"";
index 47a8e1bfe008917f399e07668677c38092652b3c..bff308727fe12c9d4bf589eaf8ee96be9bd7bb3f 100644 (file)
@@ -884,9 +884,10 @@ LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant,
 }
 
 LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty, const char *AsmString, 
-                                const char *Constraints, int HasSideEffects) {
+                                const char *Constraints, int HasSideEffects,
+                                int IsMsAsm) {
   return wrap(InlineAsm::get(dyn_cast<FunctionType>(unwrap(Ty)), AsmString, 
-                             Constraints, HasSideEffects));
+                             Constraints, HasSideEffects, IsMsAsm));
 }
 
 /*--.. Operations on global variables, functions, and aliases (globals) ....--*/
index fbd6b90f938e880d8426e95a5d67b0267fbcbc61..0520dfa17cedadf96ab4423b588ea2155501417e 100644 (file)
@@ -27,17 +27,19 @@ InlineAsm::~InlineAsm() {
 // case when the type gets refined.
 
 InlineAsm *InlineAsm::get(const FunctionType *Ty, const StringRef &AsmString,
-                          const StringRef &Constraints, bool hasSideEffects) {
+                          const StringRef &Constraints, bool hasSideEffects,
+                          bool isMsAsm) {
   // FIXME: memoize!
-  return new InlineAsm(Ty, AsmString, Constraints, hasSideEffects);  
+  return new InlineAsm(Ty, AsmString, Constraints, hasSideEffects, isMsAsm);  
 }
 
 InlineAsm::InlineAsm(const FunctionType *Ty, const StringRef &asmString,
-                     const StringRef &constraints, bool hasSideEffects)
+                     const StringRef &constraints, bool hasSideEffects,
+                     bool isMsAsm)
   : Value(PointerType::getUnqual(Ty), 
           Value::InlineAsmVal), 
     AsmString(asmString), 
-    Constraints(constraints), HasSideEffects(hasSideEffects) {
+    Constraints(constraints), HasSideEffects(hasSideEffects), IsMsAsm(isMsAsm) {
 
   // Do various checks on the constraint string and type.
   assert(Verify(Ty, constraints) && "Function type not legal for constraints!");
diff --git a/test/Assembler/msasm.ll b/test/Assembler/msasm.ll
new file mode 100644 (file)
index 0000000..5e32963
--- /dev/null
@@ -0,0 +1,36 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i386-apple-darwin10.0"
+
+define void @test1() nounwind {
+; CHECK: test1
+; CHECK: sideeffect
+; CHECK-NOT: msasm
+       tail call void asm sideeffect "mov", "~{dirflag},~{fpsr},~{flags}"() nounwind
+       ret void
+; CHECK: ret
+}
+define void @test2() nounwind {
+; CHECK: test2
+; CHECK: sideeffect
+; CHECK: msasm
+       tail call void asm sideeffect msasm "mov", "~{dirflag},~{fpsr},~{flags}"() nounwind
+       ret void
+; CHECK: ret
+}
+define void @test3() nounwind {
+; CHECK: test3
+; CHECK-NOT: sideeffect
+; CHECK: msasm
+       tail call void asm msasm "mov", "~{dirflag},~{fpsr},~{flags}"() nounwind
+       ret void
+; CHECK: ret
+}
+define void @test4() nounwind {
+; CHECK: test4
+; CHECK-NOT: sideeffect
+; CHECK-NOT: msasm
+       tail call void asm  "mov", "~{dirflag},~{fpsr},~{flags}"() nounwind
+       ret void
+; CHECK: ret
+}