From baf6893aaaee34f64315f57a55ca2a2c61ce1ca0 Mon Sep 17 00:00:00 2001 From: Sandy Carter Date: Fri, 20 Dec 2024 16:55:49 -0500 Subject: [PATCH] clang: Swich add register to register opcode 03f1 add esi, ecx --- llvm/lib/Target/X86/X86InstrArithmetic.td | 218 +++++++++++++++++++++- llvm/lib/Target/X86/X86InstrUtils.td | 13 ++ 2 files changed, 229 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/X86/X86InstrArithmetic.td b/llvm/lib/Target/X86/X86InstrArithmetic.td index 16ca2882a84daf0..fbac845c79a9a63 100644 --- a/llvm/lib/Target/X86/X86InstrArithmetic.td +++ b/llvm/lib/Target/X86/X86InstrArithmetic.td @@ -832,6 +832,220 @@ multiclass ArithBinOp_RF BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, def 64i32 : BinOpAI_AF; } +multiclass BW1_ArithBinOp_RF BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, + string mnemonic, Format RegMRM, Format MemMRM, + SDNode opnodeflag, SDNode opnode, + bit CommutableRR, bit ConvertibleToThreeAddress, + bit ConvertibleToThreeAddressRR> { + let isCommutable = CommutableRR, + isConvertibleToThreeAddress = ConvertibleToThreeAddressRR in { + let Predicates = [NoNDD] in { + def 8rr : BW1_BinOpRR_RF; + def 16rr : BW1_BinOpRR_RF, OpSize16; + def 32rr : BW1_BinOpRR_RF, OpSize32; + def 64rr : BW1_BinOpRR_RF; + } + let Predicates = [HasNDD, In64BitMode] in { + def 8rr_ND : BW1_BinOpRR_RF; + def 16rr_ND : BW1_BinOpRR_RF, PD; + def 32rr_ND : BW1_BinOpRR_RF; + def 64rr_ND : BW1_BinOpRR_RF; + def 8rr_NF_ND : BinOpRR_R, EVEX_NF; + def 16rr_NF_ND : BinOpRR_R, EVEX_NF, PD; + def 32rr_NF_ND : BinOpRR_R, EVEX_NF; + def 64rr_NF_ND : BinOpRR_R, EVEX_NF; + } + let Predicates = [In64BitMode] in { + def 8rr_NF : BinOpRR_R, NF; + def 16rr_NF : BinOpRR_R, NF, PD; + def 32rr_NF : BinOpRR_R, NF; + def 64rr_NF : BinOpRR_R, NF; + def 8rr_EVEX : BW1_BinOpRR_RF, PL; + def 16rr_EVEX : BW1_BinOpRR_RF, PL, PD; + def 32rr_EVEX : BW1_BinOpRR_RF, PL; + def 64rr_EVEX : BW1_BinOpRR_RF, PL; + } + } + + def 8rr_REV : BW1_BinOpRR_RF_Rev; + def 16rr_REV : BW1_BinOpRR_RF_Rev, OpSize16; + def 32rr_REV : BW1_BinOpRR_RF_Rev, OpSize32; + def 64rr_REV : BW1_BinOpRR_RF_Rev; + let Predicates = [In64BitMode] in { + def 8rr_EVEX_REV : BW1_BinOpRR_RF_Rev, PL; + def 16rr_EVEX_REV : BW1_BinOpRR_RF_Rev, PL, PD; + def 32rr_EVEX_REV : BW1_BinOpRR_RF_Rev, PL; + def 64rr_EVEX_REV : BW1_BinOpRR_RF_Rev, PL; + def 8rr_ND_REV : BW1_BinOpRR_RF_Rev; + def 16rr_ND_REV : BW1_BinOpRR_RF_Rev, PD; + def 32rr_ND_REV : BW1_BinOpRR_RF_Rev; + def 64rr_ND_REV : BW1_BinOpRR_RF_Rev; + def 8rr_NF_REV : BinOpRR_R_Rev, NF; + def 16rr_NF_REV : BinOpRR_R_Rev, NF, PD; + def 32rr_NF_REV : BinOpRR_R_Rev, NF; + def 64rr_NF_REV : BinOpRR_R_Rev, NF; + def 8rr_NF_ND_REV : BinOpRR_R_Rev, EVEX_NF; + def 16rr_NF_ND_REV : BinOpRR_R_Rev, EVEX_NF, PD; + def 32rr_NF_ND_REV : BinOpRR_R_Rev, EVEX_NF; + def 64rr_NF_ND_REV : BinOpRR_R_Rev, EVEX_NF; + } + + let Predicates = [NoNDD] in { + def 8rm : BinOpRM_RF; + def 16rm : BinOpRM_RF, OpSize16; + def 32rm : BinOpRM_RF, OpSize32; + def 64rm : BinOpRM_RF; + } + let Predicates = [HasNDD, In64BitMode] in { + def 8rm_ND : BinOpRM_RF; + def 16rm_ND : BinOpRM_RF, PD; + def 32rm_ND : BinOpRM_RF; + def 64rm_ND : BinOpRM_RF; + def 8rm_NF_ND : BinOpRM_R, EVEX_NF; + def 16rm_NF_ND : BinOpRM_R, EVEX_NF, PD; + def 32rm_NF_ND : BinOpRM_R, EVEX_NF; + def 64rm_NF_ND : BinOpRM_R, EVEX_NF; + } + let Predicates = [In64BitMode] in { + def 8rm_NF : BinOpRM_R, NF; + def 16rm_NF : BinOpRM_R, NF, PD; + def 32rm_NF : BinOpRM_R, NF; + def 64rm_NF : BinOpRM_R, NF; + def 8rm_EVEX : BinOpRM_RF, PL; + def 16rm_EVEX : BinOpRM_RF, PL, PD; + def 32rm_EVEX : BinOpRM_RF, PL; + def 64rm_EVEX : BinOpRM_RF, PL; + } + + let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { + let Predicates = [NoNDD] 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 16ri8 : BinOpRI8_RF<0x83, mnemonic, Xi16, RegMRM>, OpSize16; + def 32ri8 : BinOpRI8_RF<0x83, mnemonic, Xi32, RegMRM>, OpSize32; + def 64ri8 : BinOpRI8_RF<0x83, mnemonic, Xi64, RegMRM>; + def 8ri : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM>; + def 16ri : BinOpRI_RF<0x81, mnemonic, Xi16, opnodeflag, RegMRM>, OpSize16; + def 32ri : BinOpRI_RF<0x81, mnemonic, Xi32, opnodeflag, RegMRM>, OpSize32; + def 64ri32: BinOpRI_RF<0x81, mnemonic, Xi64, opnodeflag, RegMRM>; + } + let Predicates = [HasNDD, In64BitMode] in { + def 16ri8_ND : BinOpRI8_RF<0x83, mnemonic, Xi16, RegMRM, 1>, PD; + def 32ri8_ND : BinOpRI8_RF<0x83, mnemonic, Xi32, RegMRM, 1>; + def 64ri8_ND : BinOpRI8_RF<0x83, mnemonic, Xi64, RegMRM, 1>; + def 8ri_ND : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM, 1>; + def 16ri_ND : BinOpRI_RF<0x81, mnemonic, Xi16, opnodeflag, RegMRM, 1>, PD; + def 32ri_ND : BinOpRI_RF<0x81, mnemonic, Xi32, opnodeflag, RegMRM, 1>; + def 64ri32_ND: BinOpRI_RF<0x81, mnemonic, Xi64, opnodeflag, RegMRM, 1>; + def 16ri8_NF_ND : BinOpRI8_R<0x83, mnemonic, Xi16, RegMRM, 1>, EVEX_NF, PD; + def 32ri8_NF_ND : BinOpRI8_R<0x83, mnemonic, Xi32, RegMRM, 1>, EVEX_NF; + def 64ri8_NF_ND : BinOpRI8_R<0x83, mnemonic, Xi64, RegMRM, 1>, EVEX_NF; + def 8ri_NF_ND : BinOpRI_R<0x80, mnemonic, Xi8, RegMRM, 1>, EVEX_NF; + def 16ri_NF_ND : BinOpRI_R<0x81, mnemonic, Xi16, RegMRM, 1>, EVEX_NF, PD; + def 32ri_NF_ND : BinOpRI_R<0x81, mnemonic, Xi32, RegMRM, 1>, EVEX_NF; + def 64ri32_NF_ND : BinOpRI_R<0x81, mnemonic, Xi64, RegMRM, 1>, EVEX_NF; + } + let Predicates = [In64BitMode] in { + def 16ri8_NF : BinOpRI8_R<0x83, mnemonic, Xi16, RegMRM>, NF, PD; + def 32ri8_NF : BinOpRI8_R<0x83, mnemonic, Xi32, RegMRM>, NF; + def 64ri8_NF : BinOpRI8_R<0x83, mnemonic, Xi64, RegMRM>, NF; + def 8ri_NF : BinOpRI_R<0x80, mnemonic, Xi8, RegMRM>, NF; + def 16ri_NF : BinOpRI_R<0x81, mnemonic, Xi16, RegMRM>, NF, PD; + def 32ri_NF : BinOpRI_R<0x81, mnemonic, Xi32, RegMRM>, NF; + def 64ri32_NF : BinOpRI_R<0x81, mnemonic, Xi64, RegMRM>, NF; + def 16ri8_EVEX : BinOpRI8_RF<0x83, mnemonic, Xi16, RegMRM>, PL, PD; + def 32ri8_EVEX : BinOpRI8_RF<0x83, mnemonic, Xi32, RegMRM>, PL; + def 64ri8_EVEX : BinOpRI8_RF<0x83, mnemonic, Xi64, RegMRM>, PL; + def 8ri_EVEX : BinOpRI_RF<0x80, mnemonic, Xi8 , null_frag, RegMRM>, PL; + def 16ri_EVEX : BinOpRI_RF<0x81, mnemonic, Xi16, null_frag, RegMRM>, PL, PD; + def 32ri_EVEX : BinOpRI_RF<0x81, mnemonic, Xi32, null_frag, RegMRM>, PL; + def 64ri32_EVEX: BinOpRI_RF<0x81, mnemonic, Xi64, null_frag, RegMRM>, PL; + } + } + + def 8mr : BinOpMR_MF; + def 16mr : BinOpMR_MF, OpSize16; + def 32mr : BinOpMR_MF, OpSize32; + def 64mr : BinOpMR_MF; + let Predicates = [HasNDD, In64BitMode] in { + defvar node = !if(!eq(CommutableRR, 0), opnode, null_frag); + def 8mr_ND : BinOpMR_RF; + def 16mr_ND : BinOpMR_RF, PD; + def 32mr_ND : BinOpMR_RF; + def 64mr_ND : BinOpMR_RF; + def 8mr_NF_ND : BinOpMR_R, EVEX_NF; + def 16mr_NF_ND : BinOpMR_R, EVEX_NF, PD; + def 32mr_NF_ND : BinOpMR_R, EVEX_NF; + def 64mr_NF_ND : BinOpMR_R, EVEX_NF; + } + let Predicates = [In64BitMode] in { + def 8mr_NF : BinOpMR_M, NF; + def 16mr_NF : BinOpMR_M, NF, PD; + def 32mr_NF : BinOpMR_M, NF; + def 64mr_NF : BinOpMR_M, NF; + def 8mr_EVEX : BinOpMR_MF, PL; + def 16mr_EVEX : BinOpMR_MF, PL, PD; + def 32mr_EVEX : BinOpMR_MF, PL; + def 64mr_EVEX : BinOpMR_MF, PL; + } + + // 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 16mi8 : BinOpMI8_MF, OpSize16; + def 32mi8 : BinOpMI8_MF, OpSize32; + let Predicates = [In64BitMode] in + def 64mi8 : BinOpMI8_MF; + def 8mi : BinOpMI_MF<0x80, mnemonic, Xi8 , opnode, MemMRM>; + def 16mi : BinOpMI_MF<0x81, mnemonic, Xi16, opnode, MemMRM>, OpSize16; + def 32mi : BinOpMI_MF<0x81, mnemonic, Xi32, opnode, MemMRM>, OpSize32; + let Predicates = [In64BitMode] in + def 64mi32 : BinOpMI_MF<0x81, mnemonic, Xi64, opnode, MemMRM>; + let Predicates = [HasNDD, In64BitMode] in { + def 16mi8_ND : BinOpMI8_RF, PD; + def 32mi8_ND : BinOpMI8_RF; + def 64mi8_ND : BinOpMI8_RF; + def 8mi_ND : BinOpMI_RF<0x80, mnemonic, Xi8 , opnode, MemMRM>; + def 16mi_ND : BinOpMI_RF<0x81, mnemonic, Xi16, opnode, MemMRM>, PD; + def 32mi_ND : BinOpMI_RF<0x81, mnemonic, Xi32, opnode, MemMRM>; + def 64mi32_ND : BinOpMI_RF<0x81, mnemonic, Xi64, opnode, MemMRM>; + def 16mi8_NF_ND : BinOpMI8_R, NF, PD; + def 32mi8_NF_ND : BinOpMI8_R, NF; + def 64mi8_NF_ND : BinOpMI8_R, NF; + def 8mi_NF_ND : BinOpMI_R<0x80, mnemonic, Xi8, MemMRM>, NF; + def 16mi_NF_ND : BinOpMI_R<0x81, mnemonic, Xi16, MemMRM>, NF, PD; + def 32mi_NF_ND : BinOpMI_R<0x81, mnemonic, Xi32, MemMRM>, NF; + def 64mi32_NF_ND : BinOpMI_R<0x81, mnemonic, Xi64, MemMRM>, NF; + } + let Predicates = [In64BitMode] in { + def 16mi8_NF : BinOpMI8_M, NF, PD; + def 32mi8_NF : BinOpMI8_M, NF; + def 64mi8_NF : BinOpMI8_M, NF; + def 8mi_NF : BinOpMI_M<0x80, mnemonic, Xi8, MemMRM>, NF; + def 16mi_NF : BinOpMI_M<0x81, mnemonic, Xi16, MemMRM>, NF, PD; + def 32mi_NF : BinOpMI_M<0x81, mnemonic, Xi32, MemMRM>, NF; + def 64mi32_NF : BinOpMI_M<0x81, mnemonic, Xi64, MemMRM>, NF; + def 16mi8_EVEX : BinOpMI8_MF, PL, PD; + def 32mi8_EVEX : BinOpMI8_MF, PL; + def 64mi8_EVEX : BinOpMI8_MF, PL; + def 8mi_EVEX : BinOpMI_MF<0x80, mnemonic, Xi8 , null_frag, MemMRM>, PL; + def 16mi_EVEX : BinOpMI_MF<0x81, mnemonic, Xi16, null_frag, MemMRM>, PL, PD; + def 32mi_EVEX : BinOpMI_MF<0x81, mnemonic, Xi32, null_frag, MemMRM>, PL; + def 64mi32_EVEX : BinOpMI_MF<0x81, mnemonic, Xi64, null_frag, MemMRM>, PL; + } + + // These are for the disassembler since 0x82 opcode behaves like 0x80, but + // not in 64-bit mode. + let Predicates = [Not64BitMode] in { + def 8ri8 : BinOpRI8_RF<0x82, mnemonic, Xi8, RegMRM>, DisassembleOnly; + def 8mi8 : BinOpMI8_MF, DisassembleOnly; + } + + def 8i8 : BinOpAI_AF; + def 16i16 : BinOpAI_AF, OpSize16; + def 32i32 : BinOpAI_AF, OpSize32; + def 64i32 : BinOpAI_AF; +} + /// 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. @@ -1080,8 +1294,8 @@ defm OR : ArithBinOp_RF<0x09, 0x0B, 0x0D, "or", MRM1r, MRM1m, X86or_flag, or, 1, 0, 0>; defm XOR : ArithBinOp_RF<0x31, 0x33, 0x35, "xor", MRM6r, MRM6m, X86xor_flag, xor, 1, 0, 0>; -defm ADD : ArithBinOp_RF<0x01, 0x03, 0x05, "add", MRM0r, MRM0m, - X86add_flag, add, 1, 1, 1>; +defm ADD : BW1_ArithBinOp_RF<0x03, 0x01, 0x05, "add", MRM0r, MRM0m, + X86add_flag, add, 1, 1, 1>; let isCompare = 1 in { defm SUB : ArithBinOp_RF<0x29, 0x2B, 0x2D, "sub", MRM5r, MRM5m, X86sub_flag, sub, 0, 1, 0>; diff --git a/llvm/lib/Target/X86/X86InstrUtils.td b/llvm/lib/Target/X86/X86InstrUtils.td index ab171ac79fb377e..c3a2903bea23dbe 100644 --- a/llvm/lib/Target/X86/X86InstrUtils.td +++ b/llvm/lib/Target/X86/X86InstrUtils.td @@ -1004,6 +1004,19 @@ class BinOpRR_RF_Rev o, string m, X86TypeInfo t, bit ndd = 0> : BinOpRR_RF, DisassembleOnly { let Form = MRMSrcReg; } + +class BW1_BinOpRR_RF o, string m, X86TypeInfo t, SDPatternOperator node, bit ndd = 0> + : BinOpRR, DefEFLAGS, NDD { + let Form = MRMSrcReg; +} +class BW1_BinOpRR_RF_Rev o, string m, X86TypeInfo t, bit ndd = 0> + : BinOpRR_RF, DisassembleOnly { + let Form = MRMDestReg; +} + // BinOpRRF_RF - Instructions that read "reg, reg", write "reg" and read/write // EFLAGS. class BinOpRRF_RF o, string m, X86TypeInfo t, SDPatternOperator node = null_frag, bit ndd = 0>