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