10b57cec5SDimitry Andric//===-- X86InstrArithmetic.td - Integer Arithmetic Instrs --*- tablegen -*-===// 20b57cec5SDimitry Andric// 30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric// 70b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric// 90b57cec5SDimitry Andric// This file describes the integer arithmetic instructions in the X86 100b57cec5SDimitry Andric// architecture. 110b57cec5SDimitry Andric// 120b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 150b57cec5SDimitry Andric// LEA - Load Effective Address 160b57cec5SDimitry Andriclet SchedRW = [WriteLEA] in { 170b57cec5SDimitry Andric let hasSideEffects = 0 in 180b57cec5SDimitry Andric def LEA16r : I<0x8D, MRMSrcMem, 190b57cec5SDimitry Andric (outs GR16:$dst), (ins anymem:$src), 200b57cec5SDimitry Andric "lea{w}\t{$src|$dst}, {$dst|$src}", []>, OpSize16; 210b57cec5SDimitry Andric let isReMaterializable = 1 in 220b57cec5SDimitry Andric def LEA32r : I<0x8D, MRMSrcMem, 230b57cec5SDimitry Andric (outs GR32:$dst), (ins anymem:$src), 240b57cec5SDimitry Andric "lea{l}\t{$src|$dst}, {$dst|$src}", 250b57cec5SDimitry Andric [(set GR32:$dst, lea32addr:$src)]>, 260b57cec5SDimitry Andric OpSize32, Requires<[Not64BitMode]>; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric def LEA64_32r : I<0x8D, MRMSrcMem, 290b57cec5SDimitry Andric (outs GR32:$dst), (ins lea64_32mem:$src), 300b57cec5SDimitry Andric "lea{l}\t{$src|$dst}, {$dst|$src}", 310b57cec5SDimitry Andric [(set GR32:$dst, lea64_32addr:$src)]>, 320b57cec5SDimitry Andric OpSize32, Requires<[In64BitMode]>; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric let isReMaterializable = 1 in 350b57cec5SDimitry Andric def LEA64r : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src), 360b57cec5SDimitry Andric "lea{q}\t{$src|$dst}, {$dst|$src}", 370b57cec5SDimitry Andric [(set GR64:$dst, lea64addr:$src)]>; 380b57cec5SDimitry Andric} // SchedRW 390b57cec5SDimitry Andric 4006c3fb27SDimitry Andric// Pseudo instruction for lea that prevent optimizer from eliminating 4106c3fb27SDimitry Andric// the instruction. 4206c3fb27SDimitry Andriclet SchedRW = [WriteLEA], isPseudo = true, hasSideEffects = 1 in { 4306c3fb27SDimitry Andric def PLEA32r : PseudoI<(outs GR32:$dst), (ins anymem:$src), []>; 4406c3fb27SDimitry Andric def PLEA64r : PseudoI<(outs GR64:$dst), (ins anymem:$src), []>; 4506c3fb27SDimitry Andric} 4606c3fb27SDimitry Andric 47647cbc5dSDimitry Andric//===----------------------------------------------------------------------===// 48647cbc5dSDimitry Andric// MUL/IMUL and DIV/IDIV Instructions 49647cbc5dSDimitry Andric// 50647cbc5dSDimitry Andricclass MulDivOpR<bits<8> o, Format f, string m, X86TypeInfo t, 51cb14a3feSDimitry Andric X86FoldableSchedWrite sched, list<dag> p> 52647cbc5dSDimitry Andric : UnaryOpR<o, f, m, "$src1", t, (outs), p> { 53647cbc5dSDimitry Andric let SchedRW = [sched]; 54cb14a3feSDimitry Andric} 5506c3fb27SDimitry Andric 56647cbc5dSDimitry Andricclass MulDivOpM<bits<8> o, Format f, string m, X86TypeInfo t, 57647cbc5dSDimitry Andric X86FoldableSchedWrite sched, list<dag> p> 58647cbc5dSDimitry Andric : UnaryOpM<o, f, m, "$src1", t, (outs), p> { 59647cbc5dSDimitry Andric let SchedRW = 60647cbc5dSDimitry Andric [sched.Folded, 61647cbc5dSDimitry Andric // Memory operand. 62647cbc5dSDimitry Andric ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault, 63647cbc5dSDimitry Andric // Register reads (implicit or explicit). 64647cbc5dSDimitry Andric sched.ReadAfterFold, sched.ReadAfterFold]; 65647cbc5dSDimitry Andric} 6606c3fb27SDimitry Andric 67647cbc5dSDimitry Andricmulticlass Mul<bits<8> o, string m, Format RegMRM, Format MemMRM, SDPatternOperator node> { 68647cbc5dSDimitry Andric // AL is really implied by AX, but the registers in Defs must match the 69647cbc5dSDimitry Andric // SDNode results (i8, i32). 70647cbc5dSDimitry Andric // 71647cbc5dSDimitry Andric // FIXME: Used for 8-bit mul, ignore result upper 8 bits. 72647cbc5dSDimitry Andric // This probably ought to be moved to a def : Pat<> if the 73647cbc5dSDimitry Andric // syntax can be accepted. 74647cbc5dSDimitry Andric let Defs = [AL, EFLAGS, AX], Uses = [AL] in 75647cbc5dSDimitry Andric def 8r : MulDivOpR<o, RegMRM, m, Xi8, WriteIMul8, 76647cbc5dSDimitry Andric [(set AL, (node AL, GR8:$src1)), (implicit EFLAGS)]>; 77647cbc5dSDimitry Andric let Defs = [AX, DX, EFLAGS], Uses = [AX] in 78647cbc5dSDimitry Andric def 16r : MulDivOpR<o, RegMRM, m, Xi16, WriteIMul16, []>, OpSize16; 79647cbc5dSDimitry Andric let Defs = [EAX, EDX, EFLAGS], Uses = [EAX] in 80647cbc5dSDimitry Andric def 32r : MulDivOpR<o, RegMRM, m, Xi32, WriteIMul32, []>, OpSize32; 81647cbc5dSDimitry Andric let Defs = [RAX, RDX, EFLAGS], Uses = [RAX] in 82647cbc5dSDimitry Andric def 64r : MulDivOpR<o, RegMRM, m, Xi64, WriteIMul64, []>; 83647cbc5dSDimitry Andric let Defs = [AL, EFLAGS, AX], Uses = [AL] in 84647cbc5dSDimitry Andric def 8m : MulDivOpM<o, MemMRM, m, Xi8, WriteIMul8, 85647cbc5dSDimitry Andric [(set AL, (node AL, (loadi8 addr:$src1))), (implicit EFLAGS)]>; 86647cbc5dSDimitry Andric let Defs = [AX, DX, EFLAGS], Uses = [AX] in 87647cbc5dSDimitry Andric def 16m : MulDivOpM<o, MemMRM, m, Xi16, WriteIMul16, []>, OpSize16; 88647cbc5dSDimitry Andric let Defs = [EAX, EDX, EFLAGS], Uses = [EAX] in 89647cbc5dSDimitry Andric def 32m : MulDivOpM<o, MemMRM, m, Xi32, WriteIMul32, []>, OpSize32; 90647cbc5dSDimitry Andric let Defs = [RAX, RDX, EFLAGS], Uses = [RAX] in 91647cbc5dSDimitry Andric def 64m : MulDivOpM<o, MemMRM, m, Xi64, WriteIMul64, []>, Requires<[In64BitMode]>; 921db9f3b2SDimitry Andric 931db9f3b2SDimitry Andric let Predicates = [In64BitMode] in { 941db9f3b2SDimitry Andric let Defs = [AL, AX], Uses = [AL] in 951db9f3b2SDimitry Andric def 8r_NF : MulDivOpR<o, RegMRM, m, Xi8, WriteIMul8, []>, NF; 961db9f3b2SDimitry Andric let Defs = [AX, DX], Uses = [AX] in 971db9f3b2SDimitry Andric def 16r_NF : MulDivOpR<o, RegMRM, m, Xi16, WriteIMul16, []>, NF, PD; 981db9f3b2SDimitry Andric let Defs = [EAX, EDX], Uses = [EAX] in 991db9f3b2SDimitry Andric def 32r_NF : MulDivOpR<o, RegMRM, m, Xi32, WriteIMul32, []>, NF; 1001db9f3b2SDimitry Andric let Defs = [RAX, RDX], Uses = [RAX] in 1011db9f3b2SDimitry Andric def 64r_NF : MulDivOpR<o, RegMRM, m, Xi64, WriteIMul64, []>, NF; 1021db9f3b2SDimitry Andric let Defs = [AL, AX], Uses = [AL] in 1031db9f3b2SDimitry Andric def 8m_NF : MulDivOpM<o, MemMRM, m, Xi8, WriteIMul8, []>, NF; 1041db9f3b2SDimitry Andric let Defs = [AX, DX], Uses = [AX] in 1051db9f3b2SDimitry Andric def 16m_NF : MulDivOpM<o, MemMRM, m, Xi16, WriteIMul16, []>, NF, PD; 1061db9f3b2SDimitry Andric let Defs = [EAX, EDX], Uses = [EAX] in 1071db9f3b2SDimitry Andric def 32m_NF : MulDivOpM<o, MemMRM, m, Xi32, WriteIMul32, []>, NF; 1081db9f3b2SDimitry Andric let Defs = [RAX, RDX], Uses = [RAX] in 1091db9f3b2SDimitry Andric def 64m_NF : MulDivOpM<o, MemMRM, m, Xi64, WriteIMul64, []>, NF; 1101db9f3b2SDimitry Andric 1111db9f3b2SDimitry Andric let Defs = [AL, EFLAGS, AX], Uses = [AL] in 1121db9f3b2SDimitry Andric def 8r_EVEX : MulDivOpR<o, RegMRM, m, Xi8, WriteIMul8, []>, PL; 1131db9f3b2SDimitry Andric let Defs = [AX, DX, EFLAGS], Uses = [AX] in 1141db9f3b2SDimitry Andric def 16r_EVEX : MulDivOpR<o, RegMRM, m, Xi16, WriteIMul16, []>, PL, PD; 1151db9f3b2SDimitry Andric let Defs = [EAX, EDX, EFLAGS], Uses = [EAX] in 1161db9f3b2SDimitry Andric def 32r_EVEX : MulDivOpR<o, RegMRM, m, Xi32, WriteIMul32, []>, PL; 1171db9f3b2SDimitry Andric let Defs = [RAX, RDX, EFLAGS], Uses = [RAX] in 1181db9f3b2SDimitry Andric def 64r_EVEX : MulDivOpR<o, RegMRM, m, Xi64, WriteIMul64, []>, PL; 1191db9f3b2SDimitry Andric let Defs = [AL, EFLAGS, AX], Uses = [AL] in 1201db9f3b2SDimitry Andric def 8m_EVEX : MulDivOpM<o, MemMRM, m, Xi8, WriteIMul8, []>, PL; 1211db9f3b2SDimitry Andric let Defs = [AX, DX, EFLAGS], Uses = [AX] in 1221db9f3b2SDimitry Andric def 16m_EVEX : MulDivOpM<o, MemMRM, m, Xi16, WriteIMul16, []>, PL, PD; 1231db9f3b2SDimitry Andric let Defs = [EAX, EDX, EFLAGS], Uses = [EAX] in 1241db9f3b2SDimitry Andric def 32m_EVEX : MulDivOpM<o, MemMRM, m, Xi32, WriteIMul32, []>, PL; 1251db9f3b2SDimitry Andric let Defs = [RAX, RDX, EFLAGS], Uses = [RAX] in 1261db9f3b2SDimitry Andric def 64m_EVEX : MulDivOpM<o, MemMRM, m, Xi64, WriteIMul64, []>, PL; 1271db9f3b2SDimitry Andric } 128647cbc5dSDimitry Andric} 129cb14a3feSDimitry Andric 130647cbc5dSDimitry Andricdefm MUL : Mul<0xF7, "mul", MRM4r, MRM4m, mul>; 131647cbc5dSDimitry Andricdefm IMUL : Mul<0xF7, "imul", MRM5r, MRM5m, null_frag>; 13206c3fb27SDimitry Andric 133647cbc5dSDimitry Andricmulticlass Div<bits<8> o, string m, Format RegMRM, Format MemMRM> { 134647cbc5dSDimitry Andric defvar sched8 = !if(!eq(m, "div"), WriteDiv8, WriteIDiv8); 135647cbc5dSDimitry Andric defvar sched16 = !if(!eq(m, "div"), WriteDiv16, WriteIDiv16); 136647cbc5dSDimitry Andric defvar sched32 = !if(!eq(m, "div"), WriteDiv32, WriteIDiv32); 137647cbc5dSDimitry Andric defvar sched64 = !if(!eq(m, "div"), WriteDiv64, WriteIDiv64); 138647cbc5dSDimitry Andric let Defs = [AL, AH, EFLAGS], Uses = [AX] in 139647cbc5dSDimitry Andric def 8r : MulDivOpR<o, RegMRM, m, Xi8, sched8, []>; 140647cbc5dSDimitry Andric let Defs = [AX, DX, EFLAGS], Uses = [AX, DX] in 141647cbc5dSDimitry Andric def 16r : MulDivOpR<o, RegMRM, m, Xi16, sched16, []>, OpSize16; 142647cbc5dSDimitry Andric let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EDX] in 143647cbc5dSDimitry Andric def 32r : MulDivOpR<o, RegMRM, m, Xi32, sched32, []>, OpSize32; 144647cbc5dSDimitry Andric let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RDX] in 145647cbc5dSDimitry Andric def 64r : MulDivOpR<o, RegMRM, m, Xi64, sched64, []>; 146647cbc5dSDimitry Andric let Defs = [AL, AH, EFLAGS], Uses = [AX] in 147647cbc5dSDimitry Andric def 8m : MulDivOpM<o, MemMRM, m, Xi8, sched8, []>; 148647cbc5dSDimitry Andric let Defs = [AX, DX, EFLAGS], Uses = [AX, DX] in 149647cbc5dSDimitry Andric def 16m : MulDivOpM<o, MemMRM, m, Xi16, sched16, []>, OpSize16; 150647cbc5dSDimitry Andric let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EDX] in 151647cbc5dSDimitry Andric def 32m : MulDivOpM<o, MemMRM, m, Xi32, sched32, []>, OpSize32; 152647cbc5dSDimitry Andric let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RDX] in 153647cbc5dSDimitry Andric def 64m : MulDivOpM<o, MemMRM, m, Xi64, sched64, []>, Requires<[In64BitMode]>; 1541db9f3b2SDimitry Andric 1551db9f3b2SDimitry Andric let Predicates = [In64BitMode] in { 1561db9f3b2SDimitry Andric let Defs = [AL, AH], Uses = [AX] in 1571db9f3b2SDimitry Andric def 8r_NF : MulDivOpR<o, RegMRM, m, Xi8, sched8, []>, NF; 1581db9f3b2SDimitry Andric let Defs = [AX, DX], Uses = [AX, DX] in 1591db9f3b2SDimitry Andric def 16r_NF : MulDivOpR<o, RegMRM, m, Xi16, sched16, []>, NF, PD; 1601db9f3b2SDimitry Andric let Defs = [EAX, EDX], Uses = [EAX, EDX] in 1611db9f3b2SDimitry Andric def 32r_NF : MulDivOpR<o, RegMRM, m, Xi32, sched32, []>, NF; 1621db9f3b2SDimitry Andric let Defs = [RAX, RDX], Uses = [RAX, RDX] in 1631db9f3b2SDimitry Andric def 64r_NF : MulDivOpR<o, RegMRM, m, Xi64, sched64, []>, NF; 1641db9f3b2SDimitry Andric let Defs = [AL, AH], Uses = [AX] in 1651db9f3b2SDimitry Andric def 8m_NF : MulDivOpM<o, MemMRM, m, Xi8, sched8, []>, NF; 1661db9f3b2SDimitry Andric let Defs = [AX, DX], Uses = [AX, DX] in 1671db9f3b2SDimitry Andric def 16m_NF : MulDivOpM<o, MemMRM, m, Xi16, sched16, []>, NF, PD; 1681db9f3b2SDimitry Andric let Defs = [EAX, EDX], Uses = [EAX, EDX] in 1691db9f3b2SDimitry Andric def 32m_NF : MulDivOpM<o, MemMRM, m, Xi32, sched32, []>, NF; 1701db9f3b2SDimitry Andric let Defs = [RAX, RDX], Uses = [RAX, RDX] in 1711db9f3b2SDimitry Andric def 64m_NF : MulDivOpM<o, MemMRM, m, Xi64, sched64, []>, NF; 1721db9f3b2SDimitry Andric 1731db9f3b2SDimitry Andric let Defs = [AL, AH, EFLAGS], Uses = [AX] in 1741db9f3b2SDimitry Andric def 8r_EVEX : MulDivOpR<o, RegMRM, m, Xi8, sched8, []>, PL; 1751db9f3b2SDimitry Andric let Defs = [AX, DX, EFLAGS], Uses = [AX, DX] in 1761db9f3b2SDimitry Andric def 16r_EVEX : MulDivOpR<o, RegMRM, m, Xi16, sched16, []>, PL, PD; 1771db9f3b2SDimitry Andric let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EDX] in 1781db9f3b2SDimitry Andric def 32r_EVEX : MulDivOpR<o, RegMRM, m, Xi32, sched32, []>, PL; 1791db9f3b2SDimitry Andric let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RDX] in 1801db9f3b2SDimitry Andric def 64r_EVEX : MulDivOpR<o, RegMRM, m, Xi64, sched64, []>, PL; 1811db9f3b2SDimitry Andric let Defs = [AL, AH, EFLAGS], Uses = [AX] in 1821db9f3b2SDimitry Andric def 8m_EVEX : MulDivOpM<o, MemMRM, m, Xi8, sched8, []>, PL; 1831db9f3b2SDimitry Andric let Defs = [AX, DX, EFLAGS], Uses = [AX, DX] in 1841db9f3b2SDimitry Andric def 16m_EVEX : MulDivOpM<o, MemMRM, m, Xi16, sched16, []>, PL, PD; 1851db9f3b2SDimitry Andric let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EDX] in 1861db9f3b2SDimitry Andric def 32m_EVEX : MulDivOpM<o, MemMRM, m, Xi32, sched32, []>, PL; 1871db9f3b2SDimitry Andric let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RDX] in 1881db9f3b2SDimitry Andric def 64m_EVEX : MulDivOpM<o, MemMRM, m, Xi64, sched64, []>, PL; 189647cbc5dSDimitry Andric } 1901db9f3b2SDimitry Andric} 1911db9f3b2SDimitry Andric 192647cbc5dSDimitry Andriclet hasSideEffects = 1 in { // so that we don't speculatively execute 193647cbc5dSDimitry Andric defm DIV: Div<0xF7, "div", MRM6r, MRM6m>; 194647cbc5dSDimitry Andric defm IDIV: Div<0xF7, "idiv", MRM7r, MRM7m>; 195647cbc5dSDimitry Andric} 19606c3fb27SDimitry Andric 1971db9f3b2SDimitry Andricclass IMulOpRR_R<X86TypeInfo t, X86FoldableSchedWrite sched, bit ndd = 0> 1981db9f3b2SDimitry Andric : BinOpRR_R<0xAF, "imul", t, ndd> { 199cb14a3feSDimitry Andric let Form = MRMSrcReg; 200cb14a3feSDimitry Andric let SchedRW = [sched]; 201cb14a3feSDimitry Andric // X = IMUL Y, Z --> X = IMUL Z, Y 202cb14a3feSDimitry Andric let isCommutable = 1; 203cb14a3feSDimitry Andric} 2041db9f3b2SDimitry Andricclass IMulOpRR_RF<X86TypeInfo t, X86FoldableSchedWrite sched, bit ndd = 0> 2051db9f3b2SDimitry Andric : BinOpRR_RF<0xAF, "imul", t, X86smul_flag, ndd> { 2061db9f3b2SDimitry Andric let Form = MRMSrcReg; 2071db9f3b2SDimitry Andric let SchedRW = [sched]; 2081db9f3b2SDimitry Andric // X = IMUL Y, Z --> X = IMUL Z, Y 2091db9f3b2SDimitry Andric let isCommutable = 1; 2101db9f3b2SDimitry Andric} 2111db9f3b2SDimitry Andricclass IMulOpRM_R<X86TypeInfo t, X86FoldableSchedWrite sched, bit ndd = 0> 2121db9f3b2SDimitry Andric : BinOpRM_R<0xAF, "imul", t, ndd> { 2131db9f3b2SDimitry Andric let Form = MRMSrcMem; 2141db9f3b2SDimitry Andric let SchedRW = [sched.Folded, sched.ReadAfterFold]; 2151db9f3b2SDimitry Andric} 2161db9f3b2SDimitry Andricclass IMulOpRM_RF<X86TypeInfo t, X86FoldableSchedWrite sched, bit ndd = 0> 2171db9f3b2SDimitry Andric : BinOpRM_RF<0xAF, "imul", t, X86smul_flag, ndd> { 218cb14a3feSDimitry Andric let Form = MRMSrcMem; 219cb14a3feSDimitry Andric let SchedRW = [sched.Folded, sched.ReadAfterFold]; 220cb14a3feSDimitry Andric} 22106c3fb27SDimitry Andric 2221db9f3b2SDimitry Andriclet Predicates = [NoNDD] in { 2231db9f3b2SDimitry Andric def IMUL16rr : IMulOpRR_RF<Xi16, WriteIMul16Reg>, TB, OpSize16; 2241db9f3b2SDimitry Andric def IMUL32rr : IMulOpRR_RF<Xi32, WriteIMul32Reg>, TB, OpSize32; 2251db9f3b2SDimitry Andric def IMUL64rr : IMulOpRR_RF<Xi64, WriteIMul64Reg>, TB; 2261db9f3b2SDimitry Andric def IMUL16rm : IMulOpRM_RF<Xi16, WriteIMul16Reg>, TB, OpSize16; 2271db9f3b2SDimitry Andric def IMUL32rm : IMulOpRM_RF<Xi32, WriteIMul32Reg>, TB, OpSize32; 2281db9f3b2SDimitry Andric def IMUL64rm : IMulOpRM_RF<Xi64, WriteIMul64Reg>, TB; 2291db9f3b2SDimitry Andric} 2301db9f3b2SDimitry Andriclet Predicates = [HasNDD, In64BitMode] in { 2311db9f3b2SDimitry Andric def IMUL16rr_ND : IMulOpRR_RF<Xi16, WriteIMul16Reg, 1>, PD; 2321db9f3b2SDimitry Andric def IMUL32rr_ND : IMulOpRR_RF<Xi32, WriteIMul32Reg, 1>; 2331db9f3b2SDimitry Andric def IMUL64rr_ND : IMulOpRR_RF<Xi64, WriteIMul64Reg, 1>; 2341db9f3b2SDimitry Andric def IMUL16rm_ND : IMulOpRM_RF<Xi16, WriteIMul16Reg, 1>, PD; 2351db9f3b2SDimitry Andric def IMUL32rm_ND : IMulOpRM_RF<Xi32, WriteIMul32Reg, 1>; 2361db9f3b2SDimitry Andric def IMUL64rm_ND : IMulOpRM_RF<Xi64, WriteIMul64Reg, 1>; 2371db9f3b2SDimitry Andric} 2381db9f3b2SDimitry Andric 2391db9f3b2SDimitry Andriclet Predicates = [In64BitMode], Pattern = [(null_frag)] in { 2401db9f3b2SDimitry Andric def IMUL16rr_NF : IMulOpRR_R<Xi16, WriteIMul16Reg>, NF, PD; 2411db9f3b2SDimitry Andric def IMUL32rr_NF : IMulOpRR_R<Xi32, WriteIMul32Reg>, NF; 2421db9f3b2SDimitry Andric def IMUL64rr_NF : IMulOpRR_R<Xi64, WriteIMul64Reg>, NF; 2431db9f3b2SDimitry Andric def IMUL16rm_NF : IMulOpRM_R<Xi16, WriteIMul16Reg>, NF, PD; 2441db9f3b2SDimitry Andric def IMUL32rm_NF : IMulOpRM_R<Xi32, WriteIMul32Reg>, NF; 2451db9f3b2SDimitry Andric def IMUL64rm_NF : IMulOpRM_R<Xi64, WriteIMul64Reg>, NF; 2461db9f3b2SDimitry Andric 2471db9f3b2SDimitry Andric def IMUL16rr_NF_ND : IMulOpRR_R<Xi16, WriteIMul16Reg, 1>, EVEX_NF, PD; 2481db9f3b2SDimitry Andric def IMUL32rr_NF_ND : IMulOpRR_R<Xi32, WriteIMul32Reg, 1>, EVEX_NF; 2491db9f3b2SDimitry Andric def IMUL64rr_NF_ND : IMulOpRR_R<Xi64, WriteIMul64Reg, 1>, EVEX_NF; 2501db9f3b2SDimitry Andric def IMUL16rm_NF_ND : IMulOpRM_R<Xi16, WriteIMul16Reg, 1>, EVEX_NF, PD; 2511db9f3b2SDimitry Andric def IMUL32rm_NF_ND : IMulOpRM_R<Xi32, WriteIMul32Reg, 1>, EVEX_NF; 2521db9f3b2SDimitry Andric def IMUL64rm_NF_ND : IMulOpRM_R<Xi64, WriteIMul64Reg, 1>, EVEX_NF; 2531db9f3b2SDimitry Andric 2541db9f3b2SDimitry Andric def IMUL16rr_EVEX : IMulOpRR_RF<Xi16, WriteIMul16Reg>, PL, PD; 2551db9f3b2SDimitry Andric def IMUL32rr_EVEX : IMulOpRR_RF<Xi32, WriteIMul32Reg>, PL; 2561db9f3b2SDimitry Andric def IMUL64rr_EVEX : IMulOpRR_RF<Xi64, WriteIMul64Reg>, PL; 2571db9f3b2SDimitry Andric def IMUL16rm_EVEX : IMulOpRM_RF<Xi16, WriteIMul16Reg>, PL, PD; 2581db9f3b2SDimitry Andric def IMUL32rm_EVEX : IMulOpRM_RF<Xi32, WriteIMul32Reg>, PL; 2591db9f3b2SDimitry Andric def IMUL64rm_EVEX : IMulOpRM_RF<Xi64, WriteIMul64Reg>, PL; 2601db9f3b2SDimitry Andric} 26106c3fb27SDimitry Andric 262647cbc5dSDimitry Andricclass IMulOpRI8_R<X86TypeInfo t, X86FoldableSchedWrite sched> 263647cbc5dSDimitry Andric : BinOpRI8<0x6B, "imul", binop_ndd_args, t, MRMSrcReg, 2641db9f3b2SDimitry Andric (outs t.RegClass:$dst)> { 265647cbc5dSDimitry Andric let SchedRW = [sched]; 266647cbc5dSDimitry Andric} 267647cbc5dSDimitry Andricclass IMulOpRI_R<X86TypeInfo t, X86FoldableSchedWrite sched> 268647cbc5dSDimitry Andric : BinOpRI<0x69, "imul", binop_ndd_args, t, MRMSrcReg, 2691db9f3b2SDimitry Andric (outs t.RegClass:$dst), []> { 2701db9f3b2SDimitry Andric let SchedRW = [sched]; 2711db9f3b2SDimitry Andric} 2721db9f3b2SDimitry Andricclass IMulOpRI_RF<X86TypeInfo t, X86FoldableSchedWrite sched> 2731db9f3b2SDimitry Andric : BinOpRI<0x69, "imul", binop_ndd_args, t, MRMSrcReg, 274647cbc5dSDimitry Andric (outs t.RegClass:$dst), 275cb14a3feSDimitry Andric [(set t.RegClass:$dst, EFLAGS, (X86smul_flag t.RegClass:$src1, 276647cbc5dSDimitry Andric t.ImmNoSuOperator:$src2))]>, DefEFLAGS { 277647cbc5dSDimitry Andric let SchedRW = [sched]; 27806c3fb27SDimitry Andric} 279647cbc5dSDimitry Andricclass IMulOpMI8_R<X86TypeInfo t, X86FoldableSchedWrite sched> 2801db9f3b2SDimitry Andric : BinOpMI8<"imul", binop_ndd_args, t, MRMSrcMem, (outs t.RegClass:$dst)> { 281647cbc5dSDimitry Andric let Opcode = 0x6B; 282647cbc5dSDimitry Andric let SchedRW = [sched.Folded]; 28306c3fb27SDimitry Andric} 284647cbc5dSDimitry Andricclass IMulOpMI_R<X86TypeInfo t, X86FoldableSchedWrite sched> 285647cbc5dSDimitry Andric : BinOpMI<0x69, "imul", binop_ndd_args, t, MRMSrcMem, 2861db9f3b2SDimitry Andric (outs t.RegClass:$dst), []> { 2871db9f3b2SDimitry Andric let SchedRW = [sched.Folded]; 2881db9f3b2SDimitry Andric} 2891db9f3b2SDimitry Andricclass IMulOpMI_RF<X86TypeInfo t, X86FoldableSchedWrite sched> 2901db9f3b2SDimitry Andric : BinOpMI<0x69, "imul", binop_ndd_args, t, MRMSrcMem, 291647cbc5dSDimitry Andric (outs t.RegClass:$dst), 292647cbc5dSDimitry Andric [(set t.RegClass:$dst, EFLAGS, (X86smul_flag (t.LoadNode addr:$src1), 293647cbc5dSDimitry Andric t.ImmNoSuOperator:$src2))]>, 294647cbc5dSDimitry Andric DefEFLAGS { 295647cbc5dSDimitry Andric let SchedRW = [sched.Folded]; 29606c3fb27SDimitry Andric} 2971db9f3b2SDimitry Andricdef IMUL16rri8 : IMulOpRI8_R<Xi16, WriteIMul16Imm>, DefEFLAGS, OpSize16; 2981db9f3b2SDimitry Andricdef IMUL32rri8 : IMulOpRI8_R<Xi32, WriteIMul32Imm>, DefEFLAGS, OpSize32; 2991db9f3b2SDimitry Andricdef IMUL64rri8 : IMulOpRI8_R<Xi64, WriteIMul64Imm>, DefEFLAGS; 3001db9f3b2SDimitry Andricdef IMUL16rri : IMulOpRI_RF<Xi16, WriteIMul16Imm>, OpSize16; 3011db9f3b2SDimitry Andricdef IMUL32rri : IMulOpRI_RF<Xi32, WriteIMul32Imm>, OpSize32; 3021db9f3b2SDimitry Andricdef IMUL64rri32 : IMulOpRI_RF<Xi64, WriteIMul64Imm>; 3031db9f3b2SDimitry Andricdef IMUL16rmi8 : IMulOpMI8_R<Xi16, WriteIMul16Imm>, DefEFLAGS, OpSize16; 3041db9f3b2SDimitry Andricdef IMUL32rmi8 : IMulOpMI8_R<Xi32, WriteIMul32Imm>, DefEFLAGS, OpSize32; 3051db9f3b2SDimitry Andricdef IMUL64rmi8 : IMulOpMI8_R<Xi64, WriteIMul64Imm>, DefEFLAGS; 3061db9f3b2SDimitry Andricdef IMUL16rmi : IMulOpMI_RF<Xi16, WriteIMul16Imm>, OpSize16; 3071db9f3b2SDimitry Andricdef IMUL32rmi : IMulOpMI_RF<Xi32, WriteIMul32Imm>, OpSize32; 3081db9f3b2SDimitry Andricdef IMUL64rmi32 : IMulOpMI_RF<Xi64, WriteIMul64Imm>; 30906c3fb27SDimitry Andric 3101db9f3b2SDimitry Andriclet Predicates = [In64BitMode] in { 3111db9f3b2SDimitry Andric def IMUL16rri8_NF : IMulOpRI8_R<Xi16, WriteIMul16Imm>, NF, PD; 3121db9f3b2SDimitry Andric def IMUL32rri8_NF : IMulOpRI8_R<Xi32, WriteIMul32Imm>, NF; 3131db9f3b2SDimitry Andric def IMUL64rri8_NF : IMulOpRI8_R<Xi64, WriteIMul64Imm>, NF; 3141db9f3b2SDimitry Andric def IMUL16rri_NF : IMulOpRI_R<Xi16, WriteIMul16Imm>, NF, PD; 3151db9f3b2SDimitry Andric def IMUL32rri_NF : IMulOpRI_R<Xi32, WriteIMul32Imm>, NF; 3161db9f3b2SDimitry Andric def IMUL64rri32_NF : IMulOpRI_R<Xi64, WriteIMul64Imm>, NF; 3171db9f3b2SDimitry Andric def IMUL16rmi8_NF : IMulOpMI8_R<Xi16, WriteIMul16Imm>, NF, PD; 3181db9f3b2SDimitry Andric def IMUL32rmi8_NF : IMulOpMI8_R<Xi32, WriteIMul32Imm>, NF; 3191db9f3b2SDimitry Andric def IMUL64rmi8_NF : IMulOpMI8_R<Xi64, WriteIMul64Imm>, NF; 3201db9f3b2SDimitry Andric def IMUL16rmi_NF : IMulOpMI_R<Xi16, WriteIMul16Imm>, NF, PD; 3211db9f3b2SDimitry Andric def IMUL32rmi_NF : IMulOpMI_R<Xi32, WriteIMul32Imm>, NF; 3221db9f3b2SDimitry Andric def IMUL64rmi32_NF : IMulOpMI_R<Xi64, WriteIMul64Imm>, NF; 32306c3fb27SDimitry Andric 3241db9f3b2SDimitry Andric def IMUL16rri8_EVEX : IMulOpRI8_R<Xi16, WriteIMul16Imm>, DefEFLAGS, PL, PD; 3251db9f3b2SDimitry Andric def IMUL32rri8_EVEX : IMulOpRI8_R<Xi32, WriteIMul32Imm>, DefEFLAGS, PL; 3261db9f3b2SDimitry Andric def IMUL64rri8_EVEX : IMulOpRI8_R<Xi64, WriteIMul64Imm>, DefEFLAGS, PL; 3271db9f3b2SDimitry Andric def IMUL16rri_EVEX : IMulOpRI_RF<Xi16, WriteIMul16Imm>, PL, PD; 3281db9f3b2SDimitry Andric def IMUL32rri_EVEX : IMulOpRI_RF<Xi32, WriteIMul32Imm>, PL; 3291db9f3b2SDimitry Andric def IMUL64rri32_EVEX : IMulOpRI_RF<Xi64, WriteIMul64Imm>, PL; 3301db9f3b2SDimitry Andric def IMUL16rmi8_EVEX : IMulOpMI8_R<Xi16, WriteIMul16Imm>, DefEFLAGS, PL, PD; 3311db9f3b2SDimitry Andric def IMUL32rmi8_EVEX : IMulOpMI8_R<Xi32, WriteIMul32Imm>, DefEFLAGS, PL; 3321db9f3b2SDimitry Andric def IMUL64rmi8_EVEX : IMulOpMI8_R<Xi64, WriteIMul64Imm>, DefEFLAGS, PL; 3331db9f3b2SDimitry Andric def IMUL16rmi_EVEX : IMulOpMI_RF<Xi16, WriteIMul16Imm>, PL, PD; 3341db9f3b2SDimitry Andric def IMUL32rmi_EVEX : IMulOpMI_RF<Xi32, WriteIMul32Imm>, PL; 3351db9f3b2SDimitry Andric def IMUL64rmi32_EVEX : IMulOpMI_RF<Xi64, WriteIMul64Imm>, PL; 3361db9f3b2SDimitry Andric} 337*0fca6ea1SDimitry Andric 338*0fca6ea1SDimitry Andric// IMULZU instructions 339*0fca6ea1SDimitry Andricclass IMulZUOpRI8_R<X86TypeInfo t, X86FoldableSchedWrite sched> 340*0fca6ea1SDimitry Andric : BinOpRI8<0x6B, "imulzu", binop_ndd_args, t, MRMSrcReg, 341*0fca6ea1SDimitry Andric (outs t.RegClass:$dst)> { 342*0fca6ea1SDimitry Andric let SchedRW = [sched]; 343*0fca6ea1SDimitry Andric} 344*0fca6ea1SDimitry Andricclass IMulZUOpRI_R<X86TypeInfo t, X86FoldableSchedWrite sched> 345*0fca6ea1SDimitry Andric : BinOpRI<0x69, "imulzu", binop_ndd_args, t, MRMSrcReg, 346*0fca6ea1SDimitry Andric (outs t.RegClass:$dst), []> { 347*0fca6ea1SDimitry Andric let SchedRW = [sched]; 348*0fca6ea1SDimitry Andric} 349*0fca6ea1SDimitry Andricclass IMulZUOpMI8_R<X86TypeInfo t, X86FoldableSchedWrite sched> 350*0fca6ea1SDimitry Andric : BinOpMI8<"imulzu", binop_ndd_args, t, MRMSrcMem, (outs t.RegClass:$dst)> { 351*0fca6ea1SDimitry Andric let Opcode = 0x6B; 352*0fca6ea1SDimitry Andric let SchedRW = [sched.Folded]; 353*0fca6ea1SDimitry Andric} 354*0fca6ea1SDimitry Andricclass IMulZUOpMI_R<X86TypeInfo t, X86FoldableSchedWrite sched> 355*0fca6ea1SDimitry Andric : BinOpMI<0x69, "imulzu", binop_ndd_args, t, MRMSrcMem, 356*0fca6ea1SDimitry Andric (outs t.RegClass:$dst), []> { 357*0fca6ea1SDimitry Andric let SchedRW = [sched.Folded]; 358*0fca6ea1SDimitry Andric} 359*0fca6ea1SDimitry Andric 360*0fca6ea1SDimitry Andriclet Defs = [EFLAGS], Predicates = [HasEGPR, In64BitMode] in { 361*0fca6ea1SDimitry Andric def IMULZU16rri8 : IMulZUOpRI8_R<Xi16, WriteIMul16Imm>, ZU, PD; 362*0fca6ea1SDimitry Andric def IMULZU16rmi8 : IMulZUOpMI8_R<Xi16, WriteIMul16Imm>, ZU, PD; 363*0fca6ea1SDimitry Andric def IMULZU16rri : IMulZUOpRI_R<Xi16, WriteIMul16Imm>, ZU, PD; 364*0fca6ea1SDimitry Andric def IMULZU16rmi : IMulZUOpMI_R<Xi16, WriteIMul16Imm>, ZU, PD; 365*0fca6ea1SDimitry Andric def IMULZU32rri8 : IMulZUOpRI8_R<Xi32, WriteIMul32Imm>, ZU; 366*0fca6ea1SDimitry Andric def IMULZU32rmi8 : IMulZUOpMI8_R<Xi32, WriteIMul32Imm>, ZU; 367*0fca6ea1SDimitry Andric def IMULZU32rri : IMulZUOpRI_R<Xi32, WriteIMul32Imm>, ZU; 368*0fca6ea1SDimitry Andric def IMULZU32rmi : IMulZUOpMI_R<Xi32, WriteIMul32Imm>, ZU; 369*0fca6ea1SDimitry Andric def IMULZU64rri8 : IMulZUOpRI8_R<Xi64, WriteIMul64Imm>, ZU; 370*0fca6ea1SDimitry Andric def IMULZU64rmi8 : IMulZUOpMI8_R<Xi64, WriteIMul64Imm>, ZU; 371*0fca6ea1SDimitry Andric def IMULZU64rri32 : IMulZUOpRI_R<Xi64, WriteIMul64Imm>, ZU; 372*0fca6ea1SDimitry Andric def IMULZU64rmi32 : IMulZUOpMI_R<Xi64, WriteIMul64Imm>, ZU; 373*0fca6ea1SDimitry Andric} 374*0fca6ea1SDimitry Andric 375647cbc5dSDimitry Andric//===----------------------------------------------------------------------===// 376647cbc5dSDimitry Andric// INC and DEC Instructions 377647cbc5dSDimitry Andric// 3781db9f3b2SDimitry Andricclass IncOpR_RF<X86TypeInfo t, bit ndd = 0> : UnaryOpR_RF<0xFF, MRM0r, "inc", t, null_frag, ndd> { 379647cbc5dSDimitry Andric let Pattern = [(set t.RegClass:$dst, EFLAGS, 380647cbc5dSDimitry Andric (X86add_flag_nocf t.RegClass:$src1, 1))]; 381cb14a3feSDimitry Andric} 3821db9f3b2SDimitry Andricclass DecOpR_RF<X86TypeInfo t, bit ndd = 0> : UnaryOpR_RF<0xFF, MRM1r, "dec", t, null_frag, ndd> { 383647cbc5dSDimitry Andric let Pattern = [(set t.RegClass:$dst, EFLAGS, 384647cbc5dSDimitry Andric (X86sub_flag_nocf t.RegClass:$src1, 1))]; 385647cbc5dSDimitry Andric} 3861db9f3b2SDimitry Andricclass IncOpR_R<X86TypeInfo t, bit ndd = 0> : UnaryOpR_R<0xFF, MRM0r, "inc", t, null_frag, ndd>; 3871db9f3b2SDimitry Andricclass DecOpR_R<X86TypeInfo t, bit ndd = 0> : UnaryOpR_R<0xFF, MRM1r, "dec", t, null_frag, ndd>; 3881db9f3b2SDimitry Andricclass IncOpM_MF<X86TypeInfo t> : UnaryOpM_MF<0xFF, MRM0m, "inc", t, null_frag> { 389647cbc5dSDimitry Andric let Pattern = [(store (add (t.LoadNode addr:$src1), 1), addr:$src1), 390647cbc5dSDimitry Andric (implicit EFLAGS)]; 391647cbc5dSDimitry Andric} 3921db9f3b2SDimitry Andricclass DecOpM_MF<X86TypeInfo t> : UnaryOpM_MF<0xFF, MRM1m, "dec", t, null_frag> { 393647cbc5dSDimitry Andric let Pattern = [(store (add (t.LoadNode addr:$src1), -1), addr:$src1), 394647cbc5dSDimitry Andric (implicit EFLAGS)]; 395647cbc5dSDimitry Andric} 3961db9f3b2SDimitry Andricclass IncOpM_RF<X86TypeInfo t> : UnaryOpM_RF<0xFF, MRM0m, "inc", t, null_frag> { 3971db9f3b2SDimitry Andric let Pattern = [(set t.RegClass:$dst, EFLAGS, (add (t.LoadNode addr:$src1), 1))]; 3981db9f3b2SDimitry Andric} 3991db9f3b2SDimitry Andricclass DecOpM_RF<X86TypeInfo t> : UnaryOpM_RF<0xFF, MRM1m, "dec", t, null_frag> { 4001db9f3b2SDimitry Andric let Pattern = [(set t.RegClass:$dst, EFLAGS, (add (t.LoadNode addr:$src1), -1))]; 4011db9f3b2SDimitry Andric} 4021db9f3b2SDimitry Andricclass IncOpM_M<X86TypeInfo t> : UnaryOpM_M<0xFF, MRM0m, "inc", t, null_frag>; 4031db9f3b2SDimitry Andricclass DecOpM_M<X86TypeInfo t> : UnaryOpM_M<0xFF, MRM1m, "dec", t, null_frag>; 4041db9f3b2SDimitry Andricclass IncOpM_R<X86TypeInfo t> : UnaryOpM_R<0xFF, MRM0m, "inc", t, null_frag>; 4051db9f3b2SDimitry Andricclass DecOpM_R<X86TypeInfo t> : UnaryOpM_R<0xFF, MRM1m, "dec", t, null_frag>; 4061db9f3b2SDimitry Andric 407647cbc5dSDimitry Andric// IncDec_Alt - Instructions like "inc reg" short forms. 408647cbc5dSDimitry Andric// Short forms only valid in 32-bit mode. Selected during MCInst lowering. 409647cbc5dSDimitry Andricclass IncDec_Alt<bits<8> o, string m, X86TypeInfo t> 410647cbc5dSDimitry Andric : UnaryOpR_RF<o, AddRegFrm, m, t, null_frag>, Requires<[Not64BitMode]>; 411cb14a3feSDimitry Andric 412647cbc5dSDimitry Andriclet isConvertibleToThreeAddress = 1 in { 413647cbc5dSDimitry Andric def INC16r_alt : IncDec_Alt<0x40, "inc", Xi16>, OpSize16; 414647cbc5dSDimitry Andric def INC32r_alt : IncDec_Alt<0x40, "inc", Xi32>, OpSize32; 415647cbc5dSDimitry Andric def DEC16r_alt : IncDec_Alt<0x48, "dec", Xi16>, OpSize16; 416647cbc5dSDimitry Andric def DEC32r_alt : IncDec_Alt<0x48, "dec", Xi32>, OpSize32; 4171db9f3b2SDimitry Andric let Predicates = [NoNDD] in { 418647cbc5dSDimitry Andric def INC8r : IncOpR_RF<Xi8>; 419647cbc5dSDimitry Andric def INC16r : IncOpR_RF<Xi16>, OpSize16; 420647cbc5dSDimitry Andric def INC32r : IncOpR_RF<Xi32>, OpSize32; 421647cbc5dSDimitry Andric def INC64r : IncOpR_RF<Xi64>; 422647cbc5dSDimitry Andric def DEC8r : DecOpR_RF<Xi8>; 423647cbc5dSDimitry Andric def DEC16r : DecOpR_RF<Xi16>, OpSize16; 424647cbc5dSDimitry Andric def DEC32r : DecOpR_RF<Xi32>, OpSize32; 425647cbc5dSDimitry Andric def DEC64r : DecOpR_RF<Xi64>; 426647cbc5dSDimitry Andric } 4271db9f3b2SDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 4281db9f3b2SDimitry Andric def INC8r_ND : IncOpR_RF<Xi8, 1>; 4291db9f3b2SDimitry Andric def INC16r_ND : IncOpR_RF<Xi16, 1>, PD; 4301db9f3b2SDimitry Andric def INC32r_ND : IncOpR_RF<Xi32, 1>; 4311db9f3b2SDimitry Andric def INC64r_ND : IncOpR_RF<Xi64, 1>; 4321db9f3b2SDimitry Andric def DEC8r_ND : DecOpR_RF<Xi8, 1>; 4331db9f3b2SDimitry Andric def DEC16r_ND : DecOpR_RF<Xi16, 1>, PD; 4341db9f3b2SDimitry Andric def DEC32r_ND : DecOpR_RF<Xi32, 1>; 4351db9f3b2SDimitry Andric def DEC64r_ND : DecOpR_RF<Xi64, 1>; 4361db9f3b2SDimitry Andric } 4371db9f3b2SDimitry Andric let Predicates = [In64BitMode], Pattern = [(null_frag)] in { 4381db9f3b2SDimitry Andric def INC8r_NF : IncOpR_R<Xi8>, NF; 4391db9f3b2SDimitry Andric def INC16r_NF : IncOpR_R<Xi16>, NF, PD; 4401db9f3b2SDimitry Andric def INC32r_NF : IncOpR_R<Xi32>, NF; 4411db9f3b2SDimitry Andric def INC64r_NF : IncOpR_R<Xi64>, NF; 4421db9f3b2SDimitry Andric def DEC8r_NF : DecOpR_R<Xi8>, NF; 4431db9f3b2SDimitry Andric def DEC16r_NF : DecOpR_R<Xi16>, NF, PD; 4441db9f3b2SDimitry Andric def DEC32r_NF : DecOpR_R<Xi32>, NF; 4451db9f3b2SDimitry Andric def DEC64r_NF : DecOpR_R<Xi64>, NF; 4461db9f3b2SDimitry Andric def INC8r_NF_ND : IncOpR_R<Xi8, 1>, NF; 4471db9f3b2SDimitry Andric def INC16r_NF_ND : IncOpR_R<Xi16, 1>, NF, PD; 4481db9f3b2SDimitry Andric def INC32r_NF_ND : IncOpR_R<Xi32, 1>, NF; 4491db9f3b2SDimitry Andric def INC64r_NF_ND : IncOpR_R<Xi64, 1>, NF; 4501db9f3b2SDimitry Andric def DEC8r_NF_ND : DecOpR_R<Xi8, 1>, NF; 4511db9f3b2SDimitry Andric def DEC16r_NF_ND : DecOpR_R<Xi16, 1>, NF, PD; 4521db9f3b2SDimitry Andric def DEC32r_NF_ND : DecOpR_R<Xi32, 1>, NF; 4531db9f3b2SDimitry Andric def DEC64r_NF_ND : DecOpR_R<Xi64, 1>, NF; 4541db9f3b2SDimitry Andric def INC8r_EVEX : IncOpR_RF<Xi8>, PL; 4551db9f3b2SDimitry Andric def INC16r_EVEX : IncOpR_RF<Xi16>, PL, PD; 4561db9f3b2SDimitry Andric def INC32r_EVEX : IncOpR_RF<Xi32>, PL; 4571db9f3b2SDimitry Andric def INC64r_EVEX : IncOpR_RF<Xi64>, PL; 4581db9f3b2SDimitry Andric def DEC8r_EVEX : DecOpR_RF<Xi8>, PL; 4591db9f3b2SDimitry Andric def DEC16r_EVEX : DecOpR_RF<Xi16>, PL, PD; 4601db9f3b2SDimitry Andric def DEC32r_EVEX : DecOpR_RF<Xi32>, PL; 4611db9f3b2SDimitry Andric def DEC64r_EVEX : DecOpR_RF<Xi64>, PL; 4621db9f3b2SDimitry Andric } 4631db9f3b2SDimitry Andric} 46406c3fb27SDimitry Andriclet Predicates = [UseIncDec] in { 4651db9f3b2SDimitry Andric def INC8m : IncOpM_MF<Xi8>; 4661db9f3b2SDimitry Andric def INC16m : IncOpM_MF<Xi16>, OpSize16; 4671db9f3b2SDimitry Andric def INC32m : IncOpM_MF<Xi32>, OpSize32; 4681db9f3b2SDimitry Andric def DEC8m : DecOpM_MF<Xi8>; 4691db9f3b2SDimitry Andric def DEC16m : DecOpM_MF<Xi16>, OpSize16; 4701db9f3b2SDimitry Andric def DEC32m : DecOpM_MF<Xi32>, OpSize32; 471cb14a3feSDimitry Andric} 47206c3fb27SDimitry Andriclet Predicates = [UseIncDec, In64BitMode] in { 4731db9f3b2SDimitry Andric def INC64m : IncOpM_MF<Xi64>; 4741db9f3b2SDimitry Andric def DEC64m : DecOpM_MF<Xi64>; 4751db9f3b2SDimitry Andric} 4761db9f3b2SDimitry Andriclet Predicates = [HasNDD, In64BitMode, UseIncDec] in { 4771db9f3b2SDimitry Andric def INC8m_ND : IncOpM_RF<Xi8>; 4781db9f3b2SDimitry Andric def INC16m_ND : IncOpM_RF<Xi16>, PD; 4791db9f3b2SDimitry Andric def INC32m_ND : IncOpM_RF<Xi32>; 4801db9f3b2SDimitry Andric def DEC8m_ND : DecOpM_RF<Xi8>; 4811db9f3b2SDimitry Andric def DEC16m_ND : DecOpM_RF<Xi16>, PD; 4821db9f3b2SDimitry Andric def DEC32m_ND : DecOpM_RF<Xi32>; 4831db9f3b2SDimitry Andric def INC64m_ND : IncOpM_RF<Xi64>; 4841db9f3b2SDimitry Andric def DEC64m_ND : DecOpM_RF<Xi64>; 4851db9f3b2SDimitry Andric} 4861db9f3b2SDimitry Andriclet Predicates = [In64BitMode], Pattern = [(null_frag)] in { 4871db9f3b2SDimitry Andric def INC8m_NF : IncOpM_M<Xi8>, NF; 4881db9f3b2SDimitry Andric def INC16m_NF : IncOpM_M<Xi16>, NF, PD; 4891db9f3b2SDimitry Andric def INC32m_NF : IncOpM_M<Xi32>, NF; 4901db9f3b2SDimitry Andric def INC64m_NF : IncOpM_M<Xi64>, NF; 4911db9f3b2SDimitry Andric def DEC8m_NF : DecOpM_M<Xi8>, NF; 4921db9f3b2SDimitry Andric def DEC16m_NF : DecOpM_M<Xi16>, NF, PD; 4931db9f3b2SDimitry Andric def DEC32m_NF : DecOpM_M<Xi32>, NF; 4941db9f3b2SDimitry Andric def DEC64m_NF : DecOpM_M<Xi64>, NF; 4951db9f3b2SDimitry Andric def INC8m_NF_ND : IncOpM_R<Xi8>, NF; 4961db9f3b2SDimitry Andric def INC16m_NF_ND : IncOpM_R<Xi16>, NF, PD; 4971db9f3b2SDimitry Andric def INC32m_NF_ND : IncOpM_R<Xi32>, NF; 4981db9f3b2SDimitry Andric def INC64m_NF_ND : IncOpM_R<Xi64>, NF; 4991db9f3b2SDimitry Andric def DEC8m_NF_ND : DecOpM_R<Xi8>, NF; 5001db9f3b2SDimitry Andric def DEC16m_NF_ND : DecOpM_R<Xi16>, NF, PD; 5011db9f3b2SDimitry Andric def DEC32m_NF_ND : DecOpM_R<Xi32>, NF; 5021db9f3b2SDimitry Andric def DEC64m_NF_ND : DecOpM_R<Xi64>, NF; 5031db9f3b2SDimitry Andric def INC8m_EVEX : IncOpM_MF<Xi8>, PL; 5041db9f3b2SDimitry Andric def INC16m_EVEX : IncOpM_MF<Xi16>, PL, PD; 5051db9f3b2SDimitry Andric def INC32m_EVEX : IncOpM_MF<Xi32>, PL; 5061db9f3b2SDimitry Andric def INC64m_EVEX : IncOpM_MF<Xi64>, PL; 5071db9f3b2SDimitry Andric def DEC8m_EVEX : DecOpM_MF<Xi8>, PL; 5081db9f3b2SDimitry Andric def DEC16m_EVEX : DecOpM_MF<Xi16>, PL, PD; 5091db9f3b2SDimitry Andric def DEC32m_EVEX : DecOpM_MF<Xi32>, PL; 5101db9f3b2SDimitry Andric def DEC64m_EVEX : DecOpM_MF<Xi64>, PL; 511cb14a3feSDimitry Andric} 51206c3fb27SDimitry Andric 513647cbc5dSDimitry Andric//===----------------------------------------------------------------------===// 514647cbc5dSDimitry Andric// NEG and NOT Instructions 515647cbc5dSDimitry Andric// 516647cbc5dSDimitry Andricclass NegOpR_R<X86TypeInfo t, bit ndd = 0> 517647cbc5dSDimitry Andric : UnaryOpR_R<0xF7, MRM3r, "neg", t, ineg, ndd>; 518647cbc5dSDimitry Andricclass NegOpR_RF<X86TypeInfo t, bit ndd = 0> 519647cbc5dSDimitry Andric : UnaryOpR_RF<0xF7, MRM3r, "neg", t, ineg, ndd>; 520647cbc5dSDimitry Andricclass NegOpM_M<X86TypeInfo t> : UnaryOpM_M<0xF7, MRM3m, "neg", t, null_frag>; 521647cbc5dSDimitry Andricclass NegOpM_MF<X86TypeInfo t> : UnaryOpM_MF<0xF7, MRM3m, "neg", t, ineg>; 522647cbc5dSDimitry Andricclass NegOpM_R<X86TypeInfo t> : UnaryOpM_R<0xF7, MRM3m, "neg", t, null_frag>; 523647cbc5dSDimitry Andricclass NegOpM_RF<X86TypeInfo t> : UnaryOpM_RF<0xF7, MRM3m, "neg", t, ineg>; 52406c3fb27SDimitry Andric 525647cbc5dSDimitry Andricclass NotOpR_R<X86TypeInfo t, bit ndd = 0> 526647cbc5dSDimitry Andric : UnaryOpR_R<0xF7, MRM2r, "not", t, not, ndd>; 527647cbc5dSDimitry Andricclass NotOpM_M<X86TypeInfo t> : UnaryOpM_M<0xF7, MRM2m, "not", t, not>; 528647cbc5dSDimitry Andricclass NotOpM_R<X86TypeInfo t> : UnaryOpM_R<0xF7, MRM2m, "not", t, not>; 52906c3fb27SDimitry Andric 530647cbc5dSDimitry Andriclet Predicates = [NoNDD] in { 531647cbc5dSDimitry Andricdef NEG8r : NegOpR_RF<Xi8>; 532647cbc5dSDimitry Andricdef NEG16r : NegOpR_RF<Xi16>, OpSize16; 533647cbc5dSDimitry Andricdef NEG32r : NegOpR_RF<Xi32>, OpSize32; 534647cbc5dSDimitry Andricdef NEG64r : NegOpR_RF<Xi64>; 535647cbc5dSDimitry Andricdef NOT8r : NotOpR_R<Xi8>; 536647cbc5dSDimitry Andricdef NOT16r : NotOpR_R<Xi16>, OpSize16; 537647cbc5dSDimitry Andricdef NOT32r : NotOpR_R<Xi32>, OpSize32; 538647cbc5dSDimitry Andricdef NOT64r : NotOpR_R<Xi64>; 539cb14a3feSDimitry Andric} 54006c3fb27SDimitry Andric 541647cbc5dSDimitry Andriclet Predicates = [HasNDD, In64BitMode] in { 542647cbc5dSDimitry Andricdef NEG8r_ND : NegOpR_RF<Xi8, 1>; 543647cbc5dSDimitry Andricdef NEG16r_ND : NegOpR_RF<Xi16, 1>, PD; 544647cbc5dSDimitry Andricdef NEG32r_ND : NegOpR_RF<Xi32, 1>; 545647cbc5dSDimitry Andricdef NEG64r_ND : NegOpR_RF<Xi64, 1>; 54606c3fb27SDimitry Andric 547647cbc5dSDimitry Andricdef NOT8r_ND : NotOpR_R<Xi8, 1>; 548647cbc5dSDimitry Andricdef NOT16r_ND : NotOpR_R<Xi16, 1>, PD; 549647cbc5dSDimitry Andricdef NOT32r_ND : NotOpR_R<Xi32, 1>; 550647cbc5dSDimitry Andricdef NOT64r_ND : NotOpR_R<Xi64, 1>; 55106c3fb27SDimitry Andric 552647cbc5dSDimitry Andricdef NEG8r_NF_ND : NegOpR_R<Xi8, 1>, EVEX_NF; 553647cbc5dSDimitry Andricdef NEG16r_NF_ND : NegOpR_R<Xi16, 1>, EVEX_NF, PD; 554647cbc5dSDimitry Andricdef NEG32r_NF_ND : NegOpR_R<Xi32, 1>, EVEX_NF; 555647cbc5dSDimitry Andricdef NEG64r_NF_ND : NegOpR_R<Xi64, 1>, EVEX_NF; 55606c3fb27SDimitry Andric} 55706c3fb27SDimitry Andric 558647cbc5dSDimitry Andricdef NEG8m : NegOpM_MF<Xi8>; 559647cbc5dSDimitry Andricdef NEG16m : NegOpM_MF<Xi16>, OpSize16; 560647cbc5dSDimitry Andricdef NEG32m : NegOpM_MF<Xi32>, OpSize32; 561647cbc5dSDimitry Andricdef NEG64m : NegOpM_MF<Xi64>, Requires<[In64BitMode]>; 56206c3fb27SDimitry Andric 563647cbc5dSDimitry Andriclet Predicates = [HasNDD, In64BitMode] in { 564647cbc5dSDimitry Andricdef NEG8m_ND : NegOpM_RF<Xi8>; 565647cbc5dSDimitry Andricdef NEG16m_ND : NegOpM_RF<Xi16>, PD; 566647cbc5dSDimitry Andricdef NEG32m_ND : NegOpM_RF<Xi32>; 567647cbc5dSDimitry Andricdef NEG64m_ND : NegOpM_RF<Xi64>; 56806c3fb27SDimitry Andric 569647cbc5dSDimitry Andricdef NEG8m_NF_ND : NegOpM_R<Xi8>, EVEX_NF; 570647cbc5dSDimitry Andricdef NEG16m_NF_ND : NegOpM_R<Xi16>, EVEX_NF, PD; 571647cbc5dSDimitry Andricdef NEG32m_NF_ND : NegOpM_R<Xi32>, EVEX_NF; 572647cbc5dSDimitry Andricdef NEG64m_NF_ND : NegOpM_R<Xi64>, EVEX_NF; 573cb14a3feSDimitry Andric} 57406c3fb27SDimitry Andric 575647cbc5dSDimitry Andricdef NOT8m : NotOpM_M<Xi8>; 576647cbc5dSDimitry Andricdef NOT16m : NotOpM_M<Xi16>, OpSize16; 577647cbc5dSDimitry Andricdef NOT32m : NotOpM_M<Xi32>, OpSize32; 578647cbc5dSDimitry Andricdef NOT64m : NotOpM_M<Xi64>, Requires<[In64BitMode]>; 57906c3fb27SDimitry Andric 580647cbc5dSDimitry Andriclet Predicates = [HasNDD, In64BitMode] in { 581647cbc5dSDimitry Andricdef NOT8m_ND : NotOpM_R<Xi8>; 582647cbc5dSDimitry Andricdef NOT16m_ND : NotOpM_R<Xi16>, PD; 583647cbc5dSDimitry Andricdef NOT32m_ND : NotOpM_R<Xi32>; 584647cbc5dSDimitry Andricdef NOT64m_ND : NotOpM_R<Xi64>; 585cb14a3feSDimitry Andric} 58606c3fb27SDimitry Andric 587647cbc5dSDimitry Andriclet Predicates = [In64BitMode], Pattern = [(null_frag)] in { 588647cbc5dSDimitry Andricdef NEG8r_NF : NegOpR_R<Xi8>, NF; 589647cbc5dSDimitry Andricdef NEG16r_NF : NegOpR_R<Xi16>, NF, PD; 590647cbc5dSDimitry Andricdef NEG32r_NF : NegOpR_R<Xi32>, NF; 591647cbc5dSDimitry Andricdef NEG64r_NF : NegOpR_R<Xi64>, NF; 592647cbc5dSDimitry Andricdef NEG8m_NF : NegOpM_M<Xi8>, NF; 593647cbc5dSDimitry Andricdef NEG16m_NF : NegOpM_M<Xi16>, NF, PD; 594647cbc5dSDimitry Andricdef NEG32m_NF : NegOpM_M<Xi32>, NF; 595647cbc5dSDimitry Andricdef NEG64m_NF : NegOpM_M<Xi64>, NF; 596647cbc5dSDimitry Andric 597647cbc5dSDimitry Andricdef NEG8r_EVEX : NegOpR_RF<Xi8>, PL; 598647cbc5dSDimitry Andricdef NEG16r_EVEX : NegOpR_RF<Xi16>, PL, PD; 599647cbc5dSDimitry Andricdef NEG32r_EVEX : NegOpR_RF<Xi32>, PL; 600647cbc5dSDimitry Andricdef NEG64r_EVEX : NegOpR_RF<Xi64>, PL; 601647cbc5dSDimitry Andric 602647cbc5dSDimitry Andricdef NOT8r_EVEX : NotOpR_R<Xi8>, PL; 603647cbc5dSDimitry Andricdef NOT16r_EVEX : NotOpR_R<Xi16>, PL, PD; 604647cbc5dSDimitry Andricdef NOT32r_EVEX : NotOpR_R<Xi32>, PL; 605647cbc5dSDimitry Andricdef NOT64r_EVEX : NotOpR_R<Xi64>, PL; 606647cbc5dSDimitry Andric 607647cbc5dSDimitry Andricdef NEG8m_EVEX : NegOpM_MF<Xi8>, PL; 608647cbc5dSDimitry Andricdef NEG16m_EVEX : NegOpM_MF<Xi16>, PL, PD; 609647cbc5dSDimitry Andricdef NEG32m_EVEX : NegOpM_MF<Xi32>, PL; 610647cbc5dSDimitry Andricdef NEG64m_EVEX : NegOpM_MF<Xi64>, PL; 611647cbc5dSDimitry Andric 612647cbc5dSDimitry Andricdef NOT8m_EVEX : NotOpM_M<Xi8>, PL; 613647cbc5dSDimitry Andricdef NOT16m_EVEX : NotOpM_M<Xi16>, PL, PD; 614647cbc5dSDimitry Andricdef NOT32m_EVEX : NotOpM_M<Xi32>, PL; 615647cbc5dSDimitry Andricdef NOT64m_EVEX : NotOpM_M<Xi64>, PL; 616647cbc5dSDimitry Andric} 61706c3fb27SDimitry Andric 6180b57cec5SDimitry Andric/// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is 6190b57cec5SDimitry Andric/// defined with "(set GPR:$dst, EFLAGS, (...". 6200b57cec5SDimitry Andric/// 6210b57cec5SDimitry Andric/// It would be nice to get rid of the second and third argument here, but 6220b57cec5SDimitry Andric/// tblgen can't handle dependent type references aggressively enough: PR8330 6230b57cec5SDimitry Andricmulticlass ArithBinOp_RF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, 6240b57cec5SDimitry Andric string mnemonic, Format RegMRM, Format MemMRM, 6250b57cec5SDimitry Andric SDNode opnodeflag, SDNode opnode, 6260b57cec5SDimitry Andric bit CommutableRR, bit ConvertibleToThreeAddress, 6270b57cec5SDimitry Andric bit ConvertibleToThreeAddressRR> { 628cb14a3feSDimitry Andric let isCommutable = CommutableRR, 629cb14a3feSDimitry Andric isConvertibleToThreeAddress = ConvertibleToThreeAddressRR in { 630647cbc5dSDimitry Andric let Predicates = [NoNDD] in { 6311db9f3b2SDimitry Andric def 8rr : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , opnodeflag>; 6321db9f3b2SDimitry Andric def 16rr : BinOpRR_RF<BaseOpc, mnemonic, Xi16, opnodeflag>, OpSize16; 6331db9f3b2SDimitry Andric def 32rr : BinOpRR_RF<BaseOpc, mnemonic, Xi32, opnodeflag>, OpSize32; 6341db9f3b2SDimitry Andric def 64rr : BinOpRR_RF<BaseOpc, mnemonic, Xi64, opnodeflag>; 635cb14a3feSDimitry Andric } 636647cbc5dSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 6371db9f3b2SDimitry Andric def 8rr_ND : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , opnodeflag, 1>; 6381db9f3b2SDimitry Andric def 16rr_ND : BinOpRR_RF<BaseOpc, mnemonic, Xi16, opnodeflag, 1>, PD; 6391db9f3b2SDimitry Andric def 32rr_ND : BinOpRR_RF<BaseOpc, mnemonic, Xi32, opnodeflag, 1>; 6401db9f3b2SDimitry Andric def 64rr_ND : BinOpRR_RF<BaseOpc, mnemonic, Xi64, opnodeflag, 1>; 6411db9f3b2SDimitry Andric def 8rr_NF_ND : BinOpRR_R<BaseOpc, mnemonic, Xi8, 1>, EVEX_NF; 6421db9f3b2SDimitry Andric def 16rr_NF_ND : BinOpRR_R<BaseOpc, mnemonic, Xi16, 1>, EVEX_NF, PD; 6431db9f3b2SDimitry Andric def 32rr_NF_ND : BinOpRR_R<BaseOpc, mnemonic, Xi32, 1>, EVEX_NF; 6441db9f3b2SDimitry Andric def 64rr_NF_ND : BinOpRR_R<BaseOpc, mnemonic, Xi64, 1>, EVEX_NF; 645647cbc5dSDimitry Andric } 646647cbc5dSDimitry Andric let Predicates = [In64BitMode] in { 6471db9f3b2SDimitry Andric def 8rr_NF : BinOpRR_R<BaseOpc, mnemonic, Xi8>, NF; 6481db9f3b2SDimitry Andric def 16rr_NF : BinOpRR_R<BaseOpc, mnemonic, Xi16>, NF, PD; 6491db9f3b2SDimitry Andric def 32rr_NF : BinOpRR_R<BaseOpc, mnemonic, Xi32>, NF; 6501db9f3b2SDimitry Andric def 64rr_NF : BinOpRR_R<BaseOpc, mnemonic, Xi64>, NF; 6511db9f3b2SDimitry Andric def 8rr_EVEX : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , null_frag>, PL; 6521db9f3b2SDimitry Andric def 16rr_EVEX : BinOpRR_RF<BaseOpc, mnemonic, Xi16, null_frag>, PL, PD; 6531db9f3b2SDimitry Andric def 32rr_EVEX : BinOpRR_RF<BaseOpc, mnemonic, Xi32, null_frag>, PL; 6541db9f3b2SDimitry Andric def 64rr_EVEX : BinOpRR_RF<BaseOpc, mnemonic, Xi64, null_frag>, PL; 655647cbc5dSDimitry Andric } 656647cbc5dSDimitry Andric } 6570b57cec5SDimitry Andric 6581db9f3b2SDimitry Andric def 8rr_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi8>; 6591db9f3b2SDimitry Andric def 16rr_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi16>, OpSize16; 6601db9f3b2SDimitry Andric def 32rr_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi32>, OpSize32; 6611db9f3b2SDimitry Andric def 64rr_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi64>; 662647cbc5dSDimitry Andric let Predicates = [In64BitMode] in { 6631db9f3b2SDimitry Andric def 8rr_EVEX_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi8>, PL; 6641db9f3b2SDimitry Andric def 16rr_EVEX_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi16>, PL, PD; 6651db9f3b2SDimitry Andric def 32rr_EVEX_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi32>, PL; 6661db9f3b2SDimitry Andric def 64rr_EVEX_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi64>, PL; 6671db9f3b2SDimitry Andric def 8rr_ND_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi8, 1>; 6681db9f3b2SDimitry Andric def 16rr_ND_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi16, 1>, PD; 6691db9f3b2SDimitry Andric def 32rr_ND_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi32, 1>; 6701db9f3b2SDimitry Andric def 64rr_ND_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi64, 1>; 6711db9f3b2SDimitry Andric def 8rr_NF_REV : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi8>, NF; 6721db9f3b2SDimitry Andric def 16rr_NF_REV : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi16>, NF, PD; 6731db9f3b2SDimitry Andric def 32rr_NF_REV : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi32>, NF; 6741db9f3b2SDimitry Andric def 64rr_NF_REV : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi64>, NF; 6751db9f3b2SDimitry Andric def 8rr_NF_ND_REV : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi8, 1>, EVEX_NF; 6761db9f3b2SDimitry Andric def 16rr_NF_ND_REV : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi16, 1>, EVEX_NF, PD; 6771db9f3b2SDimitry Andric def 32rr_NF_ND_REV : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi32, 1>, EVEX_NF; 6781db9f3b2SDimitry Andric def 64rr_NF_ND_REV : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi64, 1>, EVEX_NF; 679647cbc5dSDimitry Andric } 6800b57cec5SDimitry Andric 681647cbc5dSDimitry Andric let Predicates = [NoNDD] in { 6821db9f3b2SDimitry Andric def 8rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , opnodeflag>; 6831db9f3b2SDimitry Andric def 16rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, opnodeflag>, OpSize16; 6841db9f3b2SDimitry Andric def 32rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, opnodeflag>, OpSize32; 6851db9f3b2SDimitry Andric def 64rm : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, opnodeflag>; 686647cbc5dSDimitry Andric } 687647cbc5dSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 6881db9f3b2SDimitry Andric def 8rm_ND : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , opnodeflag, 1>; 6891db9f3b2SDimitry Andric def 16rm_ND : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, opnodeflag, 1>, PD; 6901db9f3b2SDimitry Andric def 32rm_ND : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, opnodeflag, 1>; 6911db9f3b2SDimitry Andric def 64rm_ND : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, opnodeflag, 1>; 6921db9f3b2SDimitry Andric def 8rm_NF_ND : BinOpRM_R<BaseOpc2, mnemonic, Xi8, 1>, EVEX_NF; 6931db9f3b2SDimitry Andric def 16rm_NF_ND : BinOpRM_R<BaseOpc2, mnemonic, Xi16, 1>, EVEX_NF, PD; 6941db9f3b2SDimitry Andric def 32rm_NF_ND : BinOpRM_R<BaseOpc2, mnemonic, Xi32, 1>, EVEX_NF; 6951db9f3b2SDimitry Andric def 64rm_NF_ND : BinOpRM_R<BaseOpc2, mnemonic, Xi64, 1>, EVEX_NF; 696647cbc5dSDimitry Andric } 697647cbc5dSDimitry Andric let Predicates = [In64BitMode] in { 6981db9f3b2SDimitry Andric def 8rm_NF : BinOpRM_R<BaseOpc2, mnemonic, Xi8>, NF; 6991db9f3b2SDimitry Andric def 16rm_NF : BinOpRM_R<BaseOpc2, mnemonic, Xi16>, NF, PD; 7001db9f3b2SDimitry Andric def 32rm_NF : BinOpRM_R<BaseOpc2, mnemonic, Xi32>, NF; 7011db9f3b2SDimitry Andric def 64rm_NF : BinOpRM_R<BaseOpc2, mnemonic, Xi64>, NF; 7021db9f3b2SDimitry Andric def 8rm_EVEX : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , null_frag>, PL; 7031db9f3b2SDimitry Andric def 16rm_EVEX : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, null_frag>, PL, PD; 7041db9f3b2SDimitry Andric def 32rm_EVEX : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, null_frag>, PL; 7051db9f3b2SDimitry Andric def 64rm_EVEX : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, null_frag>, PL; 706647cbc5dSDimitry Andric } 7070b57cec5SDimitry Andric 708cb14a3feSDimitry Andric let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 709647cbc5dSDimitry Andric let Predicates = [NoNDD] in { 7100b57cec5SDimitry Andric // NOTE: These are order specific, we want the ri8 forms to be listed 7110b57cec5SDimitry Andric // first so that they are slightly preferred to the ri forms. 7121db9f3b2SDimitry Andric def 16ri8 : BinOpRI8_RF<0x83, mnemonic, Xi16, RegMRM>, OpSize16; 7131db9f3b2SDimitry Andric def 32ri8 : BinOpRI8_RF<0x83, mnemonic, Xi32, RegMRM>, OpSize32; 7141db9f3b2SDimitry Andric def 64ri8 : BinOpRI8_RF<0x83, mnemonic, Xi64, RegMRM>; 7151db9f3b2SDimitry Andric def 8ri : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM>; 7161db9f3b2SDimitry Andric def 16ri : BinOpRI_RF<0x81, mnemonic, Xi16, opnodeflag, RegMRM>, OpSize16; 7171db9f3b2SDimitry Andric def 32ri : BinOpRI_RF<0x81, mnemonic, Xi32, opnodeflag, RegMRM>, OpSize32; 7181db9f3b2SDimitry Andric def 64ri32: BinOpRI_RF<0x81, mnemonic, Xi64, opnodeflag, RegMRM>; 7190b57cec5SDimitry Andric } 720647cbc5dSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 7211db9f3b2SDimitry Andric def 16ri8_ND : BinOpRI8_RF<0x83, mnemonic, Xi16, RegMRM, 1>, PD; 7221db9f3b2SDimitry Andric def 32ri8_ND : BinOpRI8_RF<0x83, mnemonic, Xi32, RegMRM, 1>; 7231db9f3b2SDimitry Andric def 64ri8_ND : BinOpRI8_RF<0x83, mnemonic, Xi64, RegMRM, 1>; 7241db9f3b2SDimitry Andric def 8ri_ND : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM, 1>; 7251db9f3b2SDimitry Andric def 16ri_ND : BinOpRI_RF<0x81, mnemonic, Xi16, opnodeflag, RegMRM, 1>, PD; 7261db9f3b2SDimitry Andric def 32ri_ND : BinOpRI_RF<0x81, mnemonic, Xi32, opnodeflag, RegMRM, 1>; 7271db9f3b2SDimitry Andric def 64ri32_ND: BinOpRI_RF<0x81, mnemonic, Xi64, opnodeflag, RegMRM, 1>; 7281db9f3b2SDimitry Andric def 16ri8_NF_ND : BinOpRI8_R<0x83, mnemonic, Xi16, RegMRM, 1>, EVEX_NF, PD; 7291db9f3b2SDimitry Andric def 32ri8_NF_ND : BinOpRI8_R<0x83, mnemonic, Xi32, RegMRM, 1>, EVEX_NF; 7301db9f3b2SDimitry Andric def 64ri8_NF_ND : BinOpRI8_R<0x83, mnemonic, Xi64, RegMRM, 1>, EVEX_NF; 7311db9f3b2SDimitry Andric def 8ri_NF_ND : BinOpRI_R<0x80, mnemonic, Xi8, RegMRM, 1>, EVEX_NF; 7321db9f3b2SDimitry Andric def 16ri_NF_ND : BinOpRI_R<0x81, mnemonic, Xi16, RegMRM, 1>, EVEX_NF, PD; 7331db9f3b2SDimitry Andric def 32ri_NF_ND : BinOpRI_R<0x81, mnemonic, Xi32, RegMRM, 1>, EVEX_NF; 7341db9f3b2SDimitry Andric def 64ri32_NF_ND : BinOpRI_R<0x81, mnemonic, Xi64, RegMRM, 1>, EVEX_NF; 735647cbc5dSDimitry Andric } 736647cbc5dSDimitry Andric let Predicates = [In64BitMode] in { 7371db9f3b2SDimitry Andric def 16ri8_NF : BinOpRI8_R<0x83, mnemonic, Xi16, RegMRM>, NF, PD; 7381db9f3b2SDimitry Andric def 32ri8_NF : BinOpRI8_R<0x83, mnemonic, Xi32, RegMRM>, NF; 7391db9f3b2SDimitry Andric def 64ri8_NF : BinOpRI8_R<0x83, mnemonic, Xi64, RegMRM>, NF; 7401db9f3b2SDimitry Andric def 8ri_NF : BinOpRI_R<0x80, mnemonic, Xi8, RegMRM>, NF; 7411db9f3b2SDimitry Andric def 16ri_NF : BinOpRI_R<0x81, mnemonic, Xi16, RegMRM>, NF, PD; 7421db9f3b2SDimitry Andric def 32ri_NF : BinOpRI_R<0x81, mnemonic, Xi32, RegMRM>, NF; 7431db9f3b2SDimitry Andric def 64ri32_NF : BinOpRI_R<0x81, mnemonic, Xi64, RegMRM>, NF; 7441db9f3b2SDimitry Andric def 16ri8_EVEX : BinOpRI8_RF<0x83, mnemonic, Xi16, RegMRM>, PL, PD; 7451db9f3b2SDimitry Andric def 32ri8_EVEX : BinOpRI8_RF<0x83, mnemonic, Xi32, RegMRM>, PL; 7461db9f3b2SDimitry Andric def 64ri8_EVEX : BinOpRI8_RF<0x83, mnemonic, Xi64, RegMRM>, PL; 7471db9f3b2SDimitry Andric def 8ri_EVEX : BinOpRI_RF<0x80, mnemonic, Xi8 , null_frag, RegMRM>, PL; 7481db9f3b2SDimitry Andric def 16ri_EVEX : BinOpRI_RF<0x81, mnemonic, Xi16, null_frag, RegMRM>, PL, PD; 7491db9f3b2SDimitry Andric def 32ri_EVEX : BinOpRI_RF<0x81, mnemonic, Xi32, null_frag, RegMRM>, PL; 7501db9f3b2SDimitry Andric def 64ri32_EVEX: BinOpRI_RF<0x81, mnemonic, Xi64, null_frag, RegMRM>, PL; 751647cbc5dSDimitry Andric } 752647cbc5dSDimitry Andric } 7530b57cec5SDimitry Andric 7541db9f3b2SDimitry Andric def 8mr : BinOpMR_MF<BaseOpc, mnemonic, Xi8 , opnode>; 7551db9f3b2SDimitry Andric def 16mr : BinOpMR_MF<BaseOpc, mnemonic, Xi16, opnode>, OpSize16; 7561db9f3b2SDimitry Andric def 32mr : BinOpMR_MF<BaseOpc, mnemonic, Xi32, opnode>, OpSize32; 7571db9f3b2SDimitry Andric def 64mr : BinOpMR_MF<BaseOpc, mnemonic, Xi64, opnode>; 758647cbc5dSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 759*0fca6ea1SDimitry Andric defvar node = !if(!eq(CommutableRR, 0), opnode, null_frag); 760*0fca6ea1SDimitry Andric def 8mr_ND : BinOpMR_RF<BaseOpc, mnemonic, Xi8 , node>; 761*0fca6ea1SDimitry Andric def 16mr_ND : BinOpMR_RF<BaseOpc, mnemonic, Xi16, node>, PD; 762*0fca6ea1SDimitry Andric def 32mr_ND : BinOpMR_RF<BaseOpc, mnemonic, Xi32, node>; 763*0fca6ea1SDimitry Andric def 64mr_ND : BinOpMR_RF<BaseOpc, mnemonic, Xi64, node>; 7641db9f3b2SDimitry Andric def 8mr_NF_ND : BinOpMR_R<BaseOpc, mnemonic, Xi8>, EVEX_NF; 7651db9f3b2SDimitry Andric def 16mr_NF_ND : BinOpMR_R<BaseOpc, mnemonic, Xi16>, EVEX_NF, PD; 7661db9f3b2SDimitry Andric def 32mr_NF_ND : BinOpMR_R<BaseOpc, mnemonic, Xi32>, EVEX_NF; 7671db9f3b2SDimitry Andric def 64mr_NF_ND : BinOpMR_R<BaseOpc, mnemonic, Xi64>, EVEX_NF; 768647cbc5dSDimitry Andric } 769647cbc5dSDimitry Andric let Predicates = [In64BitMode] in { 7701db9f3b2SDimitry Andric def 8mr_NF : BinOpMR_M<BaseOpc, mnemonic, Xi8>, NF; 7711db9f3b2SDimitry Andric def 16mr_NF : BinOpMR_M<BaseOpc, mnemonic, Xi16>, NF, PD; 7721db9f3b2SDimitry Andric def 32mr_NF : BinOpMR_M<BaseOpc, mnemonic, Xi32>, NF; 7731db9f3b2SDimitry Andric def 64mr_NF : BinOpMR_M<BaseOpc, mnemonic, Xi64>, NF; 7741db9f3b2SDimitry Andric def 8mr_EVEX : BinOpMR_MF<BaseOpc, mnemonic, Xi8 , null_frag>, PL; 7751db9f3b2SDimitry Andric def 16mr_EVEX : BinOpMR_MF<BaseOpc, mnemonic, Xi16, null_frag>, PL, PD; 7761db9f3b2SDimitry Andric def 32mr_EVEX : BinOpMR_MF<BaseOpc, mnemonic, Xi32, null_frag>, PL; 7771db9f3b2SDimitry Andric def 64mr_EVEX : BinOpMR_MF<BaseOpc, mnemonic, Xi64, null_frag>, PL; 778647cbc5dSDimitry Andric } 7790b57cec5SDimitry Andric 7800b57cec5SDimitry Andric // NOTE: These are order specific, we want the mi8 forms to be listed 7810b57cec5SDimitry Andric // first so that they are slightly preferred to the mi forms. 7821db9f3b2SDimitry Andric def 16mi8 : BinOpMI8_MF<mnemonic, Xi16, MemMRM>, OpSize16; 7831db9f3b2SDimitry Andric def 32mi8 : BinOpMI8_MF<mnemonic, Xi32, MemMRM>, OpSize32; 7840b57cec5SDimitry Andric let Predicates = [In64BitMode] in 7851db9f3b2SDimitry Andric def 64mi8 : BinOpMI8_MF<mnemonic, Xi64, MemMRM>; 7861db9f3b2SDimitry Andric def 8mi : BinOpMI_MF<0x80, mnemonic, Xi8 , opnode, MemMRM>; 7871db9f3b2SDimitry Andric def 16mi : BinOpMI_MF<0x81, mnemonic, Xi16, opnode, MemMRM>, OpSize16; 7881db9f3b2SDimitry Andric def 32mi : BinOpMI_MF<0x81, mnemonic, Xi32, opnode, MemMRM>, OpSize32; 7890b57cec5SDimitry Andric let Predicates = [In64BitMode] in 7901db9f3b2SDimitry Andric def 64mi32 : BinOpMI_MF<0x81, mnemonic, Xi64, opnode, MemMRM>; 791647cbc5dSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 7921db9f3b2SDimitry Andric def 16mi8_ND : BinOpMI8_RF<mnemonic, Xi16, MemMRM>, PD; 7931db9f3b2SDimitry Andric def 32mi8_ND : BinOpMI8_RF<mnemonic, Xi32, MemMRM>; 7941db9f3b2SDimitry Andric def 64mi8_ND : BinOpMI8_RF<mnemonic, Xi64, MemMRM>; 7951db9f3b2SDimitry Andric def 8mi_ND : BinOpMI_RF<0x80, mnemonic, Xi8 , opnode, MemMRM>; 7961db9f3b2SDimitry Andric def 16mi_ND : BinOpMI_RF<0x81, mnemonic, Xi16, opnode, MemMRM>, PD; 7971db9f3b2SDimitry Andric def 32mi_ND : BinOpMI_RF<0x81, mnemonic, Xi32, opnode, MemMRM>; 7981db9f3b2SDimitry Andric def 64mi32_ND : BinOpMI_RF<0x81, mnemonic, Xi64, opnode, MemMRM>; 7991db9f3b2SDimitry Andric def 16mi8_NF_ND : BinOpMI8_R<mnemonic, Xi16, MemMRM>, NF, PD; 8001db9f3b2SDimitry Andric def 32mi8_NF_ND : BinOpMI8_R<mnemonic, Xi32, MemMRM>, NF; 8011db9f3b2SDimitry Andric def 64mi8_NF_ND : BinOpMI8_R<mnemonic, Xi64, MemMRM>, NF; 8021db9f3b2SDimitry Andric def 8mi_NF_ND : BinOpMI_R<0x80, mnemonic, Xi8, MemMRM>, NF; 8031db9f3b2SDimitry Andric def 16mi_NF_ND : BinOpMI_R<0x81, mnemonic, Xi16, MemMRM>, NF, PD; 8041db9f3b2SDimitry Andric def 32mi_NF_ND : BinOpMI_R<0x81, mnemonic, Xi32, MemMRM>, NF; 8051db9f3b2SDimitry Andric def 64mi32_NF_ND : BinOpMI_R<0x81, mnemonic, Xi64, MemMRM>, NF; 806647cbc5dSDimitry Andric } 807647cbc5dSDimitry Andric let Predicates = [In64BitMode] in { 8081db9f3b2SDimitry Andric def 16mi8_NF : BinOpMI8_M<mnemonic, Xi16, MemMRM>, NF, PD; 8091db9f3b2SDimitry Andric def 32mi8_NF : BinOpMI8_M<mnemonic, Xi32, MemMRM>, NF; 8101db9f3b2SDimitry Andric def 64mi8_NF : BinOpMI8_M<mnemonic, Xi64, MemMRM>, NF; 8111db9f3b2SDimitry Andric def 8mi_NF : BinOpMI_M<0x80, mnemonic, Xi8, MemMRM>, NF; 8121db9f3b2SDimitry Andric def 16mi_NF : BinOpMI_M<0x81, mnemonic, Xi16, MemMRM>, NF, PD; 8131db9f3b2SDimitry Andric def 32mi_NF : BinOpMI_M<0x81, mnemonic, Xi32, MemMRM>, NF; 8141db9f3b2SDimitry Andric def 64mi32_NF : BinOpMI_M<0x81, mnemonic, Xi64, MemMRM>, NF; 8151db9f3b2SDimitry Andric def 16mi8_EVEX : BinOpMI8_MF<mnemonic, Xi16, MemMRM>, PL, PD; 8161db9f3b2SDimitry Andric def 32mi8_EVEX : BinOpMI8_MF<mnemonic, Xi32, MemMRM>, PL; 8171db9f3b2SDimitry Andric def 64mi8_EVEX : BinOpMI8_MF<mnemonic, Xi64, MemMRM>, PL; 8181db9f3b2SDimitry Andric def 8mi_EVEX : BinOpMI_MF<0x80, mnemonic, Xi8 , null_frag, MemMRM>, PL; 8191db9f3b2SDimitry Andric def 16mi_EVEX : BinOpMI_MF<0x81, mnemonic, Xi16, null_frag, MemMRM>, PL, PD; 8201db9f3b2SDimitry Andric def 32mi_EVEX : BinOpMI_MF<0x81, mnemonic, Xi32, null_frag, MemMRM>, PL; 8211db9f3b2SDimitry Andric def 64mi32_EVEX : BinOpMI_MF<0x81, mnemonic, Xi64, null_frag, MemMRM>, PL; 822647cbc5dSDimitry Andric } 8230b57cec5SDimitry Andric 8240b57cec5SDimitry Andric // These are for the disassembler since 0x82 opcode behaves like 0x80, but 8250b57cec5SDimitry Andric // not in 64-bit mode. 826cb14a3feSDimitry Andric let Predicates = [Not64BitMode] in { 8271db9f3b2SDimitry Andric def 8ri8 : BinOpRI8_RF<0x82, mnemonic, Xi8, RegMRM>, DisassembleOnly; 8281db9f3b2SDimitry Andric def 8mi8 : BinOpMI8_MF<mnemonic, Xi8, MemMRM>, DisassembleOnly; 8290b57cec5SDimitry Andric } 8300b57cec5SDimitry Andric 831*0fca6ea1SDimitry Andric def 8i8 : BinOpAI_AF<BaseOpc4, mnemonic, Xi8 , AL, "{$src, %al|al, $src}">; 832*0fca6ea1SDimitry Andric def 16i16 : BinOpAI_AF<BaseOpc4, mnemonic, Xi16, AX, "{$src, %ax|ax, $src}">, OpSize16; 833*0fca6ea1SDimitry Andric def 32i32 : BinOpAI_AF<BaseOpc4, mnemonic, Xi32, EAX, "{$src, %eax|eax, $src}">, OpSize32; 834*0fca6ea1SDimitry Andric def 64i32 : BinOpAI_AF<BaseOpc4, mnemonic, Xi64, RAX, "{$src, %rax|rax, $src}">; 8350b57cec5SDimitry Andric} 8360b57cec5SDimitry Andric 8370b57cec5SDimitry Andric/// ArithBinOp_RFF - This is an arithmetic binary operator where the pattern is 8380b57cec5SDimitry Andric/// defined with "(set GPR:$dst, EFLAGS, (node LHS, RHS, EFLAGS))" like ADC and 8390b57cec5SDimitry Andric/// SBB. 8400b57cec5SDimitry Andric/// 8410b57cec5SDimitry Andric/// It would be nice to get rid of the second and third argument here, but 8420b57cec5SDimitry Andric/// tblgen can't handle dependent type references aggressively enough: PR8330 8430b57cec5SDimitry Andricmulticlass ArithBinOp_RFF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, 8440b57cec5SDimitry Andric string mnemonic, Format RegMRM, Format MemMRM, 8450b57cec5SDimitry Andric SDNode opnode, bit CommutableRR, 8460b57cec5SDimitry Andric bit ConvertibleToThreeAddress> { 8470b57cec5SDimitry Andric let isCommutable = CommutableRR in { 848647cbc5dSDimitry Andric let Predicates = [NoNDD] in { 8491db9f3b2SDimitry Andric def 8rr : BinOpRRF_RF<BaseOpc, mnemonic, Xi8 , opnode>; 8500b57cec5SDimitry Andric let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 8511db9f3b2SDimitry Andric def 16rr : BinOpRRF_RF<BaseOpc, mnemonic, Xi16, opnode>, OpSize16; 8521db9f3b2SDimitry Andric def 32rr : BinOpRRF_RF<BaseOpc, mnemonic, Xi32, opnode>, OpSize32; 8531db9f3b2SDimitry Andric def 64rr : BinOpRRF_RF<BaseOpc, mnemonic, Xi64, opnode>; 854647cbc5dSDimitry Andric } 855647cbc5dSDimitry Andric } 856647cbc5dSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 8571db9f3b2SDimitry Andric def 8rr_ND : BinOpRRF_RF<BaseOpc, mnemonic, Xi8 , opnode, 1>; 858647cbc5dSDimitry Andric let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 8591db9f3b2SDimitry Andric def 16rr_ND : BinOpRRF_RF<BaseOpc, mnemonic, Xi16, opnode, 1>, PD; 8601db9f3b2SDimitry Andric def 32rr_ND : BinOpRRF_RF<BaseOpc, mnemonic, Xi32, opnode, 1>; 8611db9f3b2SDimitry Andric def 64rr_ND : BinOpRRF_RF<BaseOpc, mnemonic, Xi64, opnode, 1>; 862647cbc5dSDimitry Andric } 863647cbc5dSDimitry Andric } 8640b57cec5SDimitry Andric } // isCommutable 8650b57cec5SDimitry Andric 866647cbc5dSDimitry Andric let Predicates = [In64BitMode] in { 8671db9f3b2SDimitry Andric def 8rr_EVEX : BinOpRRF_RF<BaseOpc, mnemonic, Xi8 , null_frag>, PL; 8681db9f3b2SDimitry Andric def 16rr_EVEX : BinOpRRF_RF<BaseOpc, mnemonic, Xi16, null_frag>, PL, PD; 8691db9f3b2SDimitry Andric def 32rr_EVEX : BinOpRRF_RF<BaseOpc, mnemonic, Xi32, null_frag>, PL; 8701db9f3b2SDimitry Andric def 64rr_EVEX : BinOpRRF_RF<BaseOpc, mnemonic, Xi64, null_frag>, PL; 871647cbc5dSDimitry Andric } 872647cbc5dSDimitry Andric 8731db9f3b2SDimitry Andric def 8rr_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi8>; 8741db9f3b2SDimitry Andric def 16rr_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi16>, OpSize16; 8751db9f3b2SDimitry Andric def 32rr_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi32>, OpSize32; 8761db9f3b2SDimitry Andric def 64rr_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi64>; 877647cbc5dSDimitry Andric let Predicates = [In64BitMode] in { 8781db9f3b2SDimitry Andric def 8rr_ND_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi8, 1>; 8791db9f3b2SDimitry Andric def 16rr_ND_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi16, 1>, PD; 8801db9f3b2SDimitry Andric def 32rr_ND_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi32, 1>; 8811db9f3b2SDimitry Andric def 64rr_ND_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi64, 1>; 8821db9f3b2SDimitry Andric def 8rr_EVEX_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi8>, PL; 8831db9f3b2SDimitry Andric def 16rr_EVEX_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi16>, PL, PD; 8841db9f3b2SDimitry Andric def 32rr_EVEX_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi32>, PL; 8851db9f3b2SDimitry Andric def 64rr_EVEX_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi64>, PL; 886647cbc5dSDimitry Andric } 8870b57cec5SDimitry Andric 888647cbc5dSDimitry Andric let Predicates = [NoNDD] in { 8891db9f3b2SDimitry Andric def 8rm : BinOpRMF_RF<BaseOpc2, mnemonic, Xi8 , opnode>; 8901db9f3b2SDimitry Andric def 16rm : BinOpRMF_RF<BaseOpc2, mnemonic, Xi16, opnode>, OpSize16; 8911db9f3b2SDimitry Andric def 32rm : BinOpRMF_RF<BaseOpc2, mnemonic, Xi32, opnode>, OpSize32; 8921db9f3b2SDimitry Andric def 64rm : BinOpRMF_RF<BaseOpc2, mnemonic, Xi64, opnode>; 893647cbc5dSDimitry Andric } 894647cbc5dSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 8951db9f3b2SDimitry Andric def 8rm_ND : BinOpRMF_RF<BaseOpc2, mnemonic, Xi8 , opnode, 1>; 8961db9f3b2SDimitry Andric def 16rm_ND : BinOpRMF_RF<BaseOpc2, mnemonic, Xi16, opnode, 1>, PD; 8971db9f3b2SDimitry Andric def 32rm_ND : BinOpRMF_RF<BaseOpc2, mnemonic, Xi32, opnode, 1>; 8981db9f3b2SDimitry Andric def 64rm_ND : BinOpRMF_RF<BaseOpc2, mnemonic, Xi64, opnode, 1>; 899647cbc5dSDimitry Andric } 900647cbc5dSDimitry Andric let Predicates = [In64BitMode] in { 9011db9f3b2SDimitry Andric def 8rm_EVEX : BinOpRMF_RF<BaseOpc2, mnemonic, Xi8 , opnode>, PL; 9021db9f3b2SDimitry Andric def 16rm_EVEX : BinOpRMF_RF<BaseOpc2, mnemonic, Xi16, opnode>, PL, PD; 9031db9f3b2SDimitry Andric def 32rm_EVEX : BinOpRMF_RF<BaseOpc2, mnemonic, Xi32, opnode>, PL; 9041db9f3b2SDimitry Andric def 64rm_EVEX : BinOpRMF_RF<BaseOpc2, mnemonic, Xi64, opnode>, PL; 905647cbc5dSDimitry Andric } 9060b57cec5SDimitry Andric 907647cbc5dSDimitry Andric let Predicates = [NoNDD] in { 9081db9f3b2SDimitry Andric def 8ri : BinOpRIF_RF<0x80, mnemonic, Xi8 , opnode, RegMRM>; 909cb14a3feSDimitry Andric let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 9100b57cec5SDimitry Andric // NOTE: These are order specific, we want the ri8 forms to be listed 9110b57cec5SDimitry Andric // first so that they are slightly preferred to the ri forms. 9121db9f3b2SDimitry Andric def 16ri8 : BinOpRI8F_RF<0x83, mnemonic, Xi16, RegMRM>, OpSize16; 9131db9f3b2SDimitry Andric def 32ri8 : BinOpRI8F_RF<0x83, mnemonic, Xi32, RegMRM>, OpSize32; 9141db9f3b2SDimitry Andric def 64ri8 : BinOpRI8F_RF<0x83, mnemonic, Xi64, RegMRM>; 9150b57cec5SDimitry Andric 9161db9f3b2SDimitry Andric def 16ri : BinOpRIF_RF<0x81, mnemonic, Xi16, opnode, RegMRM>, OpSize16; 9171db9f3b2SDimitry Andric def 32ri : BinOpRIF_RF<0x81, mnemonic, Xi32, opnode, RegMRM>, OpSize32; 9181db9f3b2SDimitry Andric def 64ri32: BinOpRIF_RF<0x81, mnemonic, Xi64, opnode, RegMRM>; 9190b57cec5SDimitry Andric } 920647cbc5dSDimitry Andric } 921647cbc5dSDimitry Andric 922647cbc5dSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 9231db9f3b2SDimitry Andric def 8ri_ND : BinOpRIF_RF<0x80, mnemonic, Xi8 , opnode, RegMRM, 1>; 924647cbc5dSDimitry Andric let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 9251db9f3b2SDimitry Andric def 16ri8_ND : BinOpRI8F_RF<0x83, mnemonic, Xi16, RegMRM, 1>, PD; 9261db9f3b2SDimitry Andric def 32ri8_ND : BinOpRI8F_RF<0x83, mnemonic, Xi32, RegMRM, 1>; 9271db9f3b2SDimitry Andric def 64ri8_ND : BinOpRI8F_RF<0x83, mnemonic, Xi64, RegMRM, 1>; 9281db9f3b2SDimitry Andric def 16ri_ND : BinOpRIF_RF<0x81, mnemonic, Xi16, opnode, RegMRM, 1>, PD; 9291db9f3b2SDimitry Andric def 32ri_ND : BinOpRIF_RF<0x81, mnemonic, Xi32, opnode, RegMRM, 1>; 9301db9f3b2SDimitry Andric def 64ri32_ND: BinOpRIF_RF<0x81, mnemonic, Xi64, opnode, RegMRM, 1>; 931647cbc5dSDimitry Andric } 932647cbc5dSDimitry Andric } 933647cbc5dSDimitry Andric let Predicates = [In64BitMode] in { 9341db9f3b2SDimitry Andric def 8ri_EVEX : BinOpRIF_RF<0x80, mnemonic, Xi8 , opnode, RegMRM>, PL; 9351db9f3b2SDimitry Andric def 16ri8_EVEX : BinOpRI8F_RF<0x83, mnemonic, Xi16, RegMRM>, PL, PD; 9361db9f3b2SDimitry Andric def 32ri8_EVEX : BinOpRI8F_RF<0x83, mnemonic, Xi32, RegMRM>, PL; 9371db9f3b2SDimitry Andric def 64ri8_EVEX : BinOpRI8F_RF<0x83, mnemonic, Xi64, RegMRM>, PL; 9381db9f3b2SDimitry Andric def 16ri_EVEX : BinOpRIF_RF<0x81, mnemonic, Xi16, opnode, RegMRM>, PL, PD; 9391db9f3b2SDimitry Andric def 32ri_EVEX : BinOpRIF_RF<0x81, mnemonic, Xi32, opnode, RegMRM>, PL; 9401db9f3b2SDimitry Andric def 64ri32_EVEX: BinOpRIF_RF<0x81, mnemonic, Xi64, opnode, RegMRM>, PL; 941647cbc5dSDimitry Andric } 9420b57cec5SDimitry Andric 9431db9f3b2SDimitry Andric def 8mr : BinOpMRF_MF<BaseOpc, mnemonic, Xi8 , opnode>; 9441db9f3b2SDimitry Andric def 16mr : BinOpMRF_MF<BaseOpc, mnemonic, Xi16, opnode>, OpSize16; 9451db9f3b2SDimitry Andric def 32mr : BinOpMRF_MF<BaseOpc, mnemonic, Xi32, opnode>, OpSize32; 9461db9f3b2SDimitry Andric def 64mr : BinOpMRF_MF<BaseOpc, mnemonic, Xi64, opnode>; 947647cbc5dSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 948*0fca6ea1SDimitry Andric defvar node = !if(!eq(CommutableRR, 0), opnode, null_frag); 949*0fca6ea1SDimitry Andric def 8mr_ND : BinOpMRF_RF<BaseOpc, mnemonic, Xi8 , node>; 950*0fca6ea1SDimitry Andric def 16mr_ND : BinOpMRF_RF<BaseOpc, mnemonic, Xi16, node>, PD; 951*0fca6ea1SDimitry Andric def 32mr_ND : BinOpMRF_RF<BaseOpc, mnemonic, Xi32, node>; 952*0fca6ea1SDimitry Andric def 64mr_ND : BinOpMRF_RF<BaseOpc, mnemonic, Xi64, node>; 953647cbc5dSDimitry Andric } 954647cbc5dSDimitry Andric let Predicates = [In64BitMode] in { 9551db9f3b2SDimitry Andric def 8mr_EVEX : BinOpMRF_MF<BaseOpc, mnemonic, Xi8 , null_frag>, PL; 9561db9f3b2SDimitry Andric def 16mr_EVEX : BinOpMRF_MF<BaseOpc, mnemonic, Xi16, null_frag>, PL, PD; 9571db9f3b2SDimitry Andric def 32mr_EVEX : BinOpMRF_MF<BaseOpc, mnemonic, Xi32, null_frag>, PL; 9581db9f3b2SDimitry Andric def 64mr_EVEX : BinOpMRF_MF<BaseOpc, mnemonic, Xi64, null_frag>, PL; 959647cbc5dSDimitry Andric } 9600b57cec5SDimitry Andric 9610b57cec5SDimitry Andric // NOTE: These are order specific, we want the mi8 forms to be listed 9620b57cec5SDimitry Andric // first so that they are slightly preferred to the mi forms. 9631db9f3b2SDimitry Andric def 8mi : BinOpMIF_MF<0x80, mnemonic, Xi8 , opnode, MemMRM>; 9641db9f3b2SDimitry Andric def 16mi8 : BinOpMI8F_MF<mnemonic, Xi16, MemMRM>, OpSize16; 9651db9f3b2SDimitry Andric def 32mi8 : BinOpMI8F_MF<mnemonic, Xi32, MemMRM>, OpSize32; 9660b57cec5SDimitry Andric let Predicates = [In64BitMode] in 9671db9f3b2SDimitry Andric def 64mi8 : BinOpMI8F_MF<mnemonic, Xi64, MemMRM>; 9681db9f3b2SDimitry Andric def 16mi : BinOpMIF_MF<0x81, mnemonic, Xi16, opnode, MemMRM>, OpSize16; 9691db9f3b2SDimitry Andric def 32mi : BinOpMIF_MF<0x81, mnemonic, Xi32, opnode, MemMRM>, OpSize32; 9700b57cec5SDimitry Andric let Predicates = [In64BitMode] in 9711db9f3b2SDimitry Andric def 64mi32 : BinOpMIF_MF<0x81, mnemonic, Xi64, opnode, MemMRM>; 9720b57cec5SDimitry Andric 973647cbc5dSDimitry Andric let Predicates = [HasNDD, In64BitMode] in { 9741db9f3b2SDimitry Andric def 8mi_ND : BinOpMIF_RF<0x80, mnemonic, Xi8 , opnode, MemMRM>; 9751db9f3b2SDimitry Andric def 16mi8_ND : BinOpMI8F_RF<mnemonic, Xi16, MemMRM>, PD; 9761db9f3b2SDimitry Andric def 32mi8_ND : BinOpMI8F_RF<mnemonic, Xi32, MemMRM>; 9771db9f3b2SDimitry Andric def 64mi8_ND : BinOpMI8F_RF<mnemonic, Xi64, MemMRM>; 9781db9f3b2SDimitry Andric def 16mi_ND : BinOpMIF_RF<0x81, mnemonic, Xi16, opnode, MemMRM>, PD; 9791db9f3b2SDimitry Andric def 32mi_ND : BinOpMIF_RF<0x81, mnemonic, Xi32, opnode, MemMRM>; 9801db9f3b2SDimitry Andric def 64mi32_ND : BinOpMIF_RF<0x81, mnemonic, Xi64, opnode, MemMRM>; 981647cbc5dSDimitry Andric } 982647cbc5dSDimitry Andric let Predicates = [In64BitMode] in { 9831db9f3b2SDimitry Andric def 8mi_EVEX : BinOpMIF_MF<0x80, mnemonic, Xi8 , opnode, MemMRM>, PL; 9841db9f3b2SDimitry Andric def 16mi8_EVEX : BinOpMI8F_MF<mnemonic, Xi16, MemMRM>, PL, PD; 9851db9f3b2SDimitry Andric def 32mi8_EVEX : BinOpMI8F_MF<mnemonic, Xi32, MemMRM>, PL; 9861db9f3b2SDimitry Andric def 64mi8_EVEX : BinOpMI8F_MF<mnemonic, Xi64, MemMRM>, PL; 9871db9f3b2SDimitry Andric def 16mi_EVEX : BinOpMIF_MF<0x81, mnemonic, Xi16, opnode, MemMRM>, PL, PD; 9881db9f3b2SDimitry Andric def 32mi_EVEX : BinOpMIF_MF<0x81, mnemonic, Xi32, opnode, MemMRM>, PL; 9891db9f3b2SDimitry Andric def 64mi32_EVEX : BinOpMIF_MF<0x81, mnemonic, Xi64, opnode, MemMRM>, PL; 990647cbc5dSDimitry Andric } 991647cbc5dSDimitry Andric 9920b57cec5SDimitry Andric // These are for the disassembler since 0x82 opcode behaves like 0x80, but 9930b57cec5SDimitry Andric // not in 64-bit mode. 994cb14a3feSDimitry Andric let Predicates = [Not64BitMode] in { 9951db9f3b2SDimitry Andric def 8ri8 : BinOpRI8F_RF<0x82, mnemonic, Xi8, RegMRM>, DisassembleOnly; 9961db9f3b2SDimitry Andric def 8mi8 : BinOpMI8F_MF<mnemonic, Xi8, MemMRM>, DisassembleOnly; 9970b57cec5SDimitry Andric } 9980b57cec5SDimitry Andric 999*0fca6ea1SDimitry Andric def 8i8 : BinOpAIF_AF<BaseOpc4, mnemonic, Xi8 , AL, "{$src, %al|al, $src}">; 1000*0fca6ea1SDimitry Andric def 16i16 : BinOpAIF_AF<BaseOpc4, mnemonic, Xi16, AX, "{$src, %ax|ax, $src}">, OpSize16; 1001*0fca6ea1SDimitry Andric def 32i32 : BinOpAIF_AF<BaseOpc4, mnemonic, Xi32, EAX, "{$src, %eax|eax, $src}">, OpSize32; 1002*0fca6ea1SDimitry Andric def 64i32 : BinOpAIF_AF<BaseOpc4, mnemonic, Xi64, RAX, "{$src, %rax|rax, $src}">; 10030b57cec5SDimitry Andric} 10040b57cec5SDimitry Andric 10050b57cec5SDimitry Andric/// ArithBinOp_F - This is an arithmetic binary operator where the pattern is 10060b57cec5SDimitry Andric/// defined with "(set EFLAGS, (...". It would be really nice to find a way 10070b57cec5SDimitry Andric/// to factor this with the other ArithBinOp_*. 10080b57cec5SDimitry Andric/// 10090b57cec5SDimitry Andricmulticlass ArithBinOp_F<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4, 10100b57cec5SDimitry Andric string mnemonic, Format RegMRM, Format MemMRM, 1011cb14a3feSDimitry Andric SDNode opnode, bit CommutableRR, 1012cb14a3feSDimitry Andric bit ConvertibleToThreeAddress> { 10130b57cec5SDimitry Andric let isCommutable = CommutableRR in { 10141db9f3b2SDimitry Andric def 8rr : BinOpRR_F<BaseOpc, mnemonic, Xi8 , opnode>; 10150b57cec5SDimitry Andric let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 10161db9f3b2SDimitry Andric def 16rr : BinOpRR_F<BaseOpc, mnemonic, Xi16, opnode>, OpSize16; 10171db9f3b2SDimitry Andric def 32rr : BinOpRR_F<BaseOpc, mnemonic, Xi32, opnode>, OpSize32; 10181db9f3b2SDimitry Andric def 64rr : BinOpRR_F<BaseOpc, mnemonic, Xi64, opnode>; 1019cb14a3feSDimitry Andric } // isConvertibleToThreeAddress 10200b57cec5SDimitry Andric } // isCommutable 10210b57cec5SDimitry Andric 10221db9f3b2SDimitry Andric def 8rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi8>; 10231db9f3b2SDimitry Andric def 16rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi16>, OpSize16; 10241db9f3b2SDimitry Andric def 32rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi32>, OpSize32; 10251db9f3b2SDimitry Andric def 64rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi64>; 10260b57cec5SDimitry Andric 10271db9f3b2SDimitry Andric def 8rm : BinOpRM_F<BaseOpc2, mnemonic, Xi8 , opnode>; 10281db9f3b2SDimitry Andric def 16rm : BinOpRM_F<BaseOpc2, mnemonic, Xi16, opnode>, OpSize16; 10291db9f3b2SDimitry Andric def 32rm : BinOpRM_F<BaseOpc2, mnemonic, Xi32, opnode>, OpSize32; 10301db9f3b2SDimitry Andric def 64rm : BinOpRM_F<BaseOpc2, mnemonic, Xi64, opnode>; 10310b57cec5SDimitry Andric 10321db9f3b2SDimitry Andric def 8ri : BinOpRI_F<0x80, mnemonic, Xi8 , opnode, RegMRM>; 10330b57cec5SDimitry Andric 1034cb14a3feSDimitry Andric let isConvertibleToThreeAddress = ConvertibleToThreeAddress in { 10350b57cec5SDimitry Andric // NOTE: These are order specific, we want the ri8 forms to be listed 10360b57cec5SDimitry Andric // first so that they are slightly preferred to the ri forms. 10371db9f3b2SDimitry Andric def 16ri8 : BinOpRI8_F<0x83, mnemonic, Xi16, RegMRM>, OpSize16; 10381db9f3b2SDimitry Andric def 32ri8 : BinOpRI8_F<0x83, mnemonic, Xi32, RegMRM>, OpSize32; 10391db9f3b2SDimitry Andric def 64ri8 : BinOpRI8_F<0x83, mnemonic, Xi64, RegMRM>; 10400b57cec5SDimitry Andric 10411db9f3b2SDimitry Andric def 16ri : BinOpRI_F<0x81, mnemonic, Xi16, opnode, RegMRM>, OpSize16; 10421db9f3b2SDimitry Andric def 32ri : BinOpRI_F<0x81, mnemonic, Xi32, opnode, RegMRM>, OpSize32; 10431db9f3b2SDimitry Andric def 64ri32: BinOpRI_F<0x81, mnemonic, Xi64, opnode, RegMRM>; 10440b57cec5SDimitry Andric } 10450b57cec5SDimitry Andric 10461db9f3b2SDimitry Andric def 8mr : BinOpMR_F<BaseOpc, mnemonic, Xi8 , opnode>; 10471db9f3b2SDimitry Andric def 16mr : BinOpMR_F<BaseOpc, mnemonic, Xi16, opnode>, OpSize16; 10481db9f3b2SDimitry Andric def 32mr : BinOpMR_F<BaseOpc, mnemonic, Xi32, opnode>, OpSize32; 10491db9f3b2SDimitry Andric def 64mr : BinOpMR_F<BaseOpc, mnemonic, Xi64, opnode>; 10500b57cec5SDimitry Andric 10510b57cec5SDimitry Andric // NOTE: These are order specific, we want the mi8 forms to be listed 10520b57cec5SDimitry Andric // first so that they are slightly preferred to the mi forms. 10531db9f3b2SDimitry Andric def 16mi8 : BinOpMI8_F<mnemonic, Xi16, MemMRM>, OpSize16; 10541db9f3b2SDimitry Andric def 32mi8 : BinOpMI8_F<mnemonic, Xi32, MemMRM>, OpSize32; 10550b57cec5SDimitry Andric let Predicates = [In64BitMode] in 10561db9f3b2SDimitry Andric def 64mi8 : BinOpMI8_F<mnemonic, Xi64, MemMRM>; 10570b57cec5SDimitry Andric 10581db9f3b2SDimitry Andric def 8mi : BinOpMI_F<0x80, mnemonic, Xi8 , opnode, MemMRM>; 10591db9f3b2SDimitry Andric def 16mi : BinOpMI_F<0x81, mnemonic, Xi16, opnode, MemMRM>, OpSize16; 10601db9f3b2SDimitry Andric def 32mi : BinOpMI_F<0x81, mnemonic, Xi32, opnode, MemMRM>, OpSize32; 10610b57cec5SDimitry Andric let Predicates = [In64BitMode] in 10621db9f3b2SDimitry Andric def 64mi32 : BinOpMI_F<0x81, mnemonic, Xi64, opnode, MemMRM>; 10630b57cec5SDimitry Andric 10640b57cec5SDimitry Andric // These are for the disassembler since 0x82 opcode behaves like 0x80, but 10650b57cec5SDimitry Andric // not in 64-bit mode. 1066cb14a3feSDimitry Andric let Predicates = [Not64BitMode] in { 10671db9f3b2SDimitry Andric def 8ri8 : BinOpRI8_F<0x82, mnemonic, Xi8, RegMRM>, DisassembleOnly; 10680b57cec5SDimitry Andric let mayLoad = 1 in 10691db9f3b2SDimitry Andric def 8mi8 : BinOpMI8_F<mnemonic, Xi8, MemMRM>; 10700b57cec5SDimitry Andric } 10710b57cec5SDimitry Andric 1072*0fca6ea1SDimitry Andric def 8i8 : BinOpAI_F<BaseOpc4, mnemonic, Xi8 , AL, "{$src, %al|al, $src}">; 1073*0fca6ea1SDimitry Andric def 16i16 : BinOpAI_F<BaseOpc4, mnemonic, Xi16, AX, "{$src, %ax|ax, $src}">, OpSize16; 1074*0fca6ea1SDimitry Andric def 32i32 : BinOpAI_F<BaseOpc4, mnemonic, Xi32, EAX, "{$src, %eax|eax, $src}">, OpSize32; 1075*0fca6ea1SDimitry Andric def 64i32 : BinOpAI_F<BaseOpc4, mnemonic, Xi64, RAX, "{$src, %rax|rax, $src}">; 10760b57cec5SDimitry Andric} 10770b57cec5SDimitry Andric 10780b57cec5SDimitry Andric 1079cb14a3feSDimitry Andricdefm AND : ArithBinOp_RF<0x21, 0x23, 0x25, "and", MRM4r, MRM4m, 10800b57cec5SDimitry Andric X86and_flag, and, 1, 0, 0>; 1081cb14a3feSDimitry Andricdefm OR : ArithBinOp_RF<0x09, 0x0B, 0x0D, "or", MRM1r, MRM1m, 10820b57cec5SDimitry Andric X86or_flag, or, 1, 0, 0>; 1083cb14a3feSDimitry Andricdefm XOR : ArithBinOp_RF<0x31, 0x33, 0x35, "xor", MRM6r, MRM6m, 10840b57cec5SDimitry Andric X86xor_flag, xor, 1, 0, 0>; 1085cb14a3feSDimitry Andricdefm ADD : ArithBinOp_RF<0x01, 0x03, 0x05, "add", MRM0r, MRM0m, 10860b57cec5SDimitry Andric X86add_flag, add, 1, 1, 1>; 10870b57cec5SDimitry Andriclet isCompare = 1 in { 1088cb14a3feSDimitry Andric defm SUB : ArithBinOp_RF<0x29, 0x2B, 0x2D, "sub", MRM5r, MRM5m, 10890b57cec5SDimitry Andric X86sub_flag, sub, 0, 1, 0>; 10900b57cec5SDimitry Andric} 10910b57cec5SDimitry Andric 1092e8d8bef9SDimitry Andric// Version of XOR8rr_NOREX that use GR8_NOREX. This is used by the handling of 1093e8d8bef9SDimitry Andric// __builtin_parity where the last step xors an h-register with an l-register. 1094e8d8bef9SDimitry Andriclet isCodeGenOnly = 1, hasSideEffects = 0, Constraints = "$src1 = $dst", 1095e8d8bef9SDimitry Andric Defs = [EFLAGS], isCommutable = 1 in 1096e8d8bef9SDimitry Andric def XOR8rr_NOREX : I<0x30, MRMDestReg, (outs GR8_NOREX:$dst), 1097e8d8bef9SDimitry Andric (ins GR8_NOREX:$src1, GR8_NOREX:$src2), 1098e8d8bef9SDimitry Andric "xor{b}\t{$src2, $dst|$dst, $src2}", []>, 1099e8d8bef9SDimitry Andric Sched<[WriteALU]>; 1100e8d8bef9SDimitry Andric 11010b57cec5SDimitry Andric// Arithmetic. 1102cb14a3feSDimitry Andricdefm ADC : ArithBinOp_RFF<0x11, 0x13, 0x15, "adc", MRM2r, MRM2m, X86adc_flag, 11030b57cec5SDimitry Andric 1, 0>; 1104cb14a3feSDimitry Andricdefm SBB : ArithBinOp_RFF<0x19, 0x1B, 0x1D, "sbb", MRM3r, MRM3m, X86sbb_flag, 11050b57cec5SDimitry Andric 0, 0>; 11060b57cec5SDimitry Andric 11070b57cec5SDimitry Andriclet isCompare = 1 in { 1108cb14a3feSDimitry Andric defm CMP : ArithBinOp_F<0x39, 0x3B, 0x3D, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>; 11090b57cec5SDimitry Andric} 11100b57cec5SDimitry Andric 11110b57cec5SDimitry Andric// Patterns to recognize loads on the LHS of an ADC. We can't make X86adc_flag 11120b57cec5SDimitry Andric// commutable since it has EFLAGs as an input. 1113*0fca6ea1SDimitry Andriclet Predicates = [NoNDD] in { 11140b57cec5SDimitry Andric def : Pat<(X86adc_flag (loadi8 addr:$src2), GR8:$src1, EFLAGS), 11150b57cec5SDimitry Andric (ADC8rm GR8:$src1, addr:$src2)>; 11160b57cec5SDimitry Andric def : Pat<(X86adc_flag (loadi16 addr:$src2), GR16:$src1, EFLAGS), 11170b57cec5SDimitry Andric (ADC16rm GR16:$src1, addr:$src2)>; 11180b57cec5SDimitry Andric def : Pat<(X86adc_flag (loadi32 addr:$src2), GR32:$src1, EFLAGS), 11190b57cec5SDimitry Andric (ADC32rm GR32:$src1, addr:$src2)>; 11200b57cec5SDimitry Andric def : Pat<(X86adc_flag (loadi64 addr:$src2), GR64:$src1, EFLAGS), 11210b57cec5SDimitry Andric (ADC64rm GR64:$src1, addr:$src2)>; 1122*0fca6ea1SDimitry Andric} 1123*0fca6ea1SDimitry Andriclet Predicates = [HasNDD] in { 1124*0fca6ea1SDimitry Andric def : Pat<(X86adc_flag (loadi8 addr:$src2), GR8:$src1, EFLAGS), 1125*0fca6ea1SDimitry Andric (ADC8rm_ND GR8:$src1, addr:$src2)>; 1126*0fca6ea1SDimitry Andric def : Pat<(X86adc_flag (loadi16 addr:$src2), GR16:$src1, EFLAGS), 1127*0fca6ea1SDimitry Andric (ADC16rm_ND GR16:$src1, addr:$src2)>; 1128*0fca6ea1SDimitry Andric def : Pat<(X86adc_flag (loadi32 addr:$src2), GR32:$src1, EFLAGS), 1129*0fca6ea1SDimitry Andric (ADC32rm_ND GR32:$src1, addr:$src2)>; 1130*0fca6ea1SDimitry Andric def : Pat<(X86adc_flag (loadi64 addr:$src2), GR64:$src1, EFLAGS), 1131*0fca6ea1SDimitry Andric (ADC64rm_ND GR64:$src1, addr:$src2)>; 1132*0fca6ea1SDimitry Andric} 11330b57cec5SDimitry Andric 11340b57cec5SDimitry Andric// Patterns to recognize RMW ADC with loads in operand 1. 11350b57cec5SDimitry Andricdef : Pat<(store (X86adc_flag GR8:$src, (loadi8 addr:$dst), EFLAGS), 11360b57cec5SDimitry Andric addr:$dst), 11370b57cec5SDimitry Andric (ADC8mr addr:$dst, GR8:$src)>; 11380b57cec5SDimitry Andricdef : Pat<(store (X86adc_flag GR16:$src, (loadi16 addr:$dst), EFLAGS), 11390b57cec5SDimitry Andric addr:$dst), 11400b57cec5SDimitry Andric (ADC16mr addr:$dst, GR16:$src)>; 11410b57cec5SDimitry Andricdef : Pat<(store (X86adc_flag GR32:$src, (loadi32 addr:$dst), EFLAGS), 11420b57cec5SDimitry Andric addr:$dst), 11430b57cec5SDimitry Andric (ADC32mr addr:$dst, GR32:$src)>; 11440b57cec5SDimitry Andricdef : Pat<(store (X86adc_flag GR64:$src, (loadi64 addr:$dst), EFLAGS), 11450b57cec5SDimitry Andric addr:$dst), 11460b57cec5SDimitry Andric (ADC64mr addr:$dst, GR64:$src)>; 11470b57cec5SDimitry Andric 11485ffd83dbSDimitry Andric// Patterns for basic arithmetic ops with relocImm for the immediate field. 11495ffd83dbSDimitry Andricmulticlass ArithBinOp_RF_relocImm_Pats<SDNode OpNodeFlag, SDNode OpNode> { 1150297eecfbSDimitry Andric let Predicates = [NoNDD] in { 11515ffd83dbSDimitry Andric def : Pat<(OpNodeFlag GR8:$src1, relocImm8_su:$src2), 11525ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"8ri") GR8:$src1, relocImm8_su:$src2)>; 11535ffd83dbSDimitry Andric def : Pat<(OpNodeFlag GR16:$src1, relocImm16_su:$src2), 11545ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"16ri") GR16:$src1, relocImm16_su:$src2)>; 11555ffd83dbSDimitry Andric def : Pat<(OpNodeFlag GR32:$src1, relocImm32_su:$src2), 11565ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"32ri") GR32:$src1, relocImm32_su:$src2)>; 11575ffd83dbSDimitry Andric def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt32_su:$src2), 11585ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"64ri32") GR64:$src1, i64relocImmSExt32_su:$src2)>; 11595ffd83dbSDimitry Andric 11605ffd83dbSDimitry Andric def : Pat<(store (OpNode (load addr:$dst), relocImm8_su:$src), addr:$dst), 11615ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"8mi") addr:$dst, relocImm8_su:$src)>; 11625ffd83dbSDimitry Andric def : Pat<(store (OpNode (load addr:$dst), relocImm16_su:$src), addr:$dst), 11635ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"16mi") addr:$dst, relocImm16_su:$src)>; 11645ffd83dbSDimitry Andric def : Pat<(store (OpNode (load addr:$dst), relocImm32_su:$src), addr:$dst), 11655ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"32mi") addr:$dst, relocImm32_su:$src)>; 11665ffd83dbSDimitry Andric def : Pat<(store (OpNode (load addr:$dst), i64relocImmSExt32_su:$src), addr:$dst), 11675ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"64mi32") addr:$dst, i64relocImmSExt32_su:$src)>; 11685ffd83dbSDimitry Andric } 1169297eecfbSDimitry Andric let Predicates = [HasNDD] in { 1170297eecfbSDimitry Andric def : Pat<(OpNodeFlag GR8:$src1, relocImm8_su:$src2), 1171297eecfbSDimitry Andric (!cast<Instruction>(NAME#"8ri_ND") GR8:$src1, relocImm8_su:$src2)>; 1172297eecfbSDimitry Andric def : Pat<(OpNodeFlag GR16:$src1, relocImm16_su:$src2), 1173297eecfbSDimitry Andric (!cast<Instruction>(NAME#"16ri_ND") GR16:$src1, relocImm16_su:$src2)>; 1174297eecfbSDimitry Andric def : Pat<(OpNodeFlag GR32:$src1, relocImm32_su:$src2), 1175297eecfbSDimitry Andric (!cast<Instruction>(NAME#"32ri_ND") GR32:$src1, relocImm32_su:$src2)>; 1176297eecfbSDimitry Andric def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt32_su:$src2), 1177297eecfbSDimitry Andric (!cast<Instruction>(NAME#"64ri32_ND") GR64:$src1, i64relocImmSExt32_su:$src2)>; 1178297eecfbSDimitry Andric 1179297eecfbSDimitry Andric def : Pat<(OpNode (load addr:$dst), relocImm8_su:$src), 1180297eecfbSDimitry Andric (!cast<Instruction>(NAME#"8mi_ND") addr:$dst, relocImm8_su:$src)>; 1181297eecfbSDimitry Andric def : Pat<(OpNode (load addr:$dst), relocImm16_su:$src), 1182297eecfbSDimitry Andric (!cast<Instruction>(NAME#"16mi_ND") addr:$dst, relocImm16_su:$src)>; 1183297eecfbSDimitry Andric def : Pat<(OpNode (load addr:$dst), relocImm32_su:$src), 1184297eecfbSDimitry Andric (!cast<Instruction>(NAME#"32mi_ND") addr:$dst, relocImm32_su:$src)>; 1185297eecfbSDimitry Andric def : Pat<(OpNode (load addr:$dst), i64relocImmSExt32_su:$src), 1186297eecfbSDimitry Andric (!cast<Instruction>(NAME#"64mi32_ND") addr:$dst, i64relocImmSExt32_su:$src)>; 1187297eecfbSDimitry Andric } 1188297eecfbSDimitry Andric} 11895ffd83dbSDimitry Andric 11905ffd83dbSDimitry Andricmulticlass ArithBinOp_RFF_relocImm_Pats<SDNode OpNodeFlag> { 1191297eecfbSDimitry Andric let Predicates = [NoNDD] in { 11925ffd83dbSDimitry Andric def : Pat<(OpNodeFlag GR8:$src1, relocImm8_su:$src2, EFLAGS), 11935ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"8ri") GR8:$src1, relocImm8_su:$src2)>; 11945ffd83dbSDimitry Andric def : Pat<(OpNodeFlag GR16:$src1, relocImm16_su:$src2, EFLAGS), 11955ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"16ri") GR16:$src1, relocImm16_su:$src2)>; 11965ffd83dbSDimitry Andric def : Pat<(OpNodeFlag GR32:$src1, relocImm32_su:$src2, EFLAGS), 11975ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"32ri") GR32:$src1, relocImm32_su:$src2)>; 11985ffd83dbSDimitry Andric def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt32_su:$src2, EFLAGS), 11995ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"64ri32") GR64:$src1, i64relocImmSExt32_su:$src2)>; 12005ffd83dbSDimitry Andric 12015ffd83dbSDimitry Andric def : Pat<(store (OpNodeFlag (load addr:$dst), relocImm8_su:$src, EFLAGS), addr:$dst), 12025ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"8mi") addr:$dst, relocImm8_su:$src)>; 12035ffd83dbSDimitry Andric def : Pat<(store (OpNodeFlag (load addr:$dst), relocImm16_su:$src, EFLAGS), addr:$dst), 12045ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"16mi") addr:$dst, relocImm16_su:$src)>; 12055ffd83dbSDimitry Andric def : Pat<(store (OpNodeFlag (load addr:$dst), relocImm32_su:$src, EFLAGS), addr:$dst), 12065ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"32mi") addr:$dst, relocImm32_su:$src)>; 12075ffd83dbSDimitry Andric def : Pat<(store (OpNodeFlag (load addr:$dst), i64relocImmSExt32_su:$src, EFLAGS), addr:$dst), 12085ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"64mi32") addr:$dst, i64relocImmSExt32_su:$src)>; 12095ffd83dbSDimitry Andric } 1210297eecfbSDimitry Andric let Predicates = [HasNDD] in { 1211297eecfbSDimitry Andric def : Pat<(OpNodeFlag GR8:$src1, relocImm8_su:$src2, EFLAGS), 1212297eecfbSDimitry Andric (!cast<Instruction>(NAME#"8ri_ND") GR8:$src1, relocImm8_su:$src2)>; 1213297eecfbSDimitry Andric def : Pat<(OpNodeFlag GR16:$src1, relocImm16_su:$src2, EFLAGS), 1214297eecfbSDimitry Andric (!cast<Instruction>(NAME#"16ri_ND") GR16:$src1, relocImm16_su:$src2)>; 1215297eecfbSDimitry Andric def : Pat<(OpNodeFlag GR32:$src1, relocImm32_su:$src2, EFLAGS), 1216297eecfbSDimitry Andric (!cast<Instruction>(NAME#"32ri_ND") GR32:$src1, relocImm32_su:$src2)>; 1217297eecfbSDimitry Andric def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt32_su:$src2, EFLAGS), 1218297eecfbSDimitry Andric (!cast<Instruction>(NAME#"64ri32_ND") GR64:$src1, i64relocImmSExt32_su:$src2)>; 1219297eecfbSDimitry Andric 1220297eecfbSDimitry Andric def : Pat<(OpNodeFlag (load addr:$dst), relocImm8_su:$src, EFLAGS), 1221297eecfbSDimitry Andric (!cast<Instruction>(NAME#"8mi_ND") addr:$dst, relocImm8_su:$src)>; 1222297eecfbSDimitry Andric def : Pat<(OpNodeFlag (load addr:$dst), relocImm16_su:$src, EFLAGS), 1223297eecfbSDimitry Andric (!cast<Instruction>(NAME#"16mi_ND") addr:$dst, relocImm16_su:$src)>; 1224297eecfbSDimitry Andric def : Pat<(OpNodeFlag (load addr:$dst), relocImm32_su:$src, EFLAGS), 1225297eecfbSDimitry Andric (!cast<Instruction>(NAME#"32mi_ND") addr:$dst, relocImm32_su:$src)>; 1226297eecfbSDimitry Andric def : Pat<(OpNodeFlag (load addr:$dst), i64relocImmSExt32_su:$src, EFLAGS), 1227297eecfbSDimitry Andric (!cast<Instruction>(NAME#"64mi32_ND") addr:$dst, i64relocImmSExt32_su:$src)>; 1228297eecfbSDimitry Andric } 1229297eecfbSDimitry Andric} 12305ffd83dbSDimitry Andric 12315ffd83dbSDimitry Andricmulticlass ArithBinOp_F_relocImm_Pats<SDNode OpNodeFlag> { 12325ffd83dbSDimitry Andric def : Pat<(OpNodeFlag GR8:$src1, relocImm8_su:$src2), 12335ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"8ri") GR8:$src1, relocImm8_su:$src2)>; 12345ffd83dbSDimitry Andric def : Pat<(OpNodeFlag GR16:$src1, relocImm16_su:$src2), 12355ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"16ri") GR16:$src1, relocImm16_su:$src2)>; 12365ffd83dbSDimitry Andric def : Pat<(OpNodeFlag GR32:$src1, relocImm32_su:$src2), 12375ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"32ri") GR32:$src1, relocImm32_su:$src2)>; 12385ffd83dbSDimitry Andric def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt32_su:$src2), 12395ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"64ri32") GR64:$src1, i64relocImmSExt32_su:$src2)>; 12405ffd83dbSDimitry Andric 12415ffd83dbSDimitry Andric def : Pat<(OpNodeFlag (loadi8 addr:$src1), relocImm8_su:$src2), 12425ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"8mi") addr:$src1, relocImm8_su:$src2)>; 12435ffd83dbSDimitry Andric def : Pat<(OpNodeFlag (loadi16 addr:$src1), relocImm16_su:$src2), 12445ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"16mi") addr:$src1, relocImm16_su:$src2)>; 12455ffd83dbSDimitry Andric def : Pat<(OpNodeFlag (loadi32 addr:$src1), relocImm32_su:$src2), 12465ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"32mi") addr:$src1, relocImm32_su:$src2)>; 12475ffd83dbSDimitry Andric def : Pat<(OpNodeFlag (loadi64 addr:$src1), i64relocImmSExt32_su:$src2), 12485ffd83dbSDimitry Andric (!cast<Instruction>(NAME#"64mi32") addr:$src1, i64relocImmSExt32_su:$src2)>; 12495ffd83dbSDimitry Andric} 12505ffd83dbSDimitry Andric 12515ffd83dbSDimitry Andricdefm AND : ArithBinOp_RF_relocImm_Pats<X86and_flag, and>; 12525ffd83dbSDimitry Andricdefm OR : ArithBinOp_RF_relocImm_Pats<X86or_flag, or>; 12535ffd83dbSDimitry Andricdefm XOR : ArithBinOp_RF_relocImm_Pats<X86xor_flag, xor>; 12545ffd83dbSDimitry Andricdefm ADD : ArithBinOp_RF_relocImm_Pats<X86add_flag, add>; 12555ffd83dbSDimitry Andricdefm SUB : ArithBinOp_RF_relocImm_Pats<X86sub_flag, sub>; 12565ffd83dbSDimitry Andric 12575ffd83dbSDimitry Andricdefm ADC : ArithBinOp_RFF_relocImm_Pats<X86adc_flag>; 12585ffd83dbSDimitry Andricdefm SBB : ArithBinOp_RFF_relocImm_Pats<X86sbb_flag>; 12595ffd83dbSDimitry Andric 12605ffd83dbSDimitry Andricdefm CMP : ArithBinOp_F_relocImm_Pats<X86cmp>; 12615ffd83dbSDimitry Andric 12625ffd83dbSDimitry Andric// ADC is commutable, but we can't indicate that to tablegen. So manually 12635ffd83dbSDimitry Andric// reverse the operands. 12645ffd83dbSDimitry Andricdef : Pat<(X86adc_flag GR8:$src1, relocImm8_su:$src2, EFLAGS), 12655ffd83dbSDimitry Andric (ADC8ri relocImm8_su:$src2, GR8:$src1)>; 12665ffd83dbSDimitry Andricdef : Pat<(X86adc_flag i16relocImmSExt8_su:$src2, GR16:$src1, EFLAGS), 12675ffd83dbSDimitry Andric (ADC16ri8 GR16:$src1, i16relocImmSExt8_su:$src2)>; 12685ffd83dbSDimitry Andricdef : Pat<(X86adc_flag relocImm16_su:$src2, GR16:$src1, EFLAGS), 12695ffd83dbSDimitry Andric (ADC16ri GR16:$src1, relocImm16_su:$src2)>; 12705ffd83dbSDimitry Andricdef : Pat<(X86adc_flag i32relocImmSExt8_su:$src2, GR32:$src1, EFLAGS), 12715ffd83dbSDimitry Andric (ADC32ri8 GR32:$src1, i32relocImmSExt8_su:$src2)>; 12725ffd83dbSDimitry Andricdef : Pat<(X86adc_flag relocImm32_su:$src2, GR32:$src1, EFLAGS), 12735ffd83dbSDimitry Andric (ADC32ri GR32:$src1, relocImm32_su:$src2)>; 12745ffd83dbSDimitry Andricdef : Pat<(X86adc_flag i64relocImmSExt8_su:$src2, GR64:$src1, EFLAGS), 12755ffd83dbSDimitry Andric (ADC64ri8 GR64:$src1, i64relocImmSExt8_su:$src2)>; 12765ffd83dbSDimitry Andricdef : Pat<(X86adc_flag i64relocImmSExt32_su:$src2, GR64:$src1, EFLAGS), 12775ffd83dbSDimitry Andric (ADC64ri32 GR64:$src1, i64relocImmSExt32_su:$src2)>; 12785ffd83dbSDimitry Andric 12795ffd83dbSDimitry Andricdef : Pat<(store (X86adc_flag relocImm8_su:$src, (load addr:$dst), EFLAGS), addr:$dst), 12805ffd83dbSDimitry Andric (ADC8mi addr:$dst, relocImm8_su:$src)>; 12815ffd83dbSDimitry Andricdef : Pat<(store (X86adc_flag i16relocImmSExt8_su:$src, (load addr:$dst), EFLAGS), addr:$dst), 12825ffd83dbSDimitry Andric (ADC16mi8 addr:$dst, i16relocImmSExt8_su:$src)>; 12835ffd83dbSDimitry Andricdef : Pat<(store (X86adc_flag relocImm16_su:$src, (load addr:$dst), EFLAGS), addr:$dst), 12845ffd83dbSDimitry Andric (ADC16mi addr:$dst, relocImm16_su:$src)>; 12855ffd83dbSDimitry Andricdef : Pat<(store (X86adc_flag i32relocImmSExt8_su:$src, (load addr:$dst), EFLAGS), addr:$dst), 12865ffd83dbSDimitry Andric (ADC32mi8 addr:$dst, i32relocImmSExt8_su:$src)>; 12875ffd83dbSDimitry Andricdef : Pat<(store (X86adc_flag relocImm32_su:$src, (load addr:$dst), EFLAGS), addr:$dst), 12885ffd83dbSDimitry Andric (ADC32mi addr:$dst, relocImm32_su:$src)>; 12895ffd83dbSDimitry Andricdef : Pat<(store (X86adc_flag i64relocImmSExt8_su:$src, (load addr:$dst), EFLAGS), addr:$dst), 12905ffd83dbSDimitry Andric (ADC64mi8 addr:$dst, i64relocImmSExt8_su:$src)>; 12915ffd83dbSDimitry Andricdef : Pat<(store (X86adc_flag i64relocImmSExt32_su:$src, (load addr:$dst), EFLAGS), addr:$dst), 12925ffd83dbSDimitry Andric (ADC64mi32 addr:$dst, i64relocImmSExt32_su:$src)>; 12935ffd83dbSDimitry Andric 12940b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 12950b57cec5SDimitry Andric// Semantically, test instructions are similar like AND, except they don't 12960b57cec5SDimitry Andric// generate a result. From an encoding perspective, they are very different: 12970b57cec5SDimitry Andric// they don't have all the usual imm8 and REV forms, and are encoded into a 12980b57cec5SDimitry Andric// different space. 12990b57cec5SDimitry Andriclet isCompare = 1 in { 13000b57cec5SDimitry Andric let isCommutable = 1 in { 13010b57cec5SDimitry Andric // Avoid selecting these and instead use a test+and. Post processing will 13020b57cec5SDimitry Andric // combine them. This gives bunch of other patterns that start with 13030b57cec5SDimitry Andric // and a chance to match. 13040b57cec5SDimitry Andric def TEST8rr : BinOpRR_F<0x84, "test", Xi8 , null_frag>; 1305cb14a3feSDimitry Andric def TEST16rr : BinOpRR_F<0x85, "test", Xi16, null_frag>, OpSize16; 1306cb14a3feSDimitry Andric def TEST32rr : BinOpRR_F<0x85, "test", Xi32, null_frag>, OpSize32; 1307cb14a3feSDimitry Andric def TEST64rr : BinOpRR_F<0x85, "test", Xi64, null_frag>; 13080b57cec5SDimitry Andric } // isCommutable 13090b57cec5SDimitry Andric 13100b57cec5SDimitry Andric def TEST8mr : BinOpMR_F<0x84, "test", Xi8 , null_frag>; 1311cb14a3feSDimitry Andric def TEST16mr : BinOpMR_F<0x85, "test", Xi16, null_frag>, OpSize16; 1312cb14a3feSDimitry Andric def TEST32mr : BinOpMR_F<0x85, "test", Xi32, null_frag>, OpSize32; 1313cb14a3feSDimitry Andric def TEST64mr : BinOpMR_F<0x85, "test", Xi64, null_frag>; 13140b57cec5SDimitry Andric 13150b57cec5SDimitry Andric def TEST8ri : BinOpRI_F<0xF6, "test", Xi8 , X86testpat, MRM0r>; 1316cb14a3feSDimitry Andric def TEST16ri : BinOpRI_F<0xF7, "test", Xi16, X86testpat, MRM0r>, OpSize16; 1317cb14a3feSDimitry Andric def TEST32ri : BinOpRI_F<0xF7, "test", Xi32, X86testpat, MRM0r>, OpSize32; 1318cb14a3feSDimitry Andric def TEST64ri32 : BinOpRI_F<0xF7, "test", Xi64, X86testpat, MRM0r>; 13190b57cec5SDimitry Andric 13200b57cec5SDimitry Andric def TEST8mi : BinOpMI_F<0xF6, "test", Xi8 , X86testpat, MRM0m>; 1321cb14a3feSDimitry Andric def TEST16mi : BinOpMI_F<0xF7, "test", Xi16, X86testpat, MRM0m>, OpSize16; 1322cb14a3feSDimitry Andric def TEST32mi : BinOpMI_F<0xF7, "test", Xi32, X86testpat, MRM0m>, OpSize32; 13230b57cec5SDimitry Andric 1324cb14a3feSDimitry Andric let Predicates = [In64BitMode] in 1325cb14a3feSDimitry Andric def TEST64mi32 : BinOpMI_F<0xF7, "test", Xi64, X86testpat, MRM0m>; 1326cb14a3feSDimitry Andric 1327cb14a3feSDimitry Andric def TEST8i8 : BinOpAI_F<0xA8, "test", Xi8 , AL, "{$src, %al|al, $src}">; 1328cb14a3feSDimitry Andric def TEST16i16 : BinOpAI_F<0xA9, "test", Xi16, AX, "{$src, %ax|ax, $src}">, OpSize16; 1329cb14a3feSDimitry Andric def TEST32i32 : BinOpAI_F<0xA9, "test", Xi32, EAX, "{$src, %eax|eax, $src}">, OpSize32; 1330cb14a3feSDimitry Andric def TEST64i32 : BinOpAI_F<0xA9, "test", Xi64, RAX, "{$src, %rax|rax, $src}">; 13310b57cec5SDimitry Andric} // isCompare 13320b57cec5SDimitry Andric 13335ffd83dbSDimitry Andric// Patterns to match a relocImm into the immediate field. 13345ffd83dbSDimitry Andricdef : Pat<(X86testpat GR8:$src1, relocImm8_su:$src2), 13355ffd83dbSDimitry Andric (TEST8ri GR8:$src1, relocImm8_su:$src2)>; 13365ffd83dbSDimitry Andricdef : Pat<(X86testpat GR16:$src1, relocImm16_su:$src2), 13375ffd83dbSDimitry Andric (TEST16ri GR16:$src1, relocImm16_su:$src2)>; 13385ffd83dbSDimitry Andricdef : Pat<(X86testpat GR32:$src1, relocImm32_su:$src2), 13395ffd83dbSDimitry Andric (TEST32ri GR32:$src1, relocImm32_su:$src2)>; 13405ffd83dbSDimitry Andricdef : Pat<(X86testpat GR64:$src1, i64relocImmSExt32_su:$src2), 13415ffd83dbSDimitry Andric (TEST64ri32 GR64:$src1, i64relocImmSExt32_su:$src2)>; 13425ffd83dbSDimitry Andric 13435ffd83dbSDimitry Andricdef : Pat<(X86testpat (loadi8 addr:$src1), relocImm8_su:$src2), 13445ffd83dbSDimitry Andric (TEST8mi addr:$src1, relocImm8_su:$src2)>; 13455ffd83dbSDimitry Andricdef : Pat<(X86testpat (loadi16 addr:$src1), relocImm16_su:$src2), 13465ffd83dbSDimitry Andric (TEST16mi addr:$src1, relocImm16_su:$src2)>; 13475ffd83dbSDimitry Andricdef : Pat<(X86testpat (loadi32 addr:$src1), relocImm32_su:$src2), 13485ffd83dbSDimitry Andric (TEST32mi addr:$src1, relocImm32_su:$src2)>; 13495ffd83dbSDimitry Andricdef : Pat<(X86testpat (loadi64 addr:$src1), i64relocImmSExt32_su:$src2), 13505ffd83dbSDimitry Andric (TEST64mi32 addr:$src1, i64relocImmSExt32_su:$src2)>; 13515ffd83dbSDimitry Andric 13520b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 13530b57cec5SDimitry Andric// ANDN Instruction 13540b57cec5SDimitry Andric// 1355*0fca6ea1SDimitry Andricmulticlass AndN<X86TypeInfo t, SDPatternOperator node, string suffix = ""> { 1356647cbc5dSDimitry Andric defvar andn_rr_p = 1357*0fca6ea1SDimitry Andric [(set t.RegClass:$dst, EFLAGS, (node (not t.RegClass:$src1), 1358647cbc5dSDimitry Andric t.RegClass:$src2))]; 1359647cbc5dSDimitry Andric defvar andn_rm_p = 1360*0fca6ea1SDimitry Andric [(set t.RegClass:$dst, EFLAGS, (node (not t.RegClass:$src1), 1361647cbc5dSDimitry Andric (t.LoadNode addr:$src2)))]; 1362647cbc5dSDimitry Andric def rr#suffix : ITy<0xF2, MRMSrcReg, t, (outs t.RegClass:$dst), 1363647cbc5dSDimitry Andric (ins t.RegClass:$src1, t.RegClass:$src2), "andn", 1364*0fca6ea1SDimitry Andric binop_ndd_args, andn_rr_p>, VVVV, Sched<[WriteALU]>, T8; 1365647cbc5dSDimitry Andric def rm#suffix : ITy<0xF2, MRMSrcMem, t, (outs t.RegClass:$dst), 1366647cbc5dSDimitry Andric (ins t.RegClass:$src1, t.MemOperand:$src2), "andn", 1367647cbc5dSDimitry Andric binop_ndd_args, andn_rm_p>, VVVV, 1368*0fca6ea1SDimitry Andric Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, T8; 13690b57cec5SDimitry Andric} 13700b57cec5SDimitry Andric 13710b57cec5SDimitry Andric// Complexity is reduced to give and with immediate a chance to match first. 1372647cbc5dSDimitry Andriclet AddedComplexity = -6 in { 1373*0fca6ea1SDimitry Andricdefm ANDN32 : AndN<Xi32, X86and_flag>, VEX, Requires<[HasBMI, NoEGPR]>, DefEFLAGS; 1374*0fca6ea1SDimitry Andricdefm ANDN64 : AndN<Xi64, X86and_flag>, VEX, Requires<[HasBMI, NoEGPR]>, DefEFLAGS; 1375*0fca6ea1SDimitry Andricdefm ANDN32 : AndN<Xi32, X86and_flag, "_EVEX">, EVEX, Requires<[HasBMI, HasEGPR, In64BitMode]>, DefEFLAGS; 1376*0fca6ea1SDimitry Andricdefm ANDN64 : AndN<Xi64, X86and_flag, "_EVEX">, EVEX, Requires<[HasBMI, HasEGPR, In64BitMode]>, DefEFLAGS; 1377*0fca6ea1SDimitry Andricdefm ANDN32 : AndN<Xi32, null_frag, "_NF">, EVEX, EVEX_NF, Requires<[In64BitMode]>; 1378*0fca6ea1SDimitry Andricdefm ANDN64 : AndN<Xi64, null_frag, "_NF">, EVEX, EVEX_NF, Requires<[In64BitMode]>; 13790b57cec5SDimitry Andric} 13800b57cec5SDimitry Andric 13817a6dacacSDimitry Andricmulticlass Andn_Pats<string suffix> { 13820b57cec5SDimitry Andric def : Pat<(and (not GR32:$src1), GR32:$src2), 13837a6dacacSDimitry Andric (!cast<Instruction>(ANDN32rr#suffix) GR32:$src1, GR32:$src2)>; 13840b57cec5SDimitry Andric def : Pat<(and (not GR64:$src1), GR64:$src2), 13857a6dacacSDimitry Andric (!cast<Instruction>(ANDN64rr#suffix) GR64:$src1, GR64:$src2)>; 13860b57cec5SDimitry Andric def : Pat<(and (not GR32:$src1), (loadi32 addr:$src2)), 13877a6dacacSDimitry Andric (!cast<Instruction>(ANDN32rm#suffix) GR32:$src1, addr:$src2)>; 13880b57cec5SDimitry Andric def : Pat<(and (not GR64:$src1), (loadi64 addr:$src2)), 13897a6dacacSDimitry Andric (!cast<Instruction>(ANDN64rm#suffix) GR64:$src1, addr:$src2)>; 13900b57cec5SDimitry Andric} 13910b57cec5SDimitry Andric 13927a6dacacSDimitry Andriclet Predicates = [HasBMI, NoEGPR], AddedComplexity = -6 in 13937a6dacacSDimitry Andric defm : Andn_Pats<"">; 13947a6dacacSDimitry Andric 13957a6dacacSDimitry Andriclet Predicates = [HasBMI, HasEGPR], AddedComplexity = -6 in 13967a6dacacSDimitry Andric defm : Andn_Pats<"_EVEX">; 13977a6dacacSDimitry Andric 13980b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 13990b57cec5SDimitry Andric// MULX Instruction 14000b57cec5SDimitry Andric// 1401647cbc5dSDimitry Andricmulticlass MulX<X86TypeInfo t, X86FoldableSchedWrite sched> { 1402647cbc5dSDimitry Andric defvar mulx_args = "{$src, $dst2, $dst1|$dst1, $dst2, $src}"; 1403647cbc5dSDimitry Andric defvar mulx_rm_sched = 1404647cbc5dSDimitry Andric [WriteIMulHLd, sched.Folded, 1405349cc55cSDimitry Andric // Memory operand. 1406349cc55cSDimitry Andric ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault, 1407349cc55cSDimitry Andric // Implicit read of EDX/RDX 1408647cbc5dSDimitry Andric sched.ReadAfterFold]; 14095ffd83dbSDimitry Andric 1410647cbc5dSDimitry Andric def rr : ITy<0xF6, MRMSrcReg, t, (outs t.RegClass:$dst1, t.RegClass:$dst2), 1411647cbc5dSDimitry Andric (ins t.RegClass:$src), "mulx", mulx_args, []>, T8, XD, VEX, 1412647cbc5dSDimitry Andric VVVV, Sched<[WriteIMulH, sched]>; 1413647cbc5dSDimitry Andric let mayLoad = 1 in 1414647cbc5dSDimitry Andric def rm : ITy<0xF6, MRMSrcMem, t, (outs t.RegClass:$dst1, t.RegClass:$dst2), 1415647cbc5dSDimitry Andric (ins t.MemOperand:$src), "mulx", mulx_args, []>, T8, XD, VEX, 1416647cbc5dSDimitry Andric VVVV, Sched<mulx_rm_sched>; 1417647cbc5dSDimitry Andric 1418647cbc5dSDimitry Andric let Predicates = [In64BitMode] in { 1419647cbc5dSDimitry Andric def rr_EVEX : ITy<0xF6, MRMSrcReg, t, 1420647cbc5dSDimitry Andric (outs t.RegClass:$dst1, t.RegClass:$dst2), 1421647cbc5dSDimitry Andric (ins t.RegClass:$src), "mulx", mulx_args, []>, T8, XD, 1422647cbc5dSDimitry Andric EVEX, VVVV, Sched<[WriteIMulH, sched]>; 1423647cbc5dSDimitry Andric let mayLoad = 1 in 1424647cbc5dSDimitry Andric def rm_EVEX : ITy<0xF6, MRMSrcMem, t, 1425647cbc5dSDimitry Andric (outs t.RegClass:$dst1, t.RegClass:$dst2), 1426647cbc5dSDimitry Andric (ins t.MemOperand:$src), "mulx", mulx_args, []>, T8, XD, 1427647cbc5dSDimitry Andric EVEX, VVVV, Sched<mulx_rm_sched>; 1428647cbc5dSDimitry Andric } 14295ffd83dbSDimitry Andric // Pseudo instructions to be used when the low result isn't used. The 14305ffd83dbSDimitry Andric // instruction is defined to keep the high if both destinations are the same. 1431647cbc5dSDimitry Andric def Hrr : PseudoI<(outs t.RegClass:$dst), (ins t.RegClass:$src), []>, 1432647cbc5dSDimitry Andric Sched<[sched]>; 14335ffd83dbSDimitry Andric let mayLoad = 1 in 1434647cbc5dSDimitry Andric def Hrm : PseudoI<(outs t.RegClass:$dst), (ins t.MemOperand:$src), []>, 1435647cbc5dSDimitry Andric Sched<[sched.Folded]>; 14360b57cec5SDimitry Andric} 14370b57cec5SDimitry Andric 14380b57cec5SDimitry Andriclet Uses = [EDX] in 1439647cbc5dSDimitry Andric defm MULX32 : MulX<Xi32, WriteMULX32>; 1440647cbc5dSDimitry Andric 14410b57cec5SDimitry Andriclet Uses = [RDX] in 1442647cbc5dSDimitry Andric defm MULX64 : MulX<Xi64, WriteMULX64>, REX_W; 14430b57cec5SDimitry Andric 14440b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 14450b57cec5SDimitry Andric// ADCX and ADOX Instructions 14460b57cec5SDimitry Andric// 14470b57cec5SDimitry Andric// We don't have patterns for these as there is no advantage over ADC for 14480b57cec5SDimitry Andric// most code. 1449647cbc5dSDimitry Andriclet Form = MRMSrcReg in { 14501db9f3b2SDimitry Andric def ADCX32rr : BinOpRRF_RF<0xF6, "adcx", Xi32>, T8, PD; 14511db9f3b2SDimitry Andric def ADCX64rr : BinOpRRF_RF<0xF6, "adcx", Xi64>, T8, PD; 14521db9f3b2SDimitry Andric def ADOX32rr : BinOpRRF_RF<0xF6, "adox", Xi32>, T8, XS; 14531db9f3b2SDimitry Andric def ADOX64rr : BinOpRRF_RF<0xF6, "adox", Xi64>, T8, XS; 14541db9f3b2SDimitry Andric let Predicates =[In64BitMode] in { 14551db9f3b2SDimitry Andric def ADCX32rr_EVEX : BinOpRRF_RF<0x66, "adcx", Xi32>, EVEX, T_MAP4, PD; 14561db9f3b2SDimitry Andric def ADCX64rr_EVEX : BinOpRRF_RF<0x66, "adcx", Xi64>, EVEX, T_MAP4, PD; 14571db9f3b2SDimitry Andric def ADOX32rr_EVEX : BinOpRRF_RF<0x66, "adox", Xi32>, EVEX, T_MAP4, XS; 14581db9f3b2SDimitry Andric def ADOX64rr_EVEX : BinOpRRF_RF<0x66, "adox", Xi64>, EVEX, T_MAP4, XS; 14591db9f3b2SDimitry Andric def ADCX32rr_ND : BinOpRRF_RF<0x66, "adcx", Xi32, null_frag, 1>, PD; 14601db9f3b2SDimitry Andric def ADCX64rr_ND : BinOpRRF_RF<0x66, "adcx", Xi64, null_frag, 1>, PD; 14611db9f3b2SDimitry Andric def ADOX32rr_ND : BinOpRRF_RF<0x66, "adox", Xi32, null_frag, 1>, XS; 14621db9f3b2SDimitry Andric def ADOX64rr_ND : BinOpRRF_RF<0x66, "adox", Xi64, null_frag, 1>, XS; 14631db9f3b2SDimitry Andric } 146406c3fb27SDimitry Andric} 1465647cbc5dSDimitry Andriclet Form = MRMSrcMem in { 14661db9f3b2SDimitry Andric def ADCX32rm : BinOpRMF_RF<0xF6, "adcx", Xi32>, T8, PD; 14671db9f3b2SDimitry Andric def ADCX64rm : BinOpRMF_RF<0xF6, "adcx", Xi64>, T8, PD; 14681db9f3b2SDimitry Andric def ADOX32rm : BinOpRMF_RF<0xF6, "adox", Xi32>, T8, XS; 14691db9f3b2SDimitry Andric def ADOX64rm : BinOpRMF_RF<0xF6, "adox", Xi64>, T8, XS; 14701db9f3b2SDimitry Andric let Predicates =[In64BitMode] in { 14711db9f3b2SDimitry Andric def ADCX32rm_EVEX : BinOpRMF_RF<0x66, "adcx", Xi32>, EVEX, T_MAP4, PD; 14721db9f3b2SDimitry Andric def ADCX64rm_EVEX : BinOpRMF_RF<0x66, "adcx", Xi64>, EVEX, T_MAP4, PD; 14731db9f3b2SDimitry Andric def ADOX32rm_EVEX : BinOpRMF_RF<0x66, "adox", Xi32>, EVEX, T_MAP4, XS; 14741db9f3b2SDimitry Andric def ADOX64rm_EVEX : BinOpRMF_RF<0x66, "adox", Xi64>, EVEX, T_MAP4, XS; 14751db9f3b2SDimitry Andric def ADCX32rm_ND : BinOpRMF_RF<0x66, "adcx", Xi32, null_frag, 1>, PD; 14761db9f3b2SDimitry Andric def ADCX64rm_ND : BinOpRMF_RF<0x66, "adcx", Xi64, null_frag, 1>, PD; 14771db9f3b2SDimitry Andric def ADOX32rm_ND : BinOpRMF_RF<0x66, "adox", Xi32, null_frag, 1>, XS; 14781db9f3b2SDimitry Andric def ADOX64rm_ND : BinOpRMF_RF<0x66, "adox", Xi64, null_frag, 1>, XS; 14791db9f3b2SDimitry Andric } 14800b57cec5SDimitry Andric} 1481