lib/Target/X86/X86MCAsmInfo.cpp: [PR8741] On Win64, specify explicit PrivateGlobalPre...
[oota-llvm.git] / lib / Target / X86 / AsmParser / X86AsmParser.cpp
index 4ab25cf4bf8eb43e4f75bc59d1090f07f5b1a9cd..1064effbbc67cd4d6dbbc8cb28b6d39bff3c8821 100644 (file)
@@ -622,6 +622,11 @@ ParseInstruction(StringRef Name, SMLoc NameLoc,
                  SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
   StringRef PatchedName = Name;
 
+  // FIXME: Hack to recognize setneb as setne.
+  if (PatchedName.startswith("set") && PatchedName.endswith("b") &&
+      PatchedName != "setb" && PatchedName != "setnb")
+    PatchedName = PatchedName.substr(0, Name.size()-1);
+  
   // FIXME: Hack to recognize cmp<comparison code>{ss,sd,ps,pd}.
   const MCExpr *ExtraImmOp = 0;
   if ((PatchedName.startswith("cmp") || PatchedName.startswith("vcmp")) &&
@@ -707,7 +712,8 @@ ParseInstruction(StringRef Name, SMLoc NameLoc,
   bool isPrefix =
     Name == "lock" || Name == "rep" ||
     Name == "repe" || Name == "repz" ||
-    Name == "repne" || Name == "repnz";
+    Name == "repne" || Name == "repnz" ||
+    Name == "rex64" || Name == "data16";
 
 
   // This does the actual operand parsing.  Don't parse any more if we have a
@@ -744,44 +750,18 @@ ParseInstruction(StringRef Name, SMLoc NameLoc,
     }
 
     if (getLexer().isNot(AsmToken::EndOfStatement)) {
+      SMLoc Loc = getLexer().getLoc();
       Parser.EatToEndOfStatement();
-      return TokError("unexpected token in argument list");
+      return Error(Loc, "unexpected token in argument list");
     }
   }
 
   if (getLexer().is(AsmToken::EndOfStatement))
     Parser.Lex(); // Consume the EndOfStatement
 
-  // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>.  Canonicalize to
-  // "shift <op>".
-  if ((Name.startswith("shr") || Name.startswith("sar") ||
-       Name.startswith("shl") || Name.startswith("sal")) &&
-      Operands.size() == 3) {
-    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
-    if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
-        cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
-      delete Operands[1];
-      Operands.erase(Operands.begin() + 1);
-    }
-  }
-
-  // FIXME: Hack to handle recognize "rc[lr] <op>" -> "rcl $1, <op>".
-  if ((Name.startswith("rcl") || Name.startswith("rcr")) &&
-      Operands.size() == 2) {
-    const MCExpr *One = MCConstantExpr::Create(1, getParser().getContext());
-    Operands.push_back(X86Operand::CreateImm(One, NameLoc, NameLoc));
-    std::swap(Operands[1], Operands[2]);
-  }
-
-  // FIXME: Hack to handle recognize "sh[lr]d op,op" -> "shld $1, op,op".
-  if ((Name.startswith("shld") || Name.startswith("shrd")) &&
-      Operands.size() == 3) {
-    const MCExpr *One = MCConstantExpr::Create(1, getParser().getContext());
-    Operands.insert(Operands.begin()+1,
-                    X86Operand::CreateImm(One, NameLoc, NameLoc));
-  }
-
-  // FIXME: Hack to handle "out[bwl]? %al, (%dx)" -> "outb %al, %dx".
+  // This is a terrible hack to handle "out[bwl]? %al, (%dx)" ->
+  // "outb %al, %dx".  Out doesn't take a memory form, but this is a widely
+  // documented form in various unofficial manuals, so a lot of code uses it.
   if ((Name == "outb" || Name == "outw" || Name == "outl" || Name == "out") &&
       Operands.size() == 3) {
     X86Operand &Op = *(X86Operand*)Operands.back();
@@ -794,56 +774,20 @@ ParseInstruction(StringRef Name, SMLoc NameLoc,
       delete &Op;
     }
   }
-
-  // FIXME: Hack to handle "f{mul*,add*,sub*,div*} $op, st(0)" the same as
-  // "f{mul*,add*,sub*,div*} $op"
-  if ((Name.startswith("fmul") || Name.startswith("fadd") ||
-       Name.startswith("fsub") || Name.startswith("fdiv")) &&
-      Operands.size() == 3 &&
-      static_cast<X86Operand*>(Operands[2])->isReg() &&
-      static_cast<X86Operand*>(Operands[2])->getReg() == X86::ST0) {
-    delete Operands[2];
-    Operands.erase(Operands.begin() + 2);
-  }
-
-  // FIXME: Hack to handle "f{mulp,addp} st(0), $op" the same as
-  // "f{mulp,addp} $op", since they commute.  We also allow fdivrp/fsubrp even
-  // though they don't commute, solely because gas does support this.
-  if ((Name=="fmulp" || Name=="faddp" || Name=="fsubrp" || Name=="fdivrp") &&
-      Operands.size() == 3 &&
-      static_cast<X86Operand*>(Operands[1])->isReg() &&
-      static_cast<X86Operand*>(Operands[1])->getReg() == X86::ST0) {
-    delete Operands[1];
-    Operands.erase(Operands.begin() + 1);
-  }
-
-  // The assembler accepts these instructions with no operand as a synonym for
-  // an instruction acting on st(1).  e.g. "fxch" -> "fxch %st(1)".
-  if ((Name == "fxch" || Name == "fucom" || Name == "fucomp" ||
-       Name == "faddp" || Name == "fsubp" || Name == "fsubrp" ||
-       Name == "fmulp" || Name == "fdivp" || Name == "fdivrp") &&
-      Operands.size() == 1) {
-    Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(1)"),
-                                             NameLoc, NameLoc));
-  }
-
-  // The assembler accepts these instructions with two few operands as a synonym
-  // for taking %st(1),%st(0) or X, %st(0).
-  if ((Name == "fcomi" || Name == "fucomi" || Name == "fucompi" ||
-       Name == "fcompi" ) &&
-      Operands.size() < 3) {
-    if (Operands.size() == 1)
-      Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(1)"),
-                                               NameLoc, NameLoc));
-    Operands.push_back(X86Operand::CreateReg(MatchRegisterName("st(0)"),
-                                             NameLoc, NameLoc));
-  }
-
-  // FIXME: Hack to handle recognize "aa[dm]" -> "aa[dm] $0xA".
-  if ((Name.startswith("aad") || Name.startswith("aam")) &&
-      Operands.size() == 1) {
-    const MCExpr *A = MCConstantExpr::Create(0xA, getParser().getContext());
-    Operands.push_back(X86Operand::CreateImm(A, NameLoc, NameLoc));
+  
+  // FIXME: Hack to handle recognize s{hr,ar,hl} $1, <op>.  Canonicalize to
+  // "shift <op>".
+  if ((Name.startswith("shr") || Name.startswith("sar") ||
+       Name.startswith("shl") || Name.startswith("sal") ||
+       Name.startswith("rcl") || Name.startswith("rcr") ||
+       Name.startswith("rol") || Name.startswith("ror")) &&
+      Operands.size() == 3) {
+    X86Operand *Op1 = static_cast<X86Operand*>(Operands[1]);
+    if (Op1->isImm() && isa<MCConstantExpr>(Op1->getImm()) &&
+        cast<MCConstantExpr>(Op1->getImm())->getValue() == 1) {
+      delete Operands[1];
+      Operands.erase(Operands.begin() + 1);
+    }
   }
 
   return false;
@@ -859,6 +803,8 @@ MatchAndEmitInstruction(SMLoc IDLoc,
 
   // First, handle aliases that expand to multiple instructions.
   // FIXME: This should be replaced with a real .td file alias mechanism.
+  // Also, MatchInstructionImpl should do actually *do* the EmitInstruction
+  // call.
   if (Op->getToken() == "fstsw" || Op->getToken() == "fstcw" ||
       Op->getToken() == "fstsww" || Op->getToken() == "fstcww" ||
       Op->getToken() == "finit" || Op->getToken() == "fsave" ||