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