summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2007-09-14 21:48:26 +0000
committerEvan Cheng <evan.cheng@apple.com>2007-09-14 21:48:26 +0000
commit24f2ea3971065eb9e88d50ebeddad0463337cae3 (patch)
tree3381ad12446b820dd5939a087cf92c4b20d01b45 /lib
parentf82e1e66cec02ecfa3c83c165bce6a2780c77914 (diff)
downloadllvm-24f2ea3971065eb9e88d50ebeddad0463337cae3.tar.gz
llvm-24f2ea3971065eb9e88d50ebeddad0463337cae3.tar.bz2
llvm-24f2ea3971065eb9e88d50ebeddad0463337cae3.tar.xz
Add implicit def of EFLAGS on those instructions that may modify flags.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41962 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/X86/X86InstrFPStack.td2
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp24
-rw-r--r--lib/Target/X86/X86InstrInfo.td89
-rw-r--r--lib/Target/X86/X86InstrSSE.td4
-rw-r--r--lib/Target/X86/X86InstrX86-64.td20
5 files changed, 85 insertions, 54 deletions
diff --git a/lib/Target/X86/X86InstrFPStack.td b/lib/Target/X86/X86InstrFPStack.td
index d47add6d1a..c4a4e4c8da 100644
--- a/lib/Target/X86/X86InstrFPStack.td
+++ b/lib/Target/X86/X86InstrFPStack.td
@@ -488,7 +488,7 @@ def UCOM_Fpr80 : FpI_<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP,
def UCOM_FpIr80: FpI_<(outs), (ins RFP80:$lhs, RFP80:$rhs), CompareFP,
[(X86cmp RFP80:$lhs, RFP80:$rhs)]>; // CC = ST(0) cmp ST(i)
-let Uses = [ST0] in {
+let Defs = [EFLAGS], Uses = [ST0] in {
def UCOM_Fr : FPI<0xE0, AddRegFrm, // FPSW = cmp ST(0) with ST(i)
(outs), (ins RST:$reg),
"fucom\t$reg">, DD;
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index 017c799837..5b7b8286e5 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -182,7 +182,7 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
break;
}
case X86::SHL64ri: {
- assert(MI->getNumOperands() == 3 && "Unknown shift instruction!");
+ assert(MI->getNumOperands() >= 3 && "Unknown shift instruction!");
// NOTE: LEA doesn't produce flags like shift does, but LLVM never uses
// the flags produced by a shift yet, so this is safe.
unsigned Dest = MI->getOperand(0).getReg();
@@ -195,7 +195,7 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
break;
}
case X86::SHL32ri: {
- assert(MI->getNumOperands() == 3 && "Unknown shift instruction!");
+ assert(MI->getNumOperands() >= 3 && "Unknown shift instruction!");
// NOTE: LEA doesn't produce flags like shift does, but LLVM never uses
// the flags produced by a shift yet, so this is safe.
unsigned Dest = MI->getOperand(0).getReg();
@@ -210,7 +210,7 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
break;
}
case X86::SHL16ri: {
- assert(MI->getNumOperands() == 3 && "Unknown shift instruction!");
+ assert(MI->getNumOperands() >= 3 && "Unknown shift instruction!");
// NOTE: LEA doesn't produce flags like shift does, but LLVM never uses
// the flags produced by a shift yet, so this is safe.
unsigned Dest = MI->getOperand(0).getReg();
@@ -259,40 +259,40 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
switch (MI->getOpcode()) {
case X86::INC32r:
case X86::INC64_32r:
- assert(MI->getNumOperands() == 2 && "Unknown inc instruction!");
+ assert(MI->getNumOperands() >= 2 && "Unknown inc instruction!");
NewMI = addRegOffset(BuildMI(get(X86::LEA32r), Dest), Src, 1);
break;
case X86::INC16r:
case X86::INC64_16r:
if (DisableLEA16) return 0;
- assert(MI->getNumOperands() == 2 && "Unknown inc instruction!");
+ assert(MI->getNumOperands() >= 2 && "Unknown inc instruction!");
NewMI = addRegOffset(BuildMI(get(X86::LEA16r), Dest), Src, 1);
break;
case X86::DEC32r:
case X86::DEC64_32r:
- assert(MI->getNumOperands() == 2 && "Unknown dec instruction!");
+ assert(MI->getNumOperands() >= 2 && "Unknown dec instruction!");
NewMI = addRegOffset(BuildMI(get(X86::LEA32r), Dest), Src, -1);
break;
case X86::DEC16r:
case X86::DEC64_16r:
if (DisableLEA16) return 0;
- assert(MI->getNumOperands() == 2 && "Unknown dec instruction!");
+ assert(MI->getNumOperands() >= 2 && "Unknown dec instruction!");
NewMI = addRegOffset(BuildMI(get(X86::LEA16r), Dest), Src, -1);
break;
case X86::ADD32rr:
- assert(MI->getNumOperands() == 3 && "Unknown add instruction!");
+ assert(MI->getNumOperands() >= 3 && "Unknown add instruction!");
NewMI = addRegReg(BuildMI(get(X86::LEA32r), Dest), Src,
MI->getOperand(2).getReg());
break;
case X86::ADD16rr:
if (DisableLEA16) return 0;
- assert(MI->getNumOperands() == 3 && "Unknown add instruction!");
+ assert(MI->getNumOperands() >= 3 && "Unknown add instruction!");
NewMI = addRegReg(BuildMI(get(X86::LEA16r), Dest), Src,
MI->getOperand(2).getReg());
break;
case X86::ADD32ri:
case X86::ADD32ri8:
- assert(MI->getNumOperands() == 3 && "Unknown add instruction!");
+ assert(MI->getNumOperands() >= 3 && "Unknown add instruction!");
if (MI->getOperand(2).isImmediate())
NewMI = addRegOffset(BuildMI(get(X86::LEA32r), Dest), Src,
MI->getOperand(2).getImmedValue());
@@ -300,7 +300,7 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
case X86::ADD16ri:
case X86::ADD16ri8:
if (DisableLEA16) return 0;
- assert(MI->getNumOperands() == 3 && "Unknown add instruction!");
+ assert(MI->getNumOperands() >= 3 && "Unknown add instruction!");
if (MI->getOperand(2).isImmediate())
NewMI = addRegOffset(BuildMI(get(X86::LEA16r), Dest), Src,
MI->getOperand(2).getImmedValue());
@@ -308,7 +308,7 @@ X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
case X86::SHL16ri:
if (DisableLEA16) return 0;
case X86::SHL32ri:
- assert(MI->getNumOperands() == 3 && MI->getOperand(2).isImmediate() &&
+ assert(MI->getNumOperands() >= 3 && MI->getOperand(2).isImmediate() &&
"Unknown shl instruction!");
unsigned ShAmt = MI->getOperand(2).getImmedValue();
if (ShAmt == 1 || ShAmt == 2 || ShAmt == 3) {
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 9e0dc6d3fa..4f6e372560 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -547,45 +547,45 @@ def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
//
// Extra precision multiplication
-let Defs = [AL,AH], Uses = [AL] in
+let Defs = [AL,AH,EFLAGS], 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))]>; // AL,AH = AL*GR8
-let Defs = [AX,DX], Uses = [AX] in
+let Defs = [AX,DX,EFLAGS], Uses = [AX] in
def MUL16r : I<0xF7, MRM4r, (outs), (ins GR16:$src), "mul{w}\t$src", []>,
OpSize; // AX,DX = AX*GR16
-let Defs = [EAX,EDX], Uses = [EAX] in
+let Defs = [EAX,EDX,EFLAGS], 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
+let Defs = [AL,AH,EFLAGS], 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)))]>; // AL,AH = AL*[mem8]
-let Defs = [AX,DX], Uses = [AX] in
+let Defs = [AX,DX,EFLAGS], Uses = [AX] in
def MUL16m : I<0xF7, MRM4m, (outs), (ins i16mem:$src),
"mul{w}\t$src", []>, OpSize; // AX,DX = AX*[mem16]
-let Defs = [EAX,EDX], Uses = [EAX] in
+let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
def MUL32m : I<0xF7, MRM4m, (outs), (ins i32mem:$src),
"mul{l}\t$src", []>; // EAX,EDX = EAX*[mem32]
-let Defs = [AL,AH], Uses = [AL] in
+let Defs = [AL,AH,EFLAGS], 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
+let Defs = [AX,DX,EFLAGS], Uses = [AX] in
def IMUL16r : I<0xF7, MRM5r, (outs), (ins GR16:$src), "imul{w}\t$src", []>,
OpSize; // AX,DX = AX*GR16
-let Defs = [EAX,EDX], Uses = [EAX] in
+let Defs = [EAX,EDX,EFLAGS], 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
+let Defs = [AL,AH,EFLAGS], Uses = [AL] in
def IMUL8m : I<0xF6, MRM5m, (outs), (ins i8mem :$src),
"imul{b}\t$src", []>; // AL,AH = AL*[mem8]
-let Defs = [AX,DX], Uses = [AX] in
+let Defs = [AX,DX,EFLAGS], Uses = [AX] in
def IMUL16m : I<0xF7, MRM5m, (outs), (ins i16mem:$src),
"imul{w}\t$src", []>, OpSize; // AX,DX = AX*[mem16]
let Defs = [EAX,EDX], Uses = [EAX] in
@@ -593,42 +593,42 @@ def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src),
"imul{l}\t$src", []>; // EAX,EDX = EAX*[mem32]
// unsigned division/remainder
-let Defs = [AX], Uses = [AL,AH] in
+let Defs = [AX,EFLAGS], Uses = [AL,AH] in
def DIV8r : I<0xF6, MRM6r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
"div{b}\t$src", []>;
-let Defs = [AX,DX], Uses = [AX,DX] in
+let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
def DIV16r : I<0xF7, MRM6r, (outs), (ins GR16:$src), // DX:AX/r16 = AX,DX
"div{w}\t$src", []>, OpSize;
-let Defs = [EAX,EDX], Uses = [EAX,EDX] in
+let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
def DIV32r : I<0xF7, MRM6r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
"div{l}\t$src", []>;
-let Defs = [AX], Uses = [AL,AH] in
+let Defs = [AX,EFLAGS], Uses = [AL,AH] in
def DIV8m : I<0xF6, MRM6m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
"div{b}\t$src", []>;
-let Defs = [AX,DX], Uses = [AX,DX] in
+let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
def DIV16m : I<0xF7, MRM6m, (outs), (ins i16mem:$src), // DX:AX/[mem16] = AX,DX
"div{w}\t$src", []>, OpSize;
-let Defs = [EAX,EDX], Uses = [EAX,EDX] in
+let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
def DIV32m : I<0xF7, MRM6m, (outs), (ins i32mem:$src), // EDX:EAX/[mem32] = EAX,EDX
"div{l}\t$src", []>;
// Signed division/remainder.
-let Defs = [AX], Uses = [AL,AH] in
+let Defs = [AX,EFLAGS], Uses = [AL,AH] in
def IDIV8r : I<0xF6, MRM7r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
"idiv{b}\t$src", []>;
-let Defs = [AX,DX], Uses = [AX,DX] in
+let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
def IDIV16r: I<0xF7, MRM7r, (outs), (ins GR16:$src), // DX:AX/r16 = AX,DX
"idiv{w}\t$src", []>, OpSize;
-let Defs = [EAX,EDX], Uses = [EAX,EDX] in
+let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
def IDIV32r: I<0xF7, MRM7r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
"idiv{l}\t$src", []>;
-let Defs = [AX], Uses = [AL,AH] in
+let Defs = [AX,EFLAGS], Uses = [AL,AH] in
def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
"idiv{b}\t$src", []>;
-let Defs = [AX,DX], Uses = [AX,DX] in
+let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
def IDIV16m: I<0xF7, MRM7m, (outs), (ins i16mem:$src), // DX:AX/[mem16] = AX,DX
"idiv{w}\t$src", []>, OpSize;
-let Defs = [EAX,EDX], Uses = [EAX,EDX] in
+let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
def IDIV32m: I<0xF7, MRM7m, (outs), (ins i32mem:$src), // EDX:EAX/[mem32] = EAX,EDX
"idiv{l}\t$src", []>;
@@ -992,6 +992,7 @@ def CMOVNP32rm : I<0x4B, MRMSrcMem, // if !parity, GR32 = [mem32]
// unary instructions
let CodeSize = 2 in {
+let Defs = [EFLAGS] in {
def NEG8r : I<0xF6, MRM3r, (outs GR8 :$dst), (ins GR8 :$src), "neg{b}\t$dst",
[(set GR8:$dst, (ineg GR8:$src))]>;
def NEG16r : I<0xF7, MRM3r, (outs GR16:$dst), (ins GR16:$src), "neg{w}\t$dst",
@@ -1007,6 +1008,7 @@ let isTwoAddress = 0 in {
[(store (ineg (loadi32 addr:$dst)), addr:$dst)]>;
}
+} // Defs = [EFLAGS]
def NOT8r : I<0xF6, MRM2r, (outs GR8 :$dst), (ins GR8 :$src), "not{b}\t$dst",
[(set GR8:$dst, (not GR8:$src))]>;
@@ -1025,6 +1027,7 @@ let isTwoAddress = 0 in {
} // CodeSize
// TODO: inc/dec is slow for P4, but fast for Pentium-M.
+let Defs = [EFLAGS] in {
let CodeSize = 2 in
def INC8r : I<0xFE, MRM0r, (outs GR8 :$dst), (ins GR8 :$src), "inc{b}\t$dst",
[(set GR8:$dst, (add GR8:$src, 1))]>;
@@ -1063,8 +1066,10 @@ let isTwoAddress = 0, CodeSize = 2 in {
def DEC32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
[(store (add (loadi32 addr:$dst), -1), addr:$dst)]>;
}
+} // Defs = [EFLAGS]
// Logical operators...
+let Defs = [EFLAGS] in {
let isCommutable = 1 in { // X = AND Y, Z --> X = AND Z, Y
def AND8rr : I<0x20, MRMDestReg,
(outs GR8 :$dst), (ins GR8 :$src1, GR8 :$src2),
@@ -1307,8 +1312,10 @@ let isTwoAddress = 0 in {
"xor{l}\t{$src, $dst|$dst, $src}",
[(store (xor (load addr:$dst), i32immSExt8:$src), addr:$dst)]>;
}
+} // Defs = [EFLAGS]
// Shift instructions
+let Defs = [EFLAGS] in {
let Uses = [CL] in {
def SHL8rCL : I<0xD2, MRM4r, (outs GR8 :$dst), (ins GR8 :$src),
"shl{b}\t{%cl, $dst|$dst, %CL}",
@@ -1750,9 +1757,11 @@ let isTwoAddress = 0 in {
(i8 imm:$src3)), addr:$dst)]>,
TB, OpSize;
}
+} // Defs = [EFLAGS]
// Arithmetic.
+let Defs = [EFLAGS] in {
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),
@@ -1812,7 +1821,7 @@ let isTwoAddress = 0 in {
def ADD16mr : I<0x01, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
"add{w}\t{$src2, $dst|$dst, $src2}",
[(store (add (load addr:$dst), GR16:$src2), addr:$dst)]>,
- OpSize;
+ OpSize;
def ADD32mr : I<0x01, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
"add{l}\t{$src2, $dst|$dst, $src2}",
[(store (add (load addr:$dst), GR32:$src2), addr:$dst)]>;
@@ -1822,14 +1831,14 @@ let isTwoAddress = 0 in {
def ADD16mi : Ii16<0x81, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src2),
"add{w}\t{$src2, $dst|$dst, $src2}",
[(store (add (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
- OpSize;
+ OpSize;
def ADD32mi : Ii32<0x81, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src2),
"add{l}\t{$src2, $dst|$dst, $src2}",
[(store (add (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
def ADD16mi8 : Ii8<0x83, MRM0m, (outs), (ins i16mem:$dst, i16i8imm :$src2),
"add{w}\t{$src2, $dst|$dst, $src2}",
[(store (add (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
- OpSize;
+ OpSize;
def ADD32mi8 : Ii8<0x83, MRM0m, (outs), (ins i32mem:$dst, i32i8imm :$src2),
"add{l}\t{$src2, $dst|$dst, $src2}",
[(store (add (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
@@ -1893,7 +1902,7 @@ def SUB32ri : Ii32<0x81, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2
def SUB16ri8 : Ii8<0x83, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
"sub{w}\t{$src2, $dst|$dst, $src2}",
[(set GR16:$dst, (sub GR16:$src1, i16immSExt8:$src2))]>,
- OpSize;
+ OpSize;
def SUB32ri8 : Ii8<0x83, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
"sub{l}\t{$src2, $dst|$dst, $src2}",
[(set GR32:$dst, (sub GR32:$src1, i32immSExt8:$src2))]>;
@@ -1904,7 +1913,7 @@ let isTwoAddress = 0 in {
def SUB16mr : I<0x29, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
"sub{w}\t{$src2, $dst|$dst, $src2}",
[(store (sub (load addr:$dst), GR16:$src2), addr:$dst)]>,
- OpSize;
+ OpSize;
def SUB32mr : I<0x29, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
"sub{l}\t{$src2, $dst|$dst, $src2}",
[(store (sub (load addr:$dst), GR32:$src2), addr:$dst)]>;
@@ -1914,14 +1923,14 @@ let isTwoAddress = 0 in {
def SUB16mi : Ii16<0x81, MRM5m, (outs), (ins i16mem:$dst, i16imm:$src2),
"sub{w}\t{$src2, $dst|$dst, $src2}",
[(store (sub (loadi16 addr:$dst), imm:$src2), addr:$dst)]>,
- OpSize;
+ OpSize;
def SUB32mi : Ii32<0x81, MRM5m, (outs), (ins i32mem:$dst, i32imm:$src2),
"sub{l}\t{$src2, $dst|$dst, $src2}",
[(store (sub (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
def SUB16mi8 : Ii8<0x83, MRM5m, (outs), (ins i16mem:$dst, i16i8imm :$src2),
"sub{w}\t{$src2, $dst|$dst, $src2}",
[(store (sub (load addr:$dst), i16immSExt8:$src2), addr:$dst)]>,
- OpSize;
+ OpSize;
def SUB32mi8 : Ii8<0x83, MRM5m, (outs), (ins i32mem:$dst, i32i8imm :$src2),
"sub{l}\t{$src2, $dst|$dst, $src2}",
[(store (sub (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
@@ -1929,7 +1938,7 @@ let isTwoAddress = 0 in {
def SBB32rr : I<0x19, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
"sbb{l}\t{$src2, $dst|$dst, $src2}",
- [(set GR32:$dst, (sube GR32:$src1, GR32:$src2))]>;
+ [(set GR32:$dst, (sube GR32:$src1, GR32:$src2))]>;
let isTwoAddress = 0 in {
def SBB32mr : I<0x19, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
@@ -1943,7 +1952,7 @@ let isTwoAddress = 0 in {
[(store (sube (loadi32 addr:$dst), imm:$src2), addr:$dst)]>;
def SBB32mi8 : Ii8<0x83, MRM3m, (outs), (ins i32mem:$dst, i32i8imm :$src2),
"sbb{l}\t{$src2, $dst|$dst, $src2}",
- [(store (sube (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
+ [(store (sube (load addr:$dst), i32immSExt8:$src2), addr:$dst)]>;
}
def SBB32rm : I<0x1B, MRMSrcMem, (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2),
"sbb{l}\t{$src2, $dst|$dst, $src2}",
@@ -1954,7 +1963,9 @@ def SBB32ri : Ii32<0x81, MRM3r, (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2
def SBB32ri8 : Ii8<0x83, MRM3r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
"sbb{l}\t{$src2, $dst|$dst, $src2}",
[(set GR32:$dst, (sube GR32:$src1, i32immSExt8:$src2))]>;
+} // Defs = [EFLAGS]
+let Defs = [EFLAGS] in {
let isCommutable = 1 in { // X = IMUL Y, Z --> X = IMUL Z, Y
def IMUL16rr : I<0xAF, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
"imul{w}\t{$src2, $dst|$dst, $src2}",
@@ -1970,10 +1981,11 @@ def IMUL16rm : I<0xAF, MRMSrcMem, (outs GR16:$dst), (ins GR16:$src1, i16mem:$src
def IMUL32rm : I<0xAF, MRMSrcMem, (outs GR32:$dst), (ins GR32:$src1, i32mem:$src2),
"imul{l}\t{$src2, $dst|$dst, $src2}",
[(set GR32:$dst, (mul GR32:$src1, (load addr:$src2)))]>, TB;
-
+} // Defs = [EFLAGS]
} // end Two Address instructions
// Suprisingly enough, these are not two address instructions!
+let Defs = [EFLAGS] in {
def IMUL16rri : Ii16<0x69, MRMSrcReg, // GR16 = GR16*I16
(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
"imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
@@ -2010,10 +2022,12 @@ def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem, // GR32 = [mem32]*I8
(outs GR32:$dst), (ins i32mem:$src1, i32i8imm: $src2),
"imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
[(set GR32:$dst, (mul (load addr:$src1), i32immSExt8:$src2))]>;
+} // Defs = [EFLAGS]
//===----------------------------------------------------------------------===//
// Test instructions are just like AND, except they don't generate a result.
//
+ let Defs = [EFLAGS] in {
let isCommutable = 1 in { // TEST X, Y --> TEST Y, X
def TEST8rr : I<0x84, MRMDestReg, (outs), (ins GR8:$src1, GR8:$src2),
"test{b}\t{$src2, $src1|$src1, $src2}",
@@ -2063,12 +2077,13 @@ def TEST32mi : Ii32<0xF7, MRM0m, // flags = [mem32] & imm32
(outs), (ins i32mem:$src1, i32imm:$src2),
"test{l}\t{$src2, $src1|$src1, $src2}",
[(X86cmp (and (loadi32 addr:$src1), imm:$src2), 0)]>;
+} // Defs = [EFLAGS]
// Condition code ops, incl. set if equal/not equal/...
-let Uses = [AH] in
+let Defs = [EFLAGS], Uses = [AH] in
def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf", []>; // flags = AH
-let Defs = [AH] in
+let Defs = [AH], Uses = [EFLAGS] in
def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", []>; // AH = flags
def SETEr : I<0x94, MRM0r,
@@ -2215,6 +2230,7 @@ def SETNPm : I<0x9B, MRM0m,
TB; // [mem8] = not parity
// Integer comparisons
+let Defs = [EFLAGS] in {
def CMP8rr : I<0x38, MRMDestReg,
(outs), (ins GR8 :$src1, GR8 :$src2),
"cmp{b}\t{$src2, $src1|$src1, $src2}",
@@ -2291,6 +2307,7 @@ def CMP32ri8 : Ii8<0x83, MRM7r,
(outs), (ins GR32:$src1, i32i8imm:$src2),
"cmp{l}\t{$src2, $src1|$src1, $src2}",
[(X86cmp GR32:$src1, i32immSExt8:$src2)]>;
+} // Defs = [EFLAGS]
// Sign/Zero extenders
def MOVSX16rr8 : I<0xBE, MRMSrcReg, (outs GR16:$dst), (ins GR8 :$src),
@@ -2352,7 +2369,7 @@ def CDQ : I<0x99, RawFrm, (outs), (ins),
// Alias instructions that map movr0 to xor.
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
-let isReMaterializable = 1 in {
+let Defs = [EFLAGS], isReMaterializable = 1 in {
def MOV8r0 : I<0x30, MRMInitReg, (outs GR8 :$dst), (ins),
"xor{b}\t$dst, $dst",
[(set GR8:$dst, 0)]>;
diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td
index 63f041be7f..7fb7d2efb2 100644
--- a/lib/Target/X86/X86InstrSSE.td
+++ b/lib/Target/X86/X86InstrSSE.td
@@ -360,12 +360,14 @@ let isTwoAddress = 1 in {
"cmp${cc}ss\t{$src, $dst|$dst, $src}", []>;
}
+let Defs = [EFLAGS] in {
def UCOMISSrr: PSI<0x2E, MRMSrcReg, (outs), (ins FR32:$src1, FR32:$src2),
"ucomiss\t{$src2, $src1|$src1, $src2}",
[(X86cmp FR32:$src1, FR32:$src2)]>;
def UCOMISSrm: PSI<0x2E, MRMSrcMem, (outs), (ins FR32:$src1, f32mem:$src2),
"ucomiss\t{$src2, $src1|$src1, $src2}",
[(X86cmp FR32:$src1, (loadf32 addr:$src2))]>;
+} // Defs = [EFLAGS]
// Aliases to match intrinsics which expect XMM operand(s).
let isTwoAddress = 1 in {
@@ -381,6 +383,7 @@ let isTwoAddress = 1 in {
(load addr:$src), imm:$cc))]>;
}
+let Defs = [EFLAGS] in {
def Int_UCOMISSrr: PSI<0x2E, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
"ucomiss\t{$src2, $src1|$src1, $src2}",
[(X86ucomi (v4f32 VR128:$src1), VR128:$src2)]>;
@@ -394,6 +397,7 @@ def Int_COMISSrr: PSI<0x2F, MRMSrcReg, (outs), (ins VR128:$src1, VR128:$src2),
def Int_COMISSrm: PSI<0x2F, MRMSrcMem, (outs), (ins VR128:$src1, f128mem:$src2),
"comiss\t{$src2, $src1|$src1, $src2}",
[(X86comi (v4f32 VR128:$src1), (load addr:$src2))]>;
+} // Defs = [EFLAGS]
// Aliases of packed SSE1 instructions for scalar use. These all have names that
// start with 'Fs'.
diff --git a/lib/Target/X86/X86InstrX86-64.td b/lib/Target/X86/X86InstrX86-64.td
index 794bb70db9..ca890cb5bc 100644
--- a/lib/Target/X86/X86InstrX86-64.td
+++ b/lib/Target/X86/X86InstrX86-64.td
@@ -226,6 +226,7 @@ def CQO : RI<0x99, RawFrm, (outs), (ins),
// Arithmetic Instructions...
//
+let Defs = [EFLAGS] in {
let isTwoAddress = 1 in {
let isConvertibleToThreeAddress = 1 in {
let isCommutable = 1 in
@@ -337,9 +338,10 @@ def SBB64mi32 : RIi32<0x81, MRM3m, (outs), (ins i64mem:$dst, i64i32imm:$src2),
def SBB64mi8 : RIi8<0x83, MRM3m, (outs), (ins i64mem:$dst, i64i8imm :$src2),
"sbb{q}\t{$src2, $dst|$dst, $src2}",
[(store (sube (load addr:$dst), i64immSExt8:$src2), addr:$dst)]>;
+} // Defs = [EFLAGS]
// Unsigned multiplication
-let Defs = [RAX,RDX], Uses = [RAX] in {
+let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in {
def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src),
"mul{q}\t$src", []>; // RAX,RDX = RAX*GR64
def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
@@ -352,6 +354,7 @@ def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
"imul{q}\t$src", []>; // RAX,RDX = RAX*[mem64]
}
+let Defs = [EFLAGS] in {
let isTwoAddress = 1 in {
let isCommutable = 1 in
def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
@@ -380,9 +383,10 @@ def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem, // GR64 = [mem64]*I8
(outs GR64:$dst), (ins i64mem:$src1, i64i8imm: $src2),
"imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
[(set GR64:$dst, (mul (load addr:$src1), i64immSExt8:$src2))]>;
+} // Defs = [EFLAGS]
// Unsigned division / remainder
-let Defs = [RAX,RDX], Uses = [RAX,RDX] in {
+let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in {
def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src), // RDX:RAX/r64 = RAX,RDX
"div{q}\t$src", []>;
def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64] = RAX,RDX
@@ -396,7 +400,7 @@ def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src), // RDX:RAX/[mem64]
}
// Unary instructions
-let CodeSize = 2 in {
+let Defs = [EFLAGS], CodeSize = 2 in {
let isTwoAddress = 1 in
def NEG64r : RI<0xF7, MRM3r, (outs GR64:$dst), (ins GR64:$src), "neg{q}\t$dst",
[(set GR64:$dst, (ineg GR64:$src))]>;
@@ -431,9 +435,10 @@ def DEC64_32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src), "dec{l}\t$dst"
[(set GR32:$dst, (add GR32:$src, -1))]>,
Requires<[In64BitMode]>;
} // isConvertibleToThreeAddress
-} // CodeSize
+} // Defs = [EFLAGS], CodeSize
+let Defs = [EFLAGS] in {
// Shift instructions
let isTwoAddress = 1 in {
let Uses = [CL] in
@@ -592,6 +597,7 @@ def SHRD64mri8 : RIi8<0xAC, MRMDestMem,
(outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
"shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}", []>,
TB;
+} // Defs = [EFLAGS]
//===----------------------------------------------------------------------===//
// Logical Instructions...
@@ -603,6 +609,7 @@ def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src), "not{q}\t$dst",
def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst",
[(store (not (loadi64 addr:$dst)), addr:$dst)]>;
+let Defs = [EFLAGS] in {
let isTwoAddress = 1 in {
let isCommutable = 1 in
def AND64rr : RI<0x21, MRMDestReg,
@@ -688,12 +695,14 @@ def XOR64mi32 : RIi32<0x81, MRM6m, (outs), (ins i64mem:$dst, i64i32imm:$src),
def XOR64mi8 : RIi8<0x83, MRM6m, (outs), (ins i64mem:$dst, i64i8imm :$src),
"xor{q}\t{$src, $dst|$dst, $src}",
[(store (xor (load addr:$dst), i64immSExt8:$src), addr:$dst)]>;
+} // Defs = [EFLAGS]
//===----------------------------------------------------------------------===//
// Comparison Instructions...
//
// Integer comparison
+let Defs = [EFLAGS] in {
let isCommutable = 1 in
def TEST64rr : RI<0x85, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
"test{q}\t{$src2, $src1|$src1, $src2}",
@@ -729,6 +738,7 @@ def CMP64mi8 : RIi8<0x83, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2),
def CMP64ri8 : RIi8<0x83, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2),
"cmp{q}\t{$src2, $src1|$src1, $src2}",
[(X86cmp GR64:$src1, i64immSExt8:$src2)]>;
+} // Defs = [EFLAGS]
// Conditional moves
let isTwoAddress = 1 in {
@@ -1000,7 +1010,7 @@ def PsMOVZX64rm32: I<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src),
// FIXME: remove when we can teach regalloc that xor reg, reg is ok.
// FIXME: AddedComplexity gives MOV64r0 a higher priority than MOV64ri32. Remove
// when we have a better way to specify isel priority.
-let AddedComplexity = 1, isReMaterializable = 1 in
+let Defs = [EFLAGS], AddedComplexity = 1, isReMaterializable = 1 in
def MOV64r0 : RI<0x31, MRMInitReg, (outs GR64:$dst), (ins),
"xor{q}\t$dst, $dst",
[(set GR64:$dst, 0)]>;