From 5b85654844d673939bd1ceba66cd1f5022fd7c0d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 20 Dec 2010 00:59:46 +0000 Subject: Change the X86 backend to stop using the evil ADDC/ADDE/SUBC/SUBE nodes (which their carry depenedencies with MVT::Flag operands) and use clean and beautiful EFLAGS dependences instead. We do this by changing the modelling of SBB/ADC to have EFLAGS input and outputs (which is what requires the previous scheduler change) and change X86 ISelLowering to custom lower ADDC and friends down to X86ISD::ADD/ADC/SUB/SBB nodes. With the previous series of changes, this causes no changes in the testsuite, woo. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122213 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86InstrArithmetic.td | 136 +++++++++++++++++++++++++---------- 1 file changed, 97 insertions(+), 39 deletions(-) (limited to 'lib/Target/X86/X86InstrArithmetic.td') diff --git a/lib/Target/X86/X86InstrArithmetic.td b/lib/Target/X86/X86InstrArithmetic.td index e813ec04e7..f0ea068708 100644 --- a/lib/Target/X86/X86InstrArithmetic.td +++ b/lib/Target/X86/X86InstrArithmetic.td @@ -631,6 +631,15 @@ class BinOpRR_RF opcode, string mnemonic, X86TypeInfo typeinfo, [(set typeinfo.RegClass:$dst, EFLAGS, (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))]>; +// BinOpRR_RFF - Instructions like "adc reg, reg, reg", where the pattern has +// both a regclass and EFLAGS as a result, and has EFLAGS as input. +class BinOpRR_RFF opcode, string mnemonic, X86TypeInfo typeinfo, + SDNode opnode> + : BinOpRR; + // BinOpRR_Rev - Instructions like "add reg, reg, reg" (reversed encoding). class BinOpRR_Rev opcode, string mnemonic, X86TypeInfo typeinfo> : ITy opcode, string mnemonic, X86TypeInfo typeinfo, [(set typeinfo.RegClass:$dst, EFLAGS, (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>; +// BinOpRM_RFF - Instructions like "adc reg, reg, [mem]". +class BinOpRM_RFF opcode, string mnemonic, X86TypeInfo typeinfo, + SDNode opnode> + : BinOpRM; + // BinOpRI - Instructions like "add reg, reg, imm". class BinOpRI opcode, string mnemonic, X86TypeInfo typeinfo, Format f, dag outlist, list pattern> @@ -699,6 +716,14 @@ class BinOpRI_RF opcode, string mnemonic, X86TypeInfo typeinfo, [(set typeinfo.RegClass:$dst, EFLAGS, (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>; +// BinOpRI_RFF - Instructions like "adc reg, reg, imm". +class BinOpRI_RFF 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, dag outlist, list pattern> @@ -729,6 +754,14 @@ class BinOpRI8_RF opcode, string mnemonic, X86TypeInfo typeinfo, [(set typeinfo.RegClass:$dst, EFLAGS, (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>; +// BinOpRI8_RFF - Instructions like "adc reg, reg, imm8". +class BinOpRI8_RFF opcode, string mnemonic, X86TypeInfo typeinfo, + SDNode opnode, Format f> + : BinOpRI8; + // BinOpMR - Instructions like "add [mem], reg". class BinOpMR opcode, string mnemonic, X86TypeInfo typeinfo, list pattern> @@ -743,6 +776,14 @@ class BinOpMR_RMW opcode, string mnemonic, X86TypeInfo typeinfo, [(store (opnode (load addr:$dst), typeinfo.RegClass:$src), addr:$dst), (implicit EFLAGS)]>; +// BinOpMR_RMW_FF - Instructions like "adc [mem], reg". +class BinOpMR_RMW_FF 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> @@ -766,6 +807,14 @@ class BinOpMI_RMW; +// BinOpMI_RMW_FF - Instructions like "adc [mem], imm". +class BinOpMI_RMW_FF + : BinOpMI; + // BinOpMI_F - Instructions like "cmp [mem], imm". class BinOpMI_F opcode = 0x80> @@ -791,6 +840,14 @@ class BinOpMI8_RMW; +// BinOpMI8_RMW_FF - Instructions like "adc [mem], imm8". +class BinOpMI8_RMW_FF + : BinOpMI8; + // BinOpMI8_F - Instructions like "cmp [mem], imm8". class BinOpMI8_F @@ -876,22 +933,24 @@ multiclass ArithBinOp_RF BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, } } -/// ArithBinOp_R - This is an arithmetic binary operator where the pattern is -/// defined with "(set GPR:$dst, (...". It would be really nice to find a way -/// to factor this with the other ArithBinOp_*. +/// ArithBinOp_RFF - This is an arithmetic binary operator where the pattern is +/// defined with "(set GPR:$dst, EFLAGS, (node LHS, RHS, EFLAGS))" like ADC and +/// SBB. /// -multiclass ArithBinOp_R BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, - string mnemonic, Format RegMRM, Format MemMRM, - SDNode opnode, - bit CommutableRR, bit ConvertibleToThreeAddress> { +/// It would be nice to get rid of the second and third argument here, but +/// tblgen can't handle dependent type references aggressively enough: PR8330 +multiclass ArithBinOp_RFF BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, + string mnemonic, Format RegMRM, Format MemMRM, + SDNode opnode, bit CommutableRR, + bit ConvertibleToThreeAddress> { let Defs = [EFLAGS] in { let Constraints = "$src1 = $dst" in { let isCommutable = CommutableRR, isConvertibleToThreeAddress = ConvertibleToThreeAddress in { - def #NAME#8rr : BinOpRR_R; - def #NAME#16rr : BinOpRR_R; - def #NAME#32rr : BinOpRR_R; - def #NAME#64rr : BinOpRR_R; + def #NAME#8rr : BinOpRR_RFF; + def #NAME#16rr : BinOpRR_RFF; + def #NAME#32rr : BinOpRR_RFF; + def #NAME#64rr : BinOpRR_RFF; } // isCommutable def #NAME#8rr_REV : BinOpRR_Rev; @@ -899,40 +958,40 @@ multiclass ArithBinOp_R BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, def #NAME#32rr_REV : BinOpRR_Rev; def #NAME#64rr_REV : BinOpRR_Rev; - def #NAME#8rm : BinOpRM_R; - def #NAME#16rm : BinOpRM_R; - def #NAME#32rm : BinOpRM_R; - def #NAME#64rm : BinOpRM_R; + def #NAME#8rm : BinOpRM_RFF; + def #NAME#16rm : BinOpRM_RFF; + def #NAME#32rm : BinOpRM_RFF; + def #NAME#64rm : BinOpRM_RFF; 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_RFF<0x82, mnemonic, Xi16, opnode, RegMRM>; + def #NAME#32ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi32, opnode, RegMRM>; + def #NAME#64ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi64, opnode, RegMRM>; + + def #NAME#8ri : BinOpRI_RFF<0x80, mnemonic, Xi8 , opnode, RegMRM>; + def #NAME#16ri : BinOpRI_RFF<0x80, mnemonic, Xi16, opnode, RegMRM>; + def #NAME#32ri : BinOpRI_RFF<0x80, mnemonic, Xi32, opnode, RegMRM>; + def #NAME#64ri32: BinOpRI_RFF<0x80, mnemonic, Xi64, opnode, RegMRM>; } } // Constraints = "$src1 = $dst" - def #NAME#8mr : BinOpMR_RMW; - def #NAME#16mr : BinOpMR_RMW; - def #NAME#32mr : BinOpMR_RMW; - def #NAME#64mr : BinOpMR_RMW; + def #NAME#8mr : BinOpMR_RMW_FF; + def #NAME#16mr : BinOpMR_RMW_FF; + def #NAME#32mr : BinOpMR_RMW_FF; + def #NAME#64mr : BinOpMR_RMW_FF; // 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#16mi8 : BinOpMI8_RMW_FF; + def #NAME#32mi8 : BinOpMI8_RMW_FF; + def #NAME#64mi8 : BinOpMI8_RMW_FF; - def #NAME#8mi : BinOpMI_RMW; - def #NAME#16mi : BinOpMI_RMW; - def #NAME#32mi : BinOpMI_RMW; - def #NAME#64mi32 : BinOpMI_RMW; + def #NAME#8mi : BinOpMI_RMW_FF; + def #NAME#16mi : BinOpMI_RMW_FF; + def #NAME#32mi : BinOpMI_RMW_FF; + def #NAME#64mi32 : BinOpMI_RMW_FF; def #NAME#8i8 : BinOpAI; def #NAME#16i16 : BinOpAI; @@ -1018,13 +1077,12 @@ defm SUB : ArithBinOp_RF<0x28, 0x2A, 0x2C, "sub", MRM5r, MRM5m, // Arithmetic. let Uses = [EFLAGS] in { - // FIXME: Delete ArithBinOp_R if these switch off adde/sube. - defm ADC : ArithBinOp_R<0x10, 0x12, 0x14, "adc", MRM2r, MRM2m, adde, 1, 0>; - defm SBB : ArithBinOp_R<0x18, 0x1A, 0x1C, "sbb", MRM3r, MRM3m, sube, 0, 0>; + defm ADC : ArithBinOp_RFF<0x10, 0x12, 0x14, "adc", MRM2r, MRM2m, X86adc_flag, + 1, 0>; + defm SBB : ArithBinOp_RFF<0x18, 0x1A, 0x1C, "sbb", MRM3r, MRM3m, X86sbb_flag, + 0, 0>; } - - defm CMP : ArithBinOp_F<0x38, 0x3A, 0x3C, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>; -- cgit v1.2.3