Added support for X86 instruction prefixes so llvm-mc can assemble them. The
authorKevin Enderby <enderby@apple.com>
Wed, 3 Feb 2010 21:04:42 +0000 (21:04 +0000)
committerKevin Enderby <enderby@apple.com>
Wed, 3 Feb 2010 21:04:42 +0000 (21:04 +0000)
Lock prefix, Repeat string operation prefixes and the Segment override prefixes.
Also added versions of the move string and store string instructions without the
repeat prefixes to X86InstrInfo.td. And finally marked the rep versions of
move/store string records in X86InstrInfo.td as isCodeGenOnly = 1 so tblgen is
happy building the disassembler files.

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

lib/Target/X86/AsmParser/X86AsmParser.cpp
lib/Target/X86/X86InstrInfo.td
test/MC/AsmParser/X86/x86_instructions.s

index 3a8f5d556500039e75df2f1de0dce35fde2640f0..b5e5f8b137ee1c0ebd3378693f4267a07a6d1b73 100644 (file)
@@ -462,8 +462,18 @@ ParseInstruction(const StringRef &Name, SMLoc NameLoc,
   if (Name.startswith("sal")) {
     std::string Tmp = "shl" + Name.substr(3).str();
     Operands.push_back(X86Operand::CreateToken(Tmp, NameLoc));
-  } else
-    Operands.push_back(X86Operand::CreateToken(Name, NameLoc));
+  } else {
+    // FIXME: This is a hack.  We eventually want to add a general pattern
+    // mechanism to be used in the table gen file for these assembly names that
+    // use the same opcodes.  Also we should only allow the "alternate names"
+    // for rep and repne with the instructions they can only appear with.
+    StringRef PatchedName = Name;
+    if (Name == "repe" || Name == "repz")
+      PatchedName = "rep";
+    else if (Name == "repnz")
+      PatchedName = "repne";
+    Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc));
+  }
 
   if (getLexer().isNot(AsmToken::EndOfStatement)) {
 
index d7fc23e882689fecfcbfeb90b9c7fee2b6fd1283..5c9498c64f6ddb9c5f66866ca4989faadad48dd5 100644 (file)
@@ -883,7 +883,7 @@ def LEA32r   : I<0x8D, MRMSrcMem,
                  "lea{l}\t{$src|$dst}, {$dst|$src}",
                  [(set GR32:$dst, lea32addr:$src)]>, Requires<[In32BitMode]>;
 
-let Defs = [ECX,EDI,ESI], Uses = [ECX,EDI,ESI] in {
+let Defs = [ECX,EDI,ESI], Uses = [ECX,EDI,ESI], isCodeGenOnly = 1 in {
 def REP_MOVSB : I<0xA4, RawFrm, (outs), (ins), "{rep;movsb|rep movsb}",
                   [(X86rep_movs i8)]>, REP;
 def REP_MOVSW : I<0xA5, RawFrm, (outs), (ins), "{rep;movsw|rep movsw}",
@@ -892,16 +892,31 @@ def REP_MOVSD : I<0xA5, RawFrm, (outs), (ins), "{rep;movsl|rep movsd}",
                   [(X86rep_movs i32)]>, REP;
 }
 
-let Defs = [ECX,EDI], Uses = [AL,ECX,EDI] in
+// These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
+let Defs = [EDI,ESI], Uses = [EDI,ESI,EFLAGS] in {
+def MOVSB : I<0xA4, RawFrm, (outs), (ins), "{movsb}", []>;
+def MOVSW : I<0xA5, RawFrm, (outs), (ins), "{movsw}", []>, OpSize;
+def MOVSD : I<0xA5, RawFrm, (outs), (ins), "{movsl|movsd}", []>;
+}
+
+let Defs = [ECX,EDI], Uses = [AL,ECX,EDI], isCodeGenOnly = 1 in
 def REP_STOSB : I<0xAA, RawFrm, (outs), (ins), "{rep;stosb|rep stosb}",
                   [(X86rep_stos i8)]>, REP;
-let Defs = [ECX,EDI], Uses = [AX,ECX,EDI] in
+let Defs = [ECX,EDI], Uses = [AX,ECX,EDI], isCodeGenOnly = 1 in
 def REP_STOSW : I<0xAB, RawFrm, (outs), (ins), "{rep;stosw|rep stosw}",
                   [(X86rep_stos i16)]>, REP, OpSize;
-let Defs = [ECX,EDI], Uses = [EAX,ECX,EDI] in
+let Defs = [ECX,EDI], Uses = [EAX,ECX,EDI], isCodeGenOnly = 1 in
 def REP_STOSD : I<0xAB, RawFrm, (outs), (ins), "{rep;stosl|rep stosd}",
                   [(X86rep_stos i32)]>, REP;
 
+// These uses the DF flag in the EFLAGS register to inc or dec EDI and ESI
+let Defs = [EDI], Uses = [AL,EDI,EFLAGS] in
+def STOSB : I<0xAA, RawFrm, (outs), (ins), "{stosb}", []>;
+let Defs = [EDI], Uses = [AX,EDI,EFLAGS] in
+def STOSW : I<0xAB, RawFrm, (outs), (ins), "{stosw}", []>, OpSize;
+let Defs = [EDI], Uses = [EAX,EDI,EFLAGS] in
+def STOSD : I<0xAB, RawFrm, (outs), (ins), "{stosl|stosd}", []>;
+
 def SCAS8 : I<0xAE, RawFrm, (outs), (ins), "scas{b}", []>;
 def SCAS16 : I<0xAF, RawFrm, (outs), (ins), "scas{w}", []>, OpSize;
 def SCAS32 : I<0xAF, RawFrm, (outs), (ins), "scas{l}", []>;
@@ -1002,6 +1017,7 @@ def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
                    "mov{l}\t{$src, $dst|$dst, $src}",
                    [(set GR32:$dst, imm:$src)]>;
 }
+
 def MOV8mi  : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
                    "mov{b}\t{$src, $dst|$dst, $src}",
                    [(store (i8 imm:$src), addr:$dst)]>;
@@ -4161,6 +4177,26 @@ def LLDT16r : I<0x00, MRM2r, (outs), (ins GR16:$src),
 def LLDT16m : I<0x00, MRM2m, (outs), (ins i16mem:$src),
                 "lldt{w}\t$src", []>, TB;
                 
+// Lock instruction prefix
+def LOCK_PREFIX : I<0xF0, RawFrm, (outs),  (ins), "lock", []>;
+
+// Repeat string operation instruction prefixes
+// These uses the DF flag in the EFLAGS register to inc or dec ECX
+let Defs = [ECX], Uses = [ECX,EFLAGS] in {
+// Repeat (used with INS, OUTS, MOVS, LODS and STOS)
+def REP_PREFIX : I<0xF3, RawFrm, (outs),  (ins), "rep", []>;
+// Repeat while not equal (used with CMPS and SCAS)
+def REPNE_PREFIX : I<0xF2, RawFrm, (outs),  (ins), "repne", []>;
+}
+
+// Segment override instruction prefixes
+def CS_PREFIX : I<0x2E, RawFrm, (outs),  (ins), "cs", []>;
+def SS_PREFIX : I<0x36, RawFrm, (outs),  (ins), "ss", []>;
+def DS_PREFIX : I<0x3E, RawFrm, (outs),  (ins), "ds", []>;
+def ES_PREFIX : I<0x26, RawFrm, (outs),  (ins), "es", []>;
+def FS_PREFIX : I<0x64, RawFrm, (outs),  (ins), "fs", []>;
+def GS_PREFIX : I<0x65, RawFrm, (outs),  (ins), "gs", []>;
+
 // String manipulation instructions
 
 def LODSB : I<0xAC, RawFrm, (outs), (ins), "lodsb", []>;
index a1b881b31577b0983560e8d0f56eb509cf92f99b..06a1907f23963f1a9657ce77899825dce0ef7545 100644 (file)
 
 // CHECK: shll $2, %eax
         sall $2, %eax
+
+// CHECK: rep
+// CHECK: insb
+        rep;insb
+
+// CHECK: rep
+// CHECK: outsb
+        rep;outsb
+
+// CHECK: rep
+// CHECK: movsb
+        rep;movsb
+
+// CHECK: rep
+// CHECK: lodsb
+        rep;lodsb
+
+// CHECK: rep
+// CHECK: stosb
+        rep;stosb
+
+// NOTE: repz and repe have the same opcode as rep
+// CHECK: rep
+// CHECK: cmpsb
+        repz;cmpsb
+
+// NOTE: repnz has the same opcode as repne
+// CHECK: repne
+// CHECK: cmpsb
+        repnz;cmpsb
+
+// NOTE: repe and repz have the same opcode as rep
+// CHECK: rep
+// CHECK: scasb
+        repe;scasb
+
+// CHECK: repne
+// CHECK: scasb
+        repne;scasb
+
+// CHECK: lock
+// CHECK: cmpxchgb %al, 0(%ebx)
+        lock;cmpxchgb %al, 0(%ebx)
+
+// CHECK: cs
+// CHECK: movb 0(%eax), %al
+        cs;movb 0(%eax), %al
+
+// CHECK: ss
+// CHECK: movb 0(%eax), %al
+        ss;movb 0(%eax), %al
+
+// CHECK: ds
+// CHECK: movb 0(%eax), %al
+        ds;movb 0(%eax), %al
+
+// CHECK: es
+// CHECK: movb 0(%eax), %al
+        es;movb 0(%eax), %al
+
+// CHECK: fs
+// CHECK: movb 0(%eax), %al
+        fs;movb 0(%eax), %al
+
+// CHECK: gs
+// CHECK: movb 0(%eax), %al
+        gs;movb 0(%eax), %al
+