aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlkis Evlogimenos <alkis@evlogimenos.com>2004-02-28 22:02:05 +0000
committerAlkis Evlogimenos <alkis@evlogimenos.com>2004-02-28 22:02:05 +0000
commit5ab29b504d49d3fa84d76f79e73704260f900682 (patch)
tree2326ad9d7d7f897f547d9cc9507312d40346d3ae
parentf822ee999f12e38eebf4a346f384d4bb302bdfad (diff)
Each instruction now has both an ImmType and a MemType. This describes
the size of the immediate and the memory operand on instructions that use them. This resolves problems with instructions that take both a memory and an immediate operand but their sizes differ (i.e. ADDmi32b). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11967 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/Printer.cpp16
-rw-r--r--lib/Target/X86/X86.td8
-rw-r--r--lib/Target/X86/X86AsmPrinter.cpp16
-rw-r--r--lib/Target/X86/X86CodeEmitter.cpp70
-rw-r--r--lib/Target/X86/X86InstrInfo.h32
-rw-r--r--lib/Target/X86/X86InstrInfo.td900
6 files changed, 542 insertions, 500 deletions
diff --git a/lib/Target/X86/Printer.cpp b/lib/Target/X86/Printer.cpp
index df6c41cc4a..34061852b2 100644
--- a/lib/Target/X86/Printer.cpp
+++ b/lib/Target/X86/Printer.cpp
@@ -433,16 +433,14 @@ void Printer::printOp(const MachineOperand &MO,
}
}
-static const std::string sizePtr(const TargetInstrDescriptor &Desc) {
- switch (Desc.TSFlags & X86II::ArgMask) {
+static const char* const sizePtr(const TargetInstrDescriptor &Desc) {
+ switch (Desc.TSFlags & X86II::MemMask) {
default: assert(0 && "Unknown arg size!");
- case X86II::Arg8: return "BYTE PTR";
- case X86II::Arg16: return "WORD PTR";
- case X86II::Arg32: return "DWORD PTR";
- case X86II::Arg64: return "QWORD PTR";
- case X86II::ArgF32: return "DWORD PTR";
- case X86II::ArgF64: return "QWORD PTR";
- case X86II::ArgF80: return "XWORD PTR";
+ case X86II::Mem8: return "BYTE PTR";
+ case X86II::Mem16: return "WORD PTR";
+ case X86II::Mem32: return "DWORD PTR";
+ case X86II::Mem64: return "QWORD PTR";
+ case X86II::Mem80: return "XWORD PTR";
}
}
diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td
index d26ef9a73c..f92bfa10fc 100644
--- a/lib/Target/X86/X86.td
+++ b/lib/Target/X86/X86.td
@@ -33,10 +33,10 @@ def X86InstrInfo : InstrInfo {
// Define how we want to layout our TargetSpecific information field... This
// should be kept up-to-date with the fields in the X86InstrInfo.h file.
- let TSFlagsFields = ["FormBits" , "hasOpSizePrefix" , "Prefix", "TypeBits",
- "FPFormBits", "printImplicitUses", "Opcode"];
- let TSFlagsShifts = [ 0, 5, 6, 10,
- 13, 16, 17];
+ let TSFlagsFields = ["FormBits" , "hasOpSizePrefix" , "Prefix", "MemTypeBits",
+ "ImmTypeBits", "FPFormBits", "printImplicitUses", "Opcode"];
+ let TSFlagsShifts = [0, 5, 6, 10, 13,
+ 15, 18, 19];
}
def X86 : Target {
diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp
index df6c41cc4a..34061852b2 100644
--- a/lib/Target/X86/X86AsmPrinter.cpp
+++ b/lib/Target/X86/X86AsmPrinter.cpp
@@ -433,16 +433,14 @@ void Printer::printOp(const MachineOperand &MO,
}
}
-static const std::string sizePtr(const TargetInstrDescriptor &Desc) {
- switch (Desc.TSFlags & X86II::ArgMask) {
+static const char* const sizePtr(const TargetInstrDescriptor &Desc) {
+ switch (Desc.TSFlags & X86II::MemMask) {
default: assert(0 && "Unknown arg size!");
- case X86II::Arg8: return "BYTE PTR";
- case X86II::Arg16: return "WORD PTR";
- case X86II::Arg32: return "DWORD PTR";
- case X86II::Arg64: return "QWORD PTR";
- case X86II::ArgF32: return "DWORD PTR";
- case X86II::ArgF64: return "QWORD PTR";
- case X86II::ArgF80: return "XWORD PTR";
+ case X86II::Mem8: return "BYTE PTR";
+ case X86II::Mem16: return "WORD PTR";
+ case X86II::Mem32: return "DWORD PTR";
+ case X86II::Mem64: return "QWORD PTR";
+ case X86II::Mem80: return "XWORD PTR";
}
}
diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp
index 1d12ce2d2c..8e0ba2a497 100644
--- a/lib/Target/X86/X86CodeEmitter.cpp
+++ b/lib/Target/X86/X86CodeEmitter.cpp
@@ -453,14 +453,24 @@ void Emitter::emitMemModRMByte(const MachineInstr &MI,
}
}
+static unsigned sizeOfImm(const TargetInstrDescriptor &Desc) {
+ switch (Desc.TSFlags & X86II::ImmMask) {
+ case X86II::Imm8: return 1;
+ case X86II::Imm16: return 2;
+ case X86II::Imm32: return 4;
+ default: assert(0 && "Immediate size not set!");
+ return 0;
+ }
+}
+
static unsigned sizeOfPtr(const TargetInstrDescriptor &Desc) {
- switch (Desc.TSFlags & X86II::ArgMask) {
- case X86II::Arg8: return 1;
- case X86II::Arg16: return 2;
- case X86II::Arg32: return 4;
- case X86II::ArgF32: return 4;
- case X86II::ArgF64: return 8;
- case X86II::ArgF80: return 10;
+ switch (Desc.TSFlags & X86II::MemMask) {
+ case X86II::Mem8: return 1;
+ case X86II::Mem16: return 2;
+ case X86II::Mem32: return 4;
+ case X86II::Mem64: return 8;
+ case X86II::Mem80: return 10;
+ case X86II::Mem128: return 16;
default: assert(0 && "Memory size not set!");
return 0;
}
@@ -527,25 +537,21 @@ void Emitter::emitInstruction(MachineInstr &MI) {
MCE.emitByte(BaseOpcode + getX86RegNum(MI.getOperand(0).getReg()));
if (MI.getNumOperands() == 2) {
MachineOperand &MO1 = MI.getOperand(1);
- if (MO1.isImmediate() || MO1.getVRegValueOrNull() ||
- MO1.isGlobalAddress() || MO1.isExternalSymbol()) {
- unsigned Size = sizeOfPtr(Desc);
- if (Value *V = MO1.getVRegValueOrNull()) {
- assert(Size == 4 && "Don't know how to emit non-pointer values!");
- emitGlobalAddressForPtr(cast<GlobalValue>(V));
- } else if (MO1.isGlobalAddress()) {
- assert(Size == 4 && "Don't know how to emit non-pointer values!");
- assert(!MO1.isPCRelative() && "Function pointer ref is PC relative?");
- emitGlobalAddressForPtr(MO1.getGlobal());
- } else if (MO1.isExternalSymbol()) {
- assert(Size == 4 && "Don't know how to emit non-pointer values!");
-
- unsigned Address = MCE.getGlobalValueAddress(MO1.getSymbolName());
- assert(Address && "Unknown external symbol!");
- emitMaybePCRelativeValue(Address, MO1.isPCRelative());
- } else {
- emitConstant(MO1.getImmedValue(), Size);
- }
+ if (Value *V = MO1.getVRegValueOrNull()) {
+ assert(sizeOfImm(Desc) == 4 && "Don't know how to emit non-pointer values!");
+ emitGlobalAddressForPtr(cast<GlobalValue>(V));
+ } else if (MO1.isGlobalAddress()) {
+ assert(sizeOfImm(Desc) == 4 && "Don't know how to emit non-pointer values!");
+ assert(!MO1.isPCRelative() && "Function pointer ref is PC relative?");
+ emitGlobalAddressForPtr(MO1.getGlobal());
+ } else if (MO1.isExternalSymbol()) {
+ assert(sizeOfImm(Desc) == 4 && "Don't know how to emit non-pointer values!");
+
+ unsigned Address = MCE.getGlobalValueAddress(MO1.getSymbolName());
+ assert(Address && "Unknown external symbol!");
+ emitMaybePCRelativeValue(Address, MO1.isPCRelative());
+ } else {
+ emitConstant(MO1.getImmedValue(), sizeOfImm(Desc));
}
}
break;
@@ -555,7 +561,7 @@ void Emitter::emitInstruction(MachineInstr &MI) {
emitRegModRMByte(MI.getOperand(0).getReg(),
getX86RegNum(MI.getOperand(1).getReg()));
if (MI.getNumOperands() == 3)
- emitConstant(MI.getOperand(2).getImmedValue(), sizeOfPtr(Desc));
+ emitConstant(MI.getOperand(2).getImmedValue(), sizeOfImm(Desc));
break;
}
case X86II::MRMDestMem:
@@ -569,14 +575,14 @@ void Emitter::emitInstruction(MachineInstr &MI) {
emitRegModRMByte(MI.getOperand(1).getReg(),
getX86RegNum(MI.getOperand(0).getReg()));
if (MI.getNumOperands() == 3)
- emitConstant(MI.getOperand(2).getImmedValue(), sizeOfPtr(Desc));
+ emitConstant(MI.getOperand(2).getImmedValue(), sizeOfImm(Desc));
break;
case X86II::MRMSrcMem:
MCE.emitByte(BaseOpcode);
emitMemModRMByte(MI, 1, getX86RegNum(MI.getOperand(0).getReg()));
if (MI.getNumOperands() == 2+4)
- emitConstant(MI.getOperand(5).getImmedValue(), sizeOfPtr(Desc));
+ emitConstant(MI.getOperand(5).getImmedValue(), sizeOfImm(Desc));
break;
case X86II::MRM0r: case X86II::MRM1r:
@@ -588,8 +594,7 @@ void Emitter::emitInstruction(MachineInstr &MI) {
(Desc.TSFlags & X86II::FormMask)-X86II::MRM0r);
if (MI.getOperand(MI.getNumOperands()-1).isImmediate()) {
- unsigned Size = sizeOfPtr(Desc);
- emitConstant(MI.getOperand(MI.getNumOperands()-1).getImmedValue(), Size);
+ emitConstant(MI.getOperand(MI.getNumOperands()-1).getImmedValue(), sizeOfImm(Desc));
}
break;
@@ -601,9 +606,8 @@ void Emitter::emitInstruction(MachineInstr &MI) {
emitMemModRMByte(MI, 0, (Desc.TSFlags & X86II::FormMask)-X86II::MRM0m);
if (MI.getNumOperands() == 5) {
- unsigned Size = sizeOfPtr(Desc);
if (MI.getOperand(4).isImmediate())
- emitConstant(MI.getOperand(4).getImmedValue(), Size);
+ emitConstant(MI.getOperand(4).getImmedValue(), sizeOfImm(Desc));
else if (MI.getOperand(4).isGlobalAddress())
emitGlobalAddressForPtr(MI.getOperand(4).getGlobal());
else
diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h
index 438acb0f28..5c1416eb20 100644
--- a/lib/Target/X86/X86InstrInfo.h
+++ b/lib/Target/X86/X86InstrInfo.h
@@ -111,21 +111,29 @@ namespace X86II {
//===------------------------------------------------------------------===//
// This three-bit field describes the size of a memory operand. Zero is
// unused so that we can tell if we forgot to set a value.
- ArgShift = 10,
- ArgMask = 7 << ArgShift,
- Arg8 = 1 << ArgShift,
- Arg16 = 2 << ArgShift,
- Arg32 = 3 << ArgShift,
- Arg64 = 4 << ArgShift, // 64 bit int argument for FILD64
- ArgF32 = 5 << ArgShift,
- ArgF64 = 6 << ArgShift,
- ArgF80 = 7 << ArgShift,
+ MemShift = 10,
+ MemMask = 7 << MemShift,
+ Mem8 = 1 << MemShift,
+ Mem16 = 2 << MemShift,
+ Mem32 = 3 << MemShift,
+ Mem64 = 4 << MemShift,
+ Mem80 = 5 << MemShift,
+ Mem128 = 6 << MemShift,
+
+ //===------------------------------------------------------------------===//
+ // This tow-bit field describes the size of an immediate operand. Zero is
+ // unused so that we can tell if we forgot to set a value.
+ ImmShift = 13,
+ ImmMask = 7 << ImmShift,
+ Imm8 = 1 << ImmShift,
+ Imm16 = 2 << ImmShift,
+ Imm32 = 3 << ImmShift,
//===------------------------------------------------------------------===//
// FP Instruction Classification... Zero is non-fp instruction.
// FPTypeMask - Mask for all of the FP types...
- FPTypeShift = 13,
+ FPTypeShift = 15,
FPTypeMask = 7 << FPTypeShift,
// NotFP - The default, set for instructions that do not use FP registers.
@@ -151,9 +159,9 @@ namespace X86II {
SpecialFP = 5 << FPTypeShift,
// PrintImplUses - Print out implicit uses in the assembly output.
- PrintImplUses = 1 << 16,
+ PrintImplUses = 1 << 18,
- OpcodeShift = 17,
+ OpcodeShift = 19,
OpcodeMask = 0xFF << OpcodeShift,
// Bits 25 -> 31 are unused
};
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index b9f804c58f..be795b85ce 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -31,20 +31,30 @@ def MRM0m : Format<24>; def MRM1m : Format<25>; def MRM2m : Format<26>;
def MRM3m : Format<27>; def MRM4m : Format<28>; def MRM5m : Format<29>;
def MRM6m : Format<30>; def MRM7m : Format<31>;
-// ArgType - This specifies the argument type used by an instruction. This is
+// ImmType - This specifies the immediate type used by an instruction. This is
// part of the ad-hoc solution used to emit machine instruction encodings by our
// machine code emitter.
-class ArgType<bits<3> val> {
+class ImmType<bits<2> val> {
+ bits<2> Value = val;
+}
+def NoImm : ImmType<0>;
+def Imm8 : ImmType<1>;
+def Imm16 : ImmType<2>;
+def Imm32 : ImmType<3>;
+
+// MemType - This specifies the immediate type used by an instruction. This is
+// part of the ad-hoc solution used to emit machine instruction encodings by our
+// machine code emitter.
+class MemType<bits<3> val> {
bits<3> Value = val;
}
-def NoArg : ArgType<0>;
-def Arg8 : ArgType<1>;
-def Arg16 : ArgType<2>;
-def Arg32 : ArgType<3>;
-def Arg64 : ArgType<4>; // 64 bit int argument for FILD64
-def ArgF32 : ArgType<5>;
-def ArgF64 : ArgType<6>;
-def ArgF80 : ArgType<6>;
+def NoMem : MemType<0>;
+def Mem8 : MemType<1>;
+def Mem16 : MemType<2>;
+def Mem32 : MemType<3>;
+def Mem64 : MemType<4>;
+def Mem80 : MemType<4>;
+def Mem128 : MemType<6>;
// FPFormat - This specifies what form this FP instruction has. This is used by
// the Floating-Point stackifier pass.
@@ -59,15 +69,17 @@ def TwoArgFP : FPFormat<4>;
def SpecialFP : FPFormat<5>;
-class X86Inst<string nam, bits<8> opcod, Format f, ArgType a> : Instruction {
+class X86Inst<string nam, bits<8> opcod, Format f, MemType m, ImmType i> : Instruction {
let Namespace = "X86";
let Name = nam;
bits<8> Opcode = opcod;
Format Form = f;
bits<5> FormBits = Form.Value;
- ArgType Type = a;
- bits<3> TypeBits = Type.Value;
+ MemType MemT = m;
+ bits<3> MemTypeBits = MemT.Value;
+ ImmType ImmT = i;
+ bits<2> ImmTypeBits = ImmT.Value;
// Attributes specific to X86 instructions...
bit hasOpSizePrefix = 0; // Does this inst have a 0x66 prefix?
@@ -103,33 +115,57 @@ class DE { bits<4> Prefix = 9; }
class DF { bits<4> Prefix = 10; }
+//===----------------------------------------------------------------------===//
+// Instruction templates...
+
+class I<string n, bits<8> o, Format f> : X86Inst<n, o, f, NoMem, NoImm>;
+
+class IM<string n, bits<8> o, Format f, MemType m> : X86Inst<n, o, f, m, NoImm>;
+class IM8 <string n, bits<8> o, Format f> : IM<n, o, f, Mem8 >;
+class IM16<string n, bits<8> o, Format f> : IM<n, o, f, Mem16>;
+class IM32<string n, bits<8> o, Format f> : IM<n, o, f, Mem32>;
+
+class II<string n, bits<8> o, Format f, ImmType i> : X86Inst<n, o, f, NoMem, i>;
+class II8 <string n, bits<8> o, Format f> : II<n, o, f, Imm8 >;
+class II16<string n, bits<8> o, Format f> : II<n, o, f, Imm16>;
+class II32<string n, bits<8> o, Format f> : II<n, o, f, Imm32>;
+
+class I8MI <string n, bits<8> o, Format f> : X86Inst<n, o, f, Mem8 , Imm8 >;
+class I16MI<string n, bits<8> o, Format f> : X86Inst<n, o, f, Mem16, Imm16>;
+class I32MI<string n, bits<8> o, Format f> : X86Inst<n, o, f, Mem32, Imm32>;
+
+class IM16I8<string n, bits<8> o, Format f> : X86Inst<n, o, f, Mem16, Imm8>;
+class IM32I8<string n, bits<8> o, Format f> : X86Inst<n, o, f, Mem32, Imm8>;
+
+// Helper for shift instructions
+class UsesCL { list<Register> Uses = [CL]; bit printImplicitUses = 1; }
//===----------------------------------------------------------------------===//
// Instruction list...
//
-def PHI : X86Inst<"PHI", 0, Pseudo, NoArg>; // PHI node...
+def PHI : I<"PHI", 0, Pseudo>; // PHI node...
-def NOOP : X86Inst<"nop", 0x90, RawFrm, NoArg>; // nop
+def NOOP : I<"nop", 0x90, RawFrm>; // nop
-def ADJCALLSTACKDOWN : X86Inst<"ADJCALLSTACKDOWN", 0, Pseudo, NoArg>;
-def ADJCALLSTACKUP : X86Inst<"ADJCALLSTACKUP", 0, Pseudo, NoArg>;
-def IMPLICIT_USE : X86Inst<"IMPLICIT_USE", 0, Pseudo, NoArg>;
-def IMPLICIT_DEF : X86Inst<"IMPLICIT_DEF", 0, Pseudo, NoArg>;
+def ADJCALLSTACKDOWN : I<"ADJCALLSTACKDOWN", 0, Pseudo>;
+def ADJCALLSTACKUP : I<"ADJCALLSTACKUP", 0, Pseudo>;
+def IMPLICIT_USE : I<"IMPLICIT_USE", 0, Pseudo>;
+def IMPLICIT_DEF : I<"IMPLICIT_DEF", 0, Pseudo>;
let isTerminator = 1 in
let Defs = [FP0, FP1, FP2, FP3, FP4, FP5, FP6] in
- def FP_REG_KILL : X86Inst<"FP_REG_KILL", 0, Pseudo, NoArg>;
+ def FP_REG_KILL : I<"FP_REG_KILL", 0, Pseudo>;
//===----------------------------------------------------------------------===//
// Control Flow Instructions...
//
// Return instruction...
let isTerminator = 1, isReturn = 1 in
- def RET : X86Inst<"ret", 0xC3, RawFrm, NoArg>, Pattern<(retvoid)>;
+ def RET : I<"ret", 0xC3, RawFrm>, Pattern<(retvoid)>;
// All branches are RawFrm, Void, Branch, and Terminators
let isBranch = 1, isTerminator = 1 in
- class IBr<string name, bits<8> opcode> : X86Inst<name, opcode, RawFrm, NoArg>;
+ class IBr<string name, bits<8> opcode> : I<name, opcode, RawFrm>;
def JMP : IBr<"jmp", 0xE9>, Pattern<(br basicblock)>;
def JB : IBr<"jb" , 0x82>, TB;
@@ -152,426 +188,420 @@ def JG : IBr<"jg" , 0x8F>, TB;
let isCall = 1 in
// All calls clobber the non-callee saved registers...
let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6] in {
- def CALLpcrel32 : X86Inst<"call", 0xE8, RawFrm, NoArg>;
- def CALLr32 : X86Inst<"call", 0xFF, MRM2r , Arg32>;
- def CALLm32 : X86Inst<"call", 0xFF, MRM2m , Arg32>;
+ def CALLpcrel32 : I <"call", 0xE8, RawFrm>;
+ def CALLr32 : I <"call", 0xFF, MRM2r>;
+ def CALLm32 : IM32<"call", 0xFF, MRM2m>;
}
//===----------------------------------------------------------------------===//
// Miscellaneous Instructions...
//
-def LEAVE : X86Inst<"leave", 0xC9, RawFrm, NoArg>, Imp<[EBP,ESP],[EBP,ESP]>;
-def POPr32 : X86Inst<"pop", 0x58, AddRegFrm, Arg32>, Imp<[ESP],[ESP]>;
+def LEAVE : I<"leave", 0xC9, RawFrm>, Imp<[EBP,ESP],[EBP,ESP]>;
+def POPr32 : I<"pop", 0x58, AddRegFrm>, Imp<[ESP],[ESP]>;
-let isTwoAddress = 1 in // R32 = bswap R32
- def BSWAPr32 : X86Inst<"bswap", 0xC8, AddRegFrm, Arg32>, TB;
+let isTwoAddress = 1 in // R32 = bswap R32
+ def BSWAPr32 : I<"bswap", 0xC8, AddRegFrm>, TB;
-def XCHGrr8 : X86Inst<"xchg", 0x86, MRMDestReg, Arg8>; // xchg R8, R8
-def XCHGrr16 : X86Inst<"xchg", 0x87, MRMDestReg, Arg16>, OpSize;// xchg R16, R16
-def XCHGrr32 : X86Inst<"xchg", 0x87, MRMDestReg, Arg32>; // xchg R32, R32
-def XCHGmr8 : X86Inst<"xchg", 0x86, MRMDestMem, Arg8>; // xchg [mem8], R8
-def XCHGmr16 : X86Inst<"xchg", 0x87, MRMDestMem, Arg16>, OpSize;// xchg [mem16], R16
-def XCHGmr32 : X86Inst<"xchg", 0x87, MRMDestMem, Arg32>; // xchg [mem32], R32
-def XCHGrm8 : X86Inst<"xchg", 0x86, MRMSrcMem , Arg8>; // xchg R8, [mem8]
-def XCHGrm16 : X86Inst<"xchg", 0x87, MRMSrcMem , Arg16>, OpSize;// xchg R16, [mem16]
-def XCHGrm32 : X86Inst<"xchg", 0x87, MRMSrcMem , Arg32>; // xchg R32, [mem32]
+def XCHGrr8 : I <"xchg", 0x86, MRMDestReg>; // xchg R8, R8
+def XCHGrr16 : I <"xchg", 0x87, MRMDestReg>, OpSize; // xchg R16, R16
+def XCHGrr32 : I <"xchg", 0x87, MRMDestReg>; // xchg R32, R32
+def XCHGmr8 : IM8 <"xchg", 0x86, MRMDestMem>; // xchg [mem8], R8
+def XCHGmr16 : IM16<"xchg", 0x87, MRMDestMem>, OpSize; // xchg [mem16], R16
+def XCHGmr32 : IM32<"xchg", 0x87, MRMDestMem>; // xchg [mem32], R32
+def XCHGrm8 : IM8 <"xchg", 0x86, MRMSrcMem >; // xchg R8, [mem8]
+def XCHGrm16 : IM16<"xchg", 0x87, MRMSrcMem >, OpSize; // xchg R16, [mem16]
+def XCHGrm32 : IM32<"xchg", 0x87, MRMSrcMem >; // xchg R32, [mem32]
-def LEAr16 : X86Inst<"lea", 0x8D, MRMSrcMem, Arg16>, OpSize; // R16 = lea [mem]
-def LEAr32 : X86Inst<"lea", 0x8D, MRMSrcMem, Arg32>; // R32 = lea [mem]
+def LEAr16 : IM32<"lea", 0x8D, MRMSrcMem>, OpSize; // R16 = lea [mem]
+def LEAr32 : IM32<"lea", 0x8D, MRMSrcMem>; // R32 = lea [mem]
-def REP_MOVSB : X86Inst<"rep movsb", 0xA4, RawFrm, NoArg>, REP,
+def REP_MOVSB : I<"rep movsb", 0xA4, RawFrm>, REP,
Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>;
-def REP_MOVSW : X86Inst<"rep movsw", 0xA5, RawFrm, NoArg>, REP, OpSize,
+def REP_MOVSW : I<"rep movsw", 0xA5, RawFrm>, REP, OpSize,
Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>;
-def REP_MOVSD : X86Inst<"rep movsd", 0xA5, RawFrm, NoArg>, REP,
+def REP_MOVSD : I<"rep movsd", 0xA5, RawFrm>, REP,
Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>;
-def REP_STOSB : X86Inst<"rep stosb", 0xAA, RawFrm, NoArg>, REP,
+def REP_STOSB : I<"rep stosb", 0xAA, RawFrm>, REP,
Imp<[AL,ECX,EDI], [ECX,EDI]>;
-def REP_STOSW : X86Inst<"rep stosw", 0xAB, RawFrm, NoArg>, REP, OpSize,
+def REP_STOSW : I<"rep stosw", 0xAB, RawFrm>, REP, OpSize,
Imp<[AX,ECX,EDI], [ECX,EDI]>;
-def REP_STOSD : X86Inst<"rep stosd", 0xAB, RawFrm, NoArg>, REP,
+def REP_STOSD : I<"rep stosd", 0xAB, RawFrm>, REP,
Imp<[EAX,ECX,EDI], [ECX,EDI]>;
//===----------------------------------------------------------------------===//
// Move Instructions...
//
-def MOVrr8 : X86Inst<"mov", 0x88, MRMDestReg, Arg8>, Pattern<(set R8 , R8 )>;
-def MOVrr16 : X86Inst<"mov", 0x89, MRMDestReg, Arg16>, OpSize, Pattern<(set R16, R16)>;
-def MOVrr32 : X86Inst<"mov", 0x89, MRMDestReg, Arg32>, Pattern<(set R32, R32)>;
-def MOVri8 : X86Inst<"mov", 0xB0, AddRegFrm , Arg8>, Pattern<(set R8 , imm )>;
-def MOVri16 : X86Inst<"mov", 0xB8, AddRegFrm , Arg16>, OpSize, Pattern<(set R16, imm)>;
-def MOVri32 : X86Inst<"mov", 0xB8, AddRegFrm , Arg32>, Pattern<(set R32, imm)>;
-def MOVmi8 : X86Inst<"mov", 0xC6, MRM0m , Arg8>; // [mem8] = imm8
-def MOVmi16 : X86Inst<"mov", 0xC7, MRM0m , Arg16>, OpSize; // [mem16] = imm16
-def MOVmi32 : X86Inst<"mov", 0xC7, MRM0m , Arg32>; // [mem32] = imm32
-
-def MOVrm8 : X86Inst<"mov", 0x8A, MRMSrcMem , Arg8>; // R8 = [mem8]
-def MOVrm16 : X86Inst<"mov", 0x8B, MRMSrcMem , Arg16>, OpSize, // R16 = [mem16]
+def MOVrr8 : I <"mov", 0x88, MRMDestReg>, Pattern<(set R8 , R8 )>;
+def MOVrr16 : I <"mov", 0x89, MRMDestReg>, OpSize, Pattern<(set R16, R16)>;
+def MOVrr32 : I <"mov", 0x89, MRMDestReg>, Pattern<(set R32, R32)>;
+def MOVri8 : II8 <"mov", 0xB0, AddRegFrm >, Pattern<(set R8 , imm )>;
+def MOVri16 : II16 <"mov", 0xB8, AddRegFrm >, OpSize, Pattern<(set R16, imm)>;
+def MOVri32 : II32 <"mov", 0xB8, AddRegFrm >, Pattern<(set R32, imm)>;
+def MOVmi8 : I8MI <"mov", 0xC6, MRM0m >; // [mem8] = imm8
+def MOVmi16 : I16MI<"mov", 0xC7, MRM0m >, OpSize; // [mem16] = imm16
+def MOVmi32 : I32MI<"mov", 0xC7, MRM0m >; // [mem32] = imm32
+
+def MOVrm8 : IM8 <"mov", 0x8A, MRMSrcMem>; // R8 = [mem8]
+def MOVrm16 : IM16 <"mov", 0x8B, MRMSrcMem>, OpSize, // R16 = [mem16]
Pattern<(set R16, (load (plus R32, (plus (times imm, R32), imm))))>;
-def MOVrm32 : X86Inst<"mov", 0x8B, MRMSrcMem , Arg32>, // R32 = [mem32]
+def MOVrm32 : IM32 <"mov", 0x8B, MRMSrcMem>, // R32 = [mem32]
Pattern<(set R32, (load (plus R32, (plus (times imm, R32), imm))))>;
-def MOVmr8 : X86Inst<"mov", 0x88, MRMDestMem, Arg8>; // [mem8] = R8
-def MOVmr16 : X86Inst<"mov", 0x89, MRMDestMem, Arg16>, OpSize; // [mem16] = R16
-def MOVmr32 : X86Inst<"mov", 0x89, MRMDestMem, Arg32>; // [mem32] = R32
+def MOVmr8 : IM8 <"mov", 0x88, MRMDestMem>; // [mem8] = R8
+def MOVmr16 : IM16 <"mov", 0x89, MRMDestMem>, OpSize; // [mem16] = R16
+def MOVmr32 : IM32 <"mov", 0x89, MRMDestMem>; // [mem32] = R32
//===----------------------------------------------------------------------===//
// Fixed-Register Multiplication and Division Instructions...
//
// Extra precision multiplication
-def MULr8 : X86Inst<"mul", 0xF6, MRM4r , Arg8 >, Imp<[AL],[AX]>; // AL,AH = AL*R8
-def MULr16 : X86Inst<"mul", 0xF7, MRM4r , Arg16>, Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*R16
-def MULr32 : X86Inst<"mul", 0xF7, MRM4r , Arg32>, Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*R32
-def MULm8 : X86Inst<"mul", 0xF6, MRM4m , Arg8 >, Imp<[AL],[AX]>; // AL,AH = AL*[mem8]
-def MULm16 : X86Inst<"mul", 0xF7, MRM4m , Arg16>, Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*[mem16]
-def MULm32 : X86Inst<"mul", 0xF7, MRM4m , Arg32>, Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*[mem32]
+def MULr8 : I <"mul", 0xF6, MRM4r>, Imp<[AL],[AX]>; // AL,AH = AL*R8
+def MULr16 : I <"mul", 0xF7, MRM4r>, Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*R16
+def MULr32 : I <"mul", 0xF7, MRM4r>, Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*R32
+def MULm8 : IM8 <"mul", 0xF6, MRM4m>, Imp<[AL],[AX]>; // AL,AH = AL*[mem8]
+def MULm16 : IM16<"mul", 0xF7, MRM4m>, Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*[mem16]
+def MULm32 : IM32<"mul", 0xF7, MRM4m>, Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*[mem32]
// unsigned division/remainder
-def DIVr8 : X86Inst<"div", 0xF6, MRM6r , Arg8 >, Imp<[AX],[AX]>; // AX/r8 = AL,AH
-def DIVr16 : X86Inst<"div", 0xF7, MRM6r , Arg16>, Imp<[AX,DX],[AX,DX]>, OpSize; // DX:AX/r16 = AX,DX
-def DIVr32 : X86Inst<"div", 0xF7, MRM6r , Arg32>, Imp<[EAX,EDX],[EAX,EDX]>; // EDX:EAX/r32 = EAX,EDX
-def DIVm8 : X86Inst<"div", 0xF6, MRM6m , Arg8 >, Imp<[AX],[AX]>; // AX/[mem8] = AL,AH
-def DIVm16 : X86Inst<"div", 0xF7, MRM6m , Arg16>, Imp<[AX,DX],[AX,DX]>, OpSize; // DX:AX/[mem16] = AX,DX
-def DIVm32 : X86Inst<"div", 0xF7, MRM6m , Arg32>, Imp<[EAX,EDX],[EAX,EDX]>; // EDX:EAX/[mem32] = EAX,EDX
+def DIVr8 : I <"div", 0xF6, MRM6r>, Imp<[AX],[AX]>; // AX/r8 = AL,AH
+def DIVr16 : I <"div", 0xF7, MRM6r>, Imp<[AX,DX],[AX,DX]>, OpSize; // DX:AX/r16 = AX,DX
+def DIVr32 : I <"div", 0xF7, MRM6r>, Imp<[EAX,EDX],[EAX,EDX]>; // EDX:EAX/r32 = EAX,EDX
+def DIVm8 : IM8 <"div", 0xF6, MRM6m>, Imp<[AX],[AX]>; // AX/[mem8] = AL,AH
+def DIVm16 : IM16<"div", 0xF7, MRM6m>, Imp<[AX,DX],[AX,DX]>, OpSize; // DX:AX/[mem16] = AX,DX
+def DIVm32 : IM32<"div", 0xF7, MRM6m>, Imp<[EAX,EDX],[EAX,EDX]>; // EDX:EAX/[mem32] = EAX,EDX
// signed division/remainder
-def IDIVr8 : X86Inst<"idiv",0xF6, MRM7r , Arg8 >, Imp<[AX],[AX]>; // AX/r8 = AL,AH
-def IDIVr16: X86Inst<"idiv",0xF7, MRM7r , Arg16>, Imp<[AX,DX],[AX,DX]>, OpSize; // DX:AX/r16 = AX,DX
-def IDIVr32: X86Inst<"idiv",0xF7, MRM7r , Arg32>, Imp<[EAX,EDX],[EAX,EDX]>; // EDX:EAX/r32 = EAX,EDX
-def IDIVm8 : X86Inst<"idiv",0xF6, MRM7m , Arg8 >, Imp<[AX],[AX]>; // AX/[mem8] = AL,AH
-def IDIVm16: X86Inst<"idiv",0xF7, MRM7m , Arg16>, Imp<[AX,DX],[AX,DX]>, OpSize; // DX:AX/[mem16] = AX,DX
-def IDIVm32: X86Inst<"idiv",0xF7, MRM7m , Arg32>, Imp<[EAX,EDX],[EAX,EDX]>; // EDX:EAX/[mem32] = EAX,EDX
+def IDIVr8 : I <"idiv",0xF6, MRM7r>, Imp<[AX],[AX]>; // AX/r8 = AL,AH
+def IDIVr16: I <"idiv",0xF7, MRM7r>, Imp<[AX,DX],[AX,DX]>, OpSize; // DX:AX/r16 = AX,DX
+def IDIVr32: I <"idiv",0xF7, MRM7r>, Imp<[EAX,EDX],[EAX,EDX]>; // EDX:EAX/r32 = EAX,EDX
+def IDIVm8 : IM8 <"idiv",0xF6, MRM7m>, Imp<[AX],[AX]>; // AX/[mem8] = AL,AH
+def IDIVm16: IM16<"idiv",0xF7, MRM7m>, Imp<[AX,DX],[AX,DX]>, OpSize; // DX:AX/[mem16] = AX,DX
+def IDIVm32: IM32<"idiv",0xF7, MRM7m>, Imp<[EAX,EDX],[EAX,EDX]>; // EDX:EAX/[mem32] = EAX,EDX
// Sign-extenders for division
-def CBW : X86Inst<"cbw", 0x98, RawFrm, Arg8 >, Imp<[AL],[AH]>; // AX = signext(AL)
-def CWD : X86Inst<"cwd", 0x99, RawFrm, Arg8 >, Imp<[AX],[DX]>; // DX:AX = signext(AX)
-def CDQ : X86Inst<"cdq", 0x99, RawFrm, Arg8 >, Imp<[EAX],[EDX]>; // EDX:EAX = signext(EAX)
+def CBW : I<"cbw", 0x98, RawFrm >, Imp<[AL],[AH]>; // AX = signext(AL)
+def CWD : I<"cwd", 0x99, RawFrm >, Imp<[AX],[DX]>; // DX:AX = signext(AX)
+def CDQ : I<"cdq", 0x99, RawFrm >, Imp<[EAX],[EDX]>; // EDX:EAX = signext(EAX)
//===----------------------------------------------------------------------===//
// Two address Instructions...
//
-let isTwoAddress = 1 in { // Define some helper classes to make defs shorter.
- class I2A8 <string n, bits<8> o, Format F> : X86Inst<n, o, F, Arg8>;
- class I2A16<string n, bits<8> o, Format F> : X86Inst<n, o, F, Arg16>;
- class I2A32<string n, bits<8> o, Format F> : X86Inst<n, o, F, Arg32>;
-}
+let isTwoAddress = 1 in {
+
+// Conditional moves. These are modelled as X = cmovXX Y, Z. Eventually
+// register allocated to cmovXX XY, Z
+def CMOVErr16 : I<"cmove", 0x44, MRMSrcReg>, TB, OpSize; // if ==, R16 = R16
+def CMOVNErr32: I<"cmovne",0x45, MRMSrcReg>, TB; // if !=, R32 = R32
+def CMOVSrr32 : I<"cmovs", 0x48, MRMSrcReg>, TB; // if signed, R32 = R32
// unary instructions
-def NEGr8 : I2A8 <"neg", 0xF6, MRM3r >; // R8 = -R8 = 0-R8
-def NEGr16 : I2A16<"neg", 0xF7, MRM3r >, OpSize; // R16 = -R16 = 0-R16
-def NEGr32 : I2A32<"neg", 0xF7, MRM3r >; // R32 = -R32 = 0-R32
-def NEGm8 : I2A8 <"neg", 0xF6, MRM3m >; // [mem8] = -[mem8] = 0-[mem8]
-def NEGm16 : I2A16<"neg", 0xF7, MRM3m >, OpSize; // [mem16] = -[mem16] = 0-[mem16]
-def NEGm32 : I2A32<"neg", 0xF7, MRM3m >; // [mem32] = -[mem32] = 0-[mem32]
-
-def NOTr8 : I2A8 <"not", 0xF6, MRM2r >; // R8 = ~R8 = R8^-1
-def NOTr16 : I2A16<"not", 0xF7, MRM2r >, OpSize; // R16 = ~R16 = R16^-1
-def NOTr32 : I2A32<"not", 0xF7, MRM2r >; // R32 = ~R32 = R32^-1
-def NOTm8 : I2A8 <"not", 0xF6, MRM2m >; // [mem8] = ~[mem8] = [mem8^-1]
-def NOTm16 : I2A16<"not", 0xF7, MRM2m >, OpSize; // [mem16] = ~[mem16] = [mem16^-1]
-def NOTm32 : I2A32<"not", 0xF7, MRM2m >; // [mem32] = ~[mem32] = [mem32^-1]
-
-def INCr8 : I2A8 <"inc", 0xFE, MRM0r >; // ++R8
-def INCr16 : I2A16<"inc", 0xFF, MRM0r >, OpSize; // ++R16
-def INCr32 : I2A32<"inc", 0xFF, MRM0r >; // ++R32
-def INCm8 : I2A8 <"inc", 0xFE, MRM0m >; // ++R8
-def INCm16 : I2A16<"inc", 0xFF, MRM0m >, OpSize; // ++R16
-def INCm32 : I2A32<"inc", 0xFF, MRM0m >; // ++R32
-
-def DECr8 : I2A8 <"dec", 0xFE, MRM1r >; // --R8
-def DECr16 : I2A16<"dec", 0xFF, MRM1r >, OpSize; // --R16
-def DECr32 : I2A32<"dec", 0xFF, MRM1r >; // --R32
-def DECm8 : I2A8 <"dec", 0xFE, MRM1m >; // --[mem8]
-def DECm16 : I2A16<"dec", 0xFF, MRM1m >, OpSize; // --[mem16]
-def DECm32 : I2A32<"dec", 0xFF, MRM1m >; // --[mem32]
+def NEGr8 : I <"neg", 0xF6, MRM3r>; // R8 = -R8 = 0-R8
+def NEGr16 : I <"neg", 0xF7, MRM3r>, OpSize; // R16 = -R16 = 0-R16
+def NEGr32 : I <"neg", 0xF7, MRM3r>; // R32 = -R32 = 0-R32
+def NEGm8 : IM8 <"neg", 0xF6, MRM3m>; // [mem8] = -[mem8] = 0-[mem8]
+def NEGm16 : IM16<"neg", 0xF7, MRM3m>, OpSize; // [mem16] = -[mem16] = 0-[mem16]
+def NEGm32 : IM32<"neg", 0xF7, MRM3m>; // [mem32] = -[mem32] = 0-[mem32]
+
+def NOTr8 : I <"not", 0xF6, MRM2r>; // R8 = ~R8 = R8^-1
+def NOTr16 : I <"not", 0xF7, MRM2r>, OpSize; // R16 = ~R16 = R16^-1
+def NOTr32 : I <"not", 0xF7, MRM2r>; // R32 = ~R32 = R32^-1
+def NOTm8 : IM8 <"not", 0xF6, MRM2m>; // [mem8] = ~[mem8] = [mem8^-1]
+def NOTm16 : IM16<"not", 0xF7, MRM2m>, OpSize; // [mem16] = ~[mem16] = [mem16^-1]
+def NOTm32 : IM32<"not", 0xF7, MRM2m>; // [mem32] = ~[mem32] = [mem32^-1]
+
+def INCr8 : I <"inc", 0xFE, MRM0r>; // ++R8
+def INCr16 : I <"inc", 0xFF, MRM0r>, OpSize; // ++R16
+def INCr32 : I <"inc", 0xFF, MRM0r>; // ++R32
+def INCm8 : IM8 <"inc", 0xFE, MRM0m>; // ++R8
+def INCm16 : IM16<"inc", 0xFF, MRM0m>, OpSize; // ++R16
+def INCm32 : IM32<"inc", 0xFF, MRM0m>; // ++R32
+
+def DECr8 : I <"dec", 0xFE, MRM1r>; // --R8
+def DECr16 : I <"dec", 0xFF, MRM1r>, OpSize; // --R16
+def DECr32 : I <"dec", 0xFF, MRM1r>; // --R32
+def DECm8 : IM8 <"dec", 0xFE, MRM1m>; // --[mem8]
+def DECm16 : IM16<"dec", 0xFF, MRM1m>, OpSize; // --[mem16]
+def DECm32 : IM32<"dec", 0xFF, MRM1m>; // --[mem32]
+
+// Logical operators...
+def ANDrr8 : I <"and", 0x20, MRMDestReg>, Pattern<(set R8 , (and R8 , R8 ))>;
+def ANDrr16 : I <"and", 0x21, MRMDestReg>, OpSize, Pattern<(set R16, (and R16, R16))>;
+def ANDrr32 : I <"and", 0x21, MRMDestReg>, Pattern<(set R32, (and R32, R32))>;
+def ANDmr8 : IM8 <"and", 0x20, MRMDestMem>; // [mem8] &= R8
+def ANDmr16 : IM16 <"and", 0x21, MRMDestMem>, OpSize; // [mem16] &= R16
+def ANDmr32 : IM32 <"and", 0x21, MRMDestMem>; // [mem32] &= R32
+def ANDrm8 : IM8 <"and", 0x22, MRMSrcMem >; // R8 &= [mem8]
+def ANDrm16 : IM16 <"and", 0x23, MRMSrcMem >, OpSize; // R16 &= [mem16]
+def ANDrm32 : IM32 <"and", 0x23, MRMSrcMem >; // R32 &= [mem32]
+
+def ANDri8 : II8 <"and", 0x80, MRM4r >, Pattern<(set R8 , (and R8 , imm))>;
+def ANDri16 : II16 <"and", 0x81, MRM4r >, OpSize, Pattern<(set R16, (and R16, imm))>;
+def ANDri32 : II32 <"and", 0x81, MRM4r >, Pattern<(set R32, (and R32, imm))>;
+def ANDmi8 : I8MI <"and", 0x80, MRM4m >; // [mem8] &= imm8
+def ANDmi16 : I16MI <"and", 0x81, MRM4m >, OpSize; // [mem16] &= imm16
+def ANDmi32 : I32MI <"and", 0x81, MRM4m >; // [mem32] &= imm32
+
+def ANDri16b : II8 <"and", 0x83, MRM4r >, OpSize; // R16 &= imm8
+def ANDri32b : II8 <"and", 0x83, MRM4r >; // R32 &= imm8
+def ANDmi16b : IM16I8<"and", 0x83, MRM4m >, OpSize; // [mem16] &= imm8
+def ANDmi32b : IM32I8<"and", 0x83, MRM4m >; // [mem32] &= imm8
+
+
+def ORrr8 : I <"or" , 0x08, MRMDestReg>, Pattern<(set R8 , (or R8 , R8 ))>;
+def ORrr16 : I <"or" , 0x09, MRMDestReg>, OpSize, Pattern<(set R16, (or R16, R16))>;
+def ORrr32 : I <"or" , 0x09, MRMDestReg>, Pattern<(set R32, (or R32, R32))>;
+def ORmr8 : IM8 <"or" , 0x08, MRMDestMem>; // [mem8] |= R8
+def ORmr16 : IM16 <"or" , 0x09, MRMDestMem>, OpSize; // [mem16] |= R16
+def ORmr32 : IM32 <"or" , 0x09, MRMDestMem>; // [mem32] |= R32
+def ORrm8 : IM8 <"or" , 0x0A, MRMSrcMem >; // R8 |= [mem8]
+def ORrm16 : IM16 <"or" , 0x0B, MRMSrcMem >, OpSize; // R16 |= [mem16]
+def ORrm32 : IM32 <"or" , 0x0B, MRMSrcMem >; // R32 |= [mem32]
+
+def ORri8 : II8 <"or" , 0x80, MRM1r >, Pattern<(set R8 , (or R8 , imm))>;
+def ORri16 : II16 <"or" , 0x81, MRM1r >, OpSize, Pattern<(set R16, (or R16, imm))>;
+def ORri32 : II32 <"or" , 0x81, MRM1r >, Pattern<(set R32, (or R32, imm))>;
+def ORmi8 : I8MI <"or" , 0x80, MRM1m >; // [mem8] |= imm8
+def ORmi16 : I16MI <"or" , 0x81, MRM1m >, OpSize; // [mem16] |= imm16
+def ORmi32 : I32MI <"or" , 0x81, MRM1m >; // [mem32] |= imm32
+
+def ORri16b : II8 <"or" , 0x83, MRM1r >, OpSize; // R16 |= imm8
+def ORri32b : II8 <"or" , 0x83, MRM1r >; // R32 |= imm8
+def ORmi16b : IM16I8<"or" , 0x83, MRM1m >, OpSize; // [mem16] |= imm8
+def ORmi32b : IM32I8<"or" , 0x83, MRM1m >; // [mem32] |= imm8
+
+
+def XORrr8 : I <"xor", 0x30, MRMDestReg>, Pattern<(set R8 , (xor R8 , R8 ))>;
+def XORrr16 : I <"xor", 0x31, MRMDestReg>, OpSize, Pattern<(set R16, (xor R16, R16))>;
+def XORrr32 : I <"xor", 0x31, MRMDestReg>, Pattern<(set R32, (xor R32, R32))>;
+def XORmr8 : IM8 <"xor", 0x30, MRMDestMem>; // [mem8] ^= R8
+def XORmr16 : IM16 <"xor", 0x31, MRMDestMem>, OpSize; // [mem16] ^= R16
+def XORmr32 : IM32 <"xor", 0x31, MRMDestMem>; // [mem32] ^= R32
+def XORrm8 : IM8 <"xor", 0x32, MRMSrcMem >; // R8 ^= [mem8]
+def XORrm16 : IM16 <"xor", 0x33, MRMSrcMem >, OpSize; // R16 ^= [mem16]
+def XORrm32 : IM32 <"xor", 0x33, MRMSrcMem >; // R32 ^= [mem32]
+
+def XORri8 : II8 <"xor", 0x80, MRM6r >, Pattern<(set R8 , (xor R8 , imm))>;
+def XORri16 : II16 <"xor", 0x81, MRM6r >, OpSize, Pattern<(set R16, (xor R16, imm))>;
+def XORri32 : II32 <"xor", 0x81, MRM6r >, Pattern<(set R32, (xor R32, imm))>;
+def XORmi8 : I8MI <"xor", 0x80, MRM6m >; // [mem8] ^= R8
+def XORmi16 : I16MI <"xor", 0x81, MRM6m >, OpSize; // [mem16] ^= R16
+def XORmi32 : I32MI <"xor", 0x81, MRM6m >; // [mem32] ^= R32
+
+def XORri16b : II8 <"xor", 0x83, MRM6r >, OpSize; // R16 ^= imm8
+def XORri32b : II8 <"xor", 0x83, MRM6r >; // R32 ^= imm8
+def XORmi16b : IM16I8<"xor", 0x83, MRM6m >, OpSize; // [mem16] ^= imm8
+def XORmi32b : IM32I8<"xor", 0x83, MRM6m >; // [mem32] ^= imm8
+// Shift instructions
+def SHLrCL8 : I <"shl", 0xD2, MRM4r > , UsesCL; // R8 <<= cl
+def SHLrCL16 : I <"shl", 0xD3, MRM4r >, OpSize, UsesCL; // R16 <<= cl
+def SHLrCL32 : I <"shl", 0xD3, MRM4r > , UsesCL; // R32 <<= cl
+def SHLmCL8 : IM8 <"shl", 0xD2, MRM4m > , UsesCL; // [mem8] <<= cl
+def SHLmCL16 : IM16 <"shl", 0xD3, MRM4m >, OpSize, UsesCL; // [mem16] <<= cl
+def SHLmCL32 : IM32 <"shl", 0xD3, MRM4m > , UsesCL; // [mem32] <<= cl
+
+def SHLri8 : II8 <"shl", 0xC0, MRM4r