aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp14
-rw-r--r--lib/Target/X86/X86InstrInfo.td44
-rw-r--r--test/MC/AsmParser/X86/x86_instructions.s68
3 files changed, 120 insertions, 6 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 3a8f5d5565..b5e5f8b137 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -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)) {
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index d7fc23e882..5c9498c64f 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -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", []>;
diff --git a/test/MC/AsmParser/X86/x86_instructions.s b/test/MC/AsmParser/X86/x86_instructions.s
index a1b881b315..06a1907f23 100644
--- a/test/MC/AsmParser/X86/x86_instructions.s
+++ b/test/MC/AsmParser/X86/x86_instructions.s
@@ -70,3 +70,71 @@
// 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
+