1//====-- X86InstrTBM.td - TBM X86 Instruction Definition -*- 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 defining the TBM X86 instructions. 10// 11//===----------------------------------------------------------------------===// 12 13//===----------------------------------------------------------------------===// 14// TBM Instructions 15// 16let Predicates = [HasTBM], Defs = [EFLAGS] in { 17 18multiclass tbm_bextri<bits<8> opc, RegisterClass RC, string OpcodeStr, 19 X86MemOperand x86memop, PatFrag ld_frag, 20 SDNode OpNode, Operand immtype, 21 SDPatternOperator immoperator, 22 X86FoldableSchedWrite Sched> { 23 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl), 24 !strconcat(OpcodeStr, 25 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"), 26 [(set RC:$dst, (OpNode RC:$src1, immoperator:$cntl))]>, 27 XOP, XOPA, Sched<[Sched]>; 28 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst), 29 (ins x86memop:$src1, immtype:$cntl), 30 !strconcat(OpcodeStr, 31 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"), 32 [(set RC:$dst, (OpNode (ld_frag addr:$src1), immoperator:$cntl))]>, 33 XOP, XOPA, Sched<[Sched.Folded]>; 34} 35 36defm BEXTRI32 : tbm_bextri<0x10, GR32, "bextr{l}", i32mem, loadi32, 37 X86bextri, i32imm, timm, WriteBEXTR>; 38let ImmT = Imm32S in 39defm BEXTRI64 : tbm_bextri<0x10, GR64, "bextr{q}", i64mem, loadi64, 40 X86bextri, i64i32imm, 41 i64timmSExt32, WriteBEXTR>, REX_W; 42 43multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem, 44 RegisterClass RC, string OpcodeStr, 45 X86MemOperand x86memop, X86FoldableSchedWrite Sched> { 46let hasSideEffects = 0 in { 47 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src), 48 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"), []>, 49 XOP, VVVV, XOP9, Sched<[Sched]>; 50 let mayLoad = 1 in 51 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src), 52 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"), []>, 53 XOP, VVVV, XOP9, Sched<[Sched.Folded]>; 54} 55} 56 57multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr, 58 X86FoldableSchedWrite Sched, 59 Format FormReg, Format FormMem> { 60 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr#"{l}", 61 i32mem, Sched>; 62 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr#"{q}", 63 i64mem, Sched>, REX_W; 64} 65 66defm BLCFILL : tbm_binary_intr<0x01, "blcfill", WriteALU, MRM1r, MRM1m>; 67defm BLCI : tbm_binary_intr<0x02, "blci", WriteALU, MRM6r, MRM6m>; 68defm BLCIC : tbm_binary_intr<0x01, "blcic", WriteALU, MRM5r, MRM5m>; 69defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", WriteALU, MRM1r, MRM1m>; 70defm BLCS : tbm_binary_intr<0x01, "blcs", WriteALU, MRM3r, MRM3m>; 71defm BLSFILL : tbm_binary_intr<0x01, "blsfill", WriteALU, MRM2r, MRM2m>; 72defm BLSIC : tbm_binary_intr<0x01, "blsic", WriteALU, MRM6r, MRM6m>; 73defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", WriteALU, MRM7r, MRM7m>; 74defm TZMSK : tbm_binary_intr<0x01, "tzmsk", WriteALU, MRM4r, MRM4m>; 75} // HasTBM, EFLAGS 76 77// Use BEXTRI for 64-bit 'and' with large immediate 'mask'. 78let Predicates = [HasTBM] in { 79 def : Pat<(and GR64:$src, AndMask64:$mask), 80 (BEXTRI64ri GR64:$src, (BEXTRMaskXForm imm:$mask))>; 81 82 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask), 83 (BEXTRI64mi addr:$src, (BEXTRMaskXForm imm:$mask))>; 84} 85 86//===----------------------------------------------------------------------===// 87// Pattern fragments to auto generate TBM instructions. 88//===----------------------------------------------------------------------===// 89 90let Predicates = [HasTBM] in { 91 // FIXME: patterns for the load versions are not implemented 92 def : Pat<(and GR32:$src, (add GR32:$src, 1)), 93 (BLCFILL32rr GR32:$src)>; 94 def : Pat<(and GR64:$src, (add GR64:$src, 1)), 95 (BLCFILL64rr GR64:$src)>; 96 97 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))), 98 (BLCI32rr GR32:$src)>; 99 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))), 100 (BLCI64rr GR64:$src)>; 101 102 // Extra patterns because opt can optimize the above patterns to this. 103 def : Pat<(or GR32:$src, (sub -2, GR32:$src)), 104 (BLCI32rr GR32:$src)>; 105 def : Pat<(or GR64:$src, (sub -2, GR64:$src)), 106 (BLCI64rr GR64:$src)>; 107 108 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)), 109 (BLCIC32rr GR32:$src)>; 110 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)), 111 (BLCIC64rr GR64:$src)>; 112 113 def : Pat<(xor GR32:$src, (add GR32:$src, 1)), 114 (BLCMSK32rr GR32:$src)>; 115 def : Pat<(xor GR64:$src, (add GR64:$src, 1)), 116 (BLCMSK64rr GR64:$src)>; 117 118 def : Pat<(or GR32:$src, (add GR32:$src, 1)), 119 (BLCS32rr GR32:$src)>; 120 def : Pat<(or GR64:$src, (add GR64:$src, 1)), 121 (BLCS64rr GR64:$src)>; 122 123 def : Pat<(or GR32:$src, (add GR32:$src, -1)), 124 (BLSFILL32rr GR32:$src)>; 125 def : Pat<(or GR64:$src, (add GR64:$src, -1)), 126 (BLSFILL64rr GR64:$src)>; 127 128 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)), 129 (BLSIC32rr GR32:$src)>; 130 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)), 131 (BLSIC64rr GR64:$src)>; 132 133 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)), 134 (T1MSKC32rr GR32:$src)>; 135 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)), 136 (T1MSKC64rr GR64:$src)>; 137 138 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)), 139 (TZMSK32rr GR32:$src)>; 140 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)), 141 (TZMSK64rr GR64:$src)>; 142 143 // Patterns to match flag producing ops. 144 def : Pat<(and_flag_nocf GR32:$src, (add GR32:$src, 1)), 145 (BLCFILL32rr GR32:$src)>; 146 def : Pat<(and_flag_nocf GR64:$src, (add GR64:$src, 1)), 147 (BLCFILL64rr GR64:$src)>; 148 149 def : Pat<(or_flag_nocf GR32:$src, (not (add GR32:$src, 1))), 150 (BLCI32rr GR32:$src)>; 151 def : Pat<(or_flag_nocf GR64:$src, (not (add GR64:$src, 1))), 152 (BLCI64rr GR64:$src)>; 153 154 // Extra patterns because opt can optimize the above patterns to this. 155 def : Pat<(or_flag_nocf GR32:$src, (sub -2, GR32:$src)), 156 (BLCI32rr GR32:$src)>; 157 def : Pat<(or_flag_nocf GR64:$src, (sub -2, GR64:$src)), 158 (BLCI64rr GR64:$src)>; 159 160 def : Pat<(and_flag_nocf (not GR32:$src), (add GR32:$src, 1)), 161 (BLCIC32rr GR32:$src)>; 162 def : Pat<(and_flag_nocf (not GR64:$src), (add GR64:$src, 1)), 163 (BLCIC64rr GR64:$src)>; 164 165 def : Pat<(xor_flag_nocf GR32:$src, (add GR32:$src, 1)), 166 (BLCMSK32rr GR32:$src)>; 167 def : Pat<(xor_flag_nocf GR64:$src, (add GR64:$src, 1)), 168 (BLCMSK64rr GR64:$src)>; 169 170 def : Pat<(or_flag_nocf GR32:$src, (add GR32:$src, 1)), 171 (BLCS32rr GR32:$src)>; 172 def : Pat<(or_flag_nocf GR64:$src, (add GR64:$src, 1)), 173 (BLCS64rr GR64:$src)>; 174 175 def : Pat<(or_flag_nocf GR32:$src, (add GR32:$src, -1)), 176 (BLSFILL32rr GR32:$src)>; 177 def : Pat<(or_flag_nocf GR64:$src, (add GR64:$src, -1)), 178 (BLSFILL64rr GR64:$src)>; 179 180 def : Pat<(or_flag_nocf (not GR32:$src), (add GR32:$src, -1)), 181 (BLSIC32rr GR32:$src)>; 182 def : Pat<(or_flag_nocf (not GR64:$src), (add GR64:$src, -1)), 183 (BLSIC64rr GR64:$src)>; 184 185 def : Pat<(or_flag_nocf (not GR32:$src), (add GR32:$src, 1)), 186 (T1MSKC32rr GR32:$src)>; 187 def : Pat<(or_flag_nocf (not GR64:$src), (add GR64:$src, 1)), 188 (T1MSKC64rr GR64:$src)>; 189 190 def : Pat<(and_flag_nocf (not GR32:$src), (add GR32:$src, -1)), 191 (TZMSK32rr GR32:$src)>; 192 def : Pat<(and_flag_nocf (not GR64:$src), (add GR64:$src, -1)), 193 (TZMSK64rr GR64:$src)>; 194} // HasTBM 195