1//===-- M68kInstrArithmetic.td - Integer Arith 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/// \file
10/// This file describes the integer arithmetic instructions in the M68k
11/// architecture. Here is the current status of the file:
12///
13///  Machine:
14///
15///    ADD       [~]   ADDA      [~]   ADDI        [~]   ADDQ [ ]   ADDX [~]
16///    CLR       [ ]   CMP       [~]   CMPA        [~]   CMPI [~]   CMPM [ ]
17///    CMP2      [ ]   DIVS/DIVU [~]   DIVSL/DIVUL [ ]   EXT  [~]   EXTB [ ]
18///    MULS/MULU [~]   NEG       [~]   NEGX        [~]   SUB  [~]   SUBA [~]
19///    SUBI      [~]   SUBQ      [ ]   SUBX        [~]
20///
21///  Map:
22///
23///   [ ] - was not touched at all
24///   [!] - requires extarnal stuff implemented
25///   [~] - functional implementation
26///   [X] - complete implementation
27///
28//===----------------------------------------------------------------------===//
29
30//===----------------------------------------------------------------------===//
31// Encoding
32//===----------------------------------------------------------------------===//
33
34/// Encoding for Normal forms
35/// ----------------------------------------------------
36///  F  E  D  C | B  A  9 | 8  7  6 | 5  4  3 | 2  1  0
37/// ----------------------------------------------------
38///             |         |         | EFFECTIVE ADDRESS
39///  x  x  x  x |   REG   | OP MODE |   MODE  |   REG
40/// ----------------------------------------------------
41class MxArithEncoding<MxBead4Bits CMD, MxEncOpMode OPMODE, MxBead REG,
42                      MxEncEA EA, MxEncExt EXT>
43    : MxEncoding<EA.Reg, EA.DA, EA.Mode, OPMODE.B0, OPMODE.B1, OPMODE.B2, REG,
44                 CMD,EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>;
45
46/// Encoding for Extended forms
47/// ------------------------------------------------------
48///  F  E  D  C | B  A  9 | 8 | 7  6 | 5  4 | 3 | 2  1  0
49/// ------------------------------------------------------
50///  x  x  x  x |  REG Rx | 1 | SIZE | 0  0 | M |  REG Ry
51/// ------------------------------------------------------
52/// Rx - destination
53/// Ry - source
54/// M  - address mode switch
55class MxArithXEncoding<MxBead4Bits CMD, MxEncSize SIZE, MxBead1Bit MODE,
56                       MxBeadDReg SRC, MxBeadDReg DST>
57    : MxEncoding<SRC, MODE, MxBead2Bits<0b00>, SIZE, MxBead1Bit<0b1>, DST, CMD>;
58
59/// Encoding for Immediate forms
60/// ---------------------------------------------------
61///  F  E  D  C  B  A  9  8 | 7  6 | 5  4  3 | 2  1  0
62/// ---------------------------------------------------
63///                         |      | EFFECTIVE ADDRESS
64///  x  x  x  x  x  x  x  x | SIZE |   MODE  |   REG
65/// ---------------------------------------------------
66///     16-BIT WORD DATA    |     8-BIT BYTE DATA
67/// ---------------------------------------------------
68///                 32-BIT LONG DATA
69/// ---------------------------------------------------
70/// NOTE It is used to store an immediate to memory, imm-to-reg are handled with
71/// normal version
72class MxArithImmEncoding<MxBead4Bits CMD, MxEncSize SIZE,
73                         MxEncEA DST_EA, MxEncExt DST_EXT, MxEncExt SRC_EXT>
74    : MxEncoding<DST_EA.Reg, DST_EA.DA, DST_EA.Mode, SIZE, CMD, MxBead4Bits<0>,
75                 // Source
76                 SRC_EXT.Imm, SRC_EXT.B8, SRC_EXT.Scale,
77                 SRC_EXT.WL, SRC_EXT.DAReg,
78                 // Destination
79                 DST_EXT.Imm, DST_EXT.B8, DST_EXT.Scale,
80                 DST_EXT.WL, DST_EXT.DAReg>;
81
82
83//===----------------------------------------------------------------------===//
84// Add/Sub
85//===----------------------------------------------------------------------===//
86
87let Defs = [CCR] in {
88let Constraints = "$src = $dst" in {
89
90// $reg, $ccr <- $reg op $reg
91class MxBiArOp_RFRR_xEA<string MN, SDNode NODE, MxType TYPE, bits<4> CMD, MxBead REG>
92    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd),
93             MN#"."#TYPE.Prefix#"\t$opd, $dst",
94             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd))],
95             MxArithEncoding<MxBead4Bits<CMD>,
96                             !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#TYPE.RLet#"EA"),
97                             REG,
98                             !cast<MxEncEA>("MxEncEA"#TYPE.RLet#"_2"),
99                             MxExtEmpty>>;
100
101/// This Op is similar to the one above except it uses reversed opmode, some
102/// commands(e.g. eor) do not support dEA or rEA modes and require EAd for
103/// register only operations.
104/// NOTE when using dd commands it is irrelevant which opmode to use(as it seems)
105/// but some opcodes support address register and some do not which creates this
106/// mess.
107class MxBiArOp_RFRR_EAd<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
108    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd),
109             MN#"."#TYPE.Prefix#"\t$opd, $dst",
110             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd))],
111             MxArithEncoding<MxBead4Bits<CMD>,
112                             !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#"EAd"),
113                             MxBeadDReg<2>, MxEncEAd_0, MxExtEmpty>>;
114
115// $reg <- $reg op $imm
116class MxBiArOp_RFRI_xEA<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
117    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.IOp:$opd),
118             MN#"."#TYPE.Prefix#"\t$opd, $dst",
119             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.IPat:$opd))],
120             MxArithEncoding<MxBead4Bits<CMD>,
121                             !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#TYPE.RLet#"EA"),
122                             MxBeadDReg<0>, MxEncEAi,
123                             !cast<MxEncExt>("MxExtI"#TYPE.Size#"_2")>>;
124
125// Again, there are two ways to write an immediate to Dn register either dEA
126// opmode or using *I encoding, and again some instrucitons also support address
127// registers some do not.
128class MxBiArOp_RFRI<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
129    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.IOp:$opd),
130             MN#"i."#TYPE.Prefix#"\t$opd, $dst",
131             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.IPat:$opd))],
132             MxArithImmEncoding<MxBead4Bits<CMD>, !cast<MxEncSize>("MxEncSize"#TYPE.Size),
133                                !cast<MxEncEA>("MxEncEA"#TYPE.RLet#"_0"), MxExtEmpty,
134                                !cast<MxEncExt>("MxExtI"#TYPE.Size#"_2")>>;
135
136let mayLoad = 1 in
137class MxBiArOp_RFRM<string MN, SDNode NODE, MxType TYPE, MxOperand OPD, ComplexPattern PAT,
138                    bits<4> CMD, MxEncEA EA, MxEncExt EXT>
139    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, OPD:$opd),
140             MN#"."#TYPE.Prefix#"\t$opd, $dst",
141             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, (TYPE.Load PAT:$opd)))],
142             MxArithEncoding<MxBead4Bits<CMD>,
143                             !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#TYPE.RLet#"EA"),
144                             MxBeadDReg<0>, EA, EXT>>;
145
146} // Constraints
147
148let mayLoad = 1, mayStore = 1 in {
149
150// FIXME MxBiArOp_FMR/FMI cannot consume CCR from MxAdd/MxSub which leads for
151// MxAdd to survive the match and subsequent mismatch.
152class MxBiArOp_FMR<string MN, SDNode NODE, MxType TYPE,
153                   MxOperand MEMOpd, ComplexPattern MEMPat,
154                   bits<4> CMD, MxEncEA EA, MxEncExt EXT>
155    : MxInst<(outs), (ins MEMOpd:$dst, TYPE.ROp:$opd),
156             MN#"."#TYPE.Prefix#"\t$opd, $dst",
157             [],
158             MxArithEncoding<MxBead4Bits<CMD>,
159                             !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#"EA"#TYPE.RLet),
160                             MxBeadDReg<1>, EA, EXT>>;
161
162class MxBiArOp_FMI<string MN, SDNode NODE, MxType TYPE,
163                   MxOperand MEMOpd, ComplexPattern MEMPat,
164                   bits<4> CMD, MxEncEA MEMEA, MxEncExt MEMExt>
165    : MxInst<(outs), (ins MEMOpd:$dst, TYPE.IOp:$opd),
166             MN#"."#TYPE.Prefix#"\t$opd, $dst",
167             [],
168             MxArithImmEncoding<MxBead4Bits<CMD>,
169                                !cast<MxEncSize>("MxEncSize"#TYPE.Size),
170                                MEMEA, MEMExt,
171                                !cast<MxEncExt>("MxExtI"#TYPE.Size#"_1")>>;
172} // mayLoad, mayStore
173} // Defs = [CCR]
174
175multiclass MxBiArOp_DF<string MN, SDNode NODE, bit isComm,
176                       bits<4> CMD, bits<4> CMDI> {
177
178  // op $mem, $reg
179  def NAME#"8dk"  : MxBiArOp_RFRM<MN, NODE, MxType8d,  MxType8.KOp,  MxType8.KPat,
180                                  CMD, MxEncEAk, MxExtBrief_2>;
181  def NAME#"16dk" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.KOp, MxType16.KPat,
182                                  CMD, MxEncEAk, MxExtBrief_2>;
183  def NAME#"32dk" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.KOp, MxType32.KPat,
184                                  CMD, MxEncEAk, MxExtBrief_2>;
185
186  def NAME#"8dq"  : MxBiArOp_RFRM<MN, NODE, MxType8d,  MxType8.QOp,  MxType8.QPat,
187                                  CMD, MxEncEAq, MxExtI16_2>;
188  def NAME#"16dq" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.QOp, MxType16.QPat,
189                                  CMD, MxEncEAq, MxExtI16_2>;
190  def NAME#"32dq" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.QOp, MxType32.QPat,
191                                  CMD, MxEncEAq, MxExtI16_2>;
192
193  def NAME#"8dp"  : MxBiArOp_RFRM<MN, NODE, MxType8d,  MxType8.POp,  MxType8.PPat,
194                                  CMD, MxEncEAp_2, MxExtI16_2>;
195  def NAME#"16dp" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.POp, MxType16.PPat,
196                                  CMD, MxEncEAp_2, MxExtI16_2>;
197  def NAME#"32dp" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.POp, MxType32.PPat,
198                                  CMD, MxEncEAp_2, MxExtI16_2>;
199
200  def NAME#"8df"  : MxBiArOp_RFRM<MN, NODE, MxType8d,  MxType8.FOp,  MxType8.FPat,
201                                  CMD, MxEncEAf_2, MxExtBrief_2>;
202  def NAME#"16df" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.FOp, MxType16.FPat,
203                                  CMD, MxEncEAf_2, MxExtBrief_2>;
204  def NAME#"32df" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.FOp, MxType32.FPat,
205                                  CMD, MxEncEAf_2, MxExtBrief_2>;
206
207  def NAME#"8dj"  : MxBiArOp_RFRM<MN, NODE, MxType8d,  MxType8.JOp,  MxType8.JPat,
208                                  CMD, MxEncEAj_2, MxExtEmpty>;
209  def NAME#"16dj" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.JOp, MxType16.JPat,
210                                  CMD, MxEncEAj_2, MxExtEmpty>;
211  def NAME#"32dj" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.JOp, MxType32.JPat,
212                                  CMD, MxEncEAj_2, MxExtEmpty>;
213
214  // op $imm, $reg
215  def NAME#"8di"  : MxBiArOp_RFRI_xEA<MN, NODE, MxType8d,  CMD>;
216  def NAME#"16di" : MxBiArOp_RFRI_xEA<MN, NODE, MxType16d, CMD>;
217  def NAME#"32di" : MxBiArOp_RFRI_xEA<MN, NODE, MxType32d, CMD>;
218
219  // op $reg, $mem
220  def NAME#"8pd"  : MxBiArOp_FMR<MN, NODE, MxType8d,  MxType8.POp,  MxType8.PPat,
221                                 CMD, MxEncEAp_0, MxExtI16_0>;
222  def NAME#"16pd" : MxBiArOp_FMR<MN, NODE, MxType16d, MxType16.POp, MxType16.PPat,
223                                 CMD, MxEncEAp_0, MxExtI16_0>;
224  def NAME#"32pd" : MxBiArOp_FMR<MN, NODE, MxType32d, MxType32.POp, MxType32.PPat,
225                                 CMD, MxEncEAp_0, MxExtI16_0>;
226
227  def NAME#"8fd"  : MxBiArOp_FMR<MN, NODE, MxType8d,  MxType8.FOp,  MxType8.FPat,
228                                 CMD, MxEncEAf_0, MxExtBrief_0>;
229  def NAME#"16fd" : MxBiArOp_FMR<MN, NODE, MxType16d, MxType16.FOp, MxType16.FPat,
230                                 CMD, MxEncEAf_0, MxExtBrief_0>;
231  def NAME#"32fd" : MxBiArOp_FMR<MN, NODE, MxType32d, MxType32.FOp, MxType32.FPat,
232                                 CMD, MxEncEAf_0, MxExtBrief_0>;
233
234  def NAME#"8jd"  : MxBiArOp_FMR<MN, NODE, MxType8d,  MxType8.JOp,  MxType8.JPat,
235                                 CMD, MxEncEAj_0, MxExtEmpty>;
236  def NAME#"16jd" : MxBiArOp_FMR<MN, NODE, MxType16d, MxType16.JOp, MxType16.JPat,
237                                 CMD, MxEncEAj_0, MxExtEmpty>;
238  def NAME#"32jd" : MxBiArOp_FMR<MN, NODE, MxType32d, MxType32.JOp, MxType32.JPat,
239                                 CMD, MxEncEAj_0, MxExtEmpty>;
240
241  // op $imm, $mem
242  def NAME#"8pi"  : MxBiArOp_FMI<MN, NODE, MxType8,  MxType8.POp,  MxType8.PPat,
243                                 CMDI, MxEncEAp_0, MxExtI16_0>;
244  def NAME#"16pi" : MxBiArOp_FMI<MN, NODE, MxType16, MxType16.POp, MxType16.PPat,
245                                 CMDI, MxEncEAp_0, MxExtI16_0>;
246  def NAME#"32pi" : MxBiArOp_FMI<MN, NODE, MxType32, MxType32.POp, MxType32.PPat,
247                                 CMDI, MxEncEAp_0, MxExtI16_0>;
248
249  def NAME#"8fi"  : MxBiArOp_FMI<MN, NODE, MxType8,  MxType8.FOp,  MxType8.FPat,
250                                 CMDI, MxEncEAf_0, MxExtBrief_0>;
251  def NAME#"16fi" : MxBiArOp_FMI<MN, NODE, MxType16, MxType16.FOp, MxType16.FPat,
252                                 CMDI, MxEncEAf_0, MxExtBrief_0>;
253  def NAME#"32fi" : MxBiArOp_FMI<MN, NODE, MxType32, MxType32.FOp, MxType32.FPat,
254                                 CMDI, MxEncEAf_0, MxExtBrief_0>;
255
256  def NAME#"8ji"  : MxBiArOp_FMI<MN, NODE, MxType8,  MxType8.JOp,  MxType8.JPat,
257                                 CMDI, MxEncEAj_0, MxExtEmpty>;
258  def NAME#"16ji" : MxBiArOp_FMI<MN, NODE, MxType16, MxType16.JOp, MxType16.JPat,
259                                 CMDI, MxEncEAj_0, MxExtEmpty>;
260  def NAME#"32ji" : MxBiArOp_FMI<MN, NODE, MxType32, MxType32.JOp, MxType32.JPat,
261                                 CMDI, MxEncEAj_0, MxExtEmpty>;
262
263  let isCommutable = isComm in {
264
265    def NAME#"8dd"  : MxBiArOp_RFRR_xEA<MN, NODE, MxType8d,  CMD, MxBeadDReg<0>>;
266    def NAME#"16dd" : MxBiArOp_RFRR_xEA<MN, NODE, MxType16d, CMD, MxBeadDReg<0>>;
267    def NAME#"32dd" : MxBiArOp_RFRR_xEA<MN, NODE, MxType32d, CMD, MxBeadDReg<0>>;
268
269  } // isComm
270
271} // MxBiArOp_DF
272
273
274// These special snowflakes allowed to match address registers but since *A
275// operations do not produce CCR we should not match them against Mx nodes that
276// produce it.
277let Pattern = [(null_frag)] in
278multiclass MxBiArOp_AF<string MN, SDNode NODE, bit isComm,
279                       bits<4> CMD, bits<4> CMDI> {
280
281  def NAME#"32rk" : MxBiArOp_RFRM<MN, NODE, MxType32r, MxType32.KOp, MxType32.KPat,
282                                  CMD, MxEncEAk, MxExtBrief_2>;
283  def NAME#"32rq" : MxBiArOp_RFRM<MN, NODE, MxType32r, MxType32.QOp, MxType32.QPat,
284                                  CMD, MxEncEAq, MxExtI16_2>;
285  def NAME#"32rf" : MxBiArOp_RFRM<MN, NODE, MxType32r, MxType32.FOp, MxType32.FPat,
286                                  CMD, MxEncEAf_2, MxExtBrief_2>;
287  def NAME#"32rp" : MxBiArOp_RFRM<MN, NODE, MxType32r, MxType32.POp, MxType32.PPat,
288                                  CMD, MxEncEAp_2, MxExtI16_2>;
289  def NAME#"32rj" : MxBiArOp_RFRM<MN, NODE, MxType32r, MxType32.JOp, MxType32.JPat,
290                                  CMD, MxEncEAj_2, MxExtEmpty>;
291  def NAME#"32ri" : MxBiArOp_RFRI_xEA<MN, NODE, MxType32r, CMD>;
292
293  let isCommutable = isComm in
294  def NAME#"32rr" : MxBiArOp_RFRR_xEA<MN, NODE, MxType32r, CMD, MxBeadReg<0>>;
295
296} // MxBiArOp_AF
297
298// NOTE These naturally produce CCR
299
300defm ADD : MxBiArOp_DF<"add", MxAdd, 1, 0xD, 0x6>;
301defm ADD : MxBiArOp_AF<"add", MxAdd, 1, 0xD, 0x6>;
302defm SUB : MxBiArOp_DF<"sub", MxSub, 0, 0x9, 0x4>;
303defm SUB : MxBiArOp_AF<"sub", MxSub, 0, 0x9, 0x4>;
304
305
306let Uses = [CCR], Defs = [CCR] in {
307let Constraints = "$src = $dst" in {
308
309// $reg, ccr <- $reg op $reg op ccr
310class MxBiArOp_RFRRF<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
311    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd),
312             MN#"."#TYPE.Prefix#"\t$opd, $dst",
313             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd, CCR))],
314             MxArithXEncoding<MxBead4Bits<CMD>,
315                              !cast<MxEncSize>("MxEncSize"#TYPE.Size),
316                              MxBead1Bit<0>, MxBeadDReg<2>, MxBeadDReg<0>>>;
317
318} // Constraints
319} // Uses, Defs
320
321multiclass MxBiArOp_RFF<string MN, SDNode NODE, bit isComm, bits<4> CMD> {
322
323let isCommutable = isComm in {
324
325  def NAME#"8dd"  : MxBiArOp_RFRRF<MN, NODE, MxType8d,  CMD>;
326  def NAME#"16dd" : MxBiArOp_RFRRF<MN, NODE, MxType16d, CMD>;
327  def NAME#"32dd" : MxBiArOp_RFRRF<MN, NODE, MxType32d, CMD>;
328
329} // isComm
330
331} // MxBiArOp_RFF
332
333// NOTE These consume and produce CCR
334defm ADDX : MxBiArOp_RFF<"addx", MxAddX, 1, 0xD>;
335defm SUBX : MxBiArOp_RFF<"subx", MxSubX, 0, 0x9>;
336
337
338//===----------------------------------------------------------------------===//
339// And/Xor/Or
340//===----------------------------------------------------------------------===//
341
342defm AND : MxBiArOp_DF<"and", MxAnd, 1, 0xC, 0x2>;
343defm OR  : MxBiArOp_DF<"or",  MxOr,  1, 0x8, 0x0>;
344
345multiclass MxBiArOp_DF_EAd<string MN, SDNode NODE, bits<4> CMD, bits<4> CMDI> {
346
347  let isCommutable = 1 in {
348
349  def NAME#"8dd"  : MxBiArOp_RFRR_EAd<MN, NODE, MxType8d,  CMD>;
350  def NAME#"16dd" : MxBiArOp_RFRR_EAd<MN, NODE, MxType16d, CMD>;
351  def NAME#"32dd" : MxBiArOp_RFRR_EAd<MN, NODE, MxType32d, CMD>;
352
353  } // isCommutable = 1
354
355  def NAME#"8di"  : MxBiArOp_RFRI<MN, NODE,  MxType8d, CMDI>;
356  def NAME#"16di" : MxBiArOp_RFRI<MN, NODE, MxType16d, CMDI>;
357  def NAME#"32di" : MxBiArOp_RFRI<MN, NODE, MxType32d, CMDI>;
358
359} // MxBiArOp_DF_EAd
360
361defm XOR : MxBiArOp_DF_EAd<"eor", MxXor, 0xB, 0xA>;
362
363
364//===----------------------------------------------------------------------===//
365// CMP
366//===----------------------------------------------------------------------===//
367
368let Defs = [CCR] in {
369class MxCmp_RR<MxType TYPE>
370    : MxInst<(outs), (ins TYPE.ROp:$lhs, TYPE.ROp:$rhs),
371             "cmp."#TYPE.Prefix#"\t$lhs, $rhs",
372             [(set CCR, (MxCmp TYPE.VT:$lhs, TYPE.VT:$rhs))],
373             MxArithEncoding<MxBead4Bits<0xB>,
374                             !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#"dEA"),
375                             MxBeadDReg<1>, MxEncEAd_0, MxExtEmpty>>;
376
377class MxCmp_RI<MxType TYPE>
378    : MxInst<(outs), (ins TYPE.IOp:$imm, TYPE.ROp:$reg),
379             "cmpi."#TYPE.Prefix#"\t$imm, $reg",
380             [(set CCR, (MxCmp TYPE.IPat:$imm, TYPE.VT:$reg))],
381             MxArithImmEncoding<MxBead4Bits<0xC>,
382                                !cast<MxEncSize>("MxEncSize"#TYPE.Size),
383                                MxEncEAd_1, MxExtEmpty,
384                                !cast<MxEncExt>("MxExtI"#TYPE.Size#"_0")>>;
385
386let mayLoad = 1 in {
387
388class MxCmp_MI<MxType TYPE, MxOperand MEMOpd, ComplexPattern MEMPat,
389               MxEncEA EA, MxEncExt EXT>
390    : MxInst<(outs), (ins TYPE.IOp:$imm, MEMOpd:$mem),
391             "cmpi."#TYPE.Prefix#"\t$imm, $mem",
392             [(set CCR, (MxCmp TYPE.IPat:$imm, (load MEMPat:$mem)))],
393             MxArithImmEncoding<MxBead4Bits<0xC>,
394                                !cast<MxEncSize>("MxEncSize"#TYPE.Size),
395                                EA, EXT,
396                                !cast<MxEncExt>("MxExtI"#TYPE.Size#"_0")>>;
397
398class MxCmp_BI<MxType TYPE>
399    : MxInst<(outs), (ins TYPE.IOp:$imm, MxAL32:$abs),
400             "cmpi."#TYPE.Prefix#"\t$imm, $abs",
401             [(set CCR, (MxCmp TYPE.IPat:$imm,
402                               (load (i32 (MxWrapper tglobaladdr:$abs)))))],
403             MxArithImmEncoding<MxBead4Bits<0xC>,
404                                !cast<MxEncSize>("MxEncSize"#TYPE.Size),
405                                MxEncEAb, MxExtI32_1,
406                                !cast<MxEncExt>("MxExtI"#TYPE.Size#"_0")>>;
407
408class MxCmp_RM<MxType TYPE, MxOperand MEMOpd, ComplexPattern MEMPat,
409               MxEncEA EA, MxEncExt EXT>
410    : MxInst<(outs), (ins TYPE.ROp:$reg, MEMOpd:$mem),
411             "cmp."#TYPE.Prefix#"\t$mem, $reg",
412             [(set CCR, (MxCmp (load MEMPat:$mem), TYPE.ROp:$reg))],
413             MxArithEncoding<MxBead4Bits<0xB>,
414                             !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#"dEA"),
415                             MxBeadDReg<0>, EA, EXT>>;
416} // let mayLoad = 1
417
418} // let Defs = [CCR]
419
420multiclass MMxCmp_RM<MxType TYPE> {
421  def NAME#TYPE.KOp.Letter : MxCmp_RM<TYPE, TYPE.KOp, TYPE.KPat, MxEncEAk,
422                                      MxExtBrief_1>;
423  def NAME#TYPE.QOp.Letter : MxCmp_RM<TYPE, TYPE.QOp, TYPE.QPat, MxEncEAq,
424                                      MxExtI16_1>;
425  def NAME#TYPE.POp.Letter : MxCmp_RM<TYPE, TYPE.POp, TYPE.PPat, MxEncEAp_1,
426                                      MxExtI16_1>;
427  def NAME#TYPE.FOp.Letter : MxCmp_RM<TYPE, TYPE.FOp, TYPE.FPat, MxEncEAf_1,
428                                      MxExtBrief_1>;
429  def NAME#TYPE.JOp.Letter : MxCmp_RM<TYPE, TYPE.JOp, TYPE.JPat, MxEncEAj_1,
430                                      MxExtEmpty>;
431}
432
433multiclass MMxCmp_MI<MxType TYPE> {
434  def NAME#TYPE.KOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.KOp, TYPE.KPat, MxEncEAk,
435                                          MxExtBrief_1>;
436  def NAME#TYPE.QOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.QOp, TYPE.QPat, MxEncEAq,
437                                          MxExtI16_1>;
438  def NAME#TYPE.POp.Letter#"i" : MxCmp_MI<TYPE, TYPE.POp, TYPE.PPat, MxEncEAp_1,
439                                          MxExtI16_1>;
440  def NAME#TYPE.FOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.FOp, TYPE.FPat, MxEncEAf_1,
441                                          MxExtBrief_1>;
442  def NAME#TYPE.JOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.JOp, TYPE.JPat, MxEncEAj_1,
443                                          MxExtEmpty>;
444}
445
446foreach S = [8, 16, 32] in {
447  def CMP#S#dd : MxCmp_RR<!cast<MxType>("MxType"#S#"d")>;
448  def CMP#S#di : MxCmp_RI<!cast<MxType>("MxType"#S#"d")>;
449  def CMP#S#bi : MxCmp_BI<!cast<MxType>("MxType"#S#"d")>;
450} // foreach
451
452// cmp mem, Dn
453defm CMP8d  : MMxCmp_RM<MxType8d>;
454defm CMP16d : MMxCmp_RM<MxType16d>;
455defm CMP32d : MMxCmp_RM<MxType32d>;
456
457// cmp #imm, mem
458defm CMP8  : MMxCmp_MI<MxType8d>;
459defm CMP16 : MMxCmp_MI<MxType16d>;
460defm CMP32 : MMxCmp_MI<MxType32d>;
461
462
463//===----------------------------------------------------------------------===//
464// EXT
465//===----------------------------------------------------------------------===//
466
467def MxExtOpmode_wb : MxBead3Bits<0b010>;
468def MxExtOpmode_lw : MxBead3Bits<0b011>;
469def MxExtOpmode_lb : MxBead3Bits<0b111>;
470
471/// ---------------------------------------------------
472///  F  E  D  C  B  A  9 | 8  7  6 | 5  4  3 | 2  1  0
473/// ---------------------------------------------------
474///  0  1  0  0  1  0  0 |  OPMODE | 0  0  0 |   REG
475/// ---------------------------------------------------
476class MxExtEncoding<MxBead3Bits OPMODE>
477    : MxEncoding<MxBeadDReg<0>, MxBead3Bits<0b000>, OPMODE,
478                 MxBead3Bits<0b100>, MxBead4Bits<0b0100>>;
479
480let Defs = [CCR] in
481let Constraints = "$src = $dst" in
482class MxExt<MxType TO, MxType FROM>
483    : MxInst<(outs TO.ROp:$dst), (ins TO.ROp:$src),
484             "ext."#TO.Prefix#"\t$src", [],
485             MxExtEncoding<!cast<MxBead3Bits>("MxExtOpmode_"#TO.Prefix#FROM.Prefix)>>;
486
487def EXT16 : MxExt<MxType16d, MxType8d>;
488def EXT32 : MxExt<MxType32d, MxType16d>;
489
490def : Pat<(sext_inreg i16:$src, i8),  (EXT16 $src)>;
491def : Pat<(sext_inreg i32:$src, i16), (EXT32 $src)>;
492def : Pat<(sext_inreg i32:$src, i8),
493          (EXT32 (MOVXd32d16 (EXT16 (EXTRACT_SUBREG $src, MxSubRegIndex16Lo))))>;
494
495
496//===----------------------------------------------------------------------===//
497// DIV/MUL
498//===----------------------------------------------------------------------===//
499
500def MxSDiMuOpmode : MxBead3Bits<0b111>;
501def MxUDiMuOpmode : MxBead3Bits<0b011>;
502
503/// Word operation:
504/// ----------------------------------------------------
505///  F  E  D  C | B  A  9 | 8  7  6 | 5  4  3 | 2  1  0
506/// ----------------------------------------------------
507///             |         |         | EFFECTIVE ADDRESS
508///  x  x  x  x |   REG   | OP MODE |   MODE  |   REG
509/// ----------------------------------------------------
510class MxDiMuEncoding<MxBead4Bits CMD, MxBead3Bits OPMODE, MxEncEA EA, MxEncExt EXT>
511    : MxEncoding<EA.Reg, EA.DA, EA.Mode, OPMODE, MxBeadDReg<0>, CMD,
512                 EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>;
513
514let Defs = [CCR] in {
515let Constraints = "$src = $dst" in {
516// $reg <- $reg op $reg
517class MxDiMuOp_DD<string MN, bits<4> CMD, MxBead3Bits OPMODE,
518                  MxOperand DST, MxOperand OPD>
519    : MxInst<(outs DST:$dst), (ins DST:$src, OPD:$opd), MN#"\t$opd, $dst", [],
520             MxDiMuEncoding<MxBead4Bits<CMD>, OPMODE, MxEncEAd_2, MxExtEmpty>>;
521
522// $reg <- $reg op $imm
523class MxDiMuOp_DI<string MN, bits<4> CMD, MxBead3Bits OPMODE,
524                  MxOperand DST, MxOperand OPD>
525    : MxInst<(outs DST:$dst), (ins DST:$src, OPD:$opd), MN#"\t$opd, $dst", [],
526             MxDiMuEncoding<MxBead4Bits<CMD>, OPMODE, MxEncEAi, MxExtI16_2>>;
527} // let Constraints
528} // Defs = [CCR]
529
530multiclass MxDiMuOp<string MN, bits<4> CMD, bit isComm = 0> {
531
532  let isCommutable = isComm in {
533    def "S"#NAME#"d32d16" : MxDiMuOp_DD<MN#"s", CMD, MxSDiMuOpmode, MxDRD32,
534                                        MxDRD16>;
535    def "U"#NAME#"d32d16" : MxDiMuOp_DD<MN#"u", CMD, MxUDiMuOpmode, MxDRD32,
536                                        MxDRD16>;
537  }
538
539  def "S"#NAME#"d32i16" : MxDiMuOp_DI<MN#"s", CMD, MxSDiMuOpmode, MxDRD32,
540                                      Mxi16imm>;
541  def "U"#NAME#"d32i16" : MxDiMuOp_DI<MN#"u", CMD, MxUDiMuOpmode, MxDRD32,
542                                      Mxi16imm>;
543
544}
545
546defm DIV : MxDiMuOp<"div", 0x8>;
547
548// This is used to cast immediates to 16-bits for operations which don't
549// support smaller immediate sizes.
550def as_i16imm : SDNodeXForm<imm, [{
551  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16);
552}]>;
553
554// RR i8
555def : Pat<(sdiv i8:$dst, i8:$opd),
556          (EXTRACT_SUBREG
557            (SDIVd32d16 (MOVSXd32d8 $dst), (MOVSXd16d8 $opd)),
558             MxSubRegIndex8Lo)>;
559
560def : Pat<(udiv i8:$dst, i8:$opd),
561          (EXTRACT_SUBREG
562            (UDIVd32d16 (MOVZXd32d8 $dst), (MOVZXd16d8 $opd)),
563             MxSubRegIndex8Lo)>;
564
565def : Pat<(srem i8:$dst, i8:$opd),
566          (EXTRACT_SUBREG
567            (ASR32di (ASR32di (SDIVd32d16 (MOVSXd32d8 $dst), (MOVSXd16d8 $opd)), 8), 8),
568             MxSubRegIndex8Lo)>;
569
570def : Pat<(urem i8:$dst, i8:$opd),
571          (EXTRACT_SUBREG
572            (LSR32di (LSR32di (UDIVd32d16 (MOVZXd32d8 $dst), (MOVZXd16d8 $opd)), 8), 8),
573             MxSubRegIndex8Lo)>;
574
575// RR i16
576def : Pat<(sdiv i16:$dst, i16:$opd),
577          (EXTRACT_SUBREG
578            (SDIVd32d16 (MOVSXd32d16 $dst), $opd),
579             MxSubRegIndex16Lo)>;
580
581def : Pat<(udiv i16:$dst, i16:$opd),
582          (EXTRACT_SUBREG
583            (UDIVd32d16 (MOVZXd32d16 $dst), $opd),
584             MxSubRegIndex16Lo)>;
585
586def : Pat<(srem i16:$dst, i16:$opd),
587          (EXTRACT_SUBREG
588            (ASR32di (ASR32di (SDIVd32d16 (MOVSXd32d16 $dst), $opd), 8), 8),
589             MxSubRegIndex16Lo)>;
590
591def : Pat<(urem i16:$dst, i16:$opd),
592          (EXTRACT_SUBREG
593            (LSR32di (LSR32di (UDIVd32d16 (MOVZXd32d16 $dst), $opd), 8), 8),
594             MxSubRegIndex16Lo)>;
595
596
597// RI i8
598def : Pat<(sdiv i8:$dst, MximmSExt8:$opd),
599          (EXTRACT_SUBREG
600            (SDIVd32i16 (MOVSXd32d8 $dst), (as_i16imm $opd)),
601             MxSubRegIndex8Lo)>;
602
603def : Pat<(udiv i8:$dst, MximmSExt8:$opd),
604          (EXTRACT_SUBREG
605            (UDIVd32i16 (MOVZXd32d8 $dst), (as_i16imm $opd)),
606             MxSubRegIndex8Lo)>;
607
608def : Pat<(srem i8:$dst, MximmSExt8:$opd),
609          (EXTRACT_SUBREG
610            (ASR32di (ASR32di (SDIVd32i16 (MOVSXd32d8 $dst), (as_i16imm $opd)), 8), 8),
611             MxSubRegIndex8Lo)>;
612
613def : Pat<(urem i8:$dst, MximmSExt8:$opd),
614          (EXTRACT_SUBREG
615            (LSR32di (LSR32di (UDIVd32i16 (MOVZXd32d8 $dst), (as_i16imm $opd)), 8), 8),
616             MxSubRegIndex8Lo)>;
617
618// RI i16
619def : Pat<(sdiv i16:$dst, MximmSExt16:$opd),
620          (EXTRACT_SUBREG
621            (SDIVd32i16 (MOVSXd32d16 $dst), imm:$opd),
622             MxSubRegIndex16Lo)>;
623
624def : Pat<(udiv i16:$dst, MximmSExt16:$opd),
625          (EXTRACT_SUBREG
626            (UDIVd32i16 (MOVZXd32d16 $dst), imm:$opd),
627             MxSubRegIndex16Lo)>;
628
629def : Pat<(srem i16:$dst, MximmSExt16:$opd),
630          (EXTRACT_SUBREG
631            (ASR32di (ASR32di (SDIVd32i16 (MOVSXd32d16 $dst), imm:$opd), 8), 8),
632             MxSubRegIndex16Lo)>;
633
634def : Pat<(urem i16:$dst, MximmSExt16:$opd),
635          (EXTRACT_SUBREG
636            (LSR32di (LSR32di (UDIVd32i16 (MOVZXd32d16 $dst), imm:$opd), 8), 8),
637             MxSubRegIndex16Lo)>;
638
639
640defm MUL : MxDiMuOp<"mul", 0xC, 1>;
641
642// RR
643def : Pat<(mul i16:$dst, i16:$opd),
644          (EXTRACT_SUBREG
645            (SMULd32d16 (MOVXd32d16 $dst), $opd),
646             MxSubRegIndex16Lo)>;
647
648def : Pat<(mulhs i16:$dst, i16:$opd),
649          (EXTRACT_SUBREG
650            (ASR32di (ASR32di (SMULd32d16 (MOVXd32d16 $dst), $opd), 8), 8),
651             MxSubRegIndex16Lo)>;
652
653def : Pat<(mulhu i16:$dst, i16:$opd),
654          (EXTRACT_SUBREG
655            (LSR32di (LSR32di (UMULd32d16 (MOVXd32d16 $dst), $opd), 8), 8),
656             MxSubRegIndex16Lo)>;
657
658
659// RI
660def : Pat<(mul i16:$dst, MximmSExt16:$opd),
661          (EXTRACT_SUBREG
662            (SMULd32i16 (MOVXd32d16 $dst), imm:$opd),
663             MxSubRegIndex16Lo)>;
664
665def : Pat<(mulhs i16:$dst, MximmSExt16:$opd),
666          (EXTRACT_SUBREG
667            (ASR32di (ASR32di (SMULd32i16 (MOVXd32d16 $dst), imm:$opd), 8), 8),
668             MxSubRegIndex16Lo)>;
669
670def : Pat<(mulhu i16:$dst, MximmSExt16:$opd),
671          (EXTRACT_SUBREG
672            (LSR32di (LSR32di (UMULd32i16 (MOVXd32d16 $dst), imm:$opd), 8), 8),
673             MxSubRegIndex16Lo)>;
674
675
676//===----------------------------------------------------------------------===//
677// NEG/NEGX
678//===----------------------------------------------------------------------===//
679
680/// ------------+------------+------+---------+---------
681///  F  E  D  C | B  A  9  8 | 7  6 | 5  4  3 | 2  1  0
682/// ------------+------------+------+-------------------
683///             |            |      | EFFECTIVE ADDRESS
684///  0  1  0  0 | x  x  x  x | SIZE |   MODE  |   REG
685/// ------------+------------+------+---------+---------
686class MxNEGEncoding<MxBead4Bits CMD, MxEncSize SIZE, MxEncEA EA, MxEncExt EXT>
687    : MxEncoding<EA.Reg, EA.DA, EA.Mode, SIZE, CMD, MxBead4Bits<0b0100>,
688                 EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>;
689
690let Defs = [CCR] in {
691let Constraints = "$src = $dst" in {
692
693class MxNeg_D<MxType TYPE>
694    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src),
695             "neg."#TYPE.Prefix#"\t$dst",
696             [(set TYPE.VT:$dst, (ineg TYPE.VT:$src))],
697             MxNEGEncoding<MxBead4Bits<0x4>,
698                           !cast<MxEncSize>("MxEncSize"#TYPE.Size),
699                           MxEncEAd_0, MxExtEmpty>>;
700
701let Uses = [CCR] in {
702class MxNegX_D<MxType TYPE>
703    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src),
704             "negx."#TYPE.Prefix#"\t$dst",
705             [(set TYPE.VT:$dst, (MxSubX 0, TYPE.VT:$src, CCR))],
706             MxNEGEncoding<MxBead4Bits<0x0>,
707                           !cast<MxEncSize>("MxEncSize"#TYPE.Size),
708                           MxEncEAd_0, MxExtEmpty>>;
709}
710
711} // let Constraints
712} // let Defs = [CCR]
713
714foreach S = [8, 16, 32] in {
715  def NEG#S#d  : MxNeg_D<!cast<MxType>("MxType"#S#"d")>;
716  def NEGX#S#d : MxNegX_D<!cast<MxType>("MxType"#S#"d")>;
717}
718
719def : Pat<(MxSub 0, i8 :$src), (NEG8d  MxDRD8 :$src)>;
720def : Pat<(MxSub 0, i16:$src), (NEG16d MxDRD16:$src)>;
721def : Pat<(MxSub 0, i32:$src), (NEG32d MxDRD32:$src)>;
722
723//===----------------------------------------------------------------------===//
724// no-CCR Patterns
725//===----------------------------------------------------------------------===//
726
727/// Basically the reason for this stuff is that add and addc share the same
728/// operand types constraints for whatever reasons and I had to define a common
729/// MxAdd and MxSub instructions that produce CCR and then pattern-map add and addc
730/// to it.
731/// NOTE On the other hand I see no reason why I cannot just drop explicit CCR
732/// result. Anyway works for now, hopefully I will better understand how this stuff
733/// is designed later
734foreach N = ["add", "addc"] in {
735
736  // add reg, reg
737  def : Pat<(!cast<SDNode>(N) i8 :$src, i8 :$opd),
738            (ADD8dd  MxDRD8 :$src, MxDRD8 :$opd)>;
739  def : Pat<(!cast<SDNode>(N) i16:$src, i16:$opd),
740            (ADD16dd MxDRD16:$src, MxDRD16:$opd)>;
741  def : Pat<(!cast<SDNode>(N) i32:$src, i32:$opd),
742            (ADD32rr MxXRD32:$src, MxXRD32:$opd)>;
743
744  // add (An), reg
745  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.JPat:$opd)),
746            (ADD8dj MxDRD8:$src, MxType8.JOp:$opd)>;
747  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.JPat:$opd)),
748            (ADD16dj MxDRD16:$src, MxType16.JOp:$opd)>;
749  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.JPat:$opd)),
750            (ADD32rj MxXRD32:$src, MxType32.JOp:$opd)>;
751
752  // add (i,An), reg
753  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.PPat:$opd)),
754            (ADD8dp MxDRD8:$src, MxType8.POp:$opd)>;
755  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.PPat:$opd)),
756            (ADD16dp MxDRD16:$src, MxType16.POp:$opd)>;
757  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.PPat:$opd)),
758            (ADD32rp MxXRD32:$src, MxType32.POp:$opd)>;
759
760  // add (i,An,Xn), reg
761  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.FPat:$opd)),
762            (ADD8df MxDRD8:$src, MxType8.FOp:$opd)>;
763  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.FPat:$opd)),
764            (ADD16df MxDRD16:$src, MxType16.FOp:$opd)>;
765  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.FPat:$opd)),
766            (ADD32rf MxXRD32:$src, MxType32.FOp:$opd)>;
767
768  // add reg, imm
769  def : Pat<(!cast<SDNode>(N) i8: $src, MximmSExt8:$opd),
770            (ADD8di  MxDRD8 :$src, imm:$opd)>;
771  def : Pat<(!cast<SDNode>(N) i16:$src, MximmSExt16:$opd),
772            (ADD16di MxDRD16:$src, imm:$opd)>;
773
774  // LEAp is more complex and thus will be selected over normal ADD32ri but it cannot
775  // be used with data registers, here by adding complexity to a simple ADD32ri insts
776  // we make sure it will be selected over LEAp
777  let AddedComplexity = 15 in {
778  def : Pat<(!cast<SDNode>(N) i32:$src, MximmSExt32:$opd),
779            (ADD32ri MxXRD32:$src, imm:$opd)>;
780  } // AddedComplexity = 15
781
782  // add imm, (An)
783  def : Pat<(store (!cast<SDNode>(N) (load MxType8.JPat:$dst), MxType8.IPat:$opd),
784                   MxType8.JPat:$dst),
785            (ADD8ji MxType8.JOp:$dst, imm:$opd)>;
786  def : Pat<(store (!cast<SDNode>(N) (load MxType16.JPat:$dst), MxType16.IPat:$opd),
787                   MxType16.JPat:$dst),
788            (ADD16ji MxType16.JOp:$dst, imm:$opd)>;
789  def : Pat<(store (!cast<SDNode>(N) (load MxType32.JPat:$dst), MxType32.IPat:$opd),
790                   MxType32.JPat:$dst),
791            (ADD32ji MxType32.JOp:$dst, imm:$opd)>;
792
793} // foreach add, addc
794
795def : Pat<(adde i8 :$src, i8 :$opd), (ADDX8dd  MxDRD8 :$src, MxDRD8 :$opd)>;
796def : Pat<(adde i16:$src, i16:$opd), (ADDX16dd MxDRD16:$src, MxDRD16:$opd)>;
797def : Pat<(adde i32:$src, i32:$opd), (ADDX32dd MxDRD32:$src, MxDRD32:$opd)>;
798
799
800
801foreach N = ["sub", "subc"] in {
802
803  // sub reg, reg
804  def : Pat<(!cast<SDNode>(N) i8 :$src, i8 :$opd),
805            (SUB8dd  MxDRD8 :$src, MxDRD8 :$opd)>;
806  def : Pat<(!cast<SDNode>(N) i16:$src, i16:$opd),
807            (SUB16dd MxDRD16:$src, MxDRD16:$opd)>;
808  def : Pat<(!cast<SDNode>(N) i32:$src, i32:$opd),
809            (SUB32rr MxXRD32:$src, MxXRD32:$opd)>;
810
811
812  // sub (An), reg
813  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.JPat:$opd)),
814            (SUB8dj MxDRD8:$src, MxType8.JOp:$opd)>;
815  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.JPat:$opd)),
816            (SUB16dj MxDRD16:$src, MxType16.JOp:$opd)>;
817  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.JPat:$opd)),
818            (SUB32rj MxXRD32:$src, MxType32.JOp:$opd)>;
819
820  // sub (i,An), reg
821  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.PPat:$opd)),
822            (SUB8dp MxDRD8:$src, MxType8.POp:$opd)>;
823  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.PPat:$opd)),
824            (SUB16dp MxDRD16:$src, MxType16.POp:$opd)>;
825  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.PPat:$opd)),
826            (SUB32rp MxXRD32:$src, MxType32.POp:$opd)>;
827
828  // sub (i,An,Xn), reg
829  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.FPat:$opd)),
830            (SUB8df MxDRD8:$src, MxType8.FOp:$opd)>;
831  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.FPat:$opd)),
832            (SUB16df MxDRD16:$src, MxType16.FOp:$opd)>;
833  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.FPat:$opd)),
834            (SUB32rf MxXRD32:$src, MxType32.FOp:$opd)>;
835
836  // sub reg, imm
837  def : Pat<(!cast<SDNode>(N) i8 :$src, MximmSExt8 :$opd),
838            (SUB8di  MxDRD8 :$src, imm:$opd)>;
839  def : Pat<(!cast<SDNode>(N) i16:$src, MximmSExt16:$opd),
840            (SUB16di MxDRD16:$src, imm:$opd)>;
841  def : Pat<(!cast<SDNode>(N) i32:$src, MximmSExt32:$opd),
842            (SUB32ri MxXRD32:$src, imm:$opd)>;
843
844  // sub imm, (An)
845  def : Pat<(store (!cast<SDNode>(N) (load MxType8.JPat:$dst), MxType8.IPat:$opd),
846                   MxType8.JPat:$dst),
847            (SUB8ji MxType8.JOp:$dst, imm:$opd)>;
848  def : Pat<(store (!cast<SDNode>(N) (load MxType16.JPat:$dst), MxType16.IPat:$opd),
849                   MxType16.JPat:$dst),
850            (SUB16ji MxType16.JOp:$dst, imm:$opd)>;
851  def : Pat<(store (!cast<SDNode>(N) (load MxType32.JPat:$dst), MxType32.IPat:$opd),
852                   MxType32.JPat:$dst),
853            (SUB32ji MxType32.JOp:$dst, imm:$opd)>;
854
855} // foreach sub, subx
856
857def : Pat<(sube i8 :$src, i8 :$opd), (SUBX8dd  MxDRD8 :$src, MxDRD8 :$opd)>;
858def : Pat<(sube i16:$src, i16:$opd), (SUBX16dd MxDRD16:$src, MxDRD16:$opd)>;
859def : Pat<(sube i32:$src, i32:$opd), (SUBX32dd MxDRD32:$src, MxDRD32:$opd)>;
860
861multiclass BitwisePat<string INST, SDNode OP> {
862  // op reg, reg
863  def : Pat<(OP i8 :$src, i8 :$opd),
864            (!cast<MxInst>(INST#"8dd")  MxDRD8 :$src, MxDRD8 :$opd)>;
865  def : Pat<(OP i16:$src, i16:$opd),
866            (!cast<MxInst>(INST#"16dd") MxDRD16:$src, MxDRD16:$opd)>;
867  def : Pat<(OP i32:$src, i32:$opd),
868            (!cast<MxInst>(INST#"32dd") MxDRD32:$src, MxDRD32:$opd)>;
869  // op reg, imm
870  def : Pat<(OP i8: $src, MximmSExt8 :$opd),
871            (!cast<MxInst>(INST#"8di")  MxDRD8 :$src, imm:$opd)>;
872  def : Pat<(OP i16:$src, MximmSExt16:$opd),
873            (!cast<MxInst>(INST#"16di") MxDRD16:$src, imm:$opd)>;
874  def : Pat<(OP i32:$src, MximmSExt32:$opd),
875            (!cast<MxInst>(INST#"32di") MxDRD32:$src, imm:$opd)>;
876}
877
878defm : BitwisePat<"AND", and>;
879defm : BitwisePat<"OR",  or>;
880defm : BitwisePat<"XOR", xor>;
881