brintos

brintos / llvm-project-archived public Read only

0
0
Text · 73.1 KiB · 031fdc1 Raw
1492 lines · plain
1//===-- X86InstrArithmetic.td - Integer Arithmetic Instrs --*- tablegen -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file describes the integer arithmetic instructions in the X8610// architecture.11//12//===----------------------------------------------------------------------===//13 14//===----------------------------------------------------------------------===//15// LEA - Load Effective Address16let SchedRW = [WriteLEA] in {17  let hasSideEffects = 0 in18    def LEA16r   : I<0x8D, MRMSrcMem,19                     (outs GR16:$dst), (ins anymem:$src),20                     "lea{w}\t{$src|$dst}, {$dst|$src}", []>, OpSize16;21  let isReMaterializable = 1 in22    def LEA32r   : I<0x8D, MRMSrcMem,23                     (outs GR32:$dst), (ins anymem:$src),24                     "lea{l}\t{$src|$dst}, {$dst|$src}",25                     [(set GR32:$dst, lea32addr:$src)]>,26                     OpSize32, Requires<[Not64BitMode]>;27 28  let isCodeGenOnly = 1 in {29    def LEA64_8r : I<0x8D, MRMSrcMem, (outs GR32:$dst), (ins lea64_8mem:$src),30                     "lea{l}\t{$src|$dst}, {$dst|$src}", []>, OpSize32;31 32    def LEA64_16r : I<0x8D, MRMSrcMem, (outs GR32:$dst), (ins lea64_16mem:$src),33                      "lea{l}\t{$src|$dst}, {$dst|$src}", []>, OpSize32;34  }35 36  def LEA64_32r : I<0x8D, MRMSrcMem, (outs GR32:$dst), (ins lea64_32mem:$src),37                    "lea{l}\t{$src|$dst}, {$dst|$src}",38                    [(set GR32:$dst, lea64_iaddr:$src)]>,39                  OpSize32,40                  Requires<[In64BitMode]>;41 42  let isReMaterializable = 1 in43    def LEA64r   : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src),44                      "lea{q}\t{$src|$dst}, {$dst|$src}",45                      [(set GR64:$dst, lea64addr:$src)]>;46} // SchedRW47 48let Predicates = [HasNDD] in {49  def : Pat<(i8 lea64_iaddr:$src), (EXTRACT_SUBREG (LEA64_8r lea64_8mem:$src), sub_8bit)>;50  def : Pat<(i16 lea64_iaddr:$src), (EXTRACT_SUBREG (LEA64_16r lea64_16mem:$src), sub_16bit)>;51}52 53// Pseudo instruction for lea that prevent optimizer from eliminating54// the instruction.55let SchedRW = [WriteLEA], isPseudo = true, hasSideEffects = 1 in {56  def PLEA32r   : PseudoI<(outs GR32:$dst), (ins anymem:$src), []>;57  def PLEA64r   : PseudoI<(outs GR64:$dst), (ins anymem:$src), []>;58}59 60//===----------------------------------------------------------------------===//61// MUL/IMUL and DIV/IDIV Instructions62//63class MulDivOpR<bits<8> o, Format f, string m, X86TypeInfo t,64             X86FoldableSchedWrite sched, list<dag> p>65  : UnaryOpR<o, f, m, "$src1", t, (outs), p> {66  let SchedRW = [sched];67}68 69class MulDivOpM<bits<8> o, Format f, string m, X86TypeInfo t,70             X86FoldableSchedWrite sched, list<dag> p>71  : UnaryOpM<o, f, m, "$src1", t, (outs), p> {72  let SchedRW =73    [sched.Folded,74     // Memory operand.75     ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,76     // Register reads (implicit or explicit).77     sched.ReadAfterFold, sched.ReadAfterFold];78}79 80multiclass Mul<bits<8> o, string m, Format RegMRM, Format MemMRM, SDPatternOperator node> {81  // AL is really implied by AX, but the registers in Defs must match the82  // SDNode results (i8, i32).83  //84  // FIXME: Used for 8-bit mul, ignore result upper 8 bits.85  // This probably ought to be moved to a def : Pat<> if the86  // syntax can be accepted.87  let Defs = [AL, EFLAGS, AX], Uses = [AL] in88    def 8r : MulDivOpR<o, RegMRM, m, Xi8, WriteIMul8,89                       [(set AL, EFLAGS, (node AL, GR8:$src1))]>;90  let Defs = [AX, DX, EFLAGS], Uses = [AX] in91    def 16r : MulDivOpR<o, RegMRM, m, Xi16, WriteIMul16, []>, OpSize16;92  let Defs = [EAX, EDX, EFLAGS], Uses = [EAX] in93    def 32r : MulDivOpR<o, RegMRM, m, Xi32, WriteIMul32, []>, OpSize32;94  let Defs = [RAX, RDX, EFLAGS], Uses = [RAX] in95    def 64r : MulDivOpR<o, RegMRM, m, Xi64, WriteIMul64, []>;96  let Defs = [AL, EFLAGS, AX], Uses = [AL] in97    def 8m : MulDivOpM<o, MemMRM, m, Xi8, WriteIMul8,98                       [(set AL, EFLAGS, (node AL, (loadi8 addr:$src1)))]>;99  let Defs = [AX, DX, EFLAGS], Uses = [AX] in100    def 16m : MulDivOpM<o, MemMRM, m, Xi16, WriteIMul16, []>, OpSize16;101  let Defs = [EAX, EDX, EFLAGS], Uses = [EAX] in102    def 32m : MulDivOpM<o, MemMRM, m, Xi32, WriteIMul32, []>, OpSize32;103  let Defs = [RAX, RDX, EFLAGS], Uses = [RAX] in104    def 64m : MulDivOpM<o, MemMRM, m, Xi64, WriteIMul64, []>, Requires<[In64BitMode]>;105 106  let Predicates = [In64BitMode] in {107    let Defs = [AL, AX], Uses = [AL] in108      def 8r_NF : MulDivOpR<o, RegMRM, m, Xi8, WriteIMul8, []>, NF;109    let Defs = [AX, DX], Uses = [AX] in110      def 16r_NF : MulDivOpR<o, RegMRM, m, Xi16, WriteIMul16, []>, NF, PD;111    let Defs = [EAX, EDX], Uses = [EAX] in112      def 32r_NF : MulDivOpR<o, RegMRM, m, Xi32, WriteIMul32, []>, NF;113    let Defs = [RAX, RDX], Uses = [RAX] in114      def 64r_NF : MulDivOpR<o, RegMRM, m, Xi64, WriteIMul64, []>, NF;115    let Defs = [AL, AX], Uses = [AL] in116      def 8m_NF : MulDivOpM<o, MemMRM, m, Xi8, WriteIMul8, []>, NF;117    let Defs = [AX, DX], Uses = [AX] in118      def 16m_NF : MulDivOpM<o, MemMRM, m, Xi16, WriteIMul16, []>, NF, PD;119    let Defs = [EAX, EDX], Uses = [EAX] in120      def 32m_NF : MulDivOpM<o, MemMRM, m, Xi32, WriteIMul32, []>, NF;121    let Defs = [RAX, RDX], Uses = [RAX] in122      def 64m_NF : MulDivOpM<o, MemMRM, m, Xi64, WriteIMul64, []>, NF;123 124    let Defs = [AL, EFLAGS, AX], Uses = [AL] in125      def 8r_EVEX : MulDivOpR<o, RegMRM, m, Xi8, WriteIMul8, []>, PL;126    let Defs = [AX, DX, EFLAGS], Uses = [AX] in127      def 16r_EVEX : MulDivOpR<o, RegMRM, m, Xi16, WriteIMul16, []>, PL, PD;128    let Defs = [EAX, EDX, EFLAGS], Uses = [EAX] in129      def 32r_EVEX : MulDivOpR<o, RegMRM, m, Xi32, WriteIMul32, []>, PL;130    let Defs = [RAX, RDX, EFLAGS], Uses = [RAX] in131      def 64r_EVEX : MulDivOpR<o, RegMRM, m, Xi64, WriteIMul64, []>, PL;132    let Defs = [AL, EFLAGS, AX], Uses = [AL] in133      def 8m_EVEX : MulDivOpM<o, MemMRM, m, Xi8, WriteIMul8, []>, PL;134    let Defs = [AX, DX, EFLAGS], Uses = [AX] in135      def 16m_EVEX : MulDivOpM<o, MemMRM, m, Xi16, WriteIMul16, []>, PL, PD;136    let Defs = [EAX, EDX, EFLAGS], Uses = [EAX] in137      def 32m_EVEX : MulDivOpM<o, MemMRM, m, Xi32, WriteIMul32, []>, PL;138    let Defs = [RAX, RDX, EFLAGS], Uses = [RAX] in139      def 64m_EVEX : MulDivOpM<o, MemMRM, m, Xi64, WriteIMul64, []>, PL;140  }141}142 143defm MUL : Mul<0xF7, "mul", MRM4r, MRM4m, mul>;144defm IMUL : Mul<0xF7, "imul", MRM5r, MRM5m, null_frag>;145 146multiclass Div<bits<8> o, string m, Format RegMRM, Format MemMRM> {147  defvar sched8 = !if(!eq(m, "div"), WriteDiv8, WriteIDiv8);148  defvar sched16 = !if(!eq(m, "div"), WriteDiv16, WriteIDiv16);149  defvar sched32 = !if(!eq(m, "div"), WriteDiv32, WriteIDiv32);150  defvar sched64 = !if(!eq(m, "div"), WriteDiv64, WriteIDiv64);151  let Defs = [AL, AH, EFLAGS], Uses = [AX] in152    def 8r  : MulDivOpR<o, RegMRM, m, Xi8, sched8, []>;153  let Defs = [AX, DX, EFLAGS], Uses = [AX, DX] in154    def 16r : MulDivOpR<o, RegMRM, m, Xi16, sched16, []>, OpSize16;155  let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EDX] in156    def 32r : MulDivOpR<o, RegMRM, m, Xi32, sched32, []>, OpSize32;157  let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RDX] in158    def 64r : MulDivOpR<o, RegMRM, m, Xi64, sched64, []>;159  let Defs = [AL, AH, EFLAGS], Uses = [AX] in160    def 8m  : MulDivOpM<o, MemMRM, m, Xi8, sched8, []>;161  let Defs = [AX, DX, EFLAGS], Uses = [AX, DX] in162    def 16m : MulDivOpM<o, MemMRM, m, Xi16, sched16, []>, OpSize16;163  let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EDX] in164    def 32m : MulDivOpM<o, MemMRM, m, Xi32, sched32, []>, OpSize32;165  let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RDX] in166    def 64m : MulDivOpM<o, MemMRM, m, Xi64, sched64, []>, Requires<[In64BitMode]>;167 168  let Predicates = [In64BitMode] in {169    let Defs = [AL, AH], Uses = [AX] in170      def 8r_NF  : MulDivOpR<o, RegMRM, m, Xi8, sched8, []>, NF;171    let Defs = [AX, DX], Uses = [AX, DX] in172      def 16r_NF : MulDivOpR<o, RegMRM, m, Xi16, sched16, []>, NF, PD;173    let Defs = [EAX, EDX], Uses = [EAX, EDX] in174      def 32r_NF : MulDivOpR<o, RegMRM, m, Xi32, sched32, []>, NF;175    let Defs = [RAX, RDX], Uses = [RAX, RDX] in176      def 64r_NF : MulDivOpR<o, RegMRM, m, Xi64, sched64, []>, NF;177    let Defs = [AL, AH], Uses = [AX] in178      def 8m_NF  : MulDivOpM<o, MemMRM, m, Xi8, sched8, []>, NF;179    let Defs = [AX, DX], Uses = [AX, DX] in180      def 16m_NF : MulDivOpM<o, MemMRM, m, Xi16, sched16, []>, NF, PD;181    let Defs = [EAX, EDX], Uses = [EAX, EDX] in182      def 32m_NF : MulDivOpM<o, MemMRM, m, Xi32, sched32, []>, NF;183    let Defs = [RAX, RDX], Uses = [RAX, RDX] in184      def 64m_NF : MulDivOpM<o, MemMRM, m, Xi64, sched64, []>, NF;185 186    let Defs = [AL, AH, EFLAGS], Uses = [AX] in187      def 8r_EVEX  : MulDivOpR<o, RegMRM, m, Xi8, sched8, []>, PL;188    let Defs = [AX, DX, EFLAGS], Uses = [AX, DX] in189      def 16r_EVEX : MulDivOpR<o, RegMRM, m, Xi16, sched16, []>, PL, PD;190    let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EDX] in191      def 32r_EVEX : MulDivOpR<o, RegMRM, m, Xi32, sched32, []>, PL;192    let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RDX] in193      def 64r_EVEX : MulDivOpR<o, RegMRM, m, Xi64, sched64, []>, PL;194    let Defs = [AL, AH, EFLAGS], Uses = [AX] in195      def 8m_EVEX  : MulDivOpM<o, MemMRM, m, Xi8, sched8, []>, PL;196    let Defs = [AX, DX, EFLAGS], Uses = [AX, DX] in197      def 16m_EVEX : MulDivOpM<o, MemMRM, m, Xi16, sched16, []>, PL, PD;198    let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EDX] in199      def 32m_EVEX : MulDivOpM<o, MemMRM, m, Xi32, sched32, []>, PL;200    let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RDX] in201      def 64m_EVEX : MulDivOpM<o, MemMRM, m, Xi64, sched64, []>, PL;202  }203}204 205let hasSideEffects = 1 in { // so that we don't speculatively execute206  defm DIV: Div<0xF7, "div", MRM6r, MRM6m>;207  defm IDIV: Div<0xF7, "idiv", MRM7r, MRM7m>;208}209 210class IMulOpRR_R<X86TypeInfo t, X86FoldableSchedWrite sched, bit ndd = 0>211  : BinOpRR_R<0xAF, "imul", t, ndd> {212  let Form = MRMSrcReg;213  let SchedRW = [sched];214  // X = IMUL Y, Z --> X = IMUL Z, Y215  let isCommutable = 1;216}217class IMulOpRR_RF<X86TypeInfo t, X86FoldableSchedWrite sched, bit ndd = 0>218  : BinOpRR_RF<0xAF, "imul", t, X86smul_flag, ndd> {219  let Form = MRMSrcReg;220  let SchedRW = [sched];221  // X = IMUL Y, Z --> X = IMUL Z, Y222  let isCommutable = 1;223}224class IMulOpRM_R<X86TypeInfo t, X86FoldableSchedWrite sched, bit ndd = 0>225  : BinOpRM_R<0xAF, "imul", t, ndd> {226  let Form = MRMSrcMem;227  let SchedRW = [sched.Folded, sched.ReadAfterFold];228}229class IMulOpRM_RF<X86TypeInfo t, X86FoldableSchedWrite sched, bit ndd = 0>230  : BinOpRM_RF<0xAF, "imul", t, X86smul_flag, ndd> {231  let Form = MRMSrcMem;232  let SchedRW = [sched.Folded, sched.ReadAfterFold];233}234 235let Predicates = [NoNDD] in {236  def IMUL16rr : IMulOpRR_RF<Xi16, WriteIMul16Reg>, TB, OpSize16;237  def IMUL32rr : IMulOpRR_RF<Xi32, WriteIMul32Reg>, TB, OpSize32;238  def IMUL64rr : IMulOpRR_RF<Xi64, WriteIMul64Reg>, TB;239  def IMUL16rm : IMulOpRM_RF<Xi16, WriteIMul16Reg>, TB, OpSize16;240  def IMUL32rm : IMulOpRM_RF<Xi32, WriteIMul32Reg>, TB, OpSize32;241  def IMUL64rm : IMulOpRM_RF<Xi64, WriteIMul64Reg>, TB;242}243let Predicates = [HasNDD, In64BitMode] in {244  def IMUL16rr_ND : IMulOpRR_RF<Xi16, WriteIMul16Reg, 1>, PD;245  def IMUL32rr_ND : IMulOpRR_RF<Xi32, WriteIMul32Reg, 1>;246  def IMUL64rr_ND : IMulOpRR_RF<Xi64, WriteIMul64Reg, 1>;247  def IMUL16rm_ND : IMulOpRM_RF<Xi16, WriteIMul16Reg, 1>, PD;248  def IMUL32rm_ND : IMulOpRM_RF<Xi32, WriteIMul32Reg, 1>;249  def IMUL64rm_ND : IMulOpRM_RF<Xi64, WriteIMul64Reg, 1>;250}251 252let Predicates = [In64BitMode], Pattern = [(null_frag)] in {253  def IMUL16rr_NF : IMulOpRR_R<Xi16, WriteIMul16Reg>, NF, PD;254  def IMUL32rr_NF : IMulOpRR_R<Xi32, WriteIMul32Reg>, NF;255  def IMUL64rr_NF : IMulOpRR_R<Xi64, WriteIMul64Reg>, NF;256  def IMUL16rm_NF : IMulOpRM_R<Xi16, WriteIMul16Reg>, NF, PD;257  def IMUL32rm_NF : IMulOpRM_R<Xi32, WriteIMul32Reg>, NF;258  def IMUL64rm_NF : IMulOpRM_R<Xi64, WriteIMul64Reg>, NF;259 260  def IMUL16rr_NF_ND : IMulOpRR_R<Xi16, WriteIMul16Reg, 1>, EVEX_NF, PD;261  def IMUL32rr_NF_ND : IMulOpRR_R<Xi32, WriteIMul32Reg, 1>, EVEX_NF;262  def IMUL64rr_NF_ND : IMulOpRR_R<Xi64, WriteIMul64Reg, 1>, EVEX_NF;263  def IMUL16rm_NF_ND : IMulOpRM_R<Xi16, WriteIMul16Reg, 1>, EVEX_NF, PD;264  def IMUL32rm_NF_ND : IMulOpRM_R<Xi32, WriteIMul32Reg, 1>, EVEX_NF;265  def IMUL64rm_NF_ND : IMulOpRM_R<Xi64, WriteIMul64Reg, 1>, EVEX_NF;266 267  def IMUL16rr_EVEX : IMulOpRR_RF<Xi16, WriteIMul16Reg>, PL, PD;268  def IMUL32rr_EVEX : IMulOpRR_RF<Xi32, WriteIMul32Reg>, PL;269  def IMUL64rr_EVEX : IMulOpRR_RF<Xi64, WriteIMul64Reg>, PL;270  def IMUL16rm_EVEX : IMulOpRM_RF<Xi16, WriteIMul16Reg>, PL, PD;271  def IMUL32rm_EVEX : IMulOpRM_RF<Xi32, WriteIMul32Reg>, PL;272  def IMUL64rm_EVEX : IMulOpRM_RF<Xi64, WriteIMul64Reg>, PL;273}274 275class IMulOpRI8_R<X86TypeInfo t, X86FoldableSchedWrite sched>276  : BinOpRI8<0x6B, "imul", binop_ndd_args, t, MRMSrcReg,277             (outs t.RegClass:$dst)> {278  let SchedRW = [sched];279}280class IMulOpRI_R<X86TypeInfo t, X86FoldableSchedWrite sched>281  : BinOpRI<0x69, "imul", binop_ndd_args, t, MRMSrcReg,282            (outs t.RegClass:$dst), []> {283  let SchedRW = [sched];284}285class IMulOpRI_RF<X86TypeInfo t, X86FoldableSchedWrite sched>286  : BinOpRI<0x69, "imul", binop_ndd_args, t, MRMSrcReg,287            (outs t.RegClass:$dst),288            [(set t.RegClass:$dst, EFLAGS, (X86smul_flag t.RegClass:$src1,289             t.ImmNoSuOperator:$src2))]>, DefEFLAGS {290  let SchedRW = [sched];291}292class IMulOpMI8_R<X86TypeInfo t, X86FoldableSchedWrite sched>293  : BinOpMI8<"imul", binop_ndd_args, t, MRMSrcMem, (outs t.RegClass:$dst)> {294  let Opcode = 0x6B;295  let SchedRW = [sched.Folded];296}297class IMulOpMI_R<X86TypeInfo t, X86FoldableSchedWrite sched>298  : BinOpMI<0x69, "imul", binop_ndd_args, t, MRMSrcMem,299            (outs t.RegClass:$dst), []> {300  let SchedRW = [sched.Folded];301}302class IMulOpMI_RF<X86TypeInfo t, X86FoldableSchedWrite sched>303  : BinOpMI<0x69, "imul", binop_ndd_args, t, MRMSrcMem,304            (outs t.RegClass:$dst),305            [(set t.RegClass:$dst, EFLAGS, (X86smul_flag (t.LoadNode addr:$src1),306             t.ImmNoSuOperator:$src2))]>,307    DefEFLAGS {308  let SchedRW = [sched.Folded];309}310def IMUL16rri8 : IMulOpRI8_R<Xi16, WriteIMul16Imm>, DefEFLAGS, OpSize16;311def IMUL32rri8 : IMulOpRI8_R<Xi32, WriteIMul32Imm>, DefEFLAGS, OpSize32;312def IMUL64rri8 : IMulOpRI8_R<Xi64, WriteIMul64Imm>, DefEFLAGS;313def IMUL16rri  : IMulOpRI_RF<Xi16, WriteIMul16Imm>, OpSize16;314def IMUL32rri  : IMulOpRI_RF<Xi32, WriteIMul32Imm>, OpSize32;315def IMUL64rri32 : IMulOpRI_RF<Xi64, WriteIMul64Imm>;316def IMUL16rmi8 : IMulOpMI8_R<Xi16, WriteIMul16Imm>, DefEFLAGS, OpSize16;317def IMUL32rmi8 : IMulOpMI8_R<Xi32, WriteIMul32Imm>, DefEFLAGS, OpSize32;318def IMUL64rmi8 : IMulOpMI8_R<Xi64, WriteIMul64Imm>, DefEFLAGS;319def IMUL16rmi  : IMulOpMI_RF<Xi16, WriteIMul16Imm>, OpSize16;320def IMUL32rmi  : IMulOpMI_RF<Xi32, WriteIMul32Imm>, OpSize32;321def IMUL64rmi32 : IMulOpMI_RF<Xi64, WriteIMul64Imm>;322 323let Predicates = [In64BitMode] in {324  def IMUL16rri8_NF : IMulOpRI8_R<Xi16, WriteIMul16Imm>, NF, PD;325  def IMUL32rri8_NF : IMulOpRI8_R<Xi32, WriteIMul32Imm>, NF;326  def IMUL64rri8_NF : IMulOpRI8_R<Xi64, WriteIMul64Imm>, NF;327  def IMUL16rri_NF  : IMulOpRI_R<Xi16, WriteIMul16Imm>, NF, PD;328  def IMUL32rri_NF  : IMulOpRI_R<Xi32, WriteIMul32Imm>, NF;329  def IMUL64rri32_NF : IMulOpRI_R<Xi64, WriteIMul64Imm>, NF;330  def IMUL16rmi8_NF : IMulOpMI8_R<Xi16, WriteIMul16Imm>, NF, PD;331  def IMUL32rmi8_NF : IMulOpMI8_R<Xi32, WriteIMul32Imm>, NF;332  def IMUL64rmi8_NF : IMulOpMI8_R<Xi64, WriteIMul64Imm>, NF;333  def IMUL16rmi_NF  : IMulOpMI_R<Xi16, WriteIMul16Imm>, NF, PD;334  def IMUL32rmi_NF  : IMulOpMI_R<Xi32, WriteIMul32Imm>, NF;335  def IMUL64rmi32_NF : IMulOpMI_R<Xi64, WriteIMul64Imm>, NF;336 337  def IMUL16rri8_EVEX : IMulOpRI8_R<Xi16, WriteIMul16Imm>, DefEFLAGS, PL, PD;338  def IMUL32rri8_EVEX : IMulOpRI8_R<Xi32, WriteIMul32Imm>, DefEFLAGS, PL;339  def IMUL64rri8_EVEX : IMulOpRI8_R<Xi64, WriteIMul64Imm>, DefEFLAGS, PL;340  def IMUL16rri_EVEX  : IMulOpRI_RF<Xi16, WriteIMul16Imm>, PL, PD;341  def IMUL32rri_EVEX  : IMulOpRI_RF<Xi32, WriteIMul32Imm>, PL;342  def IMUL64rri32_EVEX : IMulOpRI_RF<Xi64, WriteIMul64Imm>, PL;343  def IMUL16rmi8_EVEX : IMulOpMI8_R<Xi16, WriteIMul16Imm>, DefEFLAGS, PL, PD;344  def IMUL32rmi8_EVEX : IMulOpMI8_R<Xi32, WriteIMul32Imm>, DefEFLAGS, PL;345  def IMUL64rmi8_EVEX : IMulOpMI8_R<Xi64, WriteIMul64Imm>, DefEFLAGS, PL;346  def IMUL16rmi_EVEX  : IMulOpMI_RF<Xi16, WriteIMul16Imm>, PL, PD;347  def IMUL32rmi_EVEX  : IMulOpMI_RF<Xi32, WriteIMul32Imm>, PL;348  def IMUL64rmi32_EVEX : IMulOpMI_RF<Xi64, WriteIMul64Imm>, PL;349}350 351// IMULZU instructions352class IMulZUOpRI8_R<X86TypeInfo t, X86FoldableSchedWrite sched>353  : BinOpRI8<0x6B, "imulzu", binop_ndd_args, t, MRMSrcReg,354             (outs t.RegClass:$dst)> {355  let SchedRW = [sched];356}357class IMulZUOpRI_R<X86TypeInfo t, X86FoldableSchedWrite sched>358  : BinOpRI<0x69, "imulzu", binop_ndd_args, t, MRMSrcReg,359            (outs t.RegClass:$dst), []> {360  let SchedRW = [sched];361}362class IMulZUOpMI8_R<X86TypeInfo t, X86FoldableSchedWrite sched>363  : BinOpMI8<"imulzu", binop_ndd_args, t, MRMSrcMem, (outs t.RegClass:$dst)> {364  let Opcode = 0x6B;365  let SchedRW = [sched.Folded];366}367class IMulZUOpMI_R<X86TypeInfo t, X86FoldableSchedWrite sched>368  : BinOpMI<0x69, "imulzu", binop_ndd_args, t, MRMSrcMem,369            (outs t.RegClass:$dst), []> {370  let SchedRW = [sched.Folded];371}372 373let Defs = [EFLAGS], Predicates = [HasEGPR, In64BitMode] in {374  def IMULZU16rri8 : IMulZUOpRI8_R<Xi16, WriteIMul16Imm>, ZU, PD;375  def IMULZU16rmi8 : IMulZUOpMI8_R<Xi16, WriteIMul16Imm>, ZU, PD;376  def IMULZU16rri : IMulZUOpRI_R<Xi16, WriteIMul16Imm>, ZU, PD;377  def IMULZU16rmi : IMulZUOpMI_R<Xi16, WriteIMul16Imm>, ZU, PD;378  def IMULZU32rri8 : IMulZUOpRI8_R<Xi32, WriteIMul32Imm>, ZU;379  def IMULZU32rmi8 : IMulZUOpMI8_R<Xi32, WriteIMul32Imm>, ZU;380  def IMULZU32rri : IMulZUOpRI_R<Xi32, WriteIMul32Imm>, ZU;381  def IMULZU32rmi : IMulZUOpMI_R<Xi32, WriteIMul32Imm>, ZU;382  def IMULZU64rri8 : IMulZUOpRI8_R<Xi64, WriteIMul64Imm>, ZU;383  def IMULZU64rmi8 : IMulZUOpMI8_R<Xi64, WriteIMul64Imm>, ZU;384  def IMULZU64rri32 : IMulZUOpRI_R<Xi64, WriteIMul64Imm>, ZU;385  def IMULZU64rmi32 : IMulZUOpMI_R<Xi64, WriteIMul64Imm>, ZU;386}387 388//===----------------------------------------------------------------------===//389// INC and DEC Instructions390//391class IncOpR_RF<X86TypeInfo t, bit ndd = 0> : UnaryOpR_RF<0xFF, MRM0r, "inc", t, null_frag, ndd> {392  let Pattern = [(set t.RegClass:$dst, EFLAGS,393                 (X86add_flag_nocf t.RegClass:$src1, 1))];394}395class DecOpR_RF<X86TypeInfo t, bit ndd = 0> : UnaryOpR_RF<0xFF, MRM1r, "dec", t, null_frag, ndd> {396  let Pattern = [(set t.RegClass:$dst, EFLAGS,397                 (X86sub_flag_nocf t.RegClass:$src1, 1))];398}399class IncOpR_R<X86TypeInfo t, bit ndd = 0> : UnaryOpR_R<0xFF, MRM0r, "inc", t, null_frag, ndd>;400class DecOpR_R<X86TypeInfo t, bit ndd = 0> : UnaryOpR_R<0xFF, MRM1r, "dec", t, null_frag, ndd>;401class IncOpM_MF<X86TypeInfo t> : UnaryOpM_MF<0xFF, MRM0m, "inc", t, null_frag> {402  let Pattern = [(store (add (t.LoadNode addr:$src1), 1), addr:$src1)];403}404class DecOpM_MF<X86TypeInfo t> : UnaryOpM_MF<0xFF, MRM1m, "dec", t, null_frag> {405  let Pattern = [(store (add (t.LoadNode addr:$src1), -1), addr:$src1)];406}407class IncOpM_RF<X86TypeInfo t> : UnaryOpM_RF<0xFF, MRM0m, "inc", t, null_frag> {408  let Pattern = [(set t.RegClass:$dst, EFLAGS, (add (t.LoadNode addr:$src1), 1))];409}410class DecOpM_RF<X86TypeInfo t> : UnaryOpM_RF<0xFF, MRM1m, "dec", t, null_frag> {411  let Pattern = [(set t.RegClass:$dst, EFLAGS, (add (t.LoadNode addr:$src1), -1))];412}413class IncOpM_M<X86TypeInfo t> : UnaryOpM_M<0xFF, MRM0m, "inc", t, null_frag>;414class DecOpM_M<X86TypeInfo t> : UnaryOpM_M<0xFF, MRM1m, "dec", t, null_frag>;415class IncOpM_R<X86TypeInfo t> : UnaryOpM_R<0xFF, MRM0m, "inc", t, null_frag>;416class DecOpM_R<X86TypeInfo t> : UnaryOpM_R<0xFF, MRM1m, "dec", t, null_frag>;417 418// IncDec_Alt - Instructions like "inc reg" short forms.419// Short forms only valid in 32-bit mode. Selected during MCInst lowering.420class IncDec_Alt<bits<8> o, string m, X86TypeInfo t>421  : UnaryOpR_RF<o, AddRegFrm, m, t, null_frag>, Requires<[Not64BitMode]>;422 423let isConvertibleToThreeAddress = 1 in {424  def INC16r_alt : IncDec_Alt<0x40, "inc", Xi16>, OpSize16;425  def INC32r_alt : IncDec_Alt<0x40, "inc", Xi32>, OpSize32;426  def DEC16r_alt : IncDec_Alt<0x48, "dec", Xi16>, OpSize16;427  def DEC32r_alt : IncDec_Alt<0x48, "dec", Xi32>, OpSize32;428  let Predicates = [NoNDD] in {429    def INC8r  : IncOpR_RF<Xi8>;430    def INC16r : IncOpR_RF<Xi16>, OpSize16;431    def INC32r : IncOpR_RF<Xi32>, OpSize32;432    def INC64r : IncOpR_RF<Xi64>;433    def DEC8r  : DecOpR_RF<Xi8>;434    def DEC16r : DecOpR_RF<Xi16>, OpSize16;435    def DEC32r : DecOpR_RF<Xi32>, OpSize32;436    def DEC64r : DecOpR_RF<Xi64>;437  }438  let Predicates = [HasNDD, In64BitMode] in {439    def INC8r_ND  : IncOpR_RF<Xi8, 1>;440    def INC16r_ND : IncOpR_RF<Xi16, 1>, PD;441    def INC32r_ND : IncOpR_RF<Xi32, 1>;442    def INC64r_ND : IncOpR_RF<Xi64, 1>;443    def DEC8r_ND  : DecOpR_RF<Xi8, 1>;444    def DEC16r_ND : DecOpR_RF<Xi16, 1>, PD;445    def DEC32r_ND : DecOpR_RF<Xi32, 1>;446    def DEC64r_ND : DecOpR_RF<Xi64, 1>;447  }448  let Predicates = [In64BitMode], Pattern = [(null_frag)] in {449    def INC8r_NF  : IncOpR_R<Xi8>, NF;450    def INC16r_NF : IncOpR_R<Xi16>, NF, PD;451    def INC32r_NF : IncOpR_R<Xi32>, NF;452    def INC64r_NF : IncOpR_R<Xi64>, NF;453    def DEC8r_NF  : DecOpR_R<Xi8>, NF;454    def DEC16r_NF : DecOpR_R<Xi16>, NF, PD;455    def DEC32r_NF : DecOpR_R<Xi32>, NF;456    def DEC64r_NF : DecOpR_R<Xi64>, NF;457    def INC8r_NF_ND  : IncOpR_R<Xi8, 1>, NF;458    def INC16r_NF_ND : IncOpR_R<Xi16, 1>, NF, PD;459    def INC32r_NF_ND : IncOpR_R<Xi32, 1>, NF;460    def INC64r_NF_ND : IncOpR_R<Xi64, 1>, NF;461    def DEC8r_NF_ND  : DecOpR_R<Xi8, 1>, NF;462    def DEC16r_NF_ND : DecOpR_R<Xi16, 1>, NF, PD;463    def DEC32r_NF_ND : DecOpR_R<Xi32, 1>, NF;464    def DEC64r_NF_ND : DecOpR_R<Xi64, 1>, NF;465    def INC8r_EVEX  : IncOpR_RF<Xi8>, PL;466    def INC16r_EVEX : IncOpR_RF<Xi16>, PL, PD;467    def INC32r_EVEX : IncOpR_RF<Xi32>, PL;468    def INC64r_EVEX : IncOpR_RF<Xi64>, PL;469    def DEC8r_EVEX  : DecOpR_RF<Xi8>, PL;470    def DEC16r_EVEX : DecOpR_RF<Xi16>, PL, PD;471    def DEC32r_EVEX : DecOpR_RF<Xi32>, PL;472    def DEC64r_EVEX : DecOpR_RF<Xi64>, PL;473  }474}475let Predicates = [UseIncDec] in {476  def INC8m  : IncOpM_MF<Xi8>;477  def INC16m : IncOpM_MF<Xi16>, OpSize16;478  def INC32m : IncOpM_MF<Xi32>, OpSize32;479  def DEC8m  : DecOpM_MF<Xi8>;480  def DEC16m : DecOpM_MF<Xi16>, OpSize16;481  def DEC32m : DecOpM_MF<Xi32>, OpSize32;482}483let Predicates = [UseIncDec, In64BitMode] in {484  def INC64m : IncOpM_MF<Xi64>;485  def DEC64m : DecOpM_MF<Xi64>;486}487let Predicates = [HasNDD, In64BitMode, UseIncDec] in {488  def INC8m_ND  : IncOpM_RF<Xi8>;489  def INC16m_ND : IncOpM_RF<Xi16>, PD;490  def INC32m_ND : IncOpM_RF<Xi32>;491  def DEC8m_ND  : DecOpM_RF<Xi8>;492  def DEC16m_ND : DecOpM_RF<Xi16>, PD;493  def DEC32m_ND : DecOpM_RF<Xi32>;494  def INC64m_ND : IncOpM_RF<Xi64>;495  def DEC64m_ND : DecOpM_RF<Xi64>;496}497let Predicates = [In64BitMode], Pattern = [(null_frag)] in {498  def INC8m_NF  : IncOpM_M<Xi8>, NF;499  def INC16m_NF : IncOpM_M<Xi16>, NF, PD;500  def INC32m_NF : IncOpM_M<Xi32>, NF;501  def INC64m_NF : IncOpM_M<Xi64>, NF;502  def DEC8m_NF  : DecOpM_M<Xi8>, NF;503  def DEC16m_NF : DecOpM_M<Xi16>, NF, PD;504  def DEC32m_NF : DecOpM_M<Xi32>, NF;505  def DEC64m_NF : DecOpM_M<Xi64>, NF;506  def INC8m_NF_ND  : IncOpM_R<Xi8>, NF;507  def INC16m_NF_ND : IncOpM_R<Xi16>, NF, PD;508  def INC32m_NF_ND : IncOpM_R<Xi32>, NF;509  def INC64m_NF_ND : IncOpM_R<Xi64>, NF;510  def DEC8m_NF_ND  : DecOpM_R<Xi8>, NF;511  def DEC16m_NF_ND : DecOpM_R<Xi16>, NF, PD;512  def DEC32m_NF_ND : DecOpM_R<Xi32>, NF;513  def DEC64m_NF_ND : DecOpM_R<Xi64>, NF;514  def INC8m_EVEX  : IncOpM_MF<Xi8>, PL;515  def INC16m_EVEX : IncOpM_MF<Xi16>, PL, PD;516  def INC32m_EVEX : IncOpM_MF<Xi32>, PL;517  def INC64m_EVEX : IncOpM_MF<Xi64>, PL;518  def DEC8m_EVEX  : DecOpM_MF<Xi8>, PL;519  def DEC16m_EVEX : DecOpM_MF<Xi16>, PL, PD;520  def DEC32m_EVEX : DecOpM_MF<Xi32>, PL;521  def DEC64m_EVEX : DecOpM_MF<Xi64>, PL;522}523 524//===----------------------------------------------------------------------===//525// NEG and NOT Instructions526//527class NegOpR_R<X86TypeInfo t, bit ndd = 0>528  : UnaryOpR_R<0xF7, MRM3r, "neg", t, ineg, ndd>;529class NegOpR_RF<X86TypeInfo t, bit ndd = 0>530  : UnaryOpR_RF<0xF7, MRM3r, "neg", t, ineg, ndd>;531class NegOpM_M<X86TypeInfo t> : UnaryOpM_M<0xF7, MRM3m, "neg", t, null_frag>;532class NegOpM_MF<X86TypeInfo t> : UnaryOpM_MF<0xF7, MRM3m, "neg", t, ineg>;533class NegOpM_R<X86TypeInfo t> : UnaryOpM_R<0xF7, MRM3m, "neg", t, null_frag>;534class NegOpM_RF<X86TypeInfo t> : UnaryOpM_RF<0xF7, MRM3m, "neg", t, ineg>;535 536class NotOpR_R<X86TypeInfo t, bit ndd = 0>537  : UnaryOpR_R<0xF7, MRM2r, "not", t, not, ndd>;538class NotOpM_M<X86TypeInfo t> : UnaryOpM_M<0xF7, MRM2m, "not", t, not>;539class NotOpM_R<X86TypeInfo t> : UnaryOpM_R<0xF7, MRM2m, "not", t, not>;540 541let Predicates = [NoNDD] in {542def NEG8r  : NegOpR_RF<Xi8>;543def NEG16r : NegOpR_RF<Xi16>, OpSize16;544def NEG32r : NegOpR_RF<Xi32>, OpSize32;545def NEG64r : NegOpR_RF<Xi64>;546def NOT8r  : NotOpR_R<Xi8>;547def NOT16r : NotOpR_R<Xi16>, OpSize16;548def NOT32r : NotOpR_R<Xi32>, OpSize32;549def NOT64r : NotOpR_R<Xi64>;550}551 552let Predicates = [HasNDD, In64BitMode] in {553def NEG8r_ND  : NegOpR_RF<Xi8, 1>;554def NEG16r_ND : NegOpR_RF<Xi16, 1>, PD;555def NEG32r_ND : NegOpR_RF<Xi32, 1>;556def NEG64r_ND : NegOpR_RF<Xi64, 1>;557 558def NOT8r_ND  : NotOpR_R<Xi8, 1>;559def NOT16r_ND : NotOpR_R<Xi16, 1>, PD;560def NOT32r_ND : NotOpR_R<Xi32, 1>;561def NOT64r_ND : NotOpR_R<Xi64, 1>;562 563def NEG8r_NF_ND  : NegOpR_R<Xi8, 1>, EVEX_NF;564def NEG16r_NF_ND : NegOpR_R<Xi16, 1>, EVEX_NF, PD;565def NEG32r_NF_ND : NegOpR_R<Xi32, 1>, EVEX_NF;566def NEG64r_NF_ND : NegOpR_R<Xi64, 1>, EVEX_NF;567}568 569def NEG8m  : NegOpM_MF<Xi8>;570def NEG16m : NegOpM_MF<Xi16>, OpSize16;571def NEG32m : NegOpM_MF<Xi32>, OpSize32;572def NEG64m : NegOpM_MF<Xi64>, Requires<[In64BitMode]>;573 574let Predicates = [HasNDD, In64BitMode] in {575def NEG8m_ND  : NegOpM_RF<Xi8>;576def NEG16m_ND : NegOpM_RF<Xi16>, PD;577def NEG32m_ND : NegOpM_RF<Xi32>;578def NEG64m_ND : NegOpM_RF<Xi64>;579 580def NEG8m_NF_ND  : NegOpM_R<Xi8>, EVEX_NF;581def NEG16m_NF_ND : NegOpM_R<Xi16>, EVEX_NF, PD;582def NEG32m_NF_ND : NegOpM_R<Xi32>, EVEX_NF;583def NEG64m_NF_ND : NegOpM_R<Xi64>, EVEX_NF;584}585 586def NOT8m  : NotOpM_M<Xi8>;587def NOT16m : NotOpM_M<Xi16>, OpSize16;588def NOT32m : NotOpM_M<Xi32>, OpSize32;589def NOT64m : NotOpM_M<Xi64>, Requires<[In64BitMode]>;590 591let Predicates = [HasNDD, In64BitMode] in {592def NOT8m_ND  : NotOpM_R<Xi8>;593def NOT16m_ND : NotOpM_R<Xi16>, PD;594def NOT32m_ND : NotOpM_R<Xi32>;595def NOT64m_ND : NotOpM_R<Xi64>;596}597 598let Predicates = [In64BitMode], Pattern = [(null_frag)] in {599def NEG8r_NF  : NegOpR_R<Xi8>, NF;600def NEG16r_NF : NegOpR_R<Xi16>, NF, PD;601def NEG32r_NF : NegOpR_R<Xi32>, NF;602def NEG64r_NF : NegOpR_R<Xi64>, NF;603def NEG8m_NF  : NegOpM_M<Xi8>, NF;604def NEG16m_NF : NegOpM_M<Xi16>, NF, PD;605def NEG32m_NF : NegOpM_M<Xi32>, NF;606def NEG64m_NF : NegOpM_M<Xi64>, NF;607 608def NEG8r_EVEX  : NegOpR_RF<Xi8>, PL;609def NEG16r_EVEX : NegOpR_RF<Xi16>, PL, PD;610def NEG32r_EVEX : NegOpR_RF<Xi32>, PL;611def NEG64r_EVEX : NegOpR_RF<Xi64>, PL;612 613def NOT8r_EVEX  : NotOpR_R<Xi8>, PL;614def NOT16r_EVEX : NotOpR_R<Xi16>, PL, PD;615def NOT32r_EVEX : NotOpR_R<Xi32>, PL;616def NOT64r_EVEX : NotOpR_R<Xi64>, PL;617 618def NEG8m_EVEX  : NegOpM_MF<Xi8>, PL;619def NEG16m_EVEX : NegOpM_MF<Xi16>, PL, PD;620def NEG32m_EVEX : NegOpM_MF<Xi32>, PL;621def NEG64m_EVEX : NegOpM_MF<Xi64>, PL;622 623def NOT8m_EVEX  : NotOpM_M<Xi8>, PL;624def NOT16m_EVEX : NotOpM_M<Xi16>, PL, PD;625def NOT32m_EVEX : NotOpM_M<Xi32>, PL;626def NOT64m_EVEX : NotOpM_M<Xi64>, PL;627}628 629/// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is630/// defined with "(set GPR:$dst, EFLAGS, (...".631///632/// It would be nice to get rid of the second and third argument here, but633/// tblgen can't handle dependent type references aggressively enough: PR8330634multiclass ArithBinOp_RF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,635                         string mnemonic, Format RegMRM, Format MemMRM,636                         SDNode opnodeflag, SDNode opnode,637                         bit CommutableRR, bit ConvertibleToThreeAddress,638                         bit ConvertibleToThreeAddressRR> {639  let isCommutable = CommutableRR,640      isConvertibleToThreeAddress = ConvertibleToThreeAddressRR in {641    let Predicates = [NoNDD] in {642      def 8rr  : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , opnodeflag>;643      def 16rr : BinOpRR_RF<BaseOpc, mnemonic, Xi16, opnodeflag>, OpSize16;644      def 32rr : BinOpRR_RF<BaseOpc, mnemonic, Xi32, opnodeflag>, OpSize32;645      def 64rr : BinOpRR_RF<BaseOpc, mnemonic, Xi64, opnodeflag>;646    }647    let Predicates = [HasNDD, In64BitMode] in {648      def 8rr_ND  : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , opnodeflag, 1>;649      def 16rr_ND : BinOpRR_RF<BaseOpc, mnemonic, Xi16, opnodeflag, 1>, PD;650      def 32rr_ND : BinOpRR_RF<BaseOpc, mnemonic, Xi32, opnodeflag, 1>;651      def 64rr_ND : BinOpRR_RF<BaseOpc, mnemonic, Xi64, opnodeflag, 1>;652      def 8rr_NF_ND  : BinOpRR_R<BaseOpc, mnemonic, Xi8, 1>, EVEX_NF;653      def 16rr_NF_ND : BinOpRR_R<BaseOpc, mnemonic, Xi16, 1>, EVEX_NF, PD;654      def 32rr_NF_ND : BinOpRR_R<BaseOpc, mnemonic, Xi32, 1>, EVEX_NF;655      def 64rr_NF_ND : BinOpRR_R<BaseOpc, mnemonic, Xi64, 1>, EVEX_NF;656    }657    let Predicates = [In64BitMode] in {658      def 8rr_NF  : BinOpRR_R<BaseOpc, mnemonic, Xi8>, NF;659      def 16rr_NF : BinOpRR_R<BaseOpc, mnemonic, Xi16>, NF, PD;660      def 32rr_NF : BinOpRR_R<BaseOpc, mnemonic, Xi32>, NF;661      def 64rr_NF : BinOpRR_R<BaseOpc, mnemonic, Xi64>, NF;662      def 8rr_EVEX  : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , null_frag>, PL;663      def 16rr_EVEX : BinOpRR_RF<BaseOpc, mnemonic, Xi16, null_frag>, PL, PD;664      def 32rr_EVEX : BinOpRR_RF<BaseOpc, mnemonic, Xi32, null_frag>, PL;665      def 64rr_EVEX : BinOpRR_RF<BaseOpc, mnemonic, Xi64, null_frag>, PL;666    }667  }668 669  def 8rr_REV  : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi8>;670  def 16rr_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi16>, OpSize16;671  def 32rr_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi32>, OpSize32;672  def 64rr_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi64>;673  let Predicates = [In64BitMode] in {674    def 8rr_EVEX_REV  : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi8>, PL;675    def 16rr_EVEX_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi16>, PL, PD;676    def 32rr_EVEX_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi32>, PL;677    def 64rr_EVEX_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi64>, PL;678    def 8rr_ND_REV  : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi8, 1>;679    def 16rr_ND_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi16, 1>, PD;680    def 32rr_ND_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi32, 1>;681    def 64rr_ND_REV : BinOpRR_RF_Rev<BaseOpc2, mnemonic, Xi64, 1>;682    def 8rr_NF_REV  : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi8>, NF;683    def 16rr_NF_REV : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi16>, NF, PD;684    def 32rr_NF_REV : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi32>, NF;685    def 64rr_NF_REV : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi64>, NF;686    def 8rr_NF_ND_REV  : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi8, 1>, EVEX_NF;687    def 16rr_NF_ND_REV : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi16, 1>, EVEX_NF, PD;688    def 32rr_NF_ND_REV : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi32, 1>, EVEX_NF;689    def 64rr_NF_ND_REV : BinOpRR_R_Rev<BaseOpc2, mnemonic, Xi64, 1>, EVEX_NF;690  }691 692  let Predicates = [NoNDD] in {693    def 8rm   : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , opnodeflag>;694    def 16rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, opnodeflag>, OpSize16;695    def 32rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, opnodeflag>, OpSize32;696    def 64rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, opnodeflag>;697  }698  let Predicates = [HasNDD, In64BitMode] in {699    def 8rm_ND  : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , opnodeflag, 1>;700    def 16rm_ND : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, opnodeflag, 1>, PD;701    def 32rm_ND : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, opnodeflag, 1>;702    def 64rm_ND : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, opnodeflag, 1>;703    def 8rm_NF_ND  : BinOpRM_R<BaseOpc2, mnemonic, Xi8, 1>, EVEX_NF;704    def 16rm_NF_ND : BinOpRM_R<BaseOpc2, mnemonic, Xi16, 1>, EVEX_NF, PD;705    def 32rm_NF_ND : BinOpRM_R<BaseOpc2, mnemonic, Xi32, 1>, EVEX_NF;706    def 64rm_NF_ND : BinOpRM_R<BaseOpc2, mnemonic, Xi64, 1>, EVEX_NF;707  }708  let Predicates = [In64BitMode] in {709    def 8rm_NF  : BinOpRM_R<BaseOpc2, mnemonic, Xi8>, NF;710    def 16rm_NF : BinOpRM_R<BaseOpc2, mnemonic, Xi16>, NF, PD;711    def 32rm_NF : BinOpRM_R<BaseOpc2, mnemonic, Xi32>, NF;712    def 64rm_NF : BinOpRM_R<BaseOpc2, mnemonic, Xi64>, NF;713    def 8rm_EVEX  : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , null_frag>, PL;714    def 16rm_EVEX : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, null_frag>, PL, PD;715    def 32rm_EVEX : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, null_frag>, PL;716    def 64rm_EVEX : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, null_frag>, PL;717  }718 719  let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {720    let Predicates = [NoNDD] in {721      // NOTE: These are order specific, we want the ri8 forms to be listed722      // first so that they are slightly preferred to the ri forms.723      def 16ri8 : BinOpRI8_RF<0x83, mnemonic, Xi16, RegMRM>, OpSize16;724      def 32ri8 : BinOpRI8_RF<0x83, mnemonic, Xi32, RegMRM>, OpSize32;725      def 64ri8 : BinOpRI8_RF<0x83, mnemonic, Xi64, RegMRM>;726      def 8ri   : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM>;727      def 16ri  : BinOpRI_RF<0x81, mnemonic, Xi16, opnodeflag, RegMRM>, OpSize16;728      def 32ri  : BinOpRI_RF<0x81, mnemonic, Xi32, opnodeflag, RegMRM>, OpSize32;729      def 64ri32: BinOpRI_RF<0x81, mnemonic, Xi64, opnodeflag, RegMRM>;730    }731    let Predicates = [HasNDD, In64BitMode] in {732      def 16ri8_ND : BinOpRI8_RF<0x83, mnemonic, Xi16, RegMRM, 1>, PD;733      def 32ri8_ND : BinOpRI8_RF<0x83, mnemonic, Xi32, RegMRM, 1>;734      def 64ri8_ND : BinOpRI8_RF<0x83, mnemonic, Xi64, RegMRM, 1>;735      def 8ri_ND   : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM, 1>;736      def 16ri_ND  : BinOpRI_RF<0x81, mnemonic, Xi16, opnodeflag, RegMRM, 1>, PD;737      def 32ri_ND  : BinOpRI_RF<0x81, mnemonic, Xi32, opnodeflag, RegMRM, 1>;738      def 64ri32_ND: BinOpRI_RF<0x81, mnemonic, Xi64, opnodeflag, RegMRM, 1>;739      def 16ri8_NF_ND : BinOpRI8_R<0x83, mnemonic, Xi16, RegMRM, 1>, EVEX_NF, PD;740      def 32ri8_NF_ND : BinOpRI8_R<0x83, mnemonic, Xi32, RegMRM, 1>, EVEX_NF;741      def 64ri8_NF_ND : BinOpRI8_R<0x83, mnemonic, Xi64, RegMRM, 1>, EVEX_NF;742      def 8ri_NF_ND  : BinOpRI_R<0x80, mnemonic, Xi8, RegMRM, 1>, EVEX_NF;743      def 16ri_NF_ND : BinOpRI_R<0x81, mnemonic, Xi16, RegMRM, 1>, EVEX_NF, PD;744      def 32ri_NF_ND : BinOpRI_R<0x81, mnemonic, Xi32, RegMRM, 1>, EVEX_NF;745      def 64ri32_NF_ND : BinOpRI_R<0x81, mnemonic, Xi64, RegMRM, 1>, EVEX_NF;746    }747    let Predicates = [In64BitMode] in {748      def 16ri8_NF : BinOpRI8_R<0x83, mnemonic, Xi16, RegMRM>, NF, PD;749      def 32ri8_NF : BinOpRI8_R<0x83, mnemonic, Xi32, RegMRM>, NF;750      def 64ri8_NF : BinOpRI8_R<0x83, mnemonic, Xi64, RegMRM>, NF;751      def 8ri_NF  : BinOpRI_R<0x80, mnemonic, Xi8, RegMRM>, NF;752      def 16ri_NF : BinOpRI_R<0x81, mnemonic, Xi16, RegMRM>, NF, PD;753      def 32ri_NF : BinOpRI_R<0x81, mnemonic, Xi32, RegMRM>, NF;754      def 64ri32_NF : BinOpRI_R<0x81, mnemonic, Xi64, RegMRM>, NF;755      def 16ri8_EVEX : BinOpRI8_RF<0x83, mnemonic, Xi16, RegMRM>, PL, PD;756      def 32ri8_EVEX : BinOpRI8_RF<0x83, mnemonic, Xi32, RegMRM>, PL;757      def 64ri8_EVEX : BinOpRI8_RF<0x83, mnemonic, Xi64, RegMRM>, PL;758      def 8ri_EVEX   : BinOpRI_RF<0x80, mnemonic, Xi8 , null_frag, RegMRM>, PL;759      def 16ri_EVEX  : BinOpRI_RF<0x81, mnemonic, Xi16, null_frag, RegMRM>, PL, PD;760      def 32ri_EVEX  : BinOpRI_RF<0x81, mnemonic, Xi32, null_frag, RegMRM>, PL;761      def 64ri32_EVEX: BinOpRI_RF<0x81, mnemonic, Xi64, null_frag, RegMRM>, PL;762    }763  }764 765  def 8mr    : BinOpMR_MF<BaseOpc, mnemonic, Xi8 , opnode>;766  def 16mr   : BinOpMR_MF<BaseOpc, mnemonic, Xi16, opnode>, OpSize16;767  def 32mr   : BinOpMR_MF<BaseOpc, mnemonic, Xi32, opnode>, OpSize32;768  def 64mr   : BinOpMR_MF<BaseOpc, mnemonic, Xi64, opnode>;769  let Predicates = [HasNDD, In64BitMode] in {770    defvar node = !if(!eq(CommutableRR, 0), opnode, null_frag);771    def 8mr_ND    : BinOpMR_RF<BaseOpc, mnemonic, Xi8 , node>;772    def 16mr_ND   : BinOpMR_RF<BaseOpc, mnemonic, Xi16, node>, PD;773    def 32mr_ND   : BinOpMR_RF<BaseOpc, mnemonic, Xi32, node>;774    def 64mr_ND   : BinOpMR_RF<BaseOpc, mnemonic, Xi64, node>;775    def 8mr_NF_ND    : BinOpMR_R<BaseOpc, mnemonic, Xi8>, EVEX_NF;776    def 16mr_NF_ND   : BinOpMR_R<BaseOpc, mnemonic, Xi16>, EVEX_NF, PD;777    def 32mr_NF_ND   : BinOpMR_R<BaseOpc, mnemonic, Xi32>, EVEX_NF;778    def 64mr_NF_ND   : BinOpMR_R<BaseOpc, mnemonic, Xi64>, EVEX_NF;779  }780  let Predicates = [In64BitMode] in {781    def 8mr_NF    : BinOpMR_M<BaseOpc, mnemonic, Xi8>, NF;782    def 16mr_NF   : BinOpMR_M<BaseOpc, mnemonic, Xi16>, NF, PD;783    def 32mr_NF   : BinOpMR_M<BaseOpc, mnemonic, Xi32>, NF;784    def 64mr_NF   : BinOpMR_M<BaseOpc, mnemonic, Xi64>, NF;785    def 8mr_EVEX    : BinOpMR_MF<BaseOpc, mnemonic, Xi8 , null_frag>, PL;786    def 16mr_EVEX   : BinOpMR_MF<BaseOpc, mnemonic, Xi16, null_frag>, PL, PD;787    def 32mr_EVEX   : BinOpMR_MF<BaseOpc, mnemonic, Xi32, null_frag>, PL;788    def 64mr_EVEX   : BinOpMR_MF<BaseOpc, mnemonic, Xi64, null_frag>, PL;789  }790 791  // NOTE: These are order specific, we want the mi8 forms to be listed792  // first so that they are slightly preferred to the mi forms.793  def 16mi8  : BinOpMI8_MF<mnemonic, Xi16, MemMRM>, OpSize16;794  def 32mi8  : BinOpMI8_MF<mnemonic, Xi32, MemMRM>, OpSize32;795  let Predicates = [In64BitMode] in796    def 64mi8  : BinOpMI8_MF<mnemonic, Xi64, MemMRM>;797  def 8mi    : BinOpMI_MF<0x80, mnemonic, Xi8 , opnode, MemMRM>;798  def 16mi   : BinOpMI_MF<0x81, mnemonic, Xi16, opnode, MemMRM>, OpSize16;799  def 32mi   : BinOpMI_MF<0x81, mnemonic, Xi32, opnode, MemMRM>, OpSize32;800  let Predicates = [In64BitMode] in801    def 64mi32 : BinOpMI_MF<0x81, mnemonic, Xi64, opnode, MemMRM>;802  let Predicates = [HasNDD, In64BitMode] in {803    def 16mi8_ND  : BinOpMI8_RF<mnemonic, Xi16, MemMRM>, PD;804    def 32mi8_ND  : BinOpMI8_RF<mnemonic, Xi32, MemMRM>;805    def 64mi8_ND  : BinOpMI8_RF<mnemonic, Xi64, MemMRM>;806    def 8mi_ND    : BinOpMI_RF<0x80, mnemonic, Xi8 , opnode, MemMRM>;807    def 16mi_ND   : BinOpMI_RF<0x81, mnemonic, Xi16, opnode, MemMRM>, PD;808    def 32mi_ND   : BinOpMI_RF<0x81, mnemonic, Xi32, opnode, MemMRM>;809    def 64mi32_ND : BinOpMI_RF<0x81, mnemonic, Xi64, opnode, MemMRM>;810    def 16mi8_NF_ND  : BinOpMI8_R<mnemonic, Xi16, MemMRM>, NF, PD;811    def 32mi8_NF_ND  : BinOpMI8_R<mnemonic, Xi32, MemMRM>, NF;812    def 64mi8_NF_ND  : BinOpMI8_R<mnemonic, Xi64, MemMRM>, NF;813    def 8mi_NF_ND    : BinOpMI_R<0x80, mnemonic, Xi8, MemMRM>, NF;814    def 16mi_NF_ND   : BinOpMI_R<0x81, mnemonic, Xi16, MemMRM>, NF, PD;815    def 32mi_NF_ND   : BinOpMI_R<0x81, mnemonic, Xi32, MemMRM>, NF;816    def 64mi32_NF_ND : BinOpMI_R<0x81, mnemonic, Xi64, MemMRM>, NF;817  }818  let Predicates = [In64BitMode] in {819    def 16mi8_NF  : BinOpMI8_M<mnemonic, Xi16, MemMRM>, NF, PD;820    def 32mi8_NF  : BinOpMI8_M<mnemonic, Xi32, MemMRM>, NF;821    def 64mi8_NF  : BinOpMI8_M<mnemonic, Xi64, MemMRM>, NF;822    def 8mi_NF    : BinOpMI_M<0x80, mnemonic, Xi8, MemMRM>, NF;823    def 16mi_NF   : BinOpMI_M<0x81, mnemonic, Xi16, MemMRM>, NF, PD;824    def 32mi_NF   : BinOpMI_M<0x81, mnemonic, Xi32, MemMRM>, NF;825    def 64mi32_NF : BinOpMI_M<0x81, mnemonic, Xi64, MemMRM>, NF;826    def 16mi8_EVEX  : BinOpMI8_MF<mnemonic, Xi16, MemMRM>, PL, PD;827    def 32mi8_EVEX  : BinOpMI8_MF<mnemonic, Xi32, MemMRM>, PL;828    def 64mi8_EVEX  : BinOpMI8_MF<mnemonic, Xi64, MemMRM>, PL;829    def 8mi_EVEX    : BinOpMI_MF<0x80, mnemonic, Xi8 , null_frag, MemMRM>, PL;830    def 16mi_EVEX   : BinOpMI_MF<0x81, mnemonic, Xi16, null_frag, MemMRM>, PL, PD;831    def 32mi_EVEX   : BinOpMI_MF<0x81, mnemonic, Xi32, null_frag, MemMRM>, PL;832    def 64mi32_EVEX : BinOpMI_MF<0x81, mnemonic, Xi64, null_frag, MemMRM>, PL;833  }834 835  // These are for the disassembler since 0x82 opcode behaves like 0x80, but836  // not in 64-bit mode.837  let Predicates = [Not64BitMode] in {838    def 8ri8 : BinOpRI8_RF<0x82, mnemonic, Xi8, RegMRM>, DisassembleOnly;839    def 8mi8 : BinOpMI8_MF<mnemonic, Xi8, MemMRM>, DisassembleOnly;840  }841 842  def 8i8 : BinOpAI_AF<BaseOpc4, mnemonic, Xi8 , AL, "{$src, %al|al, $src}">;843  def 16i16 : BinOpAI_AF<BaseOpc4, mnemonic, Xi16, AX, "{$src, %ax|ax, $src}">, OpSize16;844  def 32i32 : BinOpAI_AF<BaseOpc4, mnemonic, Xi32, EAX, "{$src, %eax|eax, $src}">, OpSize32;845  def 64i32 : BinOpAI_AF<BaseOpc4, mnemonic, Xi64, RAX, "{$src, %rax|rax, $src}">;846}847 848/// ArithBinOp_RFF - This is an arithmetic binary operator where the pattern is849/// defined with "(set GPR:$dst, EFLAGS, (node LHS, RHS, EFLAGS))" like ADC and850/// SBB.851///852/// It would be nice to get rid of the second and third argument here, but853/// tblgen can't handle dependent type references aggressively enough: PR8330854multiclass ArithBinOp_RFF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,855                          string mnemonic, Format RegMRM, Format MemMRM,856                          SDNode opnode, bit CommutableRR,857                           bit ConvertibleToThreeAddress> {858  let isCommutable = CommutableRR in {859    let Predicates = [NoNDD] in {860      def 8rr  : BinOpRRF_RF<BaseOpc, mnemonic, Xi8 , opnode>;861      let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {862        def 16rr : BinOpRRF_RF<BaseOpc, mnemonic, Xi16, opnode>, OpSize16;863        def 32rr : BinOpRRF_RF<BaseOpc, mnemonic, Xi32, opnode>, OpSize32;864        def 64rr : BinOpRRF_RF<BaseOpc, mnemonic, Xi64, opnode>;865      }866    }867    let Predicates = [HasNDD, In64BitMode] in {868      def 8rr_ND  : BinOpRRF_RF<BaseOpc, mnemonic, Xi8 , opnode, 1>;869      let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {870        def 16rr_ND : BinOpRRF_RF<BaseOpc, mnemonic, Xi16, opnode, 1>, PD;871        def 32rr_ND : BinOpRRF_RF<BaseOpc, mnemonic, Xi32, opnode, 1>;872        def 64rr_ND : BinOpRRF_RF<BaseOpc, mnemonic, Xi64, opnode, 1>;873      }874    }875  } // isCommutable876 877  let Predicates = [In64BitMode] in {878    def 8rr_EVEX  : BinOpRRF_RF<BaseOpc, mnemonic, Xi8 , null_frag>, PL;879    def 16rr_EVEX : BinOpRRF_RF<BaseOpc, mnemonic, Xi16, null_frag>, PL, PD;880    def 32rr_EVEX : BinOpRRF_RF<BaseOpc, mnemonic, Xi32, null_frag>, PL;881    def 64rr_EVEX : BinOpRRF_RF<BaseOpc, mnemonic, Xi64, null_frag>, PL;882  }883 884  def 8rr_REV  : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi8>;885  def 16rr_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi16>, OpSize16;886  def 32rr_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi32>, OpSize32;887  def 64rr_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi64>;888  let Predicates = [In64BitMode] in {889    def 8rr_ND_REV  : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi8, 1>;890    def 16rr_ND_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi16, 1>, PD;891    def 32rr_ND_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi32, 1>;892    def 64rr_ND_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi64, 1>;893    def 8rr_EVEX_REV  : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi8>, PL;894    def 16rr_EVEX_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi16>, PL, PD;895    def 32rr_EVEX_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi32>, PL;896    def 64rr_EVEX_REV : BinOpRRF_RF_Rev<BaseOpc2, mnemonic, Xi64>, PL;897  }898 899  let Predicates = [NoNDD] in {900    def 8rm   : BinOpRMF_RF<BaseOpc2, mnemonic, Xi8 , opnode>;901    def 16rm  : BinOpRMF_RF<BaseOpc2, mnemonic, Xi16, opnode>, OpSize16;902    def 32rm  : BinOpRMF_RF<BaseOpc2, mnemonic, Xi32, opnode>, OpSize32;903    def 64rm  : BinOpRMF_RF<BaseOpc2, mnemonic, Xi64, opnode>;904  }905  let Predicates = [HasNDD, In64BitMode] in {906    def 8rm_ND   : BinOpRMF_RF<BaseOpc2, mnemonic, Xi8 , opnode, 1>;907    def 16rm_ND  : BinOpRMF_RF<BaseOpc2, mnemonic, Xi16, opnode, 1>, PD;908    def 32rm_ND  : BinOpRMF_RF<BaseOpc2, mnemonic, Xi32, opnode, 1>;909    def 64rm_ND  : BinOpRMF_RF<BaseOpc2, mnemonic, Xi64, opnode, 1>;910  }911  let Predicates = [In64BitMode] in {912    def 8rm_EVEX   : BinOpRMF_RF<BaseOpc2, mnemonic, Xi8 , opnode>, PL;913    def 16rm_EVEX  : BinOpRMF_RF<BaseOpc2, mnemonic, Xi16, opnode>, PL, PD;914    def 32rm_EVEX  : BinOpRMF_RF<BaseOpc2, mnemonic, Xi32, opnode>, PL;915    def 64rm_EVEX  : BinOpRMF_RF<BaseOpc2, mnemonic, Xi64, opnode>, PL;916  }917 918  let Predicates = [NoNDD] in {919    def 8ri   : BinOpRIF_RF<0x80, mnemonic, Xi8 , opnode, RegMRM>;920    let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {921      // NOTE: These are order specific, we want the ri8 forms to be listed922      // first so that they are slightly preferred to the ri forms.923      def 16ri8 : BinOpRI8F_RF<0x83, mnemonic, Xi16, RegMRM>, OpSize16;924      def 32ri8 : BinOpRI8F_RF<0x83, mnemonic, Xi32, RegMRM>, OpSize32;925      def 64ri8 : BinOpRI8F_RF<0x83, mnemonic, Xi64, RegMRM>;926 927      def 16ri  : BinOpRIF_RF<0x81, mnemonic, Xi16, opnode, RegMRM>, OpSize16;928      def 32ri  : BinOpRIF_RF<0x81, mnemonic, Xi32, opnode, RegMRM>, OpSize32;929      def 64ri32: BinOpRIF_RF<0x81, mnemonic, Xi64, opnode, RegMRM>;930    }931  }932 933  let Predicates = [HasNDD, In64BitMode] in {934    def 8ri_ND   : BinOpRIF_RF<0x80, mnemonic, Xi8 , opnode, RegMRM, 1>;935    let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {936      def 16ri8_ND : BinOpRI8F_RF<0x83, mnemonic, Xi16, RegMRM, 1>, PD;937      def 32ri8_ND : BinOpRI8F_RF<0x83, mnemonic, Xi32, RegMRM, 1>;938      def 64ri8_ND : BinOpRI8F_RF<0x83, mnemonic, Xi64, RegMRM, 1>;939      def 16ri_ND  : BinOpRIF_RF<0x81, mnemonic, Xi16, opnode, RegMRM, 1>, PD;940      def 32ri_ND  : BinOpRIF_RF<0x81, mnemonic, Xi32, opnode, RegMRM, 1>;941      def 64ri32_ND: BinOpRIF_RF<0x81, mnemonic, Xi64, opnode, RegMRM, 1>;942    }943  }944  let Predicates = [In64BitMode] in {945    def 8ri_EVEX   : BinOpRIF_RF<0x80, mnemonic, Xi8 , opnode, RegMRM>, PL;946    def 16ri8_EVEX : BinOpRI8F_RF<0x83, mnemonic, Xi16, RegMRM>, PL, PD;947    def 32ri8_EVEX : BinOpRI8F_RF<0x83, mnemonic, Xi32, RegMRM>, PL;948    def 64ri8_EVEX : BinOpRI8F_RF<0x83, mnemonic, Xi64, RegMRM>, PL;949    def 16ri_EVEX  : BinOpRIF_RF<0x81, mnemonic, Xi16, opnode, RegMRM>, PL, PD;950    def 32ri_EVEX  : BinOpRIF_RF<0x81, mnemonic, Xi32, opnode, RegMRM>, PL;951    def 64ri32_EVEX: BinOpRIF_RF<0x81, mnemonic, Xi64, opnode, RegMRM>, PL;952  }953 954  def 8mr    : BinOpMRF_MF<BaseOpc, mnemonic, Xi8 , opnode>;955  def 16mr   : BinOpMRF_MF<BaseOpc, mnemonic, Xi16, opnode>, OpSize16;956  def 32mr   : BinOpMRF_MF<BaseOpc, mnemonic, Xi32, opnode>, OpSize32;957  def 64mr   : BinOpMRF_MF<BaseOpc, mnemonic, Xi64, opnode>;958  let Predicates = [HasNDD, In64BitMode] in {959    defvar node = !if(!eq(CommutableRR, 0), opnode, null_frag);960    def 8mr_ND    : BinOpMRF_RF<BaseOpc, mnemonic, Xi8 , node>;961    def 16mr_ND   : BinOpMRF_RF<BaseOpc, mnemonic, Xi16, node>, PD;962    def 32mr_ND   : BinOpMRF_RF<BaseOpc, mnemonic, Xi32, node>;963    def 64mr_ND   : BinOpMRF_RF<BaseOpc, mnemonic, Xi64, node>;964  }965  let Predicates = [In64BitMode] in {966    def 8mr_EVEX    : BinOpMRF_MF<BaseOpc, mnemonic, Xi8 , null_frag>, PL;967    def 16mr_EVEX   : BinOpMRF_MF<BaseOpc, mnemonic, Xi16, null_frag>, PL, PD;968    def 32mr_EVEX   : BinOpMRF_MF<BaseOpc, mnemonic, Xi32, null_frag>, PL;969    def 64mr_EVEX   : BinOpMRF_MF<BaseOpc, mnemonic, Xi64, null_frag>, PL;970  }971 972  // NOTE: These are order specific, we want the mi8 forms to be listed973  // first so that they are slightly preferred to the mi forms.974  def 8mi    : BinOpMIF_MF<0x80, mnemonic, Xi8 , opnode, MemMRM>;975  def 16mi8  : BinOpMI8F_MF<mnemonic, Xi16, MemMRM>, OpSize16;976  def 32mi8  : BinOpMI8F_MF<mnemonic, Xi32, MemMRM>, OpSize32;977  let Predicates = [In64BitMode] in978    def 64mi8  : BinOpMI8F_MF<mnemonic, Xi64, MemMRM>;979  def 16mi   : BinOpMIF_MF<0x81, mnemonic, Xi16, opnode, MemMRM>, OpSize16;980  def 32mi   : BinOpMIF_MF<0x81, mnemonic, Xi32, opnode, MemMRM>, OpSize32;981  let Predicates = [In64BitMode] in982    def 64mi32 : BinOpMIF_MF<0x81, mnemonic, Xi64, opnode, MemMRM>;983 984  let Predicates = [HasNDD, In64BitMode] in {985    def 8mi_ND    : BinOpMIF_RF<0x80, mnemonic, Xi8 , opnode, MemMRM>;986    def 16mi8_ND  : BinOpMI8F_RF<mnemonic, Xi16, MemMRM>, PD;987    def 32mi8_ND  : BinOpMI8F_RF<mnemonic, Xi32, MemMRM>;988    def 64mi8_ND  : BinOpMI8F_RF<mnemonic, Xi64, MemMRM>;989    def 16mi_ND   : BinOpMIF_RF<0x81, mnemonic, Xi16, opnode, MemMRM>, PD;990    def 32mi_ND   : BinOpMIF_RF<0x81, mnemonic, Xi32, opnode, MemMRM>;991    def 64mi32_ND : BinOpMIF_RF<0x81, mnemonic, Xi64, opnode, MemMRM>;992  }993  let Predicates = [In64BitMode] in {994    def 8mi_EVEX    : BinOpMIF_MF<0x80, mnemonic, Xi8 , opnode, MemMRM>, PL;995    def 16mi8_EVEX  : BinOpMI8F_MF<mnemonic, Xi16, MemMRM>, PL, PD;996    def 32mi8_EVEX  : BinOpMI8F_MF<mnemonic, Xi32, MemMRM>, PL;997    def 64mi8_EVEX  : BinOpMI8F_MF<mnemonic, Xi64, MemMRM>, PL;998    def 16mi_EVEX   : BinOpMIF_MF<0x81, mnemonic, Xi16, opnode, MemMRM>, PL, PD;999    def 32mi_EVEX   : BinOpMIF_MF<0x81, mnemonic, Xi32, opnode, MemMRM>, PL;1000    def 64mi32_EVEX : BinOpMIF_MF<0x81, mnemonic, Xi64, opnode, MemMRM>, PL;1001  }1002 1003  // These are for the disassembler since 0x82 opcode behaves like 0x80, but1004  // not in 64-bit mode.1005  let Predicates = [Not64BitMode]  in {1006    def 8ri8 : BinOpRI8F_RF<0x82, mnemonic, Xi8, RegMRM>, DisassembleOnly;1007    def 8mi8 : BinOpMI8F_MF<mnemonic, Xi8, MemMRM>, DisassembleOnly;1008  }1009 1010  def 8i8 : BinOpAIF_AF<BaseOpc4, mnemonic, Xi8 , AL, "{$src, %al|al, $src}">;1011  def 16i16 : BinOpAIF_AF<BaseOpc4, mnemonic, Xi16, AX, "{$src, %ax|ax, $src}">, OpSize16;1012  def 32i32 : BinOpAIF_AF<BaseOpc4, mnemonic, Xi32, EAX, "{$src, %eax|eax, $src}">, OpSize32;1013  def 64i32 : BinOpAIF_AF<BaseOpc4, mnemonic, Xi64, RAX, "{$src, %rax|rax, $src}">;1014}1015 1016/// ArithBinOp_F - This is an arithmetic binary operator where the pattern is1017/// defined with "(set EFLAGS, (...".  It would be really nice to find a way1018/// to factor this with the other ArithBinOp_*.1019///1020multiclass ArithBinOp_F<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,1021                        string mnemonic, Format RegMRM, Format MemMRM,1022                        SDNode opnode, bit CommutableRR,1023                        bit ConvertibleToThreeAddress> {1024  let isCommutable = CommutableRR in {1025    def 8rr  : BinOpRR_F<BaseOpc, mnemonic, Xi8 , opnode>;1026    let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {1027      def 16rr : BinOpRR_F<BaseOpc, mnemonic, Xi16, opnode>, OpSize16;1028      def 32rr : BinOpRR_F<BaseOpc, mnemonic, Xi32, opnode>, OpSize32;1029      def 64rr : BinOpRR_F<BaseOpc, mnemonic, Xi64, opnode>;1030    } // isConvertibleToThreeAddress1031  } // isCommutable1032 1033  def 8rr_REV  : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi8>;1034  def 16rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi16>, OpSize16;1035  def 32rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi32>, OpSize32;1036  def 64rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi64>;1037 1038  def 8rm   : BinOpRM_F<BaseOpc2, mnemonic, Xi8 , opnode>;1039  def 16rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi16, opnode>, OpSize16;1040  def 32rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi32, opnode>, OpSize32;1041  def 64rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi64, opnode>;1042 1043  def 8ri   : BinOpRI_F<0x80, mnemonic, Xi8 , opnode, RegMRM>;1044 1045  let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {1046    // NOTE: These are order specific, we want the ri8 forms to be listed1047    // first so that they are slightly preferred to the ri forms.1048    def 16ri8 : BinOpRI8_F<0x83, mnemonic, Xi16, RegMRM>, OpSize16;1049    def 32ri8 : BinOpRI8_F<0x83, mnemonic, Xi32, RegMRM>, OpSize32;1050    def 64ri8 : BinOpRI8_F<0x83, mnemonic, Xi64, RegMRM>;1051 1052    def 16ri  : BinOpRI_F<0x81, mnemonic, Xi16, opnode, RegMRM>, OpSize16;1053    def 32ri  : BinOpRI_F<0x81, mnemonic, Xi32, opnode, RegMRM>, OpSize32;1054    def 64ri32: BinOpRI_F<0x81, mnemonic, Xi64, opnode, RegMRM>;1055  }1056 1057  def 8mr    : BinOpMR_F<BaseOpc, mnemonic, Xi8 , opnode>;1058  def 16mr   : BinOpMR_F<BaseOpc, mnemonic, Xi16, opnode>, OpSize16;1059  def 32mr   : BinOpMR_F<BaseOpc, mnemonic, Xi32, opnode>, OpSize32;1060  def 64mr   : BinOpMR_F<BaseOpc, mnemonic, Xi64, opnode>;1061 1062  // NOTE: These are order specific, we want the mi8 forms to be listed1063  // first so that they are slightly preferred to the mi forms.1064  def 16mi8  : BinOpMI8_F<mnemonic, Xi16, MemMRM>, OpSize16;1065  def 32mi8  : BinOpMI8_F<mnemonic, Xi32, MemMRM>, OpSize32;1066  let Predicates = [In64BitMode] in1067  def 64mi8  : BinOpMI8_F<mnemonic, Xi64, MemMRM>;1068 1069  def 8mi    : BinOpMI_F<0x80, mnemonic, Xi8 , opnode, MemMRM>;1070  def 16mi   : BinOpMI_F<0x81, mnemonic, Xi16, opnode, MemMRM>, OpSize16;1071  def 32mi   : BinOpMI_F<0x81, mnemonic, Xi32, opnode, MemMRM>, OpSize32;1072  let Predicates = [In64BitMode] in1073    def 64mi32 : BinOpMI_F<0x81, mnemonic, Xi64, opnode, MemMRM>;1074 1075  // These are for the disassembler since 0x82 opcode behaves like 0x80, but1076  // not in 64-bit mode.1077  let Predicates = [Not64BitMode] in {1078    def 8ri8 : BinOpRI8_F<0x82, mnemonic, Xi8, RegMRM>, DisassembleOnly;1079    let mayLoad = 1 in1080      def 8mi8 : BinOpMI8_F<mnemonic, Xi8, MemMRM>;1081  }1082 1083  def 8i8 : BinOpAI_F<BaseOpc4, mnemonic, Xi8 , AL, "{$src, %al|al, $src}">;1084  def 16i16 : BinOpAI_F<BaseOpc4, mnemonic, Xi16, AX, "{$src, %ax|ax, $src}">, OpSize16;1085  def 32i32 : BinOpAI_F<BaseOpc4, mnemonic, Xi32, EAX, "{$src, %eax|eax, $src}">, OpSize32;1086  def 64i32 : BinOpAI_F<BaseOpc4, mnemonic, Xi64, RAX, "{$src, %rax|rax, $src}">;1087}1088 1089 1090defm AND : ArithBinOp_RF<0x21, 0x23, 0x25, "and", MRM4r, MRM4m,1091                         X86and_flag, and, 1, 0, 0>;1092defm OR  : ArithBinOp_RF<0x09, 0x0B, 0x0D, "or", MRM1r, MRM1m,1093                         X86or_flag, or, 1, 0, 0>;1094defm XOR : ArithBinOp_RF<0x31, 0x33, 0x35, "xor", MRM6r, MRM6m,1095                         X86xor_flag, xor, 1, 0, 0>;1096defm ADD : ArithBinOp_RF<0x01, 0x03, 0x05, "add", MRM0r, MRM0m,1097                         X86add_flag, add, 1, 1, 1>;1098let isCompare = 1 in {1099  defm SUB : ArithBinOp_RF<0x29, 0x2B, 0x2D, "sub", MRM5r, MRM5m,1100                           X86sub_flag, sub, 0, 1, 0>;1101}1102 1103// Version of XOR8rr_NOREX that use GR8_NOREX. This is used by the handling of1104// __builtin_parity where the last step xors an h-register with an l-register.1105let isCodeGenOnly = 1, hasSideEffects = 0, Constraints = "$src1 = $dst",1106    Defs = [EFLAGS], isCommutable = 1 in1107  def XOR8rr_NOREX : I<0x30, MRMDestReg, (outs GR8_NOREX:$dst),1108                       (ins GR8_NOREX:$src1, GR8_NOREX:$src2),1109                       "xor{b}\t{$src2, $dst|$dst, $src2}", []>,1110                       Sched<[WriteALU]>;1111 1112// Arithmetic.1113defm ADC : ArithBinOp_RFF<0x11, 0x13, 0x15, "adc", MRM2r, MRM2m, X86adc_flag,1114                          1, 0>;1115defm SBB : ArithBinOp_RFF<0x19, 0x1B, 0x1D, "sbb", MRM3r, MRM3m, X86sbb_flag,1116                          0, 0>;1117 1118let isCompare = 1 in {1119  defm CMP : ArithBinOp_F<0x39, 0x3B, 0x3D, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>;1120}1121 1122// Patterns to recognize loads on the LHS of an ADC. We can't make X86adc_flag1123// commutable since it has EFLAGs as an input.1124let Predicates = [NoNDD] in {1125  def : Pat<(X86adc_flag (loadi8 addr:$src2), GR8:$src1, EFLAGS),1126            (ADC8rm GR8:$src1, addr:$src2)>;1127  def : Pat<(X86adc_flag (loadi16 addr:$src2), GR16:$src1, EFLAGS),1128            (ADC16rm GR16:$src1, addr:$src2)>;1129  def : Pat<(X86adc_flag (loadi32 addr:$src2), GR32:$src1, EFLAGS),1130            (ADC32rm GR32:$src1, addr:$src2)>;1131  def : Pat<(X86adc_flag (loadi64 addr:$src2), GR64:$src1, EFLAGS),1132            (ADC64rm GR64:$src1, addr:$src2)>;1133}1134let Predicates = [HasNDD] in {1135  def : Pat<(X86adc_flag (loadi8 addr:$src2), GR8:$src1, EFLAGS),1136            (ADC8rm_ND GR8:$src1, addr:$src2)>;1137  def : Pat<(X86adc_flag (loadi16 addr:$src2), GR16:$src1, EFLAGS),1138            (ADC16rm_ND GR16:$src1, addr:$src2)>;1139  def : Pat<(X86adc_flag (loadi32 addr:$src2), GR32:$src1, EFLAGS),1140            (ADC32rm_ND GR32:$src1, addr:$src2)>;1141  def : Pat<(X86adc_flag (loadi64 addr:$src2), GR64:$src1, EFLAGS),1142            (ADC64rm_ND GR64:$src1, addr:$src2)>;1143}1144 1145// Patterns to recognize RMW ADC with loads in operand 1.1146def : Pat<(store (X86adc_flag GR8:$src, (loadi8 addr:$dst), EFLAGS),1147                 addr:$dst),1148          (ADC8mr addr:$dst, GR8:$src)>;1149def : Pat<(store (X86adc_flag GR16:$src, (loadi16 addr:$dst), EFLAGS),1150                 addr:$dst),1151          (ADC16mr addr:$dst, GR16:$src)>;1152def : Pat<(store (X86adc_flag GR32:$src, (loadi32 addr:$dst), EFLAGS),1153                 addr:$dst),1154          (ADC32mr addr:$dst, GR32:$src)>;1155def : Pat<(store (X86adc_flag GR64:$src, (loadi64 addr:$dst), EFLAGS),1156                 addr:$dst),1157          (ADC64mr addr:$dst, GR64:$src)>;1158 1159// Patterns for basic arithmetic ops with relocImm for the immediate field.1160multiclass ArithBinOp_RF_relocImm_Pats<SDNode OpNodeFlag, SDNode OpNode> {1161  let Predicates = [NoNDD] in {1162    def : Pat<(OpNodeFlag GR8:$src1, relocImm8_su:$src2),1163              (!cast<Instruction>(NAME#"8ri") GR8:$src1, relocImm8_su:$src2)>;1164    def : Pat<(OpNodeFlag GR16:$src1, relocImm16_su:$src2),1165              (!cast<Instruction>(NAME#"16ri") GR16:$src1, relocImm16_su:$src2)>;1166    def : Pat<(OpNodeFlag GR32:$src1, relocImm32_su:$src2),1167              (!cast<Instruction>(NAME#"32ri") GR32:$src1, relocImm32_su:$src2)>;1168    def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt32_su:$src2),1169              (!cast<Instruction>(NAME#"64ri32") GR64:$src1, i64relocImmSExt32_su:$src2)>;1170 1171    def : Pat<(store (OpNode (load addr:$dst), relocImm8_su:$src), addr:$dst),1172              (!cast<Instruction>(NAME#"8mi") addr:$dst, relocImm8_su:$src)>;1173    def : Pat<(store (OpNode (load addr:$dst), relocImm16_su:$src), addr:$dst),1174              (!cast<Instruction>(NAME#"16mi") addr:$dst, relocImm16_su:$src)>;1175    def : Pat<(store (OpNode (load addr:$dst), relocImm32_su:$src), addr:$dst),1176              (!cast<Instruction>(NAME#"32mi") addr:$dst, relocImm32_su:$src)>;1177    def : Pat<(store (OpNode (load addr:$dst), i64relocImmSExt32_su:$src), addr:$dst),1178              (!cast<Instruction>(NAME#"64mi32") addr:$dst, i64relocImmSExt32_su:$src)>;1179  }1180  let Predicates = [HasNDD] in {1181    def : Pat<(OpNodeFlag GR8:$src1, relocImm8_su:$src2),1182              (!cast<Instruction>(NAME#"8ri_ND") GR8:$src1, relocImm8_su:$src2)>;1183    def : Pat<(OpNodeFlag GR16:$src1, relocImm16_su:$src2),1184              (!cast<Instruction>(NAME#"16ri_ND") GR16:$src1, relocImm16_su:$src2)>;1185    def : Pat<(OpNodeFlag GR32:$src1, relocImm32_su:$src2),1186              (!cast<Instruction>(NAME#"32ri_ND") GR32:$src1, relocImm32_su:$src2)>;1187    def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt32_su:$src2),1188              (!cast<Instruction>(NAME#"64ri32_ND") GR64:$src1, i64relocImmSExt32_su:$src2)>;1189 1190    def : Pat<(OpNode (load addr:$dst), relocImm8_su:$src),1191              (!cast<Instruction>(NAME#"8mi_ND") addr:$dst, relocImm8_su:$src)>;1192    def : Pat<(OpNode (load addr:$dst), relocImm16_su:$src),1193              (!cast<Instruction>(NAME#"16mi_ND") addr:$dst, relocImm16_su:$src)>;1194    def : Pat<(OpNode (load addr:$dst), relocImm32_su:$src),1195              (!cast<Instruction>(NAME#"32mi_ND") addr:$dst, relocImm32_su:$src)>;1196    def : Pat<(OpNode (load addr:$dst), i64relocImmSExt32_su:$src),1197              (!cast<Instruction>(NAME#"64mi32_ND") addr:$dst, i64relocImmSExt32_su:$src)>;1198  }1199}1200 1201multiclass ArithBinOp_RFF_relocImm_Pats<SDNode OpNodeFlag> {1202  let Predicates = [NoNDD] in {1203    def : Pat<(OpNodeFlag GR8:$src1, relocImm8_su:$src2, EFLAGS),1204              (!cast<Instruction>(NAME#"8ri") GR8:$src1, relocImm8_su:$src2)>;1205    def : Pat<(OpNodeFlag GR16:$src1, relocImm16_su:$src2, EFLAGS),1206              (!cast<Instruction>(NAME#"16ri") GR16:$src1, relocImm16_su:$src2)>;1207    def : Pat<(OpNodeFlag GR32:$src1, relocImm32_su:$src2, EFLAGS),1208              (!cast<Instruction>(NAME#"32ri") GR32:$src1, relocImm32_su:$src2)>;1209    def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt32_su:$src2, EFLAGS),1210              (!cast<Instruction>(NAME#"64ri32") GR64:$src1, i64relocImmSExt32_su:$src2)>;1211 1212    def : Pat<(store (OpNodeFlag (load addr:$dst), relocImm8_su:$src, EFLAGS), addr:$dst),1213              (!cast<Instruction>(NAME#"8mi") addr:$dst, relocImm8_su:$src)>;1214    def : Pat<(store (OpNodeFlag (load addr:$dst), relocImm16_su:$src, EFLAGS), addr:$dst),1215              (!cast<Instruction>(NAME#"16mi") addr:$dst, relocImm16_su:$src)>;1216    def : Pat<(store (OpNodeFlag (load addr:$dst), relocImm32_su:$src, EFLAGS), addr:$dst),1217              (!cast<Instruction>(NAME#"32mi") addr:$dst, relocImm32_su:$src)>;1218    def : Pat<(store (OpNodeFlag (load addr:$dst), i64relocImmSExt32_su:$src, EFLAGS), addr:$dst),1219              (!cast<Instruction>(NAME#"64mi32") addr:$dst, i64relocImmSExt32_su:$src)>;1220  }1221  let Predicates = [HasNDD] in {1222    def : Pat<(OpNodeFlag GR8:$src1, relocImm8_su:$src2, EFLAGS),1223              (!cast<Instruction>(NAME#"8ri_ND") GR8:$src1, relocImm8_su:$src2)>;1224    def : Pat<(OpNodeFlag GR16:$src1, relocImm16_su:$src2, EFLAGS),1225              (!cast<Instruction>(NAME#"16ri_ND") GR16:$src1, relocImm16_su:$src2)>;1226    def : Pat<(OpNodeFlag GR32:$src1, relocImm32_su:$src2, EFLAGS),1227              (!cast<Instruction>(NAME#"32ri_ND") GR32:$src1, relocImm32_su:$src2)>;1228    def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt32_su:$src2, EFLAGS),1229              (!cast<Instruction>(NAME#"64ri32_ND") GR64:$src1, i64relocImmSExt32_su:$src2)>;1230 1231    def : Pat<(OpNodeFlag (load addr:$dst), relocImm8_su:$src, EFLAGS),1232              (!cast<Instruction>(NAME#"8mi_ND") addr:$dst, relocImm8_su:$src)>;1233    def : Pat<(OpNodeFlag (load addr:$dst), relocImm16_su:$src, EFLAGS),1234              (!cast<Instruction>(NAME#"16mi_ND") addr:$dst, relocImm16_su:$src)>;1235    def : Pat<(OpNodeFlag (load addr:$dst), relocImm32_su:$src, EFLAGS),1236              (!cast<Instruction>(NAME#"32mi_ND") addr:$dst, relocImm32_su:$src)>;1237    def : Pat<(OpNodeFlag (load addr:$dst), i64relocImmSExt32_su:$src, EFLAGS),1238              (!cast<Instruction>(NAME#"64mi32_ND") addr:$dst, i64relocImmSExt32_su:$src)>;1239  }1240}1241 1242multiclass ArithBinOp_F_relocImm_Pats<SDNode OpNodeFlag> {1243  def : Pat<(OpNodeFlag GR8:$src1, relocImm8_su:$src2),1244            (!cast<Instruction>(NAME#"8ri") GR8:$src1, relocImm8_su:$src2)>;1245  def : Pat<(OpNodeFlag GR16:$src1, relocImm16_su:$src2),1246            (!cast<Instruction>(NAME#"16ri") GR16:$src1, relocImm16_su:$src2)>;1247  def : Pat<(OpNodeFlag GR32:$src1, relocImm32_su:$src2),1248            (!cast<Instruction>(NAME#"32ri") GR32:$src1, relocImm32_su:$src2)>;1249  def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt32_su:$src2),1250            (!cast<Instruction>(NAME#"64ri32") GR64:$src1, i64relocImmSExt32_su:$src2)>;1251 1252  def : Pat<(OpNodeFlag (loadi8 addr:$src1), relocImm8_su:$src2),1253            (!cast<Instruction>(NAME#"8mi") addr:$src1, relocImm8_su:$src2)>;1254  def : Pat<(OpNodeFlag (loadi16 addr:$src1), relocImm16_su:$src2),1255            (!cast<Instruction>(NAME#"16mi") addr:$src1, relocImm16_su:$src2)>;1256  def : Pat<(OpNodeFlag (loadi32 addr:$src1), relocImm32_su:$src2),1257            (!cast<Instruction>(NAME#"32mi") addr:$src1, relocImm32_su:$src2)>;1258  def : Pat<(OpNodeFlag (loadi64 addr:$src1), i64relocImmSExt32_su:$src2),1259            (!cast<Instruction>(NAME#"64mi32") addr:$src1, i64relocImmSExt32_su:$src2)>;1260}1261 1262defm AND : ArithBinOp_RF_relocImm_Pats<X86and_flag, and>;1263defm OR  : ArithBinOp_RF_relocImm_Pats<X86or_flag, or>;1264defm XOR : ArithBinOp_RF_relocImm_Pats<X86xor_flag, xor>;1265defm ADD : ArithBinOp_RF_relocImm_Pats<X86add_flag, add>;1266defm SUB : ArithBinOp_RF_relocImm_Pats<X86sub_flag, sub>;1267 1268defm ADC : ArithBinOp_RFF_relocImm_Pats<X86adc_flag>;1269defm SBB : ArithBinOp_RFF_relocImm_Pats<X86sbb_flag>;1270 1271defm CMP : ArithBinOp_F_relocImm_Pats<X86cmp>;1272 1273// ADC is commutable, but we can't indicate that to tablegen. So manually1274// reverse the operands.1275def : Pat<(X86adc_flag GR8:$src1, relocImm8_su:$src2, EFLAGS),1276          (ADC8ri relocImm8_su:$src2, GR8:$src1)>;1277def : Pat<(X86adc_flag i16relocImmSExt8_su:$src2, GR16:$src1, EFLAGS),1278          (ADC16ri8 GR16:$src1, i16relocImmSExt8_su:$src2)>;1279def : Pat<(X86adc_flag relocImm16_su:$src2, GR16:$src1, EFLAGS),1280          (ADC16ri GR16:$src1, relocImm16_su:$src2)>;1281def : Pat<(X86adc_flag i32relocImmSExt8_su:$src2, GR32:$src1, EFLAGS),1282          (ADC32ri8 GR32:$src1, i32relocImmSExt8_su:$src2)>;1283def : Pat<(X86adc_flag relocImm32_su:$src2, GR32:$src1, EFLAGS),1284          (ADC32ri GR32:$src1, relocImm32_su:$src2)>;1285def : Pat<(X86adc_flag i64relocImmSExt8_su:$src2, GR64:$src1, EFLAGS),1286          (ADC64ri8 GR64:$src1, i64relocImmSExt8_su:$src2)>;1287def : Pat<(X86adc_flag i64relocImmSExt32_su:$src2, GR64:$src1, EFLAGS),1288          (ADC64ri32 GR64:$src1, i64relocImmSExt32_su:$src2)>;1289 1290def : Pat<(store (X86adc_flag relocImm8_su:$src, (load addr:$dst), EFLAGS), addr:$dst),1291          (ADC8mi addr:$dst, relocImm8_su:$src)>;1292def : Pat<(store (X86adc_flag i16relocImmSExt8_su:$src, (load addr:$dst), EFLAGS), addr:$dst),1293          (ADC16mi8 addr:$dst, i16relocImmSExt8_su:$src)>;1294def : Pat<(store (X86adc_flag relocImm16_su:$src, (load addr:$dst), EFLAGS), addr:$dst),1295          (ADC16mi addr:$dst, relocImm16_su:$src)>;1296def : Pat<(store (X86adc_flag i32relocImmSExt8_su:$src, (load addr:$dst), EFLAGS), addr:$dst),1297          (ADC32mi8 addr:$dst, i32relocImmSExt8_su:$src)>;1298def : Pat<(store (X86adc_flag relocImm32_su:$src, (load addr:$dst), EFLAGS), addr:$dst),1299          (ADC32mi addr:$dst, relocImm32_su:$src)>;1300def : Pat<(store (X86adc_flag i64relocImmSExt8_su:$src, (load addr:$dst), EFLAGS), addr:$dst),1301          (ADC64mi8 addr:$dst, i64relocImmSExt8_su:$src)>;1302def : Pat<(store (X86adc_flag i64relocImmSExt32_su:$src, (load addr:$dst), EFLAGS), addr:$dst),1303          (ADC64mi32 addr:$dst, i64relocImmSExt32_su:$src)>;1304 1305//===----------------------------------------------------------------------===//1306// Semantically, test instructions are similar like AND, except they don't1307// generate a result.  From an encoding perspective, they are very different:1308// they don't have all the usual imm8 and REV forms, and are encoded into a1309// different space.1310let isCompare = 1 in {1311  let isCommutable = 1 in {1312  // Avoid selecting these and instead use a test+and. Post processing will1313  // combine them. This gives bunch of other patterns that start with1314  // and a chance to match.1315    def TEST8rr  : BinOpRR_F<0x84, "test", Xi8 , null_frag>;1316    def TEST16rr : BinOpRR_F<0x85, "test", Xi16, null_frag>, OpSize16;1317    def TEST32rr : BinOpRR_F<0x85, "test", Xi32, null_frag>, OpSize32;1318    def TEST64rr : BinOpRR_F<0x85, "test", Xi64, null_frag>;1319  } // isCommutable1320 1321  def TEST8mr    : BinOpMR_F<0x84, "test", Xi8 , null_frag>;1322  def TEST16mr   : BinOpMR_F<0x85, "test", Xi16, null_frag>, OpSize16;1323  def TEST32mr   : BinOpMR_F<0x85, "test", Xi32, null_frag>, OpSize32;1324  def TEST64mr   : BinOpMR_F<0x85, "test", Xi64, null_frag>;1325 1326  def TEST8ri    : BinOpRI_F<0xF6, "test", Xi8 , X86testpat, MRM0r>;1327  def TEST16ri   : BinOpRI_F<0xF7, "test", Xi16, X86testpat, MRM0r>, OpSize16;1328  def TEST32ri   : BinOpRI_F<0xF7, "test", Xi32, X86testpat, MRM0r>, OpSize32;1329  def TEST64ri32 : BinOpRI_F<0xF7, "test", Xi64, X86testpat, MRM0r>;1330 1331  def TEST8mi    : BinOpMI_F<0xF6, "test", Xi8 , X86testpat, MRM0m>;1332  def TEST16mi   : BinOpMI_F<0xF7, "test", Xi16, X86testpat, MRM0m>, OpSize16;1333  def TEST32mi   : BinOpMI_F<0xF7, "test", Xi32, X86testpat, MRM0m>, OpSize32;1334 1335  let Predicates = [In64BitMode] in1336    def TEST64mi32 : BinOpMI_F<0xF7, "test", Xi64, X86testpat, MRM0m>;1337 1338  def TEST8i8 : BinOpAI_F<0xA8, "test", Xi8 , AL, "{$src, %al|al, $src}">;1339  def TEST16i16 : BinOpAI_F<0xA9, "test", Xi16, AX, "{$src, %ax|ax, $src}">, OpSize16;1340  def TEST32i32 : BinOpAI_F<0xA9, "test", Xi32, EAX, "{$src, %eax|eax, $src}">, OpSize32;1341  def TEST64i32 : BinOpAI_F<0xA9, "test", Xi64, RAX, "{$src, %rax|rax, $src}">;1342} // isCompare1343 1344// Patterns to match a relocImm into the immediate field.1345def : Pat<(X86testpat GR8:$src1, relocImm8_su:$src2),1346          (TEST8ri GR8:$src1, relocImm8_su:$src2)>;1347def : Pat<(X86testpat GR16:$src1, relocImm16_su:$src2),1348          (TEST16ri GR16:$src1, relocImm16_su:$src2)>;1349def : Pat<(X86testpat GR32:$src1, relocImm32_su:$src2),1350          (TEST32ri GR32:$src1, relocImm32_su:$src2)>;1351def : Pat<(X86testpat GR64:$src1, i64relocImmSExt32_su:$src2),1352          (TEST64ri32 GR64:$src1, i64relocImmSExt32_su:$src2)>;1353 1354def : Pat<(X86testpat (loadi8 addr:$src1), relocImm8_su:$src2),1355          (TEST8mi addr:$src1, relocImm8_su:$src2)>;1356def : Pat<(X86testpat (loadi16 addr:$src1), relocImm16_su:$src2),1357          (TEST16mi addr:$src1, relocImm16_su:$src2)>;1358def : Pat<(X86testpat (loadi32 addr:$src1), relocImm32_su:$src2),1359          (TEST32mi addr:$src1, relocImm32_su:$src2)>;1360def : Pat<(X86testpat (loadi64 addr:$src1), i64relocImmSExt32_su:$src2),1361          (TEST64mi32 addr:$src1, i64relocImmSExt32_su:$src2)>;1362 1363//===----------------------------------------------------------------------===//1364// ANDN Instruction1365//1366multiclass AndN<X86TypeInfo t, SDPatternOperator node, string suffix = ""> {1367  defvar andn_rr_p =1368    [(set t.RegClass:$dst, EFLAGS, (node (not t.RegClass:$src1),1369     t.RegClass:$src2))];1370  defvar andn_rm_p =1371    [(set t.RegClass:$dst, EFLAGS, (node (not t.RegClass:$src1),1372     (t.LoadNode addr:$src2)))];1373  def rr#suffix : ITy<0xF2, MRMSrcReg, t, (outs t.RegClass:$dst),1374                      (ins t.RegClass:$src1, t.RegClass:$src2), "andn",1375                      binop_ndd_args, andn_rr_p>, VVVV, Sched<[WriteALU]>, T8;1376  def rm#suffix : ITy<0xF2, MRMSrcMem, t, (outs t.RegClass:$dst),1377                       (ins t.RegClass:$src1, t.MemOperand:$src2), "andn",1378                       binop_ndd_args, andn_rm_p>, VVVV,1379                       Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>, T8;1380}1381 1382// Complexity is reduced to give and with immediate a chance to match first.1383let AddedComplexity = -6 in {1384defm ANDN32 : AndN<Xi32, X86and_flag>, VEX, Requires<[HasBMI, NoEGPR]>, DefEFLAGS;1385defm ANDN64 : AndN<Xi64, X86and_flag>, VEX, Requires<[HasBMI, NoEGPR]>, DefEFLAGS;1386defm ANDN32 : AndN<Xi32, X86and_flag, "_EVEX">, EVEX, Requires<[HasBMI, HasEGPR, In64BitMode]>, DefEFLAGS;1387defm ANDN64 : AndN<Xi64, X86and_flag, "_EVEX">, EVEX, Requires<[HasBMI, HasEGPR, In64BitMode]>, DefEFLAGS;1388defm ANDN32 : AndN<Xi32, null_frag, "_NF">, EVEX, EVEX_NF, Requires<[In64BitMode]>;1389defm ANDN64 : AndN<Xi64, null_frag, "_NF">, EVEX, EVEX_NF, Requires<[In64BitMode]>;1390}1391 1392multiclass Andn_Pats<string suffix> {1393  def : Pat<(and (not GR32:$src1), GR32:$src2),1394            (!cast<Instruction>(ANDN32rr#suffix) GR32:$src1, GR32:$src2)>;1395  def : Pat<(and (not GR64:$src1), GR64:$src2),1396            (!cast<Instruction>(ANDN64rr#suffix) GR64:$src1, GR64:$src2)>;1397  def : Pat<(and (not GR32:$src1), (loadi32 addr:$src2)),1398            (!cast<Instruction>(ANDN32rm#suffix) GR32:$src1, addr:$src2)>;1399  def : Pat<(and (not GR64:$src1), (loadi64 addr:$src2)),1400            (!cast<Instruction>(ANDN64rm#suffix) GR64:$src1, addr:$src2)>;1401}1402 1403let Predicates = [HasBMI, NoEGPR], AddedComplexity = -6 in1404  defm : Andn_Pats<"">;1405 1406let Predicates = [HasBMI, HasEGPR], AddedComplexity = -6 in1407  defm : Andn_Pats<"_EVEX">;1408 1409//===----------------------------------------------------------------------===//1410// MULX Instruction1411//1412multiclass MulX<X86TypeInfo t, X86FoldableSchedWrite sched> {1413  defvar mulx_args = "{$src, $dst2, $dst1|$dst1, $dst2, $src}";1414  defvar mulx_rm_sched =1415    [WriteIMulHLd, sched.Folded,1416     // Memory operand.1417     ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,1418     // Implicit read of EDX/RDX1419     sched.ReadAfterFold];1420 1421  def rr : ITy<0xF6, MRMSrcReg, t, (outs t.RegClass:$dst1, t.RegClass:$dst2),1422               (ins t.RegClass:$src), "mulx", mulx_args, []>, T8, XD, VEX,1423           VVVV, Sched<[WriteIMulH, sched]>;1424  let mayLoad = 1 in1425    def rm : ITy<0xF6, MRMSrcMem, t, (outs t.RegClass:$dst1, t.RegClass:$dst2),1426                 (ins t.MemOperand:$src), "mulx", mulx_args, []>, T8, XD, VEX,1427                 VVVV, Sched<mulx_rm_sched>;1428 1429  let Predicates = [In64BitMode] in {1430    def rr_EVEX : ITy<0xF6, MRMSrcReg, t,1431                      (outs t.RegClass:$dst1, t.RegClass:$dst2),1432                      (ins t.RegClass:$src), "mulx", mulx_args, []>, T8, XD,1433                  EVEX, VVVV, Sched<[WriteIMulH, sched]>;1434    let mayLoad = 1 in1435      def rm_EVEX : ITy<0xF6, MRMSrcMem, t,1436                        (outs t.RegClass:$dst1, t.RegClass:$dst2),1437                        (ins t.MemOperand:$src), "mulx", mulx_args, []>, T8, XD,1438                    EVEX, VVVV, Sched<mulx_rm_sched>;1439  }1440  // Pseudo instructions to be used when the low result isn't used. The1441  // instruction is defined to keep the high if both destinations are the same.1442  def Hrr : PseudoI<(outs t.RegClass:$dst), (ins t.RegClass:$src), []>,1443            Sched<[sched]>;1444  let mayLoad = 1 in1445  def Hrm : PseudoI<(outs t.RegClass:$dst), (ins t.MemOperand:$src), []>,1446            Sched<[sched.Folded]>;1447}1448 1449let Uses = [EDX] in1450  defm MULX32 : MulX<Xi32, WriteMULX32>;1451 1452let Uses = [RDX] in1453  defm MULX64 : MulX<Xi64, WriteMULX64>, REX_W;1454 1455//===----------------------------------------------------------------------===//1456// ADCX and ADOX Instructions1457//1458// We don't have patterns for these as there is no advantage over ADC for1459// most code.1460let Form = MRMSrcReg in {1461  def ADCX32rr : BinOpRRF_RF<0xF6, "adcx", Xi32>, T8, PD;1462  def ADCX64rr : BinOpRRF_RF<0xF6, "adcx", Xi64>, T8, PD;1463  def ADOX32rr : BinOpRRF_RF<0xF6, "adox", Xi32>, T8, XS;1464  def ADOX64rr : BinOpRRF_RF<0xF6, "adox", Xi64>, T8, XS;1465  let Predicates =[In64BitMode] in {1466    def ADCX32rr_EVEX : BinOpRRF_RF<0x66, "adcx", Xi32>, EVEX, T_MAP4, PD;1467    def ADCX64rr_EVEX : BinOpRRF_RF<0x66, "adcx", Xi64>, EVEX, T_MAP4, PD;1468    def ADOX32rr_EVEX : BinOpRRF_RF<0x66, "adox", Xi32>, EVEX, T_MAP4, XS;1469    def ADOX64rr_EVEX : BinOpRRF_RF<0x66, "adox", Xi64>, EVEX, T_MAP4, XS;1470    def ADCX32rr_ND : BinOpRRF_RF<0x66, "adcx", Xi32, null_frag, 1>, PD;1471    def ADCX64rr_ND : BinOpRRF_RF<0x66, "adcx", Xi64, null_frag, 1>, PD;1472    def ADOX32rr_ND : BinOpRRF_RF<0x66, "adox", Xi32, null_frag, 1>, XS;1473    def ADOX64rr_ND : BinOpRRF_RF<0x66, "adox", Xi64, null_frag, 1>, XS;1474  }1475}1476let Form = MRMSrcMem in {1477  def ADCX32rm : BinOpRMF_RF<0xF6, "adcx", Xi32>, T8, PD;1478  def ADCX64rm : BinOpRMF_RF<0xF6, "adcx", Xi64>, T8, PD;1479  def ADOX32rm : BinOpRMF_RF<0xF6, "adox", Xi32>, T8, XS;1480  def ADOX64rm : BinOpRMF_RF<0xF6, "adox", Xi64>, T8, XS;1481  let Predicates =[In64BitMode] in {1482    def ADCX32rm_EVEX : BinOpRMF_RF<0x66, "adcx", Xi32>, EVEX, T_MAP4, PD;1483    def ADCX64rm_EVEX : BinOpRMF_RF<0x66, "adcx", Xi64>, EVEX, T_MAP4, PD;1484    def ADOX32rm_EVEX : BinOpRMF_RF<0x66, "adox", Xi32>, EVEX, T_MAP4, XS;1485    def ADOX64rm_EVEX : BinOpRMF_RF<0x66, "adox", Xi64>, EVEX, T_MAP4, XS;1486    def ADCX32rm_ND : BinOpRMF_RF<0x66, "adcx", Xi32, null_frag, 1>, PD;1487    def ADCX64rm_ND : BinOpRMF_RF<0x66, "adcx", Xi64, null_frag, 1>, PD;1488    def ADOX32rm_ND : BinOpRMF_RF<0x66, "adox", Xi32, null_frag, 1>, XS;1489    def ADOX64rm_ND : BinOpRMF_RF<0x66, "adox", Xi64, null_frag, 1>, XS;1490  }1491}1492