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