// ADJCALLSTACKDOWN/UP implicitly use/def ESP because they may be expanded into
// a stack adjustment and the codegen must know that they may modify the stack
// pointer before prolog-epilog rewriting occurs.
+let Defs = [ESP], Uses = [ESP] in {
def ADJCALLSTACKDOWN : I<0, Pseudo, (outs), (ins i32imm:$amt), "#ADJCALLSTACKDOWN",
- [(X86callseq_start imm:$amt)]>, Imp<[ESP],[ESP]>;
+ [(X86callseq_start imm:$amt)]>;
def ADJCALLSTACKUP : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2),
"#ADJCALLSTACKUP",
- [(X86callseq_end imm:$amt1, imm:$amt2)]>,
- Imp<[ESP],[ESP]>;
+ [(X86callseq_end imm:$amt1, imm:$amt2)]>;
+}
def IMPLICIT_USE : I<0, Pseudo, (outs), (ins variable_ops),
"#IMPLICIT_USE", []>;
def IMPLICIT_DEF : I<0, Pseudo, (outs variable_ops), (ins),
//===----------------------------------------------------------------------===//
// Miscellaneous Instructions...
//
+let Defs = [EBP, ESP], Uses = [EBP, ESP] in
def LEAVE : I<0xC9, RawFrm,
- (outs), (ins), "leave", []>, Imp<[EBP,ESP],[EBP,ESP]>;
+ (outs), (ins), "leave", []>;
+
+let Defs = [ESP], Uses = [ESP] in {
def POP32r : I<0x58, AddRegFrm,
- (outs GR32:$reg), (ins), "pop{l}\t$reg", []>, Imp<[ESP],[ESP]>;
+ (outs GR32:$reg), (ins), "pop{l}\t$reg", []>;
def PUSH32r : I<0x50, AddRegFrm,
- (outs), (ins GR32:$reg), "push{l}\t$reg", []>, Imp<[ESP],[ESP]>;
+ (outs), (ins GR32:$reg), "push{l}\t$reg", []>;
+}
def MovePCtoStack : I<0, Pseudo, (outs), (ins piclabel:$label),
"call\t$label", []>;
"lea{l}\t{$src|$dst}, {$dst|$src}",
[(set GR32:$dst, lea32addr:$src)]>, Requires<[In32BitMode]>;
+let Defs = [ECX,EDI,ESI], Uses = [ECX,EDI,ESI] in {
def REP_MOVSB : I<0xA4, RawFrm, (outs), (ins), "{rep;movsb|rep movsb}",
- [(X86rep_movs i8)]>,
- Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP;
+ [(X86rep_movs i8)]>, REP;
def REP_MOVSW : I<0xA5, RawFrm, (outs), (ins), "{rep;movsw|rep movsw}",
- [(X86rep_movs i16)]>,
- Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP, OpSize;
+ [(X86rep_movs i16)]>, REP, OpSize;
def REP_MOVSD : I<0xA5, RawFrm, (outs), (ins), "{rep;movsl|rep movsd}",
- [(X86rep_movs i32)]>,
- Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>, REP;
+ [(X86rep_movs i32)]>, REP;
+}
+let Defs = [ECX,EDI], Uses = [AL,ECX,EDI] in
def REP_STOSB : I<0xAA, RawFrm, (outs), (ins), "{rep;stosb|rep stosb}",
- [(X86rep_stos i8)]>,
- Imp<[AL,ECX,EDI], [ECX,EDI]>, REP;
+ [(X86rep_stos i8)]>, REP;
+let Defs = [ECX,EDI], Uses = [AX,ECX,EDI] in
def REP_STOSW : I<0xAB, RawFrm, (outs), (ins), "{rep;stosw|rep stosw}",
- [(X86rep_stos i16)]>,
- Imp<[AX,ECX,EDI], [ECX,EDI]>, REP, OpSize;
+ [(X86rep_stos i16)]>, REP, OpSize;
+let Defs = [ECX,EDI], Uses = [EAX,ECX,EDI] in
def REP_STOSD : I<0xAB, RawFrm, (outs), (ins), "{rep;stosl|rep stosd}",
- [(X86rep_stos i32)]>,
- Imp<[EAX,ECX,EDI], [ECX,EDI]>, REP;
+ [(X86rep_stos i32)]>, REP;
+let Defs = [RAX, RDX] in
def RDTSC : I<0x31, RawFrm, (outs), (ins), "rdtsc", [(X86rdtsc)]>,
- TB, Imp<[],[RAX,RDX]>;
+ TB;
//===----------------------------------------------------------------------===//
// Input/Output Instructions...
//
+let Defs = [AL], Uses = [DX] in
def IN8rr : I<0xEC, RawFrm, (outs), (ins),
- "in{b}\t{%dx, %al|%AL, %DX}",
- []>, Imp<[DX], [AL]>;
+ "in{b}\t{%dx, %al|%AL, %DX}", []>;
+let Defs = [AX], Uses = [DX] in
def IN16rr : I<0xED, RawFrm, (outs), (ins),
- "in{w}\t{%dx, %ax|%AX, %DX}",
- []>, Imp<[DX], [AX]>, OpSize;
+ "in{w}\t{%dx, %ax|%AX, %DX}", []>, OpSize;
+let Defs = [EAX], Uses = [DX] in
def IN32rr : I<0xED, RawFrm, (outs), (ins),
- "in{l}\t{%dx, %eax|%EAX, %DX}",
- []>, Imp<[DX],[EAX]>;
+ "in{l}\t{%dx, %eax|%EAX, %DX}", []>;
+let Defs = [AL] in
def IN8ri : Ii8<0xE4, RawFrm, (outs), (ins i16i8imm:$port),
- "in{b}\t{$port, %al|%AL, $port}",
- []>,
- Imp<[], [AL]>;
+ "in{b}\t{$port, %al|%AL, $port}", []>;
+let Defs = [AX] in
def IN16ri : Ii8<0xE5, RawFrm, (outs), (ins i16i8imm:$port),
- "in{w}\t{$port, %ax|%AX, $port}",
- []>,
- Imp<[], [AX]>, OpSize;
+ "in{w}\t{$port, %ax|%AX, $port}", []>, OpSize;
+let Defs = [EAX] in
def IN32ri : Ii8<0xE5, RawFrm, (outs), (ins i16i8imm:$port),
- "in{l}\t{$port, %eax|%EAX, $port}",
- []>,
- Imp<[],[EAX]>;
+ "in{l}\t{$port, %eax|%EAX, $port}", []>;
+let Uses = [DX, AL] in
def OUT8rr : I<0xEE, RawFrm, (outs), (ins),
- "out{b}\t{%al, %dx|%DX, %AL}",
- []>, Imp<[DX, AL], []>;
+ "out{b}\t{%al, %dx|%DX, %AL}", []>;
+let Uses = [DX, AX] in
def OUT16rr : I<0xEF, RawFrm, (outs), (ins),
- "out{w}\t{%ax, %dx|%DX, %AX}",
- []>, Imp<[DX, AX], []>, OpSize;
+ "out{w}\t{%ax, %dx|%DX, %AX}", []>, OpSize;
+let Uses = [DX, EAX] in
def OUT32rr : I<0xEF, RawFrm, (outs), (ins),
- "out{l}\t{%eax, %dx|%DX, %EAX}",
- []>, Imp<[DX, EAX], []>;
+ "out{l}\t{%eax, %dx|%DX, %EAX}", []>;
+let Uses = [AL] in
def OUT8ir : Ii8<0xE6, RawFrm, (outs), (ins i16i8imm:$port),
- "out{b}\t{%al, $port|$port, %AL}",
- []>,
- Imp<[AL], []>;
+ "out{b}\t{%al, $port|$port, %AL}", []>;
+let Uses = [AX] in
def OUT16ir : Ii8<0xE7, RawFrm, (outs), (ins i16i8imm:$port),
- "out{w}\t{%ax, $port|$port, %AX}",
- []>,
- Imp<[AX], []>, OpSize;
+ "out{w}\t{%ax, $port|$port, %AX}", []>, OpSize;
+let Uses = [EAX] in
def OUT32ir : Ii8<0xE7, RawFrm, (outs), (ins i16i8imm:$port),
- "out{l}\t{%eax, $port|$port, %EAX}",
- []>,
- Imp<[EAX], []>;
+ "out{l}\t{%eax, $port|$port, %EAX}", []>;
//===----------------------------------------------------------------------===//
// Move Instructions...
//
// Extra precision multiplication
+let Defs = [AL,AH], Uses = [AL] in
def MUL8r : I<0xF6, MRM4r, (outs), (ins GR8:$src), "mul{b}\t$src",
// FIXME: Used for 8-bit mul, ignore result upper 8 bits.
// This probably ought to be moved to a def : Pat<> if the
// syntax can be accepted.
- [(set AL, (mul AL, GR8:$src))]>,
- Imp<[AL],[AL,AH]>; // AL,AH = AL*GR8
+ [(set AL, (mul AL, GR8:$src))]>; // AL,AH = AL*GR8
+let Defs = [AX,DX], Uses = [AX] in
def MUL16r : I<0xF7, MRM4r, (outs), (ins GR16:$src), "mul{w}\t$src", []>,
- Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*GR16
-def MUL32r : I<0xF7, MRM4r, (outs), (ins GR32:$src), "mul{l}\t$src", []>,
- Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*GR32
+ OpSize; // AX,DX = AX*GR16
+let Defs = [EAX,EDX], Uses = [EAX] in
+def MUL32r : I<0xF7, MRM4r, (outs), (ins GR32:$src), "mul{l}\t$src", []>;
+ // EAX,EDX = EAX*GR32
+let Defs = [AL,AH], Uses = [AL] in
def MUL8m : I<0xF6, MRM4m, (outs), (ins i8mem :$src),
"mul{b}\t$src",
// FIXME: Used for 8-bit mul, ignore result upper 8 bits.
// This probably ought to be moved to a def : Pat<> if the
// syntax can be accepted.
- [(set AL, (mul AL, (loadi8 addr:$src)))]>,
- Imp<[AL],[AL,AH]>; // AL,AH = AL*[mem8]
+ [(set AL, (mul AL, (loadi8 addr:$src)))]>; // AL,AH = AL*[mem8]
+let Defs = [AX,DX], Uses = [AX] in
def MUL16m : I<0xF7, MRM4m, (outs), (ins i16mem:$src),
- "mul{w}\t$src", []>, Imp<[AX],[AX,DX]>,
- OpSize; // AX,DX = AX*[mem16]
+ "mul{w}\t$src", []>, OpSize; // AX,DX = AX*[mem16]
+let Defs = [EAX,EDX], Uses = [EAX] in
def MUL32m : I<0xF7, MRM4m, (outs), (ins i32mem:$src),
- "mul{l}\t$src", []>, Imp<[EAX],[EAX,EDX]>;// EAX,EDX = EAX*[mem32]
+ "mul{l}\t$src", []>; // EAX,EDX = EAX*[mem32]
-def IMUL8r : I<0xF6, MRM5r, (outs), (ins GR8:$src), "imul{b}\t$src", []>,
- Imp<[AL],[AL,AH]>; // AL,AH = AL*GR8
+let Defs = [AL,AH], Uses = [AL] in
+def IMUL8r : I<0xF6, MRM5r, (outs), (ins GR8:$src), "imul{b}\t$src", []>;
+ // AL,AH = AL*GR8
+let Defs = [AX,DX], Uses = [AX] in
def IMUL16r : I<0xF7, MRM5r, (outs), (ins GR16:$src), "imul{w}\t$src", []>,
- Imp<[AX],[AX,DX]>, OpSize; // AX,DX = AX*GR16
-def IMUL32r : I<0xF7, MRM5r, (outs), (ins GR32:$src), "imul{l}\t$src", []>,
- Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*GR32
+ OpSize; // AX,DX = AX*GR16
+let Defs = [EAX,EDX], Uses = [EAX] in
+def IMUL32r : I<0xF7, MRM5r, (outs), (ins GR32:$src), "imul{l}\t$src", []>;
+ // EAX,EDX = EAX*GR32
+let Defs = [AL,AH], Uses = [AL] in
def IMUL8m : I<0xF6, MRM5m, (outs), (ins i8mem :$src),
- "imul{b}\t$src", []>, Imp<[AL],[AL,AH]>; // AL,AH = AL*[mem8]
+ "imul{b}\t$src", []>; // AL,AH = AL*[mem8]
+let Defs = [AX,DX], Uses = [AX] in
def IMUL16m : I<0xF7, MRM5m, (outs), (ins i16mem:$src),
- "imul{w}\t$src", []>, Imp<[AX],[AX,DX]>,
- OpSize; // AX,DX = AX*[mem16]
+ "imul{w}\t$src", []>, OpSize; // AX,DX = AX*[mem16]
+let Defs = [EAX,EDX], Uses = [EAX] in
def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src),
- "imul{l}\t$src", []>,
- Imp<[EAX],[EAX,EDX]>; // EAX,EDX = EAX*[mem32]
+ "imul{l}\t$src", []>; // EAX,EDX = EAX*[mem32]
// unsigned division/remainder
+let Defs = [AX], Uses = [AL,AH] in
def DIV8r : I<0xF6, MRM6r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
- "div{b}\t$src", []>, Imp<[AX],[AX]>;
+ "div{b}\t$src", []>;
+let Defs = [AX,DX], Uses = [AX,DX] in
def DIV16r : I<0xF7, MRM6r, (outs), (ins GR16:$src), // DX:AX/r16 = AX,DX
- "div{w}\t$src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
+ "div{w}\t$src", []>, OpSize;
+let Defs = [EAX,EDX], Uses = [EAX,EDX] in
def DIV32r : I<0xF7, MRM6r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
- "div{l}\t$src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
+ "div{l}\t$src", []>;
+let Defs = [AX], Uses = [AL,AH] in
def DIV8m : I<0xF6, MRM6m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
- "div{b}\t$src", []>, Imp<[AX],[AX]>;
+ "div{b}\t$src", []>;
+let Defs = [AX,DX], Uses = [AX,DX] in
def DIV16m : I<0xF7, MRM6m, (outs), (ins i16mem:$src), // DX:AX/[mem16] = AX,DX
- "div{w}\t$src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
+ "div{w}\t$src", []>, OpSize;
+let Defs = [EAX,EDX], Uses = [EAX,EDX] in
def DIV32m : I<0xF7, MRM6m, (outs), (ins i32mem:$src), // EDX:EAX/[mem32] = EAX,EDX
- "div{l}\t$src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
+ "div{l}\t$src", []>;
// Signed division/remainder.
+let Defs = [AX], Uses = [AL,AH] in
def IDIV8r : I<0xF6, MRM7r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
- "idiv{b}\t$src", []>, Imp<[AX],[AX]>;
+ "idiv{b}\t$src", []>;
+let Defs = [AX,DX], Uses = [AX,DX] in
def IDIV16r: I<0xF7, MRM7r, (outs), (ins GR16:$src), // DX:AX/r16 = AX,DX
- "idiv{w}\t$src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
+ "idiv{w}\t$src", []>, OpSize;
+let Defs = [EAX,EDX], Uses = [EAX,EDX] in
def IDIV32r: I<0xF7, MRM7r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
- "idiv{l}\t$src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
+ "idiv{l}\t$src", []>;
+let Defs = [AX], Uses = [AL,AH] in
def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
- "idiv{b}\t$src", []>, Imp<[AX],[AX]>;
+ "idiv{b}\t$src", []>;
+let Defs = [AX,DX], Uses = [AX,DX] in
def IDIV16m: I<0xF7, MRM7m, (outs), (ins i16mem:$src), // DX:AX/[mem16] = AX,DX
- "idiv{w}\t$src", []>, Imp<[AX,DX],[AX,DX]>, OpSize;
+ "idiv{w}\t$src", []>, OpSize;
+let Defs = [EAX,EDX], Uses = [EAX,EDX] in
def IDIV32m: I<0xF7, MRM7m, (outs), (ins i32mem:$src), // EDX:EAX/[mem32] = EAX,EDX
- "idiv{l}\t$src", []>, Imp<[EAX,EDX],[EAX,EDX]>;
+ "idiv{l}\t$src", []>;
//===----------------------------------------------------------------------===//
}
// Shift instructions
+let Uses = [CL] in {
def SHL8rCL : I<0xD2, MRM4r, (outs GR8 :$dst), (ins GR8 :$src),
"shl{b}\t{%cl, $dst|$dst, %CL}",
- [(set GR8:$dst, (shl GR8:$src, CL))]>, Imp<[CL],[]>;
+ [(set GR8:$dst, (shl GR8:$src, CL))]>;
def SHL16rCL : I<0xD3, MRM4r, (outs GR16:$dst), (ins GR16:$src),
"shl{w}\t{%cl, $dst|$dst, %CL}",
- [(set GR16:$dst, (shl GR16:$src, CL))]>, Imp<[CL],[]>, OpSize;
+ [(set GR16:$dst, (shl GR16:$src, CL))]>, OpSize;
def SHL32rCL : I<0xD3, MRM4r, (outs GR32:$dst), (ins GR32:$src),
"shl{l}\t{%cl, $dst|$dst, %CL}",
- [(set GR32:$dst, (shl GR32:$src, CL))]>, Imp<[CL],[]>;
+ [(set GR32:$dst, (shl GR32:$src, CL))]>;
+}
def SHL8ri : Ii8<0xC0, MRM4r, (outs GR8 :$dst), (ins GR8 :$src1, i8imm:$src2),
"shl{b}\t{$src2, $dst|$dst, $src2}",
"shl{l}\t$dst", []>;
let isTwoAddress = 0 in {
+ let Uses = [CL] in {
def SHL8mCL : I<0xD2, MRM4m, (outs), (ins i8mem :$dst),
"shl{b}\t{%cl, $dst|$dst, %CL}",
- [(store (shl (loadi8 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>;
+ [(store (shl (loadi8 addr:$dst), CL), addr:$dst)]>;
def SHL16mCL : I<0xD3, MRM4m, (outs), (ins i16mem:$dst),
"shl{w}\t{%cl, $dst|$dst, %CL}",
- [(store (shl (loadi16 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>, OpSize;
+ [(store (shl (loadi16 addr:$dst), CL), addr:$dst)]>, OpSize;
def SHL32mCL : I<0xD3, MRM4m, (outs), (ins i32mem:$dst),
"shl{l}\t{%cl, $dst|$dst, %CL}",
- [(store (shl (loadi32 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>;
+ [(store (shl (loadi32 addr:$dst), CL), addr:$dst)]>;
+ }
def SHL8mi : Ii8<0xC0, MRM4m, (outs), (ins i8mem :$dst, i8imm:$src),
"shl{b}\t{$src, $dst|$dst, $src}",
[(store (shl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
[(store (shl (loadi32 addr:$dst), (i8 1)), addr:$dst)]>;
}
+let Uses = [CL] in {
def SHR8rCL : I<0xD2, MRM5r, (outs GR8 :$dst), (ins GR8 :$src),
"shr{b}\t{%cl, $dst|$dst, %CL}",
- [(set GR8:$dst, (srl GR8:$src, CL))]>, Imp<[CL],[]>;
+ [(set GR8:$dst, (srl GR8:$src, CL))]>;
def SHR16rCL : I<0xD3, MRM5r, (outs GR16:$dst), (ins GR16:$src),
"shr{w}\t{%cl, $dst|$dst, %CL}",
- [(set GR16:$dst, (srl GR16:$src, CL))]>, Imp<[CL],[]>, OpSize;
+ [(set GR16:$dst, (srl GR16:$src, CL))]>, OpSize;
def SHR32rCL : I<0xD3, MRM5r, (outs GR32:$dst), (ins GR32:$src),
"shr{l}\t{%cl, $dst|$dst, %CL}",
- [(set GR32:$dst, (srl GR32:$src, CL))]>, Imp<[CL],[]>;
+ [(set GR32:$dst, (srl GR32:$src, CL))]>;
+}
def SHR8ri : Ii8<0xC0, MRM5r, (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
"shr{b}\t{$src2, $dst|$dst, $src2}",
[(set GR32:$dst, (srl GR32:$src1, (i8 1)))]>;
let isTwoAddress = 0 in {
+ let Uses = [CL] in {
def SHR8mCL : I<0xD2, MRM5m, (outs), (ins i8mem :$dst),
"shr{b}\t{%cl, $dst|$dst, %CL}",
- [(store (srl (loadi8 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>;
+ [(store (srl (loadi8 addr:$dst), CL), addr:$dst)]>;
def SHR16mCL : I<0xD3, MRM5m, (outs), (ins i16mem:$dst),
"shr{w}\t{%cl, $dst|$dst, %CL}",
[(store (srl (loadi16 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>, OpSize;
+ OpSize;
def SHR32mCL : I<0xD3, MRM5m, (outs), (ins i32mem:$dst),
"shr{l}\t{%cl, $dst|$dst, %CL}",
- [(store (srl (loadi32 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>;
+ [(store (srl (loadi32 addr:$dst), CL), addr:$dst)]>;
+ }
def SHR8mi : Ii8<0xC0, MRM5m, (outs), (ins i8mem :$dst, i8imm:$src),
"shr{b}\t{$src, $dst|$dst, $src}",
[(store (srl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
[(store (srl (loadi32 addr:$dst), (i8 1)), addr:$dst)]>;
}
+let Uses = [CL] in {
def SAR8rCL : I<0xD2, MRM7r, (outs GR8 :$dst), (ins GR8 :$src),
"sar{b}\t{%cl, $dst|$dst, %CL}",
- [(set GR8:$dst, (sra GR8:$src, CL))]>, Imp<[CL],[]>;
+ [(set GR8:$dst, (sra GR8:$src, CL))]>;
def SAR16rCL : I<0xD3, MRM7r, (outs GR16:$dst), (ins GR16:$src),
"sar{w}\t{%cl, $dst|$dst, %CL}",
- [(set GR16:$dst, (sra GR16:$src, CL))]>, Imp<[CL],[]>, OpSize;
+ [(set GR16:$dst, (sra GR16:$src, CL))]>, OpSize;
def SAR32rCL : I<0xD3, MRM7r, (outs GR32:$dst), (ins GR32:$src),
"sar{l}\t{%cl, $dst|$dst, %CL}",
- [(set GR32:$dst, (sra GR32:$src, CL))]>, Imp<[CL],[]>;
+ [(set GR32:$dst, (sra GR32:$src, CL))]>;
+}
def SAR8ri : Ii8<0xC0, MRM7r, (outs GR8 :$dst), (ins GR8 :$src1, i8imm:$src2),
"sar{b}\t{$src2, $dst|$dst, $src2}",
[(set GR32:$dst, (sra GR32:$src1, (i8 1)))]>;
let isTwoAddress = 0 in {
+ let Uses = [CL] in {
def SAR8mCL : I<0xD2, MRM7m, (outs), (ins i8mem :$dst),
"sar{b}\t{%cl, $dst|$dst, %CL}",
- [(store (sra (loadi8 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>;
+ [(store (sra (loadi8 addr:$dst), CL), addr:$dst)]>;
def SAR16mCL : I<0xD3, MRM7m, (outs), (ins i16mem:$dst),
"sar{w}\t{%cl, $dst|$dst, %CL}",
- [(store (sra (loadi16 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>, OpSize;
+ [(store (sra (loadi16 addr:$dst), CL), addr:$dst)]>, OpSize;
def SAR32mCL : I<0xD3, MRM7m, (outs), (ins i32mem:$dst),
"sar{l}\t{%cl, $dst|$dst, %CL}",
- [(store (sra (loadi32 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>;
+ [(store (sra (loadi32 addr:$dst), CL), addr:$dst)]>;
+ }
def SAR8mi : Ii8<0xC0, MRM7m, (outs), (ins i8mem :$dst, i8imm:$src),
"sar{b}\t{$src, $dst|$dst, $src}",
[(store (sra (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
// Rotate instructions
// FIXME: provide shorter instructions when imm8 == 1
+let Uses = [CL] in {
def ROL8rCL : I<0xD2, MRM0r, (outs GR8 :$dst), (ins GR8 :$src),
"rol{b}\t{%cl, $dst|$dst, %CL}",
- [(set GR8:$dst, (rotl GR8:$src, CL))]>, Imp<[CL],[]>;
+ [(set GR8:$dst, (rotl GR8:$src, CL))]>;
def ROL16rCL : I<0xD3, MRM0r, (outs GR16:$dst), (ins GR16:$src),
"rol{w}\t{%cl, $dst|$dst, %CL}",
- [(set GR16:$dst, (rotl GR16:$src, CL))]>, Imp<[CL],[]>, OpSize;
+ [(set GR16:$dst, (rotl GR16:$src, CL))]>, OpSize;
def ROL32rCL : I<0xD3, MRM0r, (outs GR32:$dst), (ins GR32:$src),
"rol{l}\t{%cl, $dst|$dst, %CL}",
- [(set GR32:$dst, (rotl GR32:$src, CL))]>, Imp<[CL],[]>;
+ [(set GR32:$dst, (rotl GR32:$src, CL))]>;
+}
def ROL8ri : Ii8<0xC0, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1, i8imm:$src2),
"rol{b}\t{$src2, $dst|$dst, $src2}",
[(set GR32:$dst, (rotl GR32:$src1, (i8 1)))]>;
let isTwoAddress = 0 in {
+ let Uses = [CL] in {
def ROL8mCL : I<0xD2, MRM0m, (outs), (ins i8mem :$dst),
"rol{b}\t{%cl, $dst|$dst, %CL}",
- [(store (rotl (loadi8 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>;
+ [(store (rotl (loadi8 addr:$dst), CL), addr:$dst)]>;
def ROL16mCL : I<0xD3, MRM0m, (outs), (ins i16mem:$dst),
"rol{w}\t{%cl, $dst|$dst, %CL}",
- [(store (rotl (loadi16 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>, OpSize;
+ [(store (rotl (loadi16 addr:$dst), CL), addr:$dst)]>, OpSize;
def ROL32mCL : I<0xD3, MRM0m, (outs), (ins i32mem:$dst),
"rol{l}\t{%cl, $dst|$dst, %CL}",
- [(store (rotl (loadi32 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>;
+ [(store (rotl (loadi32 addr:$dst), CL), addr:$dst)]>;
+ }
def ROL8mi : Ii8<0xC0, MRM0m, (outs), (ins i8mem :$dst, i8imm:$src),
"rol{b}\t{$src, $dst|$dst, $src}",
[(store (rotl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
[(store (rotl (loadi32 addr:$dst), (i8 1)), addr:$dst)]>;
}
+let Uses = [CL] in {
def ROR8rCL : I<0xD2, MRM1r, (outs GR8 :$dst), (ins GR8 :$src),
"ror{b}\t{%cl, $dst|$dst, %CL}",
- [(set GR8:$dst, (rotr GR8:$src, CL))]>, Imp<[CL],[]>;
+ [(set GR8:$dst, (rotr GR8:$src, CL))]>;
def ROR16rCL : I<0xD3, MRM1r, (outs GR16:$dst), (ins GR16:$src),
"ror{w}\t{%cl, $dst|$dst, %CL}",
- [(set GR16:$dst, (rotr GR16:$src, CL))]>, Imp<[CL],[]>, OpSize;
+ [(set GR16:$dst, (rotr GR16:$src, CL))]>, OpSize;
def ROR32rCL : I<0xD3, MRM1r, (outs GR32:$dst), (ins GR32:$src),
"ror{l}\t{%cl, $dst|$dst, %CL}",
- [(set GR32:$dst, (rotr GR32:$src, CL))]>, Imp<[CL],[]>;
+ [(set GR32:$dst, (rotr GR32:$src, CL))]>;
+}
def ROR8ri : Ii8<0xC0, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1, i8imm:$src2),
"ror{b}\t{$src2, $dst|$dst, $src2}",
[(set GR32:$dst, (rotr GR32:$src1, (i8 1)))]>;
let isTwoAddress = 0 in {
+ let Uses = [CL] in {
def ROR8mCL : I<0xD2, MRM1m, (outs), (ins i8mem :$dst),
"ror{b}\t{%cl, $dst|$dst, %CL}",
- [(store (rotr (loadi8 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>;
+ [(store (rotr (loadi8 addr:$dst), CL), addr:$dst)]>;
def ROR16mCL : I<0xD3, MRM1m, (outs), (ins i16mem:$dst),
"ror{w}\t{%cl, $dst|$dst, %CL}",
- [(store (rotr (loadi16 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>, OpSize;
+ [(store (rotr (loadi16 addr:$dst), CL), addr:$dst)]>, OpSize;
def ROR32mCL : I<0xD3, MRM1m, (outs), (ins i32mem:$dst),
"ror{l}\t{%cl, $dst|$dst, %CL}",
- [(store (rotr (loadi32 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>;
+ [(store (rotr (loadi32 addr:$dst), CL), addr:$dst)]>;
+ }
def ROR8mi : Ii8<0xC0, MRM1m, (outs), (ins i8mem :$dst, i8imm:$src),
"ror{b}\t{$src, $dst|$dst, $src}",
[(store (rotr (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
// Double shift instructions (generalizations of rotate)
+let Uses = [CL] in {
def SHLD32rrCL : I<0xA5, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
"shld{l}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
- [(set GR32:$dst, (X86shld GR32:$src1, GR32:$src2, CL))]>,
- Imp<[CL],[]>, TB;
+ [(set GR32:$dst, (X86shld GR32:$src1, GR32:$src2, CL))]>, TB;
def SHRD32rrCL : I<0xAD, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
"shrd{l}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
- [(set GR32:$dst, (X86shrd GR32:$src1, GR32:$src2, CL))]>,
- Imp<[CL],[]>, TB;
+ [(set GR32:$dst, (X86shrd GR32:$src1, GR32:$src2, CL))]>, TB;
def SHLD16rrCL : I<0xA5, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
"shld{w}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
[(set GR16:$dst, (X86shld GR16:$src1, GR16:$src2, CL))]>,
- Imp<[CL],[]>, TB, OpSize;
+ TB, OpSize;
def SHRD16rrCL : I<0xAD, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
"shrd{w}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
[(set GR16:$dst, (X86shrd GR16:$src1, GR16:$src2, CL))]>,
- Imp<[CL],[]>, TB, OpSize;
+ TB, OpSize;
+}
let isCommutable = 1 in { // These instructions commute to each other.
def SHLD32rri8 : Ii8<0xA4, MRMDestReg,
}
let isTwoAddress = 0 in {
+ let Uses = [CL] in {
def SHLD32mrCL : I<0xA5, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
"shld{l}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
[(store (X86shld (loadi32 addr:$dst), GR32:$src2, CL),
- addr:$dst)]>,
- Imp<[CL],[]>, TB;
+ addr:$dst)]>, TB;
def SHRD32mrCL : I<0xAD, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
"shrd{l}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
[(store (X86shrd (loadi32 addr:$dst), GR32:$src2, CL),
- addr:$dst)]>,
- Imp<[CL],[]>, TB;
+ addr:$dst)]>, TB;
+ }
def SHLD32mri8 : Ii8<0xA4, MRMDestMem,
(outs), (ins i32mem:$dst, GR32:$src2, i8imm:$src3),
"shld{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
(i8 imm:$src3)), addr:$dst)]>,
TB;
+ let Uses = [CL] in {
def SHLD16mrCL : I<0xA5, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
"shld{w}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
[(store (X86shld (loadi16 addr:$dst), GR16:$src2, CL),
- addr:$dst)]>,
- Imp<[CL],[]>, TB, OpSize;
+ addr:$dst)]>, TB, OpSize;
def SHRD16mrCL : I<0xAD, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
"shrd{w}\t{%cl, $src2, $dst|$dst, $src2, %CL}",
[(store (X86shrd (loadi16 addr:$dst), GR16:$src2, CL),
- addr:$dst)]>,
- Imp<[CL],[]>, TB, OpSize;
+ addr:$dst)]>, TB, OpSize;
+ }
def SHLD16mri8 : Ii8<0xA4, MRMDestMem,
(outs), (ins i16mem:$dst, GR16:$src2, i8imm:$src3),
"shld{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
// Arithmetic.
let isCommutable = 1 in { // X = ADD Y, Z --> X = ADD Z, Y
-def ADD8rr : I<0x00, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src1, GR8 :$src2),
+def ADD8rr : I<0x00, MRMDestReg, (outs GR8 :$dst),
+ (ins GR8 :$src1, GR8 :$src2),
"add{b}\t{$src2, $dst|$dst, $src2}",
[(set GR8:$dst, (add GR8:$src1, GR8:$src2))]>;
let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
-def ADD16rr : I<0x01, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+def ADD16rr : I<0x01, MRMDestReg, (outs GR16:$dst),
+ (ins GR16:$src1, GR16:$src2),
"add{w}\t{$src2, $dst|$dst, $src2}",
[(set GR16:$dst, (add GR16:$src1, GR16:$src2))]>, OpSize;
-def ADD32rr : I<0x01, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
+def ADD32rr : I<0x01, MRMDestReg, (outs GR32:$dst),
+ (ins GR32:$src1, GR32:$src2),
"add{l}\t{$src2, $dst|$dst, $src2}",
[(set GR32:$dst, (add GR32:$src1, GR32:$src2))]>;
} // end isConvertibleToThreeAddress
} // end isCommutable
-def ADD8rm : I<0x02, MRMSrcMem, (outs GR8 :$dst), (ins GR8 :$src1, i8mem :$src2),
+def ADD8rm : I<0x02, MRMSrcMem, (outs GR8 :$dst),
+ (ins GR8 :$src1, i8mem :$src2),
"add{b}\t{$src2, $dst|$dst, $src2}",
[(set GR8:$dst, (add GR8:$src1, (load addr:$src2)))]>;
-def ADD16rm : I<0x03, MRMSrcMem, (outs GR16:$dst), (ins GR16:$src1, i16mem:$src2),
+def ADD16rm : I<0x03, MRMSrcMem, (outs GR16:$dst),
+ (ins GR16:$src1, i16mem:$src2),
"add{w}\t{$src2, $dst|$dst, $src2}",
- [(set GR16:$dst, (add GR16:$src1, (load addr:$src2)))]>, OpSize;
-def ADD32rm : I<0x03, MRMSrcMem, (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2),
+ [(set GR16:$dst, (add GR16:$src1, (load addr:$src2)))]>,OpSize;
+def ADD32rm : I<0x03, MRMSrcMem, (outs GR32:$dst),
+ (ins GR32:$src1, i32mem:$src2),
"add{l}\t{$src2, $dst|$dst, $src2}",
[(set GR32:$dst, (add GR32:$src1, (load addr:$src2)))]>;
[(set GR8:$dst, (add GR8:$src1, imm:$src2))]>;
let isConvertibleToThreeAddress = 1 in { // Can transform into LEA.
-def ADD16ri : Ii16<0x81, MRM0r, (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
+def ADD16ri : Ii16<0x81, MRM0r, (outs GR16:$dst),
+ (ins GR16:$src1, i16imm:$src2),
"add{w}\t{$src2, $dst|$dst, $src2}",
[(set GR16:$dst, (add GR16:$src1, imm:$src2))]>, OpSize;
-def ADD32ri : Ii32<0x81, MRM0r, (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
+def ADD32ri : Ii32<0x81, MRM0r, (outs GR32:$dst),
+ (ins GR32:$src1, i32imm:$src2),
"add{l}\t{$src2, $dst|$dst, $src2}",
[(set GR32:$dst, (add GR32:$src1, imm:$src2))]>;
-def ADD16ri8 : Ii8<0x83, MRM0r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
+def ADD16ri8 : Ii8<0x83, MRM0r, (outs GR16:$dst),
+ (ins GR16:$src1, i16i8imm:$src2),
"add{w}\t{$src2, $dst|$dst, $src2}",
- [(set GR16:$dst, (add GR16:$src1, i16immSExt8:$src2))]>,
- OpSize;
-def ADD32ri8 : Ii8<0x83, MRM0r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
+ [(set GR16:$dst, (add GR16:$src1, i16immSExt8:$src2))]>, OpSize;
+def ADD32ri8 : Ii8<0x83, MRM0r, (outs GR32:$dst),
+ (ins GR32:$src1, i32i8imm:$src2),
"add{l}\t{$src2, $dst|$dst, $src2}",
- [(set GR32:$dst, (add GR32:$src1, i32immSExt8:$src2))]>;
+ [(set GR32:$dst, (add GR32:$src1, i32immSExt8:$src2))]>;
}
let isTwoAddress = 0 in {
// Condition code ops, incl. set if equal/not equal/...
-def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf", []>, Imp<[AH],[]>; // flags = AH
-def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", []>, Imp<[],[AH]>; // AH = flags
+let Uses = [AH] in
+def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf", []>; // flags = AH
+let Defs = [AH] in
+def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", []>; // AH = flags
def SETEr : I<0x94, MRM0r,
(outs GR8 :$dst), (ins),
"movz{wl|x}\t{$src, $dst|$dst, $src}",
[(set GR32:$dst, (zextloadi32i16 addr:$src))]>, TB;
+let Defs = [AX], Uses = [AL] in
def CBW : I<0x98, RawFrm, (outs), (ins),
- "{cbtw|cbw}", []>, Imp<[AL],[AX]>, OpSize; // AX = signext(AL)
+ "{cbtw|cbw}", []>, OpSize; // AX = signext(AL)
+let Defs = [EAX], Uses = [AX] in
def CWDE : I<0x98, RawFrm, (outs), (ins),
- "{cwtl|cwde}", []>, Imp<[AX],[EAX]>; // EAX = signext(AX)
+ "{cwtl|cwde}", []>; // EAX = signext(AX)
+let Defs = [AX,DX], Uses = [AX] in
def CWD : I<0x99, RawFrm, (outs), (ins),
- "{cwtd|cwd}", []>, Imp<[AX],[AX,DX]>, OpSize; // DX:AX = signext(AX)
+ "{cwtd|cwd}", []>, OpSize; // DX:AX = signext(AX)
+let Defs = [EAX,EDX], Uses = [EAX] in
def CDQ : I<0x99, RawFrm, (outs), (ins),
- "{cltd|cdq}", []>, Imp<[EAX],[EAX,EDX]>; // EDX:EAX = signext(EAX)
+ "{cltd|cdq}", []>; // EDX:EAX = signext(EAX)
//===----------------------------------------------------------------------===//
// Thread Local Storage Instructions
//
+let Uses = [EBX] in
def TLS_addr : I<0, Pseudo, (outs GR32:$dst), (ins i32imm:$sym),
"leal\t${sym:mem}(,%ebx,1), $dst",
- [(set GR32:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>,
- Imp<[EBX],[]>;
+ [(set GR32:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>;
let AddedComplexity = 10 in
def TLS_gs_rr : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$src),
//===----------------------------------------------------------------------===//
// Miscellaneous Instructions...
//
+let Defs = [RBP,RSP], Uses = [RBP,RSP] in
def LEAVE64 : I<0xC9, RawFrm,
- (outs), (ins), "leave", []>, Imp<[RBP,RSP],[RBP,RSP]>;
+ (outs), (ins), "leave", []>;
+let Defs = [RSP], Uses = [RSP] in {
def POP64r : I<0x58, AddRegFrm,
- (outs GR64:$reg), (ins), "pop{q}\t$reg", []>, Imp<[RSP],[RSP]>;
+ (outs GR64:$reg), (ins), "pop{q}\t$reg", []>;
def PUSH64r : I<0x50, AddRegFrm,
- (outs), (ins GR64:$reg), "push{q}\t$reg", []>, Imp<[RSP],[RSP]>;
+ (outs), (ins GR64:$reg), "push{q}\t$reg", []>;
+}
def LEA64_32r : I<0x8D, MRMSrcMem,
(outs GR32:$dst), (ins lea64_32mem:$src),
"xchg{q}\t{$src2|$src1}, {$src1|$src2}", []>;
// Repeat string ops
+let Defs = [RCX,RDI,RSI], Uses = [RCX,RDI,RSI] in
def REP_MOVSQ : RI<0xA5, RawFrm, (outs), (ins), "{rep;movsq|rep movsq}",
- [(X86rep_movs i64)]>,
- Imp<[RCX,RDI,RSI], [RCX,RDI,RSI]>, REP;
+ [(X86rep_movs i64)]>, REP;
+let Defs = [RCX,RDI], Uses = [RAX,RCX,RDI] in
def REP_STOSQ : RI<0xAB, RawFrm, (outs), (ins), "{rep;stosq|rep stosq}",
- [(X86rep_stos i64)]>,
- Imp<[RAX,RCX,RDI], [RCX,RDI]>, REP;
+ [(X86rep_stos i64)]>, REP;
//===----------------------------------------------------------------------===//
// Move Instructions...
"movz{wq|x}\t{$src, $dst|$dst, $src}",
[(set GR64:$dst, (zextloadi64i16 addr:$src))]>, TB;
+let Defs = [RAX], Uses = [EAX] in
def CDQE : RI<0x98, RawFrm, (outs), (ins),
- "{cltq|cdqe}", []>, Imp<[EAX],[RAX]>; // RAX = signext(EAX)
+ "{cltq|cdqe}", []>; // RAX = signext(EAX)
+let Defs = [RAX,RDX], Uses = [RAX] in
def CQO : RI<0x99, RawFrm, (outs), (ins),
- "{cqto|cqo}", []>, Imp<[RAX],[RAX,RDX]>; // RDX:RAX = signext(RAX)
+ "{cqto|cqo}", []>; // RDX:RAX = signext(RAX)
//===----------------------------------------------------------------------===//
// Arithmetic Instructions...
[(store (sube (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
// Unsigned multiplication
+let Defs = [RAX,RDX], Uses = [RAX] in {
def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src),
- "mul{q}\t$src", []>,
- Imp<[RAX],[RAX,RDX]>; // RAX,RDX = RAX*GR64
+ "mul{q}\t$src", []>; // RAX,RDX = RAX*GR64
def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
- "mul{q}\t$src", []>,
- Imp<[RAX],[RAX,RDX]>; // RAX,RDX = RAX*[mem64]
+ "mul{q}\t$src", []>; // RAX,RDX = RAX*[mem64]
// Signed multiplication
def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src),
- "imul{q}\t$src", []>,
- Imp<[RAX],[RAX,RDX]>; // RAX,RDX = RAX*GR64
+ "imul{q}\t$src", []>; // RAX,RDX = RAX*GR64
def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
- "imul{q}\t$src", []>,
- Imp<[RAX],[RAX,RDX]>; // RAX,RDX = RAX*[mem64]
+ "imul{q}\t$src", []>; // RAX,RDX = RAX*[mem64]
+}
let isTwoAddress = 1 in {
let isCommutable = 1 in
[(set GR64:$dst, (mul (load addr:$src1), i64immSExt8:$src2))]>;
// Unsigned division / remainder
+let Defs = [RAX,RDX], Uses = [RAX,RDX] in {
def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX
- "div{q}\t$src", []>, Imp<[RAX,RDX],[RAX,RDX]>;
+ "div{q}\t$src", []>;
def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX
- "div{q}\t$src", []>, Imp<[RAX,RDX],[RAX,RDX]>;
+ "div{q}\t$src", []>;
// Signed division / remainder
def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX
- "idiv{q}\t$src", []>, Imp<[RAX,RDX],[RAX,RDX]>;
+ "idiv{q}\t$src", []>;
def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX
- "idiv{q}\t$src", []>, Imp<[RAX,RDX],[RAX,RDX]>;
+ "idiv{q}\t$src", []>;
+}
// Unary instructions
let CodeSize = 2 in {
// Shift instructions
let isTwoAddress = 1 in {
+let Uses = [CL] in
def SHL64rCL : RI<0xD3, MRM4r, (outs GR64:$dst), (ins GR64:$src),
"shl{q}\t{%cl, $dst|$dst, %CL}",
- [(set GR64:$dst, (shl GR64:$src, CL))]>,
- Imp<[CL],[]>;
+ [(set GR64:$dst, (shl GR64:$src, CL))]>;
def SHL64ri : RIi8<0xC1, MRM4r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
"shl{q}\t{$src2, $dst|$dst, $src2}",
[(set GR64:$dst, (shl GR64:$src1, (i8 imm:$src2)))]>;
"shl{q}\t$dst", []>;
} // isTwoAddress
+let Uses = [CL] in
def SHL64mCL : RI<0xD3, MRM4m, (outs), (ins i64mem:$dst),
"shl{q}\t{%cl, $dst|$dst, %CL}",
- [(store (shl (loadi64 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>;
+ [(store (shl (loadi64 addr:$dst), CL), addr:$dst)]>;
def SHL64mi : RIi8<0xC1, MRM4m, (outs), (ins i64mem:$dst, i8imm:$src),
"shl{q}\t{$src, $dst|$dst, $src}",
[(store (shl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
[(store (shl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
let isTwoAddress = 1 in {
+let Uses = [CL] in
def SHR64rCL : RI<0xD3, MRM5r, (outs GR64:$dst), (ins GR64:$src),
"shr{q}\t{%cl, $dst|$dst, %CL}",
- [(set GR64:$dst, (srl GR64:$src, CL))]>,
- Imp<[CL],[]>;
+ [(set GR64:$dst, (srl GR64:$src, CL))]>;
def SHR64ri : RIi8<0xC1, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
"shr{q}\t{$src2, $dst|$dst, $src2}",
[(set GR64:$dst, (srl GR64:$src1, (i8 imm:$src2)))]>;
[(set GR64:$dst, (srl GR64:$src1, (i8 1)))]>;
} // isTwoAddress
+let Uses = [CL] in
def SHR64mCL : RI<0xD3, MRM5m, (outs), (ins i64mem:$dst),
"shr{q}\t{%cl, $dst|$dst, %CL}",
- [(store (srl (loadi64 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>;
+ [(store (srl (loadi64 addr:$dst), CL), addr:$dst)]>;
def SHR64mi : RIi8<0xC1, MRM5m, (outs), (ins i64mem:$dst, i8imm:$src),
"shr{q}\t{$src, $dst|$dst, $src}",
[(store (srl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
[(store (srl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
let isTwoAddress = 1 in {
+let Uses = [CL] in
def SAR64rCL : RI<0xD3, MRM7r, (outs GR64:$dst), (ins GR64:$src),
"sar{q}\t{%cl, $dst|$dst, %CL}",
- [(set GR64:$dst, (sra GR64:$src, CL))]>, Imp<[CL],[]>;
+ [(set GR64:$dst, (sra GR64:$src, CL))]>;
def SAR64ri : RIi8<0xC1, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
"sar{q}\t{$src2, $dst|$dst, $src2}",
[(set GR64:$dst, (sra GR64:$src1, (i8 imm:$src2)))]>;
[(set GR64:$dst, (sra GR64:$src1, (i8 1)))]>;
} // isTwoAddress
+let Uses = [CL] in
def SAR64mCL : RI<0xD3, MRM7m, (outs), (ins i64mem:$dst),
"sar{q}\t{%cl, $dst|$dst, %CL}",
- [(store (sra (loadi64 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>;
+ [(store (sra (loadi64 addr:$dst), CL), addr:$dst)]>;
def SAR64mi : RIi8<0xC1, MRM7m, (outs), (ins i64mem:$dst, i8imm:$src),
"sar{q}\t{$src, $dst|$dst, $src}",
[(store (sra (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
// Rotate instructions
let isTwoAddress = 1 in {
+let Uses = [CL] in
def ROL64rCL : RI<0xD3, MRM0r, (outs GR64:$dst), (ins GR64:$src),
"rol{q}\t{%cl, $dst|$dst, %CL}",
- [(set GR64:$dst, (rotl GR64:$src, CL))]>, Imp<[CL],[]>;
+ [(set GR64:$dst, (rotl GR64:$src, CL))]>;
def ROL64ri : RIi8<0xC1, MRM0r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
"rol{q}\t{$src2, $dst|$dst, $src2}",
[(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$src2)))]>;
[(set GR64:$dst, (rotl GR64:$src1, (i8 1)))]>;
} // isTwoAddress
+let Uses = [CL] in
def ROL64mCL : I<0xD3, MRM0m, (outs), (ins i64mem:$dst),
"rol{q}\t{%cl, $dst|$dst, %CL}",
- [(store (rotl (loadi64 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>;
+ [(store (rotl (loadi64 addr:$dst), CL), addr:$dst)]>;
def ROL64mi : RIi8<0xC1, MRM0m, (outs), (ins i64mem:$dst, i8imm:$src),
"rol{q}\t{$src, $dst|$dst, $src}",
[(store (rotl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
[(store (rotl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
let isTwoAddress = 1 in {
+let Uses = [CL] in
def ROR64rCL : RI<0xD3, MRM1r, (outs GR64:$dst), (ins GR64:$src),
"ror{q}\t{%cl, $dst|$dst, %CL}",
- [(set GR64:$dst, (rotr GR64:$src, CL))]>, Imp<[CL],[]>;
+ [(set GR64:$dst, (rotr GR64:$src, CL))]>;
def ROR64ri : RIi8<0xC1, MRM1r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
"ror{q}\t{$src2, $dst|$dst, $src2}",
[(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$src2)))]>;
[(set GR64:$dst, (rotr GR64:$src1, (i8 1)))]>;
} // isTwoAddress
+let Uses = [CL] in
def ROR64mCL : RI<0xD3, MRM1m, (outs), (ins i64mem:$dst),
"ror{q}\t{%cl, $dst|$dst, %CL}",
- [(store (rotr (loadi64 addr:$dst), CL), addr:$dst)]>,
- Imp<[CL],[]>;
+ [(store (rotr (loadi64 addr:$dst), CL), addr:$dst)]>;
def ROR64mi : RIi8<0xC1, MRM1m, (outs), (ins i64mem:$dst, i8imm:$src),
"ror{q}\t{$src, $dst|$dst, $src}",
[(store (rotr (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
// Double shift instructions (generalizations of rotate)
let isTwoAddress = 1 in {
+let Uses = [CL] in {
def SHLD64rrCL : RI<0xA5, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
- "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}", []>,
- Imp<[CL],[]>, TB;
+ "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}", []>, TB;
def SHRD64rrCL : RI<0xAD, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
- "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}", []>,
- Imp<[CL],[]>, TB;
+ "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}", []>, TB;
+}
let isCommutable = 1 in { // FIXME: Update X86InstrInfo::commuteInstruction
def SHLD64rri8 : RIi8<0xA4, MRMDestReg,
// Temporary hack: there is no patterns associated with these instructions
// so we have to tell tblgen that these do not produce results.
+let Uses = [CL] in {
def SHLD64mrCL : RI<0xA5, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
- "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}", []>,
- Imp<[CL],[]>, TB;
+ "shld{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}", []>, TB;
def SHRD64mrCL : RI<0xAD, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
- "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}", []>,
- Imp<[CL],[]>, TB;
+ "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, %CL}", []>, TB;
+}
def SHLD64mri8 : RIi8<0xA4, MRMDestMem,
(outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
"shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}", []>,