1 //===-- M68kInstrArithmetic.td - Integer Arith Instrs ------*- tablegen -*-===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file describes the integer arithmetic instructions in the M68k
11 /// architecture. Here is the current status of the file:
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 [~]
23 /// [ ] - was not touched at all
24 /// [!] - requires extarnal stuff implemented
25 /// [~] - functional implementation
26 /// [X] - complete implementation
28 //===----------------------------------------------------------------------===//
30 //===----------------------------------------------------------------------===//
32 //===----------------------------------------------------------------------===//
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>;
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 /// ------------------------------------------------------
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>;
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 /// ---------------------------------------------------
69 /// ---------------------------------------------------
70 /// NOTE It is used to store an immediate to memory, imm-to-reg are handled with
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>,
76 SRC_EXT.Imm, SRC_EXT.B8, SRC_EXT.Scale,
77 SRC_EXT.WL, SRC_EXT.DAReg,
79 DST_EXT.Imm, DST_EXT.B8, DST_EXT.Scale,
80 DST_EXT.WL, DST_EXT.DAReg>;
83 //===----------------------------------------------------------------------===//
85 //===----------------------------------------------------------------------===//
88 let Constraints = "$src = $dst" in {
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"),
99 !cast<MxEncEA>("MxEncEA"#SRC_TYPE.RLet#"_2"),
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
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>>;
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")>>;
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")>>;
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>>;
149 let mayLoad = 1, mayStore = 1 in {
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",
158 MxArithEncoding<MxBead4Bits<CMD>,
159 !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#"EA"#TYPE.RLet),
160 MxBeadDReg<1>, EA, EXT>>;
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",
167 MxArithImmEncoding<MxBead4Bits<CMD>,
168 !cast<MxEncSize>("MxEncSize"#TYPE.Size),
170 !cast<MxEncExt>("MxExtI"#TYPE.Size#"_1")>>;
171 } // mayLoad, mayStore
174 multiclass MxBiArOp_DF<string MN, SDNode NODE, bit isComm,
175 bits<4> CMD, bits<4> CMDI> {
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>;
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>;
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>;
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>;
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>;
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>;
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>;
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>;
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>;
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>;
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>;
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>;
262 def NAME#"16dr" : MxBiArOp_RFRR_xEA<MN, NODE, MxType16d, MxType16r,
264 def NAME#"32dr" : MxBiArOp_RFRR_xEA<MN, NODE, MxType32d, MxType32r,
267 let isCommutable = isComm in {
269 def NAME#"8dd" : MxBiArOp_RFRR_xEA<MN, NODE, MxType8d, MxType8d,
271 def NAME#"16dd" : MxBiArOp_RFRR_xEA<MN, NODE, MxType16d, MxType16d,
273 def NAME#"32dd" : MxBiArOp_RFRR_xEA<MN, NODE, MxType32d, MxType32d,
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
284 let Pattern = [(null_frag)] in
285 multiclass MxBiArOp_AF<string MN, SDNode NODE, bits<4> CMD> {
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>;
299 def NAME#"32ar" : MxBiArOp_RFRR_xEA<MN, NODE, MxType32a, MxType32r,
304 // NOTE These naturally produce CCR
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>;
312 let Uses = [CCR], Defs = [CCR] in {
313 let Constraints = "$src = $dst" in {
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>>>;
327 multiclass MxBiArOp_RFF<string MN, SDNode NODE, bit isComm, bits<4> CMD> {
329 let isCommutable = isComm in {
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>;
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>;
344 //===----------------------------------------------------------------------===//
346 //===----------------------------------------------------------------------===//
348 defm AND : MxBiArOp_DF<"and", MxAnd, 1, 0xC, 0x2>;
349 defm OR : MxBiArOp_DF<"or", MxOr, 1, 0x8, 0x0>;
351 multiclass MxBiArOp_DF_EAd<string MN, SDNode NODE, bits<4> CMD, bits<4> CMDI> {
353 let isCommutable = 1 in {
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>;
359 } // isCommutable = 1
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>;
367 defm XOR : MxBiArOp_DF_EAd<"eor", MxXor, 0xB, 0xA>;
370 //===----------------------------------------------------------------------===//
372 //===----------------------------------------------------------------------===//
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"),
383 !cast<MxEncEA>("MxEncEA"#LHS_TYPE.RLet#"_0"),
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")>>;
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),
405 !cast<MxEncExt>("MxExtI"#TYPE.Size#"_0")>>;
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")>>;
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>>;
427 } // let Defs = [CCR]
429 multiclass MMxCmp_RM<MxType TYPE> {
430 def NAME#TYPE.KOp.Letter : MxCmp_RM<TYPE, TYPE.KOp, TYPE.KPat, MxEncEAk,
432 def NAME#TYPE.QOp.Letter : MxCmp_RM<TYPE, TYPE.QOp, TYPE.QPat, MxEncEAq,
434 def NAME#TYPE.POp.Letter : MxCmp_RM<TYPE, TYPE.POp, TYPE.PPat, MxEncEAp_1,
436 def NAME#TYPE.FOp.Letter : MxCmp_RM<TYPE, TYPE.FOp, TYPE.FPat, MxEncEAf_1,
438 def NAME#TYPE.JOp.Letter : MxCmp_RM<TYPE, TYPE.JOp, TYPE.JPat, MxEncEAj_1,
442 multiclass MMxCmp_MI<MxType TYPE> {
443 def NAME#TYPE.KOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.KOp, TYPE.KPat, MxEncEAk,
445 def NAME#TYPE.QOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.QOp, TYPE.QPat, MxEncEAq,
447 def NAME#TYPE.POp.Letter#"i" : MxCmp_MI<TYPE, TYPE.POp, TYPE.PPat, MxEncEAp_1,
449 def NAME#TYPE.FOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.FOp, TYPE.FPat, MxEncEAf_1,
451 def NAME#TYPE.JOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.JOp, TYPE.JPat, MxEncEAj_1,
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")>;
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")>;
467 defm CMP8d : MMxCmp_RM<MxType8d>;
468 defm CMP16d : MMxCmp_RM<MxType16d>;
469 defm CMP32d : MMxCmp_RM<MxType32d>;
472 defm CMP8 : MMxCmp_MI<MxType8d>;
473 defm CMP16 : MMxCmp_MI<MxType16d>;
474 defm CMP32 : MMxCmp_MI<MxType32d>;
477 //===----------------------------------------------------------------------===//
479 //===----------------------------------------------------------------------===//
481 def MxExtOpmode_wb : MxBead3Bits<0b010>;
482 def MxExtOpmode_lw : MxBead3Bits<0b011>;
483 def MxExtOpmode_lb : MxBead3Bits<0b111>;
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>>;
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)>>;
501 def EXT16 : MxExt<MxType16d, MxType8d>;
502 def EXT32 : MxExt<MxType32d, MxType16d>;
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))))>;
510 //===----------------------------------------------------------------------===//
512 //===----------------------------------------------------------------------===//
514 def MxSDiMuOpmode : MxBead3Bits<0b111>;
515 def MxUDiMuOpmode : MxBead3Bits<0b011>;
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>;
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>>;
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>>;
544 multiclass MxDiMuOp<string MN, bits<4> CMD, bit isComm = 0> {
546 let isCommutable = isComm in {
547 def "S"#NAME#"d32d16" : MxDiMuOp_DD<MN#"s", CMD, MxSDiMuOpmode, MxDRD32,
549 def "U"#NAME#"d32d16" : MxDiMuOp_DD<MN#"u", CMD, MxUDiMuOpmode, MxDRD32,
553 def "S"#NAME#"d32i16" : MxDiMuOp_DI<MN#"s", CMD, MxSDiMuOpmode, MxDRD32,
555 def "U"#NAME#"d32i16" : MxDiMuOp_DI<MN#"u", CMD, MxUDiMuOpmode, MxDRD32,
560 defm DIV : MxDiMuOp<"div", 0x8>;
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);
569 def : Pat<(sdiv i8:$dst, i8:$opd),
571 (SDIVd32d16 (MOVSXd32d8 $dst), (MOVSXd16d8 $opd)),
574 def : Pat<(udiv i8:$dst, i8:$opd),
576 (UDIVd32d16 (MOVZXd32d8 $dst), (MOVZXd16d8 $opd)),
579 def : Pat<(srem i8:$dst, i8:$opd),
581 (ASR32di (ASR32di (SDIVd32d16 (MOVSXd32d8 $dst), (MOVSXd16d8 $opd)), 8), 8),
584 def : Pat<(urem i8:$dst, i8:$opd),
586 (LSR32di (LSR32di (UDIVd32d16 (MOVZXd32d8 $dst), (MOVZXd16d8 $opd)), 8), 8),
590 def : Pat<(sdiv i16:$dst, i16:$opd),
592 (SDIVd32d16 (MOVSXd32d16 $dst), $opd),
595 def : Pat<(udiv i16:$dst, i16:$opd),
597 (UDIVd32d16 (MOVZXd32d16 $dst), $opd),
600 def : Pat<(srem i16:$dst, i16:$opd),
602 (ASR32di (ASR32di (SDIVd32d16 (MOVSXd32d16 $dst), $opd), 8), 8),
605 def : Pat<(urem i16:$dst, i16:$opd),
607 (LSR32di (LSR32di (UDIVd32d16 (MOVZXd32d16 $dst), $opd), 8), 8),
612 def : Pat<(sdiv i8:$dst, MximmSExt8:$opd),
614 (SDIVd32i16 (MOVSXd32d8 $dst), (as_i16imm $opd)),
617 def : Pat<(udiv i8:$dst, MximmSExt8:$opd),
619 (UDIVd32i16 (MOVZXd32d8 $dst), (as_i16imm $opd)),
622 def : Pat<(srem i8:$dst, MximmSExt8:$opd),
624 (ASR32di (ASR32di (SDIVd32i16 (MOVSXd32d8 $dst), (as_i16imm $opd)), 8), 8),
627 def : Pat<(urem i8:$dst, MximmSExt8:$opd),
629 (LSR32di (LSR32di (UDIVd32i16 (MOVZXd32d8 $dst), (as_i16imm $opd)), 8), 8),
633 def : Pat<(sdiv i16:$dst, MximmSExt16:$opd),
635 (SDIVd32i16 (MOVSXd32d16 $dst), imm:$opd),
638 def : Pat<(udiv i16:$dst, MximmSExt16:$opd),
640 (UDIVd32i16 (MOVZXd32d16 $dst), imm:$opd),
643 def : Pat<(srem i16:$dst, MximmSExt16:$opd),
645 (ASR32di (ASR32di (SDIVd32i16 (MOVSXd32d16 $dst), imm:$opd), 8), 8),
648 def : Pat<(urem i16:$dst, MximmSExt16:$opd),
650 (LSR32di (LSR32di (UDIVd32i16 (MOVZXd32d16 $dst), imm:$opd), 8), 8),
654 defm MUL : MxDiMuOp<"mul", 0xC, 1>;
657 def : Pat<(mul i16:$dst, i16:$opd),
659 (SMULd32d16 (MOVXd32d16 $dst), $opd),
662 def : Pat<(mulhs i16:$dst, i16:$opd),
664 (ASR32di (ASR32di (SMULd32d16 (MOVXd32d16 $dst), $opd), 8), 8),
667 def : Pat<(mulhu i16:$dst, i16:$opd),
669 (LSR32di (LSR32di (UMULd32d16 (MOVXd32d16 $dst), $opd), 8), 8),
674 def : Pat<(mul i16:$dst, MximmSExt16:$opd),
676 (SMULd32i16 (MOVXd32d16 $dst), imm:$opd),
679 def : Pat<(mulhs i16:$dst, MximmSExt16:$opd),
681 (ASR32di (ASR32di (SMULd32i16 (MOVXd32d16 $dst), imm:$opd), 8), 8),
684 def : Pat<(mulhu i16:$dst, MximmSExt16:$opd),
686 (LSR32di (LSR32di (UMULd32i16 (MOVXd32d16 $dst), imm:$opd), 8), 8),
690 //===----------------------------------------------------------------------===//
692 //===----------------------------------------------------------------------===//
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>;
704 let Defs = [CCR] in {
705 let Constraints = "$src = $dst" in {
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>>;
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>>;
726 } // let Defs = [CCR]
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")>;
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)>;
737 //===----------------------------------------------------------------------===//
739 //===----------------------------------------------------------------------===//
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
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 {
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)>;
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)>;
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)>;
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)>;
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)>;
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
797 def : Pat<(store (!cast<SDNode>(N) (load MxType8.JPat:$dst), MxType8.IPat:$opd),
799 (ADD8ji MxType8.JOp:$dst, imm:$opd)>;
800 def : Pat<(store (!cast<SDNode>(N) (load MxType16.JPat:$dst), MxType16.IPat:$opd),
802 (ADD16ji MxType16.JOp:$dst, imm:$opd)>;
803 def : Pat<(store (!cast<SDNode>(N) (load MxType32.JPat:$dst), MxType32.IPat:$opd),
805 (ADD32ji MxType32.JOp:$dst, imm:$opd)>;
807 } // foreach add, addc
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)>;
815 foreach N = ["sub", "subc"] in {
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)>;
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)>;
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)>;
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)>;
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)>;
859 def : Pat<(store (!cast<SDNode>(N) (load MxType8.JPat:$dst), MxType8.IPat:$opd),
861 (SUB8ji MxType8.JOp:$dst, imm:$opd)>;
862 def : Pat<(store (!cast<SDNode>(N) (load MxType16.JPat:$dst), MxType16.IPat:$opd),
864 (SUB16ji MxType16.JOp:$dst, imm:$opd)>;
865 def : Pat<(store (!cast<SDNode>(N) (load MxType32.JPat:$dst), MxType32.IPat:$opd),
867 (SUB32ji MxType32.JOp:$dst, imm:$opd)>;
869 } // foreach sub, subx
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)>;
875 multiclass BitwisePat<string INST, SDNode OP> {
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)>;
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)>;
892 defm : BitwisePat<"AND", and>;
893 defm : BitwisePat<"OR", or>;
894 defm : BitwisePat<"XOR", xor>;