1*0fca6ea1SDimitry Andric//===-- X86InstrConditionalCompare.td - Conditional Compare --*- tablegen -*-==// 2*0fca6ea1SDimitry Andric// 3*0fca6ea1SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric// 7*0fca6ea1SDimitry Andric//===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric// 9*0fca6ea1SDimitry Andric// This file describes the X86 conditional compare instructions. 10*0fca6ea1SDimitry Andric// 11*0fca6ea1SDimitry Andric//===----------------------------------------------------------------------===// 12*0fca6ea1SDimitry Andric 13*0fca6ea1SDimitry Andricclass BinCondOp<bits<8> o, Format f, X86TypeInfo t, DAGOperand op1, DAGOperand op2, string m> 14*0fca6ea1SDimitry Andric : ITy<o, f, t, (outs), (ins op1:$src1, op2:$src2, cflags:$dcf, ccode:$cond), 15*0fca6ea1SDimitry Andric m#"${cond}", "$dcf\t{$src2, $src1|$src1, $src2}" , []>, T_MAP4, EVEX, Requires<[In64BitMode]> { 16*0fca6ea1SDimitry Andric let isCodeGenOnly = 1; 17*0fca6ea1SDimitry Andric let ForceDisassemble = 1; 18*0fca6ea1SDimitry Andric let Uses = [EFLAGS]; 19*0fca6ea1SDimitry Andric let Defs = [EFLAGS]; 20*0fca6ea1SDimitry Andric let hasTwoConditionalOps = 1; 21*0fca6ea1SDimitry Andric let ImmT = !if(!eq(op2, i16i8imm), Imm8, 22*0fca6ea1SDimitry Andric !if(!eq(op2, i32i8imm), Imm8, 23*0fca6ea1SDimitry Andric !if(!eq(op2, i64i8imm), Imm8, 24*0fca6ea1SDimitry Andric !if(!eq(op2, i8imm), Imm8, 25*0fca6ea1SDimitry Andric !if(!eq(op2, i16imm), Imm16, 26*0fca6ea1SDimitry Andric !if(!eq(op2, i32imm), Imm32, 27*0fca6ea1SDimitry Andric !if(!eq(op2, i64i32imm), Imm32S, NoImm))))))); 28*0fca6ea1SDimitry Andric} 29*0fca6ea1SDimitry Andric 30*0fca6ea1SDimitry Andricclass Ccmp<bits<8> o, Format f, X86TypeInfo t, DAGOperand op1, DAGOperand op2>: 31*0fca6ea1SDimitry Andric BinCondOp<o, f, t, op1, op2, "ccmp">; 32*0fca6ea1SDimitry Andric 33*0fca6ea1SDimitry Andricclass Ctest<bits<8> o, Format f, X86TypeInfo t, DAGOperand op1, DAGOperand op2>: 34*0fca6ea1SDimitry Andric BinCondOp<o, f, t, op1, op2, "ctest">; 35*0fca6ea1SDimitry Andric 36*0fca6ea1SDimitry Andric//===----------------------------------------------------------------------===// 37*0fca6ea1SDimitry Andric// CCMP Instructions 38*0fca6ea1SDimitry Andric// 39*0fca6ea1SDimitry Andriclet SchedRW = [WriteALU] in { 40*0fca6ea1SDimitry Andric def CCMP8rr : Ccmp<0x38, MRMDestReg, Xi8, GR8, GR8>; 41*0fca6ea1SDimitry Andric def CCMP16rr: Ccmp<0x39, MRMDestReg, Xi16, GR16, GR16>, PD; 42*0fca6ea1SDimitry Andric def CCMP32rr: Ccmp<0x39, MRMDestReg, Xi32, GR32, GR32>; 43*0fca6ea1SDimitry Andric def CCMP64rr: Ccmp<0x39, MRMDestReg, Xi64, GR64, GR64>; 44*0fca6ea1SDimitry Andric def CCMP8rr_REV : Ccmp<0x3a, MRMSrcReg, Xi8, GR8, GR8>; 45*0fca6ea1SDimitry Andric def CCMP16rr_REV: Ccmp<0x3b, MRMSrcReg, Xi16, GR16, GR16>, PD; 46*0fca6ea1SDimitry Andric def CCMP32rr_REV: Ccmp<0x3b, MRMSrcReg, Xi32, GR32, GR32>; 47*0fca6ea1SDimitry Andric def CCMP64rr_REV: Ccmp<0x3b, MRMSrcReg, Xi64, GR64, GR64>; 48*0fca6ea1SDimitry Andric def CCMP16ri8: Ccmp<0x83, MRM7r, Xi16, GR16, i16i8imm>, PD; 49*0fca6ea1SDimitry Andric def CCMP32ri8: Ccmp<0x83, MRM7r, Xi32, GR32, i32i8imm>; 50*0fca6ea1SDimitry Andric def CCMP64ri8: Ccmp<0x83, MRM7r, Xi64, GR64, i64i8imm>; 51*0fca6ea1SDimitry Andric 52*0fca6ea1SDimitry Andric def CCMP8ri : Ccmp<0x80, MRM7r, Xi8, GR8, i8imm>; 53*0fca6ea1SDimitry Andric def CCMP16ri: Ccmp<0x81, MRM7r, Xi16, GR16, i16imm>, PD; 54*0fca6ea1SDimitry Andric def CCMP32ri: Ccmp<0x81, MRM7r, Xi32, GR32, i32imm>; 55*0fca6ea1SDimitry Andric def CCMP64ri32: Ccmp<0x81, MRM7r, Xi64, GR64, i64i32imm>; 56*0fca6ea1SDimitry Andric} 57*0fca6ea1SDimitry Andric 58*0fca6ea1SDimitry Andriclet mayLoad = 1 in { 59*0fca6ea1SDimitry Andric let SchedRW = [WriteALU.Folded] in { 60*0fca6ea1SDimitry Andric def CCMP16mi8: Ccmp<0x83, MRM7m, Xi16, i16mem, i16i8imm>, PD; 61*0fca6ea1SDimitry Andric def CCMP32mi8: Ccmp<0x83, MRM7m, Xi32, i32mem, i32i8imm>; 62*0fca6ea1SDimitry Andric def CCMP64mi8: Ccmp<0x83, MRM7m, Xi64, i64mem, i64i8imm>; 63*0fca6ea1SDimitry Andric def CCMP8mi : Ccmp<0x80, MRM7m, Xi8, i8mem, i8imm>; 64*0fca6ea1SDimitry Andric def CCMP16mi: Ccmp<0x81, MRM7m, Xi16, i16mem, i16imm>, PD; 65*0fca6ea1SDimitry Andric def CCMP32mi: Ccmp<0x81, MRM7m, Xi32, i32mem, i32imm>; 66*0fca6ea1SDimitry Andric def CCMP64mi32: Ccmp<0x81, MRM7m, Xi64, i64mem, i64i32imm>; 67*0fca6ea1SDimitry Andric } 68*0fca6ea1SDimitry Andric let SchedRW = [WriteALU.Folded, WriteALU.ReadAfterFold] in { 69*0fca6ea1SDimitry Andric def CCMP8rm : Ccmp<0x3a, MRMSrcMem, Xi8, GR8, i8mem>; 70*0fca6ea1SDimitry Andric def CCMP16rm: Ccmp<0x3b, MRMSrcMem, Xi16, GR16, i16mem>, PD; 71*0fca6ea1SDimitry Andric def CCMP32rm: Ccmp<0x3b, MRMSrcMem, Xi32, GR32, i32mem>; 72*0fca6ea1SDimitry Andric def CCMP64rm: Ccmp<0x3b, MRMSrcMem, Xi64, GR64, i64mem>; 73*0fca6ea1SDimitry Andric 74*0fca6ea1SDimitry Andric def CCMP8mr : Ccmp<0x38, MRMDestMem, Xi8, i8mem, GR8>; 75*0fca6ea1SDimitry Andric def CCMP16mr: Ccmp<0x39, MRMDestMem, Xi16, i16mem, GR16>, PD; 76*0fca6ea1SDimitry Andric def CCMP32mr: Ccmp<0x39, MRMDestMem, Xi32, i32mem, GR32>; 77*0fca6ea1SDimitry Andric def CCMP64mr: Ccmp<0x39, MRMDestMem, Xi64, i64mem, GR64>; 78*0fca6ea1SDimitry Andric } 79*0fca6ea1SDimitry Andric} 80*0fca6ea1SDimitry Andric 81*0fca6ea1SDimitry Andricdef : Pat<(X86ccmp GR8:$src1, GR8:$src2, timm:$dcf, timm:$cond, EFLAGS), 82*0fca6ea1SDimitry Andric (CCMP8rr GR8:$src1, GR8:$src2, timm:$dcf, timm:$cond)>; 83*0fca6ea1SDimitry Andricdef : Pat<(X86ccmp GR16:$src1, GR16:$src2, timm:$dcf, timm:$cond, EFLAGS), 84*0fca6ea1SDimitry Andric (CCMP16rr GR16:$src1, GR16:$src2, timm:$dcf, timm:$cond)>; 85*0fca6ea1SDimitry Andricdef : Pat<(X86ccmp GR32:$src1, GR32:$src2, timm:$dcf, timm:$cond, EFLAGS), 86*0fca6ea1SDimitry Andric (CCMP32rr GR32:$src1, GR32:$src2, timm:$dcf, timm:$cond)>; 87*0fca6ea1SDimitry Andricdef : Pat<(X86ccmp GR64:$src1, GR64:$src2, timm:$dcf, timm:$cond, EFLAGS), 88*0fca6ea1SDimitry Andric (CCMP64rr GR64:$src1, GR64:$src2, timm:$dcf, timm:$cond)>; 89*0fca6ea1SDimitry Andric 90*0fca6ea1SDimitry Andricdef : Pat<(X86ccmp GR8:$src1, (i8 imm:$src2), timm:$dcf, timm:$cond, EFLAGS), 91*0fca6ea1SDimitry Andric (CCMP8ri GR8:$src1, imm:$src2, timm:$dcf, timm:$cond)>; 92*0fca6ea1SDimitry Andricdef : Pat<(X86ccmp GR16:$src1, (i16 imm:$src2), timm:$dcf, timm:$cond, EFLAGS), 93*0fca6ea1SDimitry Andric (CCMP16ri GR16:$src1, imm:$src2, timm:$dcf, timm:$cond)>; 94*0fca6ea1SDimitry Andricdef : Pat<(X86ccmp GR32:$src1, (i32 imm:$src2), timm:$dcf, timm:$cond, EFLAGS), 95*0fca6ea1SDimitry Andric (CCMP32ri GR32:$src1, imm:$src2, timm:$dcf, timm:$cond)>; 96*0fca6ea1SDimitry Andricdef : Pat<(X86ccmp GR64:$src1, i64immSExt32_su:$src2, timm:$dcf, timm:$cond, EFLAGS), 97*0fca6ea1SDimitry Andric (CCMP64ri32 GR64:$src1, i64immSExt32_su:$src2, timm:$dcf, timm:$cond)>; 98*0fca6ea1SDimitry Andric 99*0fca6ea1SDimitry Andricdef : Pat<(X86ccmp GR8:$src1, (loadi8 addr:$src2), timm:$dcf, timm:$cond, EFLAGS), 100*0fca6ea1SDimitry Andric (CCMP8rm GR8:$src1, addr:$src2, timm:$dcf, timm:$cond)>; 101*0fca6ea1SDimitry Andricdef : Pat<(X86ccmp GR16:$src1, (loadi16 addr:$src2), timm:$dcf, timm:$cond, EFLAGS), 102*0fca6ea1SDimitry Andric (CCMP16rm GR16:$src1, addr:$src2, timm:$dcf, timm:$cond)>; 103*0fca6ea1SDimitry Andricdef : Pat<(X86ccmp GR32:$src1, (loadi32 addr:$src2), timm:$dcf, timm:$cond, EFLAGS), 104*0fca6ea1SDimitry Andric (CCMP32rm GR32:$src1, addr:$src2, timm:$dcf, timm:$cond)>; 105*0fca6ea1SDimitry Andricdef : Pat<(X86ccmp GR64:$src1, (loadi64 addr:$src2), timm:$dcf, timm:$cond, EFLAGS), 106*0fca6ea1SDimitry Andric (CCMP64rm GR64:$src1, addr:$src2, timm:$dcf, timm:$cond)>; 107*0fca6ea1SDimitry Andric 108*0fca6ea1SDimitry Andric 109*0fca6ea1SDimitry Andric//===----------------------------------------------------------------------===// 110*0fca6ea1SDimitry Andric// CTEST Instructions 111*0fca6ea1SDimitry Andric// 112*0fca6ea1SDimitry Andriclet SchedRW = [WriteALU] in { 113*0fca6ea1SDimitry Andric let isCommutable = 1 in { 114*0fca6ea1SDimitry Andric def CTEST8rr : Ctest<0x84, MRMDestReg, Xi8, GR8, GR8>; 115*0fca6ea1SDimitry Andric def CTEST16rr: Ctest<0x85, MRMDestReg, Xi16, GR16, GR16>, PD; 116*0fca6ea1SDimitry Andric def CTEST32rr: Ctest<0x85, MRMDestReg, Xi32, GR32, GR32>; 117*0fca6ea1SDimitry Andric def CTEST64rr: Ctest<0x85, MRMDestReg, Xi64, GR64, GR64>; 118*0fca6ea1SDimitry Andric } 119*0fca6ea1SDimitry Andric def CTEST8ri : Ctest<0xF6, MRM0r, Xi8, GR8, i8imm>; 120*0fca6ea1SDimitry Andric def CTEST16ri: Ctest<0xF7, MRM0r, Xi16, GR16, i16imm>, PD; 121*0fca6ea1SDimitry Andric def CTEST32ri: Ctest<0xF7, MRM0r, Xi32, GR32, i32imm>; 122*0fca6ea1SDimitry Andric def CTEST64ri32: Ctest<0xF7, MRM0r, Xi64, GR64, i64i32imm>; 123*0fca6ea1SDimitry Andric} 124*0fca6ea1SDimitry Andric 125*0fca6ea1SDimitry Andriclet mayLoad = 1 in { 126*0fca6ea1SDimitry Andric let SchedRW = [WriteALU.Folded] in { 127*0fca6ea1SDimitry Andric def CTEST8mi : Ctest<0xF6, MRM0m, Xi8, i8mem, i8imm>; 128*0fca6ea1SDimitry Andric def CTEST16mi: Ctest<0xF7, MRM0m, Xi16, i16mem, i16imm>, PD; 129*0fca6ea1SDimitry Andric def CTEST32mi: Ctest<0xF7, MRM0m, Xi32, i32mem, i32imm>; 130*0fca6ea1SDimitry Andric def CTEST64mi32: Ctest<0xF7, MRM0m, Xi64, i64mem, i64i32imm>; 131*0fca6ea1SDimitry Andric } 132*0fca6ea1SDimitry Andric let SchedRW = [WriteALU.Folded, WriteALU.ReadAfterFold] in { 133*0fca6ea1SDimitry Andric def CTEST8mr : Ctest<0x84, MRMDestMem, Xi8, i8mem, GR8>; 134*0fca6ea1SDimitry Andric def CTEST16mr: Ctest<0x85, MRMDestMem, Xi16, i16mem, GR16>, PD; 135*0fca6ea1SDimitry Andric def CTEST32mr: Ctest<0x85, MRMDestMem, Xi32, i32mem, GR32>; 136*0fca6ea1SDimitry Andric def CTEST64mr: Ctest<0x85, MRMDestMem, Xi64, i64mem, GR64>; 137*0fca6ea1SDimitry Andric } 138*0fca6ea1SDimitry Andric} 139*0fca6ea1SDimitry Andric 140*0fca6ea1SDimitry Andricdef : Pat<(X86ctest GR8:$src1, GR8:$src2, timm:$dcf, timm:$cond, EFLAGS), 141*0fca6ea1SDimitry Andric (CTEST8rr GR8:$src1, GR8:$src2, timm:$dcf, timm:$cond)>; 142*0fca6ea1SDimitry Andricdef : Pat<(X86ctest GR16:$src1, GR16:$src2, timm:$dcf, timm:$cond, EFLAGS), 143*0fca6ea1SDimitry Andric (CTEST16rr GR16:$src1, GR16:$src2, timm:$dcf, timm:$cond)>; 144*0fca6ea1SDimitry Andricdef : Pat<(X86ctest GR32:$src1, GR32:$src2, timm:$dcf, timm:$cond, EFLAGS), 145*0fca6ea1SDimitry Andric (CTEST32rr GR32:$src1, GR32:$src2, timm:$dcf, timm:$cond)>; 146*0fca6ea1SDimitry Andricdef : Pat<(X86ctest GR64:$src1, GR64:$src2, timm:$dcf, timm:$cond, EFLAGS), 147*0fca6ea1SDimitry Andric (CTEST64rr GR64:$src1, GR64:$src2, timm:$dcf, timm:$cond)>; 148*0fca6ea1SDimitry Andric 149*0fca6ea1SDimitry Andricdef : Pat<(X86ctestpat GR8:$src1, imm:$src2, timm:$dcf, timm:$cond), 150*0fca6ea1SDimitry Andric (CTEST8ri GR8:$src1, imm:$src2, timm:$dcf, timm:$cond)>; 151*0fca6ea1SDimitry Andricdef : Pat<(X86ctestpat GR16:$src1, imm:$src2, timm:$dcf, timm:$cond), 152*0fca6ea1SDimitry Andric (CTEST16ri GR16:$src1, imm:$src2, timm:$dcf, timm:$cond)>; 153*0fca6ea1SDimitry Andricdef : Pat<(X86ctestpat GR32:$src1, imm:$src2, timm:$dcf, timm:$cond), 154*0fca6ea1SDimitry Andric (CTEST32ri GR32:$src1, imm:$src2, timm:$dcf, timm:$cond)>; 155*0fca6ea1SDimitry Andricdef : Pat<(X86ctestpat GR64:$src1, i64immSExt32_su:$src2, timm:$dcf, timm:$cond), 156*0fca6ea1SDimitry Andric (CTEST64ri32 GR64:$src1, i64immSExt32_su:$src2, timm:$dcf, timm:$cond)>; 157