diff --git a/lib/Target/X86/X86InstrArithmetic.td b/lib/Target/X86/X86InstrArithmetic.td index 72ec37da5e1..a56156e8c84 100644 --- a/lib/Target/X86/X86InstrArithmetic.td +++ b/lib/Target/X86/X86InstrArithmetic.td @@ -600,25 +600,32 @@ class ITy opcode, Format f, X86TypeInfo typeinfo, dag outs, dag ins, // BinOpRR - Instructions like "add reg, reg, reg". class BinOpRR opcode, string mnemonic, X86TypeInfo typeinfo, - list pattern> - : ITy pattern> + : ITy; + mnemonic, "{$src2, $src1|$src1, $src2}", pattern>; // BinOpRR_R - Instructions like "add reg, reg, reg", where the pattern has // just a regclass (no eflags) as a result. class BinOpRR_R opcode, string mnemonic, X86TypeInfo typeinfo, SDNode opnode> - : BinOpRR; +// BinOpRR_F - Instructions like "cmp reg, Reg", where the pattern has +// just a EFLAGS as a result. +class BinOpRR_F opcode, string mnemonic, X86TypeInfo typeinfo, + SDNode opnode> + : BinOpRR; + // BinOpRR_RF - Instructions like "add reg, reg, reg", where the pattern has // both a regclass and EFLAGS as a result. class BinOpRR_RF opcode, string mnemonic, X86TypeInfo typeinfo, SDNode opnode> - : BinOpRR; @@ -634,107 +641,160 @@ class BinOpRR_Rev opcode, string mnemonic, X86TypeInfo typeinfo> // BinOpRM - Instructions like "add reg, reg, [mem]". class BinOpRM opcode, string mnemonic, X86TypeInfo typeinfo, - list pattern> - : ITy pattern> + : ITy; + mnemonic, "{$src2, $src1|$src1, $src2}", pattern>; // BinOpRM_R - Instructions like "add reg, reg, [mem]". class BinOpRM_R opcode, string mnemonic, X86TypeInfo typeinfo, SDNode opnode> - : BinOpRM; +// BinOpRM_F - Instructions like "cmp reg, [mem]". +class BinOpRM_F opcode, string mnemonic, X86TypeInfo typeinfo, + SDNode opnode> + : BinOpRM; + // BinOpRM_RF - Instructions like "add reg, reg, [mem]". class BinOpRM_RF opcode, string mnemonic, X86TypeInfo typeinfo, SDNode opnode> - : BinOpRM; // BinOpRI - Instructions like "add reg, reg, imm". class BinOpRI opcode, string mnemonic, X86TypeInfo typeinfo, - Format f, list pattern> - : ITy pattern> + : ITy { + mnemonic, "{$src2, $src1|$src1, $src2}", pattern> { let ImmT = typeinfo.ImmEncoding; } // BinOpRI_R - Instructions like "add reg, reg, imm". class BinOpRI_R opcode, string mnemonic, X86TypeInfo typeinfo, SDNode opnode, Format f> - : BinOpRI; +// BinOpRI_F - Instructions like "cmp reg, imm". +class BinOpRI_F opcode, string mnemonic, X86TypeInfo typeinfo, + SDNode opnode, Format f> + : BinOpRI; + // BinOpRI_RF - Instructions like "add reg, reg, imm". class BinOpRI_RF opcode, string mnemonic, X86TypeInfo typeinfo, SDNode opnode, Format f> - : BinOpRI; // BinOpRI8 - Instructions like "add reg, reg, imm8". class BinOpRI8 opcode, string mnemonic, X86TypeInfo typeinfo, - Format f, list pattern> - : ITy pattern> + : ITy { + mnemonic, "{$src2, $src1|$src1, $src2}", pattern> { let ImmT = Imm8; // Always 8-bit immediate. } // BinOpRI8_R - Instructions like "add reg, reg, imm8". class BinOpRI8_R opcode, string mnemonic, X86TypeInfo typeinfo, SDNode opnode, Format f> - : BinOpRI8; + +// BinOpRI8_F - Instructions like "cmp reg, imm8". +class BinOpRI8_F opcode, string mnemonic, X86TypeInfo typeinfo, + SDNode opnode, Format f> + : BinOpRI8; // BinOpRI8_RF - Instructions like "add reg, reg, imm8". class BinOpRI8_RF opcode, string mnemonic, X86TypeInfo typeinfo, SDNode opnode, Format f> - : BinOpRI8; // BinOpMR - Instructions like "add [mem], reg". class BinOpMR opcode, string mnemonic, X86TypeInfo typeinfo, - SDNode opnode> + list pattern> : ITy; + mnemonic, "{$src, $dst|$dst, $src}", pattern>; + +// BinOpMR_RMW - Instructions like "add [mem], reg". +class BinOpMR_RMW opcode, string mnemonic, X86TypeInfo typeinfo, + SDNode opnode> + : BinOpMR; + +// BinOpMR_F - Instructions like "cmp [mem], reg". +class BinOpMR_F opcode, string mnemonic, X86TypeInfo typeinfo, + SDNode opnode> + : BinOpMR; // BinOpMI - Instructions like "add [mem], imm". class BinOpMI + Format f, list pattern> : ITy<0x80, f, typeinfo, (outs), (ins typeinfo.MemOperand:$dst, typeinfo.ImmOperand:$src), - mnemonic, "{$src, $dst|$dst, $src}", - [(store (opnode (typeinfo.VT (load addr:$dst)), - typeinfo.ImmOperator:$src), addr:$dst), - (implicit EFLAGS)]> { + mnemonic, "{$src, $dst|$dst, $src}", pattern> { let ImmT = typeinfo.ImmEncoding; } +// BinOpMI_RMW - Instructions like "add [mem], imm". +class BinOpMI_RMW + : BinOpMI; + +// BinOpMI_F - Instructions like "cmp [mem], imm". +class BinOpMI_F + : BinOpMI; + // BinOpMI8 - Instructions like "add [mem], imm8". class BinOpMI8 + Format f, list pattern> : ITy<0x82, f, typeinfo, (outs), (ins typeinfo.MemOperand:$dst, typeinfo.Imm8Operand:$src), - mnemonic, "{$src, $dst|$dst, $src}", - [(store (opnode (load addr:$dst), - typeinfo.Imm8Operator:$src), addr:$dst), - (implicit EFLAGS)]> { + mnemonic, "{$src, $dst|$dst, $src}", pattern> { let ImmT = Imm8; // Always 8-bit immediate. } +// BinOpMI8_RMW - Instructions like "add [mem], imm8". +class BinOpMI8_RMW + : BinOpMI8; + +// BinOpMI8_F - Instructions like "cmp [mem], imm8". +class BinOpMI8_F + : BinOpMI8; + // BinOpAI - Instructions like "add %eax, %eax, imm". class BinOpAI opcode, string mnemonic, X86TypeInfo typeinfo, Register areg> @@ -788,19 +848,19 @@ multiclass ArithBinOp_RF BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, } } // Constraints = "$src1 = $dst" - def #NAME#8mr : BinOpMR; - def #NAME#16mr : BinOpMR; - def #NAME#32mr : BinOpMR; - def #NAME#64mr : BinOpMR; + def #NAME#8mr : BinOpMR_RMW; + def #NAME#16mr : BinOpMR_RMW; + def #NAME#32mr : BinOpMR_RMW; + def #NAME#64mr : BinOpMR_RMW; - def #NAME#8mi : BinOpMI; - def #NAME#16mi : BinOpMI; - def #NAME#32mi : BinOpMI; - def #NAME#64mi32 : BinOpMI; + def #NAME#8mi : BinOpMI_RMW; + def #NAME#16mi : BinOpMI_RMW; + def #NAME#32mi : BinOpMI_RMW; + def #NAME#64mi32 : BinOpMI_RMW; - def #NAME#16mi8 : BinOpMI8; - def #NAME#32mi8 : BinOpMI8; - def #NAME#64mi8 : BinOpMI8; + def #NAME#16mi8 : BinOpMI8_RMW; + def #NAME#32mi8 : BinOpMI8_RMW; + def #NAME#64mi8 : BinOpMI8_RMW; def #NAME#8i8 : BinOpAI; def #NAME#16i16 : BinOpAI; @@ -849,19 +909,78 @@ multiclass ArithBinOp_R BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, } } // Constraints = "$src1 = $dst" - def #NAME#8mr : BinOpMR; - def #NAME#16mr : BinOpMR; - def #NAME#32mr : BinOpMR; - def #NAME#64mr : BinOpMR; + def #NAME#8mr : BinOpMR_RMW; + def #NAME#16mr : BinOpMR_RMW; + def #NAME#32mr : BinOpMR_RMW; + def #NAME#64mr : BinOpMR_RMW; - def #NAME#8mi : BinOpMI; - def #NAME#16mi : BinOpMI; - def #NAME#32mi : BinOpMI; - def #NAME#64mi32 : BinOpMI; + def #NAME#8mi : BinOpMI_RMW; + def #NAME#16mi : BinOpMI_RMW; + def #NAME#32mi : BinOpMI_RMW; + def #NAME#64mi32 : BinOpMI_RMW; - def #NAME#16mi8 : BinOpMI8; - def #NAME#32mi8 : BinOpMI8; - def #NAME#64mi8 : BinOpMI8; + def #NAME#16mi8 : BinOpMI8_RMW; + def #NAME#32mi8 : BinOpMI8_RMW; + def #NAME#64mi8 : BinOpMI8_RMW; + + def #NAME#8i8 : BinOpAI; + def #NAME#16i16 : BinOpAI; + def #NAME#32i32 : BinOpAI; + def #NAME#64i32 : BinOpAI; + } +} + +/// ArithBinOp_F - This is an arithmetic binary operator where the pattern is +/// defined with "(set EFLAGS, (...". It would be really nice to find a way +/// to factor this with the other ArithBinOp_*. +/// +multiclass ArithBinOp_F BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, + string mnemonic, Format RegMRM, Format MemMRM, + SDNode opnode, + bit CommutableRR, bit ConvertibleToThreeAddress> { + let Defs = [EFLAGS] in { + let isCommutable = CommutableRR, + isConvertibleToThreeAddress = ConvertibleToThreeAddress in { + def #NAME#8rr : BinOpRR_F; + def #NAME#16rr : BinOpRR_F; + def #NAME#32rr : BinOpRR_F; + def #NAME#64rr : BinOpRR_F; + } // isCommutable + + def #NAME#8rr_REV : BinOpRR_Rev; + def #NAME#16rr_REV : BinOpRR_Rev; + def #NAME#32rr_REV : BinOpRR_Rev; + def #NAME#64rr_REV : BinOpRR_Rev; + + def #NAME#8rm : BinOpRM_F; + def #NAME#16rm : BinOpRM_F; + def #NAME#32rm : BinOpRM_F; + def #NAME#64rm : BinOpRM_F; + + let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { + def #NAME#8ri : BinOpRI_F<0x80, mnemonic, Xi8 , opnode, RegMRM>; + def #NAME#16ri : BinOpRI_F<0x80, mnemonic, Xi16, opnode, RegMRM>; + def #NAME#32ri : BinOpRI_F<0x80, mnemonic, Xi32, opnode, RegMRM>; + def #NAME#64ri32: BinOpRI_F<0x80, mnemonic, Xi64, opnode, RegMRM>; + + def #NAME#16ri8 : BinOpRI8_F<0x82, mnemonic, Xi16, opnode, RegMRM>; + def #NAME#32ri8 : BinOpRI8_F<0x82, mnemonic, Xi32, opnode, RegMRM>; + def #NAME#64ri8 : BinOpRI8_F<0x82, mnemonic, Xi64, opnode, RegMRM>; + } + + def #NAME#8mr : BinOpMR_F; + def #NAME#16mr : BinOpMR_F; + def #NAME#32mr : BinOpMR_F; + def #NAME#64mr : BinOpMR_F; + + def #NAME#8mi : BinOpMI_F; + def #NAME#16mi : BinOpMI_F; + def #NAME#32mi : BinOpMI_F; + def #NAME#64mi32 : BinOpMI_F; + + def #NAME#16mi8 : BinOpMI8_F; + def #NAME#32mi8 : BinOpMI8_F; + def #NAME#64mi8 : BinOpMI8_F; def #NAME#8i8 : BinOpAI; def #NAME#16i16 : BinOpAI; @@ -983,141 +1102,4 @@ def TEST64i32 : RIi32<0xa9, RawFrm, (outs), (ins i64i32imm:$src), //===----------------------------------------------------------------------===// // Integer comparisons -let Defs = [EFLAGS] in { - -def CMP8rr : I<0x38, MRMDestReg, - (outs), (ins GR8 :$src1, GR8 :$src2), - "cmp{b}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp GR8:$src1, GR8:$src2))]>; -def CMP16rr : I<0x39, MRMDestReg, - (outs), (ins GR16:$src1, GR16:$src2), - "cmp{w}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp GR16:$src1, GR16:$src2))]>, OpSize; -def CMP32rr : I<0x39, MRMDestReg, - (outs), (ins GR32:$src1, GR32:$src2), - "cmp{l}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp GR32:$src1, GR32:$src2))]>; -def CMP64rr : RI<0x39, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp GR64:$src1, GR64:$src2))]>; - -def CMP8mr : I<0x38, MRMDestMem, - (outs), (ins i8mem :$src1, GR8 :$src2), - "cmp{b}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (loadi8 addr:$src1), GR8:$src2))]>; -def CMP16mr : I<0x39, MRMDestMem, - (outs), (ins i16mem:$src1, GR16:$src2), - "cmp{w}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (loadi16 addr:$src1), GR16:$src2))]>, - OpSize; -def CMP32mr : I<0x39, MRMDestMem, - (outs), (ins i32mem:$src1, GR32:$src2), - "cmp{l}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (loadi32 addr:$src1), GR32:$src2))]>; -def CMP64mr : RI<0x39, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (loadi64 addr:$src1), GR64:$src2))]>; - -def CMP8rm : I<0x3A, MRMSrcMem, - (outs), (ins GR8 :$src1, i8mem :$src2), - "cmp{b}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp GR8:$src1, (loadi8 addr:$src2)))]>; -def CMP16rm : I<0x3B, MRMSrcMem, - (outs), (ins GR16:$src1, i16mem:$src2), - "cmp{w}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp GR16:$src1, (loadi16 addr:$src2)))]>, - OpSize; -def CMP32rm : I<0x3B, MRMSrcMem, - (outs), (ins GR32:$src1, i32mem:$src2), - "cmp{l}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp GR32:$src1, (loadi32 addr:$src2)))]>; -def CMP64rm : RI<0x3B, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp GR64:$src1, (loadi64 addr:$src2)))]>; - -// These are alternate spellings for use by the disassembler, we mark them as -// code gen only to ensure they aren't matched by the assembler. -let isCodeGenOnly = 1 in { - def CMP8rr_alt : I<0x3A, MRMSrcReg, (outs), (ins GR8:$src1, GR8:$src2), - "cmp{b}\t{$src2, $src1|$src1, $src2}", []>; - def CMP16rr_alt : I<0x3B, MRMSrcReg, (outs), (ins GR16:$src1, GR16:$src2), - "cmp{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize; - def CMP32rr_alt : I<0x3B, MRMSrcReg, (outs), (ins GR32:$src1, GR32:$src2), - "cmp{l}\t{$src2, $src1|$src1, $src2}", []>; - def CMP64rr_alt : RI<0x3B, MRMSrcReg, (outs), (ins GR64:$src1, GR64:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", []>; -} - -def CMP8ri : Ii8<0x80, MRM7r, - (outs), (ins GR8:$src1, i8imm:$src2), - "cmp{b}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp GR8:$src1, imm:$src2))]>; -def CMP16ri : Ii16<0x81, MRM7r, - (outs), (ins GR16:$src1, i16imm:$src2), - "cmp{w}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp GR16:$src1, imm:$src2))]>, OpSize; -def CMP32ri : Ii32<0x81, MRM7r, - (outs), (ins GR32:$src1, i32imm:$src2), - "cmp{l}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp GR32:$src1, imm:$src2))]>; -def CMP64ri32 : RIi32<0x81, MRM7r, (outs), (ins GR64:$src1, i64i32imm:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp GR64:$src1, i64immSExt32:$src2))]>; - -def CMP8mi : Ii8 <0x80, MRM7m, - (outs), (ins i8mem :$src1, i8imm :$src2), - "cmp{b}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (loadi8 addr:$src1), imm:$src2))]>; -def CMP16mi : Ii16<0x81, MRM7m, - (outs), (ins i16mem:$src1, i16imm:$src2), - "cmp{w}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (loadi16 addr:$src1), imm:$src2))]>, - OpSize; -def CMP32mi : Ii32<0x81, MRM7m, - (outs), (ins i32mem:$src1, i32imm:$src2), - "cmp{l}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (loadi32 addr:$src1), imm:$src2))]>; -def CMP64mi32 : RIi32<0x81, MRM7m, (outs), - (ins i64mem:$src1, i64i32imm:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (loadi64 addr:$src1), - i64immSExt32:$src2))]>; - -def CMP16ri8 : Ii8<0x83, MRM7r, - (outs), (ins GR16:$src1, i16i8imm:$src2), - "cmp{w}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp GR16:$src1, i16immSExt8:$src2))]>, - OpSize; -def CMP32ri8 : Ii8<0x83, MRM7r, - (outs), (ins GR32:$src1, i32i8imm:$src2), - "cmp{l}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp GR32:$src1, i32immSExt8:$src2))]>; -def CMP64ri8 : RIi8<0x83, MRM7r, (outs), (ins GR64:$src1, i64i8imm:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp GR64:$src1, i64immSExt8:$src2))]>; - -def CMP16mi8 : Ii8<0x83, MRM7m, - (outs), (ins i16mem:$src1, i16i8imm:$src2), - "cmp{w}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (loadi16 addr:$src1), - i16immSExt8:$src2))]>, OpSize; -def CMP32mi8 : Ii8<0x83, MRM7m, - (outs), (ins i32mem:$src1, i32i8imm:$src2), - "cmp{l}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (loadi32 addr:$src1), - i32immSExt8:$src2))]>; -def CMP64mi8 : RIi8<0x83, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2), - "cmp{q}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (loadi64 addr:$src1), - i64immSExt8:$src2))]>; - -def CMP8i8 : Ii8<0x3C, RawFrm, (outs), (ins i8imm:$src), - "cmp{b}\t{$src, %al|%al, $src}", []>; -def CMP16i16 : Ii16<0x3D, RawFrm, (outs), (ins i16imm:$src), - "cmp{w}\t{$src, %ax|%ax, $src}", []>, OpSize; -def CMP32i32 : Ii32<0x3D, RawFrm, (outs), (ins i32imm:$src), - "cmp{l}\t{$src, %eax|%eax, $src}", []>; -def CMP64i32 : RIi32<0x3D, RawFrm, (outs), (ins i64i32imm:$src), - "cmp{q}\t{$src, %rax|%rax, $src}", []>; - -} // Defs = [EFLAGS] +defm CMP : ArithBinOp_F<0x38, 0x3A, 0x3C, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>; diff --git a/test/CodeGen/X86/cmp-test.ll b/test/CodeGen/X86/cmp-test.ll index 898c09b82f5..4f627e9704d 100644 --- a/test/CodeGen/X86/cmp-test.ll +++ b/test/CodeGen/X86/cmp-test.ll @@ -1,7 +1,7 @@ ; RUN: llc < %s -march=x86 | grep cmp | count 1 ; RUN: llc < %s -march=x86 | grep test | count 1 -define i32 @f1(i32 %X, i32* %y) { +define i32 @f1(i32 %X, i32* %y) nounwind { %tmp = load i32* %y ; [#uses=1] %tmp.upgrd.1 = icmp eq i32 %tmp, 0 ; [#uses=1] br i1 %tmp.upgrd.1, label %ReturnBlock, label %cond_true @@ -13,7 +13,7 @@ ReturnBlock: ; preds = %0 ret i32 0 } -define i32 @f2(i32 %X, i32* %y) { +define i32 @f2(i32 %X, i32* %y) nounwind { %tmp = load i32* %y ; [#uses=1] %tmp1 = shl i32 %tmp, 3 ; [#uses=1] %tmp1.upgrd.2 = icmp eq i32 %tmp1, 0 ; [#uses=1] diff --git a/test/CodeGen/X86/memcmp.ll b/test/CodeGen/X86/memcmp.ll index b90d2e21187..36be1f308cc 100644 --- a/test/CodeGen/X86/memcmp.ll +++ b/test/CodeGen/X86/memcmp.ll @@ -20,8 +20,8 @@ bb: ; preds = %entry return: ; preds = %entry ret void ; CHECK: memcmp2: -; CHECK: movw (%rsi), %ax -; CHECK: cmpw %ax, (%rdi) +; CHECK: movw (%rdi), %ax +; CHECK: cmpw (%rsi), %ax } define void @memcmp2a(i8* %X, i32* nocapture %P) nounwind { @@ -54,8 +54,8 @@ bb: ; preds = %entry return: ; preds = %entry ret void ; CHECK: memcmp4: -; CHECK: movl (%rsi), %eax -; CHECK: cmpl %eax, (%rdi) +; CHECK: movl (%rdi), %eax +; CHECK: cmpl (%rsi), %eax } define void @memcmp4a(i8* %X, i32* nocapture %P) nounwind { @@ -87,8 +87,8 @@ bb: ; preds = %entry return: ; preds = %entry ret void ; CHECK: memcmp8: -; CHECK: movq (%rsi), %rax -; CHECK: cmpq %rax, (%rdi) +; CHECK: movq (%rdi), %rax +; CHECK: cmpq (%rsi), %rax } define void @memcmp8a(i8* %X, i32* nocapture %P) nounwind {