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