diff --git a/lib/Target/X86/X86InstrFPStack.td b/lib/Target/X86/X86InstrFPStack.td index d47add6d1ae..c4a4e4c8dad 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 017c799837c..5b7b8286e51 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 9e0dc6d3fac..4f6e372560e 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 63f041be7fe..7fb7d2efb25 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 794bb70db90..ca890cb5bca 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)]>;