X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FX86%2FX86InstrArithmetic.td;h=f82e1c666ed80b493aeef975ac8542a9459f12f4;hb=0be938e38916cecd4d3406c8531a341b2e1c9ec5;hp=7c024000314c26a6a8eb96c21f536a70273adf4d;hpb=a2b8b16c7ece17cd964844915ff9e729fbab44c7;p=oota-llvm.git diff --git a/lib/Target/X86/X86InstrArithmetic.td b/lib/Target/X86/X86InstrArithmetic.td index 7c024000314..f82e1c666ed 100644 --- a/lib/Target/X86/X86InstrArithmetic.td +++ b/lib/Target/X86/X86InstrArithmetic.td @@ -598,27 +598,37 @@ class ITy opcode, Format f, X86TypeInfo typeinfo, dag outs, dag ins, let hasREX_WPrefix = typeinfo.HasREX_WPrefix; } +// BinOpRR - Instructions like "add reg, reg, reg". +class BinOpRR opcode, string mnemonic, X86TypeInfo typeinfo, + dag outlist, list pattern, Format f = MRMDestReg> + : ITy; + // 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> - : ITy; + : 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, + SDPatternOperator opnode, Format f = MRMDestReg> + : 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> - : ITy; + : BinOpRR; // BinOpRR_Rev - Instructions like "add reg, reg, reg" (reversed encoding). class BinOpRR_Rev opcode, string mnemonic, X86TypeInfo typeinfo> @@ -630,107 +640,163 @@ class BinOpRR_Rev opcode, string mnemonic, X86TypeInfo typeinfo> let isCodeGenOnly = 1; } +// BinOpRM - Instructions like "add reg, reg, [mem]". +class BinOpRM opcode, string mnemonic, X86TypeInfo typeinfo, + dag outlist, list pattern> + : ITy; + // BinOpRM_R - Instructions like "add reg, reg, [mem]". class BinOpRM_R opcode, string mnemonic, X86TypeInfo typeinfo, SDNode opnode> - : ITy; + +// BinOpRM_F - Instructions like "cmp reg, [mem]". +class BinOpRM_F opcode, string mnemonic, X86TypeInfo typeinfo, + SDPatternOperator opnode> + : BinOpRM; // BinOpRM_RF - Instructions like "add reg, reg, [mem]". class BinOpRM_RF opcode, string mnemonic, X86TypeInfo typeinfo, SDNode opnode> - : ITy; -// BinOpRI_R - Instructions like "add reg, reg, imm". -class BinOpRI_R opcode, string mnemonic, X86TypeInfo typeinfo, - SDNode opnode, Format f> - : ITy opcode, string mnemonic, X86TypeInfo typeinfo, + Format f, dag outlist, list 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, + SDPatternOperator opnode, Format f> + : BinOpRI; + // BinOpRI_RF - Instructions like "add reg, reg, imm". class BinOpRI_RF opcode, string mnemonic, X86TypeInfo typeinfo, SDNode opnode, Format f> - : ITy { - let ImmT = typeinfo.ImmEncoding; + : BinOpRI; + +// BinOpRI8 - Instructions like "add reg, reg, imm8". +class BinOpRI8 opcode, string mnemonic, X86TypeInfo typeinfo, + Format f, dag outlist, list pattern> + : ITy { + 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> - : ITy { - let ImmT = Imm8; // Always 8-bit immediate. -} + : 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> - : ITy { - let ImmT = Imm8; // Always 8-bit immediate. -} + : 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 - : ITy<0x80, f, typeinfo, + Format f, list pattern, bits<8> opcode = 0x80> + : ITy { + 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 opcode = 0x80> + : 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> @@ -773,31 +839,35 @@ multiclass ArithBinOp_RF BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, def #NAME#64rm : BinOpRM_RF; let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { + // NOTE: These are order specific, we want the ri8 forms to be listed + // first so that they are slightly preferred to the ri forms. + def #NAME#16ri8 : BinOpRI8_RF<0x82, mnemonic, Xi16, opnodeflag, RegMRM>; + def #NAME#32ri8 : BinOpRI8_RF<0x82, mnemonic, Xi32, opnodeflag, RegMRM>; + def #NAME#64ri8 : BinOpRI8_RF<0x82, mnemonic, Xi64, opnodeflag, RegMRM>; + def #NAME#8ri : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM>; def #NAME#16ri : BinOpRI_RF<0x80, mnemonic, Xi16, opnodeflag, RegMRM>; def #NAME#32ri : BinOpRI_RF<0x80, mnemonic, Xi32, opnodeflag, RegMRM>; def #NAME#64ri32: BinOpRI_RF<0x80, mnemonic, Xi64, opnodeflag, RegMRM>; - - def #NAME#16ri8 : BinOpRI8_RF<0x82, mnemonic, Xi16, opnodeflag, RegMRM>; - def #NAME#32ri8 : BinOpRI8_RF<0x82, mnemonic, Xi32, opnodeflag, RegMRM>; - def #NAME#64ri8 : BinOpRI8_RF<0x82, mnemonic, Xi64, opnodeflag, RegMRM>; } } // Constraints = "$src1 = $dst" - def #NAME#8mr : BinOpMR; - def #NAME#16mr : BinOpMR; - def #NAME#32mr : BinOpMR; - def #NAME#64mr : BinOpMR; - - def #NAME#8mi : BinOpMI; - def #NAME#16mi : BinOpMI; - def #NAME#32mi : BinOpMI; - def #NAME#64mi32 : BinOpMI; + def #NAME#8mr : BinOpMR_RMW; + def #NAME#16mr : BinOpMR_RMW; + def #NAME#32mr : BinOpMR_RMW; + def #NAME#64mr : BinOpMR_RMW; - def #NAME#16mi8 : BinOpMI8; - def #NAME#32mi8 : BinOpMI8; - def #NAME#64mi8 : BinOpMI8; + // NOTE: These are order specific, we want the mi8 forms to be listed + // first so that they are slightly preferred to the mi forms. + def #NAME#16mi8 : BinOpMI8_RMW; + def #NAME#32mi8 : BinOpMI8_RMW; + def #NAME#64mi8 : BinOpMI8_RMW; + def #NAME#8mi : BinOpMI_RMW; + def #NAME#16mi : BinOpMI_RMW; + def #NAME#32mi : BinOpMI_RMW; + def #NAME#64mi32 : BinOpMI_RMW; + def #NAME#8i8 : BinOpAI; def #NAME#16i16 : BinOpAI; def #NAME#32i32 : BinOpAI; @@ -834,31 +904,98 @@ multiclass ArithBinOp_R BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, def #NAME#64rm : BinOpRM_R; let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { + // NOTE: These are order specific, we want the ri8 forms to be listed + // first so that they are slightly preferred to the ri forms. + def #NAME#16ri8 : BinOpRI8_R<0x82, mnemonic, Xi16, opnode, RegMRM>; + def #NAME#32ri8 : BinOpRI8_R<0x82, mnemonic, Xi32, opnode, RegMRM>; + def #NAME#64ri8 : BinOpRI8_R<0x82, mnemonic, Xi64, opnode, RegMRM>; + def #NAME#8ri : BinOpRI_R<0x80, mnemonic, Xi8 , opnode, RegMRM>; def #NAME#16ri : BinOpRI_R<0x80, mnemonic, Xi16, opnode, RegMRM>; def #NAME#32ri : BinOpRI_R<0x80, mnemonic, Xi32, opnode, RegMRM>; def #NAME#64ri32: BinOpRI_R<0x80, mnemonic, Xi64, opnode, RegMRM>; - - def #NAME#16ri8 : BinOpRI8_R<0x82, mnemonic, Xi16, opnode, RegMRM>; - def #NAME#32ri8 : BinOpRI8_R<0x82, mnemonic, Xi32, opnode, RegMRM>; - def #NAME#64ri8 : BinOpRI8_R<0x82, mnemonic, Xi64, opnode, RegMRM>; } } // 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; + + // NOTE: These are order specific, we want the mi8 forms to be listed + // first so that they are slightly preferred to the mi forms. + def #NAME#16mi8 : BinOpMI8_RMW; + def #NAME#32mi8 : BinOpMI8_RMW; + def #NAME#64mi8 : BinOpMI8_RMW; + + def #NAME#8mi : BinOpMI_RMW; + def #NAME#16mi : BinOpMI_RMW; + def #NAME#32mi : BinOpMI_RMW; + def #NAME#64mi32 : BinOpMI_RMW; - def #NAME#8mi : BinOpMI; - def #NAME#16mi : BinOpMI; - def #NAME#32mi : BinOpMI; - def #NAME#64mi32 : BinOpMI; + def #NAME#8i8 : BinOpAI; + def #NAME#16i16 : BinOpAI; + def #NAME#32i32 : BinOpAI; + def #NAME#64i32 : BinOpAI; + } +} - def #NAME#16mi8 : BinOpMI8; - def #NAME#32mi8 : BinOpMI8; - def #NAME#64mi8 : BinOpMI8; +/// 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 { + // NOTE: These are order specific, we want the ri8 forms to be listed + // first so that they are slightly preferred to the ri forms. + 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#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#8mr : BinOpMR_F; + def #NAME#16mr : BinOpMR_F; + def #NAME#32mr : BinOpMR_F; + def #NAME#64mr : BinOpMR_F; + + // NOTE: These are order specific, we want the mi8 forms to be listed + // first so that they are slightly preferred to the mi forms. + def #NAME#16mi8 : BinOpMI8_F; + def #NAME#32mi8 : BinOpMI8_F; + def #NAME#64mi8 : BinOpMI8_F; + def #NAME#8mi : BinOpMI_F; + def #NAME#16mi : BinOpMI_F; + def #NAME#32mi : BinOpMI_F; + def #NAME#64mi32 : BinOpMI_F; + def #NAME#8i8 : BinOpAI; def #NAME#16i16 : BinOpAI; def #NAME#32i32 : BinOpAI; @@ -885,235 +1022,45 @@ let Uses = [EFLAGS] in { defm SBB : ArithBinOp_R<0x18, 0x1A, 0x1C, "sbb", MRM3r, MRM3m, sube, 0, 0>; } -//===----------------------------------------------------------------------===// -// 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, MRMSrcReg, (outs), (ins GR8:$src1, GR8:$src2), - "test{b}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and_su GR8:$src1, GR8:$src2), 0))]>; -def TEST16rr : I<0x85, MRMSrcReg, (outs), (ins GR16:$src1, GR16:$src2), - "test{w}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and_su GR16:$src1, GR16:$src2), - 0))]>, - OpSize; -def TEST32rr : I<0x85, MRMSrcReg, (outs), (ins GR32:$src1, GR32:$src2), - "test{l}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and_su GR32:$src1, GR32:$src2), - 0))]>; -def TEST64rr : RI<0x85, MRMSrcReg, (outs), (ins GR64:$src1, GR64:$src2), - "test{q}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and GR64:$src1, GR64:$src2), 0))]>; -} -def TEST8rm : I<0x84, MRMSrcMem, (outs), (ins GR8 :$src1, i8mem :$src2), - "test{b}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and GR8:$src1, (loadi8 addr:$src2)), - 0))]>; -def TEST16rm : I<0x85, MRMSrcMem, (outs), (ins GR16:$src1, i16mem:$src2), - "test{w}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and GR16:$src1, - (loadi16 addr:$src2)), 0))]>, OpSize; -def TEST32rm : I<0x85, MRMSrcMem, (outs), (ins GR32:$src1, i32mem:$src2), - "test{l}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and GR32:$src1, - (loadi32 addr:$src2)), 0))]>; -def TEST64rm : RI<0x85, MRMSrcMem, (outs), (ins GR64:$src1, i64mem:$src2), - "test{q}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and GR64:$src1, (loadi64 addr:$src2)), - 0))]>; - -def TEST8ri : Ii8 <0xF6, MRM0r, // flags = GR8 & imm8 - (outs), (ins GR8:$src1, i8imm:$src2), - "test{b}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and_su GR8:$src1, imm:$src2), 0))]>; -def TEST16ri : Ii16<0xF7, MRM0r, // flags = GR16 & imm16 - (outs), (ins GR16:$src1, i16imm:$src2), - "test{w}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and_su GR16:$src1, imm:$src2), 0))]>, - OpSize; -def TEST32ri : Ii32<0xF7, MRM0r, // flags = GR32 & imm32 - (outs), (ins GR32:$src1, i32imm:$src2), - "test{l}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and_su GR32:$src1, imm:$src2), 0))]>; -def TEST64ri32 : RIi32<0xF7, MRM0r, (outs), - (ins GR64:$src1, i64i32imm:$src2), - "test{q}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and GR64:$src1, i64immSExt32:$src2), - 0))]>; - -def TEST8mi : Ii8 <0xF6, MRM0m, // flags = [mem8] & imm8 - (outs), (ins i8mem:$src1, i8imm:$src2), - "test{b}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and (loadi8 addr:$src1), imm:$src2), - 0))]>; -def TEST16mi : Ii16<0xF7, MRM0m, // flags = [mem16] & imm16 - (outs), (ins i16mem:$src1, i16imm:$src2), - "test{w}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and (loadi16 addr:$src1), imm:$src2), - 0))]>, OpSize; -def TEST32mi : Ii32<0xF7, MRM0m, // flags = [mem32] & imm32 - (outs), (ins i32mem:$src1, i32imm:$src2), - "test{l}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and (loadi32 addr:$src1), imm:$src2), - 0))]>; -def TEST64mi32 : RIi32<0xF7, MRM0m, (outs), - (ins i64mem:$src1, i64i32imm:$src2), - "test{q}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86cmp (and (loadi64 addr:$src1), - i64immSExt32:$src2), 0))]>; - -def TEST8i8 : Ii8<0xA8, RawFrm, (outs), (ins i8imm:$src), - "test{b}\t{$src, %al|%al, $src}", []>; -def TEST16i16 : Ii16<0xA9, RawFrm, (outs), (ins i16imm:$src), - "test{w}\t{$src, %ax|%ax, $src}", []>, OpSize; -def TEST32i32 : Ii32<0xA9, RawFrm, (outs), (ins i32imm:$src), - "test{l}\t{$src, %eax|%eax, $src}", []>; -def TEST64i32 : RIi32<0xa9, RawFrm, (outs), (ins i64i32imm:$src), - "test{q}\t{$src, %rax|%rax, $src}", []>; -} // Defs = [EFLAGS] +defm CMP : ArithBinOp_F<0x38, 0x3A, 0x3C, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>; //===----------------------------------------------------------------------===// -// Integer comparisons +// Semantically, test instructions are similar like AND, except they don't +// generate a result. From an encoding perspective, they are very different: +// they don't have all the usual imm8 and REV forms, and are encoded into a +// different space. +def X86testpat : PatFrag<(ops node:$lhs, node:$rhs), + (X86cmp (and_su node:$lhs, node:$rhs), 0)>; let Defs = [EFLAGS] in { + let isCommutable = 1 in { + def TEST8rr : BinOpRR_F<0x84, "test", Xi8 , X86testpat, MRMSrcReg>; + def TEST16rr : BinOpRR_F<0x84, "test", Xi16, X86testpat, MRMSrcReg>; + def TEST32rr : BinOpRR_F<0x84, "test", Xi32, X86testpat, MRMSrcReg>; + def TEST64rr : BinOpRR_F<0x84, "test", Xi64, X86testpat, MRMSrcReg>; + } // isCommutable + + def TEST8rm : BinOpRM_F<0x84, "test", Xi8 , X86testpat>; + def TEST16rm : BinOpRM_F<0x84, "test", Xi16, X86testpat>; + def TEST32rm : BinOpRM_F<0x84, "test", Xi32, X86testpat>; + def TEST64rm : BinOpRM_F<0x84, "test", Xi64, X86testpat>; + + def TEST8ri : BinOpRI_F<0xF6, "test", Xi8 , X86testpat, MRM0r>; + def TEST16ri : BinOpRI_F<0xF6, "test", Xi16, X86testpat, MRM0r>; + def TEST32ri : BinOpRI_F<0xF6, "test", Xi32, X86testpat, MRM0r>; + def TEST64ri32 : BinOpRI_F<0xF6, "test", Xi64, X86testpat, MRM0r>; + + def TEST8mi : BinOpMI_F<"test", Xi8 , X86testpat, MRM0m, 0xF6>; + def TEST16mi : BinOpMI_F<"test", Xi16, X86testpat, MRM0m, 0xF6>; + def TEST32mi : BinOpMI_F<"test", Xi32, X86testpat, MRM0m, 0xF6>; + def TEST64mi32 : BinOpMI_F<"test", Xi64, X86testpat, MRM0m, 0xF6>; + + def TEST8i8 : BinOpAI<0xA8, "test", Xi8 , AL>; + def TEST16i16 : BinOpAI<0xA8, "test", Xi16, AX>; + def TEST32i32 : BinOpAI<0xA8, "test", Xi32, EAX>; + def TEST64i32 : BinOpAI<0xA8, "test", Xi64, RAX>; +} -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]