106c3fb27SDimitry Andric//====-- X86InstrTBM.td - TBM X86 Instruction Definition -*- tablegen -*-=====// 206c3fb27SDimitry Andric// 306c3fb27SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406c3fb27SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 506c3fb27SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606c3fb27SDimitry Andric// 706c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 806c3fb27SDimitry Andric// 906c3fb27SDimitry Andric// This file defining the TBM X86 instructions. 1006c3fb27SDimitry Andric// 1106c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 1206c3fb27SDimitry Andric 1306c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 1406c3fb27SDimitry Andric// TBM Instructions 1506c3fb27SDimitry Andric// 1606c3fb27SDimitry Andriclet Predicates = [HasTBM], Defs = [EFLAGS] in { 1706c3fb27SDimitry Andric 1806c3fb27SDimitry Andricmulticlass tbm_bextri<bits<8> opc, RegisterClass RC, string OpcodeStr, 1906c3fb27SDimitry Andric X86MemOperand x86memop, PatFrag ld_frag, 2006c3fb27SDimitry Andric SDNode OpNode, Operand immtype, 2106c3fb27SDimitry Andric SDPatternOperator immoperator, 2206c3fb27SDimitry Andric X86FoldableSchedWrite Sched> { 2306c3fb27SDimitry Andric def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl), 2406c3fb27SDimitry Andric !strconcat(OpcodeStr, 2506c3fb27SDimitry Andric "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"), 2606c3fb27SDimitry Andric [(set RC:$dst, (OpNode RC:$src1, immoperator:$cntl))]>, 2706c3fb27SDimitry Andric XOP, XOPA, Sched<[Sched]>; 2806c3fb27SDimitry Andric def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst), 2906c3fb27SDimitry Andric (ins x86memop:$src1, immtype:$cntl), 3006c3fb27SDimitry Andric !strconcat(OpcodeStr, 3106c3fb27SDimitry Andric "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"), 3206c3fb27SDimitry Andric [(set RC:$dst, (OpNode (ld_frag addr:$src1), immoperator:$cntl))]>, 3306c3fb27SDimitry Andric XOP, XOPA, Sched<[Sched.Folded]>; 3406c3fb27SDimitry Andric} 3506c3fb27SDimitry Andric 3606c3fb27SDimitry Andricdefm BEXTRI32 : tbm_bextri<0x10, GR32, "bextr{l}", i32mem, loadi32, 3706c3fb27SDimitry Andric X86bextri, i32imm, timm, WriteBEXTR>; 3806c3fb27SDimitry Andriclet ImmT = Imm32S in 3906c3fb27SDimitry Andricdefm BEXTRI64 : tbm_bextri<0x10, GR64, "bextr{q}", i64mem, loadi64, 4006c3fb27SDimitry Andric X86bextri, i64i32imm, 4106c3fb27SDimitry Andric i64timmSExt32, WriteBEXTR>, REX_W; 4206c3fb27SDimitry Andric 4306c3fb27SDimitry Andricmulticlass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem, 4406c3fb27SDimitry Andric RegisterClass RC, string OpcodeStr, 4506c3fb27SDimitry Andric X86MemOperand x86memop, X86FoldableSchedWrite Sched> { 4606c3fb27SDimitry Andriclet hasSideEffects = 0 in { 4706c3fb27SDimitry Andric def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src), 4806c3fb27SDimitry Andric !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"), []>, 49*cb14a3feSDimitry Andric XOP, VVVV, XOP9, Sched<[Sched]>; 5006c3fb27SDimitry Andric let mayLoad = 1 in 5106c3fb27SDimitry Andric def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src), 5206c3fb27SDimitry Andric !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"), []>, 53*cb14a3feSDimitry Andric XOP, VVVV, XOP9, Sched<[Sched.Folded]>; 5406c3fb27SDimitry Andric} 5506c3fb27SDimitry Andric} 5606c3fb27SDimitry Andric 5706c3fb27SDimitry Andricmulticlass tbm_binary_intr<bits<8> opc, string OpcodeStr, 5806c3fb27SDimitry Andric X86FoldableSchedWrite Sched, 5906c3fb27SDimitry Andric Format FormReg, Format FormMem> { 6006c3fb27SDimitry Andric defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr#"{l}", 6106c3fb27SDimitry Andric i32mem, Sched>; 6206c3fb27SDimitry Andric defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr#"{q}", 6306c3fb27SDimitry Andric i64mem, Sched>, REX_W; 6406c3fb27SDimitry Andric} 6506c3fb27SDimitry Andric 6606c3fb27SDimitry Andricdefm BLCFILL : tbm_binary_intr<0x01, "blcfill", WriteALU, MRM1r, MRM1m>; 6706c3fb27SDimitry Andricdefm BLCI : tbm_binary_intr<0x02, "blci", WriteALU, MRM6r, MRM6m>; 6806c3fb27SDimitry Andricdefm BLCIC : tbm_binary_intr<0x01, "blcic", WriteALU, MRM5r, MRM5m>; 6906c3fb27SDimitry Andricdefm BLCMSK : tbm_binary_intr<0x02, "blcmsk", WriteALU, MRM1r, MRM1m>; 7006c3fb27SDimitry Andricdefm BLCS : tbm_binary_intr<0x01, "blcs", WriteALU, MRM3r, MRM3m>; 7106c3fb27SDimitry Andricdefm BLSFILL : tbm_binary_intr<0x01, "blsfill", WriteALU, MRM2r, MRM2m>; 7206c3fb27SDimitry Andricdefm BLSIC : tbm_binary_intr<0x01, "blsic", WriteALU, MRM6r, MRM6m>; 7306c3fb27SDimitry Andricdefm T1MSKC : tbm_binary_intr<0x01, "t1mskc", WriteALU, MRM7r, MRM7m>; 7406c3fb27SDimitry Andricdefm TZMSK : tbm_binary_intr<0x01, "tzmsk", WriteALU, MRM4r, MRM4m>; 7506c3fb27SDimitry Andric} // HasTBM, EFLAGS 7606c3fb27SDimitry Andric 7706c3fb27SDimitry Andric// Use BEXTRI for 64-bit 'and' with large immediate 'mask'. 7806c3fb27SDimitry Andriclet Predicates = [HasTBM] in { 7906c3fb27SDimitry Andric def : Pat<(and GR64:$src, AndMask64:$mask), 8006c3fb27SDimitry Andric (BEXTRI64ri GR64:$src, (BEXTRMaskXForm imm:$mask))>; 8106c3fb27SDimitry Andric 8206c3fb27SDimitry Andric def : Pat<(and (loadi64 addr:$src), AndMask64:$mask), 8306c3fb27SDimitry Andric (BEXTRI64mi addr:$src, (BEXTRMaskXForm imm:$mask))>; 8406c3fb27SDimitry Andric} 8506c3fb27SDimitry Andric 8606c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 8706c3fb27SDimitry Andric// Pattern fragments to auto generate TBM instructions. 8806c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 8906c3fb27SDimitry Andric 9006c3fb27SDimitry Andriclet Predicates = [HasTBM] in { 9106c3fb27SDimitry Andric // FIXME: patterns for the load versions are not implemented 9206c3fb27SDimitry Andric def : Pat<(and GR32:$src, (add GR32:$src, 1)), 9306c3fb27SDimitry Andric (BLCFILL32rr GR32:$src)>; 9406c3fb27SDimitry Andric def : Pat<(and GR64:$src, (add GR64:$src, 1)), 9506c3fb27SDimitry Andric (BLCFILL64rr GR64:$src)>; 9606c3fb27SDimitry Andric 9706c3fb27SDimitry Andric def : Pat<(or GR32:$src, (not (add GR32:$src, 1))), 9806c3fb27SDimitry Andric (BLCI32rr GR32:$src)>; 9906c3fb27SDimitry Andric def : Pat<(or GR64:$src, (not (add GR64:$src, 1))), 10006c3fb27SDimitry Andric (BLCI64rr GR64:$src)>; 10106c3fb27SDimitry Andric 10206c3fb27SDimitry Andric // Extra patterns because opt can optimize the above patterns to this. 10306c3fb27SDimitry Andric def : Pat<(or GR32:$src, (sub -2, GR32:$src)), 10406c3fb27SDimitry Andric (BLCI32rr GR32:$src)>; 10506c3fb27SDimitry Andric def : Pat<(or GR64:$src, (sub -2, GR64:$src)), 10606c3fb27SDimitry Andric (BLCI64rr GR64:$src)>; 10706c3fb27SDimitry Andric 10806c3fb27SDimitry Andric def : Pat<(and (not GR32:$src), (add GR32:$src, 1)), 10906c3fb27SDimitry Andric (BLCIC32rr GR32:$src)>; 11006c3fb27SDimitry Andric def : Pat<(and (not GR64:$src), (add GR64:$src, 1)), 11106c3fb27SDimitry Andric (BLCIC64rr GR64:$src)>; 11206c3fb27SDimitry Andric 11306c3fb27SDimitry Andric def : Pat<(xor GR32:$src, (add GR32:$src, 1)), 11406c3fb27SDimitry Andric (BLCMSK32rr GR32:$src)>; 11506c3fb27SDimitry Andric def : Pat<(xor GR64:$src, (add GR64:$src, 1)), 11606c3fb27SDimitry Andric (BLCMSK64rr GR64:$src)>; 11706c3fb27SDimitry Andric 11806c3fb27SDimitry Andric def : Pat<(or GR32:$src, (add GR32:$src, 1)), 11906c3fb27SDimitry Andric (BLCS32rr GR32:$src)>; 12006c3fb27SDimitry Andric def : Pat<(or GR64:$src, (add GR64:$src, 1)), 12106c3fb27SDimitry Andric (BLCS64rr GR64:$src)>; 12206c3fb27SDimitry Andric 12306c3fb27SDimitry Andric def : Pat<(or GR32:$src, (add GR32:$src, -1)), 12406c3fb27SDimitry Andric (BLSFILL32rr GR32:$src)>; 12506c3fb27SDimitry Andric def : Pat<(or GR64:$src, (add GR64:$src, -1)), 12606c3fb27SDimitry Andric (BLSFILL64rr GR64:$src)>; 12706c3fb27SDimitry Andric 12806c3fb27SDimitry Andric def : Pat<(or (not GR32:$src), (add GR32:$src, -1)), 12906c3fb27SDimitry Andric (BLSIC32rr GR32:$src)>; 13006c3fb27SDimitry Andric def : Pat<(or (not GR64:$src), (add GR64:$src, -1)), 13106c3fb27SDimitry Andric (BLSIC64rr GR64:$src)>; 13206c3fb27SDimitry Andric 13306c3fb27SDimitry Andric def : Pat<(or (not GR32:$src), (add GR32:$src, 1)), 13406c3fb27SDimitry Andric (T1MSKC32rr GR32:$src)>; 13506c3fb27SDimitry Andric def : Pat<(or (not GR64:$src), (add GR64:$src, 1)), 13606c3fb27SDimitry Andric (T1MSKC64rr GR64:$src)>; 13706c3fb27SDimitry Andric 13806c3fb27SDimitry Andric def : Pat<(and (not GR32:$src), (add GR32:$src, -1)), 13906c3fb27SDimitry Andric (TZMSK32rr GR32:$src)>; 14006c3fb27SDimitry Andric def : Pat<(and (not GR64:$src), (add GR64:$src, -1)), 14106c3fb27SDimitry Andric (TZMSK64rr GR64:$src)>; 14206c3fb27SDimitry Andric 14306c3fb27SDimitry Andric // Patterns to match flag producing ops. 14406c3fb27SDimitry Andric def : Pat<(and_flag_nocf GR32:$src, (add GR32:$src, 1)), 14506c3fb27SDimitry Andric (BLCFILL32rr GR32:$src)>; 14606c3fb27SDimitry Andric def : Pat<(and_flag_nocf GR64:$src, (add GR64:$src, 1)), 14706c3fb27SDimitry Andric (BLCFILL64rr GR64:$src)>; 14806c3fb27SDimitry Andric 14906c3fb27SDimitry Andric def : Pat<(or_flag_nocf GR32:$src, (not (add GR32:$src, 1))), 15006c3fb27SDimitry Andric (BLCI32rr GR32:$src)>; 15106c3fb27SDimitry Andric def : Pat<(or_flag_nocf GR64:$src, (not (add GR64:$src, 1))), 15206c3fb27SDimitry Andric (BLCI64rr GR64:$src)>; 15306c3fb27SDimitry Andric 15406c3fb27SDimitry Andric // Extra patterns because opt can optimize the above patterns to this. 15506c3fb27SDimitry Andric def : Pat<(or_flag_nocf GR32:$src, (sub -2, GR32:$src)), 15606c3fb27SDimitry Andric (BLCI32rr GR32:$src)>; 15706c3fb27SDimitry Andric def : Pat<(or_flag_nocf GR64:$src, (sub -2, GR64:$src)), 15806c3fb27SDimitry Andric (BLCI64rr GR64:$src)>; 15906c3fb27SDimitry Andric 16006c3fb27SDimitry Andric def : Pat<(and_flag_nocf (not GR32:$src), (add GR32:$src, 1)), 16106c3fb27SDimitry Andric (BLCIC32rr GR32:$src)>; 16206c3fb27SDimitry Andric def : Pat<(and_flag_nocf (not GR64:$src), (add GR64:$src, 1)), 16306c3fb27SDimitry Andric (BLCIC64rr GR64:$src)>; 16406c3fb27SDimitry Andric 16506c3fb27SDimitry Andric def : Pat<(xor_flag_nocf GR32:$src, (add GR32:$src, 1)), 16606c3fb27SDimitry Andric (BLCMSK32rr GR32:$src)>; 16706c3fb27SDimitry Andric def : Pat<(xor_flag_nocf GR64:$src, (add GR64:$src, 1)), 16806c3fb27SDimitry Andric (BLCMSK64rr GR64:$src)>; 16906c3fb27SDimitry Andric 17006c3fb27SDimitry Andric def : Pat<(or_flag_nocf GR32:$src, (add GR32:$src, 1)), 17106c3fb27SDimitry Andric (BLCS32rr GR32:$src)>; 17206c3fb27SDimitry Andric def : Pat<(or_flag_nocf GR64:$src, (add GR64:$src, 1)), 17306c3fb27SDimitry Andric (BLCS64rr GR64:$src)>; 17406c3fb27SDimitry Andric 17506c3fb27SDimitry Andric def : Pat<(or_flag_nocf GR32:$src, (add GR32:$src, -1)), 17606c3fb27SDimitry Andric (BLSFILL32rr GR32:$src)>; 17706c3fb27SDimitry Andric def : Pat<(or_flag_nocf GR64:$src, (add GR64:$src, -1)), 17806c3fb27SDimitry Andric (BLSFILL64rr GR64:$src)>; 17906c3fb27SDimitry Andric 18006c3fb27SDimitry Andric def : Pat<(or_flag_nocf (not GR32:$src), (add GR32:$src, -1)), 18106c3fb27SDimitry Andric (BLSIC32rr GR32:$src)>; 18206c3fb27SDimitry Andric def : Pat<(or_flag_nocf (not GR64:$src), (add GR64:$src, -1)), 18306c3fb27SDimitry Andric (BLSIC64rr GR64:$src)>; 18406c3fb27SDimitry Andric 18506c3fb27SDimitry Andric def : Pat<(or_flag_nocf (not GR32:$src), (add GR32:$src, 1)), 18606c3fb27SDimitry Andric (T1MSKC32rr GR32:$src)>; 18706c3fb27SDimitry Andric def : Pat<(or_flag_nocf (not GR64:$src), (add GR64:$src, 1)), 18806c3fb27SDimitry Andric (T1MSKC64rr GR64:$src)>; 18906c3fb27SDimitry Andric 19006c3fb27SDimitry Andric def : Pat<(and_flag_nocf (not GR32:$src), (add GR32:$src, -1)), 19106c3fb27SDimitry Andric (TZMSK32rr GR32:$src)>; 19206c3fb27SDimitry Andric def : Pat<(and_flag_nocf (not GR64:$src), (add GR64:$src, -1)), 19306c3fb27SDimitry Andric (TZMSK64rr GR64:$src)>; 19406c3fb27SDimitry Andric} // HasTBM 195