[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / Target / M68k / M68kInstrData.td
blob40b9e4a2a7fa576e9112d816a94c7f0174585d55
1 //== M68kInstrData.td - M68k Data Movement Instructions -*- 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 Motorola 680x0 data movement instructions which are
11 /// the basic means of transferring and storing addresses and data. Here is the
12 /// current status of the file:
13 ///
14 ///  Machine:
15 ///
16 ///     EXG   [ ]     FMOVE [ ]     FSMOVE [ ]     FDMOVE [ ]     FMOVEM [ ]
17 ///     LEA   [~]     PEA   [ ]     MOVE   [~]     MOVE16 [ ]     MOVEA  [ ]
18 ///     MOVEM [ ]     MOVEP [ ]     MOVEQ  [ ]     LINK   [ ]     UNLK   [ ]
19 ///
20 ///  Pseudo:
21 ///
22 ///     MOVSX [x]     MOVZX [x]     MOVX   [x]
23 ///
24 ///  Map:
25 ///
26 ///   [ ] - was not touched at all
27 ///   [!] - requires extarnal stuff implemented
28 ///   [~] - in progress but usable
29 ///   [x] - done
30 ///
31 //===----------------------------------------------------------------------===//
33 //===----------------------------------------------------------------------===//
34 // MOVE
35 //===----------------------------------------------------------------------===//
37 /// -----------------------------------------------------
38 ///  F  E | D  C | B  A  9 | 8  7  6 | 5  4  3 | 2  1  0
39 /// -----------------------------------------------------
40 ///       |      |    DESTINATION    |       SOURCE
41 ///  0  0 | SIZE |   REG   |   MODE  |   MODE  |   REG
42 /// -----------------------------------------------------
43 ///
44 /// NOTE Move requires EA X version for direct register destination(0)
45 class MxMoveEncoding<MxBead2Bits size,
46                      MxEncEA srcEA, MxEncExt srcExt,
47                      MxEncEA dstEA, MxEncExt dstExt>
48     : MxEncoding<srcEA.Reg, srcEA.DA, srcEA.Mode, dstEA.DA, dstEA.Mode, dstEA.Reg,
49                  size, MxBead2Bits<0b00>,
50                  srcExt.Imm, srcExt.B8, srcExt.Scale, srcExt.WL, srcExt.DAReg,
51                  dstExt.Imm, dstExt.B8, dstExt.Scale, dstExt.WL, dstExt.DAReg>;
53 /// MOVE has alternate size encoding
54 class MxMoveSize<bits<2> value> : MxBead2Bits<value>;
55 def MxMoveSize8  : MxMoveSize<0b01>;
56 def MxMoveSize16 : MxMoveSize<0b11>;
57 def MxMoveSize32 : MxMoveSize<0b10>;
59 let Defs = [CCR] in
60 class MxMove<string size, dag outs, dag ins, list<dag> pattern, MxEncoding enc>
61     : MxInst<outs, ins, "move."#size#"\t$src, $dst", pattern, enc>;
63 class MxMove_RR<MxType DST, MxType SRC, MxMoveEncoding ENC>
64     : MxMove<DST.Prefix, (outs DST.ROp:$dst), (ins SRC.ROp:$src),
65              [(null_frag)], ENC>;
67 let mayStore = 1 in {
68 class MxMove_MR<MxOperand MEMOpd, ComplexPattern MEMPat, MxType REG,
69                 MxMoveEncoding ENC>
70     : MxMove<REG.Prefix, (outs), (ins MEMOpd:$dst, REG.ROp:$src),
71              [(store REG.VT:$src, MEMPat:$dst)], ENC>;
73 class MxMove_MI<MxOperand MEMOpd, ComplexPattern MEMPat, MxType TYPE,
74                 MxMoveEncoding ENC>
75     : MxMove<TYPE.Prefix, (outs), (ins MEMOpd:$dst, TYPE.IOp:$src),
76              [(store TYPE.IPat:$src, MEMPat:$dst)], ENC>;
77 } // let mayStore = 1
79 class MxMove_RI<MxType DST, MxMoveEncoding ENC>
80     : MxMove<DST.Prefix, (outs DST.ROp:$dst), (ins DST.IOp:$src),
81               [(set DST.VT:$dst, DST.IPat:$src)], ENC>;
84 let mayLoad = 1 in
85 class MxMove_RM<MxType REG, MxOperand MEMOpd, ComplexPattern MEMPat,
86                 MxBead2Bits SIZE,
87                 MxEncEA SRCEA, MxEncExt SRCEXT,
88                 MxEncEA DSTEA, MxEncExt DSTEXT>
89     : MxMove<REG.Prefix, (outs REG.ROp:$dst), (ins MEMOpd:$src),
90              [(set REG.VT:$dst, (REG.Load MEMPat:$src))],
91              MxMoveEncoding<SIZE, SRCEA, SRCEXT, DSTEA, DSTEXT>>;
93 multiclass MMxMove_RM<MxType REG, MxMoveSize SIZE, MxEncEA EA_0> {
95   // REG <- (An)+
96   def NAME#REG.OOp.Letter#REG.Postfix : MxMove_RM<REG, REG.OOp, REG.OPat,
97       SIZE, MxEncEAo_1, MxExtEmpty, EA_0, MxExtEmpty>;
99   // REG <- -(An)
100   def NAME#REG.EOp.Letter#REG.Postfix : MxMove_RM<REG, REG.EOp, REG.EPat,
101       SIZE, MxEncEAe_1, MxExtEmpty, EA_0, MxExtEmpty>;
103   // REG <- (i,PC,Xn)
104   def NAME#REG.KOp.Letter#REG.Postfix : MxMove_RM<REG, REG.KOp, REG.KPat,
105       SIZE, MxEncEAk, MxExtBrief_1, EA_0, MxExtEmpty>;
107   // REG <- (i,PC)
108   def NAME#REG.QOp.Letter#REG.Postfix : MxMove_RM<REG, REG.QOp, REG.QPat,
109       SIZE, MxEncEAq, MxExtI16_1, EA_0, MxExtEmpty>;
111   // REG <- (i,An,Xn)
112   def NAME#REG.FOp.Letter#REG.Postfix : MxMove_RM<REG, REG.FOp, REG.FPat,
113       SIZE, MxEncEAf_1, MxExtBrief_1, EA_0, MxExtEmpty>;
115   // REG <- (i,An)
116   def NAME#REG.POp.Letter#REG.Postfix : MxMove_RM<REG, REG.POp, REG.PPat,
117       SIZE, MxEncEAp_1, MxExtI16_1, EA_0, MxExtEmpty>;
119   // REG <- (ABS)
120   def NAME#REG.BOp.Letter#REG.Postfix : MxMove_RM<REG, REG.BOp, REG.BPat,
121       SIZE, MxEncEAb, MxExtI32_1, EA_0, MxExtEmpty>;
123   // REG <- (An)
124   def NAME#REG.JOp.Letter#REG.Postfix : MxMove_RM<REG, REG.JOp, REG.JPat,
125       SIZE, MxEncEAj_1, MxExtEmpty, EA_0, MxExtEmpty>;
128 let mayLoad = 1, mayStore = 1 in {
129 class MxMove_MM<string SIZE, PatFrag LOAD,
130                 MxOperand DSTOpd, ComplexPattern DSTPat,
131                 MxOperand SRCOpd, ComplexPattern SRCPat,
132                 MxBead2Bits ESIZE,
133                 MxEncEA SRCEA, MxEncExt SRCEXT,
134                 MxEncEA DSTEA, MxEncExt DSTEXT>
135     : MxMove<SIZE, (outs), (ins DSTOpd:$dst, SRCOpd:$src),
136              [(store (LOAD SRCPat:$src), DSTPat:$dst)],
137              MxMoveEncoding<ESIZE, SRCEA, SRCEXT, DSTEA, DSTEXT>>;
138 } // let mayLoad = 1, mayStore = 1
140 multiclass MMxMove_MM<MxType TYPE, MxOperand DSTOpd, ComplexPattern DSTPat,
141                       MxMoveSize SIZE, MxEncEA EA_0, MxEncExt EXT_0> {
143   // MEM <- (An)+
144   def NAME#TYPE.OOp.Letter#TYPE.Postfix
145     : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.OOp, TYPE.OPat,
146                 SIZE, MxEncEAo_1, MxExtEmpty, EA_0, EXT_0>;
148   // MEM <- -(An)
149   def NAME#TYPE.EOp.Letter#TYPE.Postfix
150     : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.EOp, TYPE.EPat,
151                 SIZE, MxEncEAe_1, MxExtEmpty, EA_0, EXT_0>;
153   // MEM <- (i,An)
154   def NAME#TYPE.POp.Letter#TYPE.Postfix
155     : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.POp, TYPE.PPat,
156                 SIZE, MxEncEAp_1, MxExtI16_1, EA_0, EXT_0>;
158   // MEM <- (i,An,Xn)
159   def NAME#TYPE.FOp.Letter#TYPE.Postfix
160     : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.FOp, TYPE.FPat,
161                 SIZE, MxEncEAf_1, MxExtBrief_1, EA_0, EXT_0>;
163   // MEM <- (i,PC,Xn)
164   def NAME#TYPE.KOp.Letter#TYPE.Postfix
165     : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.KOp, TYPE.KPat,
166                 SIZE, MxEncEAk, MxExtBrief_1, EA_0, EXT_0>;
168   // MEM <- (i,PC)
169   def NAME#TYPE.QOp.Letter#TYPE.Postfix
170     : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.QOp, TYPE.QPat,
171                 SIZE, MxEncEAq, MxExtI16_1, EA_0, EXT_0>;
173   // MEM <- (ABS)
174   def NAME#TYPE.BOp.Letter#TYPE.Postfix
175     : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.BOp, TYPE.BPat,
176                 SIZE, MxEncEAb, MxExtI32_1, EA_0, EXT_0>;
178   // MEM <- (An)
179   def NAME#TYPE.JOp.Letter#TYPE.Postfix
180     : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.JOp, TYPE.JPat,
181                 SIZE, MxEncEAj_1, MxExtEmpty, EA_0, EXT_0>;
184 def MOV8dd
185   : MxMove_RR<MxType8d, MxType8d,
186     MxMoveEncoding<MxMoveSize8, MxEncEAd_1, MxExtEmpty, MxEncEAd_0, MxExtEmpty>>;
188 // M <- R
189 def MOV8fd : MxMove_MR<MxType8.FOp, MxType8.FPat, MxType8d,
190                        MxMoveEncoding<MxMoveSize8,
191                             /*src*/   MxEncEAd_1, MxExtEmpty,
192                             /*dst*/   MxEncEAf_0, MxExtBrief_0>>;
194 def MOV8pd : MxMove_MR<MxType8.POp, MxType8.PPat, MxType8d,
195                        MxMoveEncoding<MxMoveSize8,
196                             /*src*/   MxEncEAd_1, MxExtEmpty,
197                             /*dst*/   MxEncEAp_0, MxExtI16_0>>;
199 def MOV8ed : MxMove_MR<MxType8.EOp, MxType8.EPat, MxType8d,
200                        MxMoveEncoding<MxMoveSize8,
201                             /*src*/   MxEncEAd_1, MxExtEmpty,
202                             /*dst*/   MxEncEAe_0, MxExtEmpty>>;
204 def MOV8od : MxMove_MR<MxType8.OOp, MxType8.OPat, MxType8d,
205                        MxMoveEncoding<MxMoveSize8,
206                             /*src*/   MxEncEAd_1, MxExtEmpty,
207                             /*dst*/   MxEncEAo_0, MxExtEmpty>>;
209 def MOV8bd : MxMove_MR<MxType8.BOp, MxType8.BPat, MxType8d,
210                        MxMoveEncoding<MxMoveSize8,
211                             /*src*/   MxEncEAd_1, MxExtEmpty,
212                             /*dst*/   MxEncEAb,   MxExtI32_0>>;
214 def MOV8jd : MxMove_MR<MxType8.JOp, MxType8.JPat, MxType8d,
215                        MxMoveEncoding<MxMoveSize8,
216                             /*src*/   MxEncEAd_1, MxExtEmpty,
217                             /*dst*/   MxEncEAj_0, MxExtEmpty>>;
220 // R <- I
221 def MOV8di : MxMove_RI<MxType8d,
222     MxMoveEncoding<MxMoveSize8, MxEncEAi, MxExtI8_1, MxEncEAd_0, MxExtEmpty>>;
224 foreach S = [16, 32] in {
225   foreach D = [ "r", "a" ] in {
227     foreach O = [ "r", "a" ] in {
228       def MOV#S#D#O : MxMove_RR<
229         !cast<MxType>("MxType"#S#D),
230         !cast<MxType>("MxType"#S#O),
231         MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
232                        !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty,
233                        !cast<MxEncEA>("MxEncEA"#D#"_0_reflected"), MxExtEmpty>>;
234     }
236     // M <- R
237     def MOV#S#"f"#D : MxMove_MR<
238       !cast<MxType>("MxType"#S).FOp,
239       !cast<MxType>("MxType"#S).FPat,
240       !cast<MxType>("MxType"#S#D),
241       MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
242                      !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty,
243                      MxEncEAf_0, MxExtBrief_0>>;
245     def MOV#S#"p"#D : MxMove_MR<
246       !cast<MxType>("MxType"#S).POp,
247       !cast<MxType>("MxType"#S).PPat,
248       !cast<MxType>("MxType"#S#D),
249       MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
250                      !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty,
251                      MxEncEAp_0, MxExtI16_0>>;
253     def MOV#S#"e"#D : MxMove_MR<
254       !cast<MxType>("MxType"#S).EOp,
255       !cast<MxType>("MxType"#S).EPat,
256       !cast<MxType>("MxType"#S#D),
257       MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
258                      !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty,
259                      MxEncEAe_0, MxExtEmpty>>;
261     def MOV#S#"o"#D : MxMove_MR<
262       !cast<MxType>("MxType"#S).OOp,
263       !cast<MxType>("MxType"#S).OPat,
264       !cast<MxType>("MxType"#S#D),
265       MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
266                      !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty,
267                      MxEncEAo_0, MxExtEmpty>>;
269     def MOV#S#"b"#D : MxMove_MR<
270       !cast<MxType>("MxType"#S).BOp,
271       !cast<MxType>("MxType"#S).BPat,
272       !cast<MxType>("MxType"#S#D),
273       MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
274                      !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty,
275                      MxEncEAb, MxExtI32_0>>;
277     def MOV#S#"j"#D : MxMove_MR<
278       !cast<MxType>("MxType"#S).JOp,
279       !cast<MxType>("MxType"#S).JPat,
280       !cast<MxType>("MxType"#S#D),
281       MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
282                      !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty,
283                      MxEncEAj_0, MxExtEmpty>>;
286     // R <- I
287     def MOV#S#D#"i" : MxMove_RI<
288       !cast<MxType>("MxType"#S#D),
289       MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
290                      MxEncEAi, !cast<MxEncExt>("MxExtI"#S#"_1"),
291                      !cast<MxEncEA>("MxEncEA"#D#"_0_reflected"), MxExtEmpty>>;
292   }
295 // M <- I
296 foreach S = [8, 16, 32] in {
297   def MOV#S#"f"#"i" : MxMove_MI<
298     !cast<MxType>("MxType"#S).FOp,
299     !cast<MxType>("MxType"#S).FPat,
300     !cast<MxType>("MxType"#S),
301     MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
302                    MxEncEAi, !cast<MxEncExt>("MxExtI"#S#"_1"),
303                    MxEncEAf_0, MxExtBrief_0>>;
305   def MOV#S#"p"#"i" : MxMove_MI<
306     !cast<MxType>("MxType"#S).POp,
307     !cast<MxType>("MxType"#S).PPat,
308     !cast<MxType>("MxType"#S),
309     MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
310                    MxEncEAi, !cast<MxEncExt>("MxExtI"#S#"_1"),
311                    MxEncEAp_0, MxExtI16_0>>;
313   def MOV#S#"b"#"i" : MxMove_MI<
314     !cast<MxType>("MxType"#S).BOp,
315     !cast<MxType>("MxType"#S).BPat,
316     !cast<MxType>("MxType"#S),
317     MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
318                    MxEncEAi, !cast<MxEncExt>("MxExtI"#S#"_1"),
319                    MxEncEAb, MxExtI32_0>>;
321   def MOV#S#"j"#"i" : MxMove_MI<
322     !cast<MxType>("MxType"#S).JOp,
323     !cast<MxType>("MxType"#S).JPat,
324     !cast<MxType>("MxType"#S),
325     MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
326                    MxEncEAi, !cast<MxEncExt>("MxExtI"#S#"_1"),
327                    MxEncEAj_0, MxExtEmpty>>;
330 // Store ABS(basically pointer) as Immdiate to Mem
331 def : Pat<(store   MxType32.BPat :$src, MxType32.PPat :$dst),
332           (MOV32pi MxType32.POp  :$dst, MxType32.IOp  :$src)>;
334 def : Pat<(store   MxType32.BPat :$src, MxType32.FPat :$dst),
335           (MOV32fi MxType32.FOp  :$dst, MxType32.IOp  :$src)>;
337 def : Pat<(store   MxType32.BPat :$src, MxType32.BPat :$dst),
338           (MOV32bi MxType32.BOp  :$dst, MxType32.IOp  :$src)>;
340 def : Pat<(store   MxType32.BPat :$src, MxType32.JPat :$dst),
341           (MOV32ji MxType32.JOp  :$dst, MxType32.IOp  :$src)>;
343 // R <- M
344 defm MOV8d  : MMxMove_RM<MxType8d, MxMoveSize8, MxEncEAd_0>;
346 defm MOV16r : MMxMove_RM<MxType16r, MxMoveSize16, MxEncEAr_0_reflected>;
347 defm MOV16a : MMxMove_RM<MxType16a, MxMoveSize16, MxEncEAa_0>;
349 defm MOV32r : MMxMove_RM<MxType32r, MxMoveSize32, MxEncEAr_0_reflected>;
350 defm MOV32a : MMxMove_RM<MxType32a, MxMoveSize32, MxEncEAa_0>;
352 let Pattern = [(null_frag)] in {
353 defm MOV16r : MMxMove_RM<MxType16r_TC, MxMoveSize16, MxEncEAr_0_reflected>;
354 defm MOV16a : MMxMove_RM<MxType16a_TC, MxMoveSize16, MxEncEAa_0>;
356 defm MOV32r : MMxMove_RM<MxType32r_TC, MxMoveSize32, MxEncEAr_0_reflected>;
357 defm MOV32a : MMxMove_RM<MxType32a_TC, MxMoveSize32, MxEncEAa_0>;
358 } // Pattern
360 // M <- M
361 defm MOV8p  : MMxMove_MM<MxType8,      MxType8.POp,  MxType8.PPat,
362                          MxMoveSize8,  MxEncEAp_0,   MxExtI16_0>;
363 defm MOV16p : MMxMove_MM<MxType16,     MxType16.POp, MxType16.PPat,
364                          MxMoveSize16, MxEncEAp_0,   MxExtI16_0>;
365 defm MOV32p : MMxMove_MM<MxType32,     MxType32.POp, MxType32.PPat,
366                          MxMoveSize32, MxEncEAp_0,   MxExtI16_0>;
368 defm MOV8f  : MMxMove_MM<MxType8,      MxType8.FOp,  MxType8.FPat,
369                          MxMoveSize8,  MxEncEAf_0,   MxExtBrief_0>;
370 defm MOV16f : MMxMove_MM<MxType16,     MxType16.FOp, MxType16.FPat,
371                          MxMoveSize16, MxEncEAf_0,   MxExtBrief_0>;
372 defm MOV32f : MMxMove_MM<MxType32,     MxType32.FOp, MxType32.FPat,
373                          MxMoveSize32, MxEncEAf_0,   MxExtBrief_0>;
375 defm MOV8b  : MMxMove_MM<MxType8,      MxType8.BOp,  MxType8.BPat,
376                          MxMoveSize8,  MxEncEAb,     MxExtI32_0>;
377 defm MOV16b : MMxMove_MM<MxType16,     MxType16.BOp, MxType16.BPat,
378                          MxMoveSize16, MxEncEAb,     MxExtI32_0>;
379 defm MOV32b : MMxMove_MM<MxType32,     MxType32.BOp, MxType32.BPat,
380                          MxMoveSize32, MxEncEAb,     MxExtI32_0>;
382 defm MOV8e  : MMxMove_MM<MxType8,      MxType8.EOp,  MxType8.EPat,
383                          MxMoveSize8,  MxEncEAe_0,   MxExtEmpty>;
384 defm MOV16e : MMxMove_MM<MxType16,     MxType16.EOp, MxType16.EPat,
385                          MxMoveSize16, MxEncEAe_0,   MxExtEmpty>;
386 defm MOV32e : MMxMove_MM<MxType32,     MxType32.EOp, MxType32.EPat,
387                          MxMoveSize32, MxEncEAe_0,   MxExtEmpty>;
389 defm MOV8o  : MMxMove_MM<MxType8,      MxType8.OOp,  MxType8.OPat,
390                          MxMoveSize8,  MxEncEAo_0,   MxExtEmpty>;
391 defm MOV16o : MMxMove_MM<MxType16,     MxType16.OOp, MxType16.OPat,
392                          MxMoveSize16, MxEncEAo_0,   MxExtEmpty>;
393 defm MOV32o : MMxMove_MM<MxType32,     MxType32.OOp, MxType32.OPat,
394                          MxMoveSize32, MxEncEAo_0,   MxExtEmpty>;
396 defm MOV8j  : MMxMove_MM<MxType8,      MxType8.JOp,  MxType8.JPat,
397                          MxMoveSize8,  MxEncEAj_0,   MxExtEmpty>;
398 defm MOV16j : MMxMove_MM<MxType16,     MxType16.JOp, MxType16.JPat,
399                          MxMoveSize16, MxEncEAj_0,   MxExtEmpty>;
400 defm MOV32j : MMxMove_MM<MxType32,     MxType32.JOp, MxType32.JPat,
401                          MxMoveSize32, MxEncEAj_0,   MxExtEmpty>;
403 //===----------------------------------------------------------------------===//
404 // MOVEM
406 // The mask is already pre-processed by the save/restore spill hook
407 //===----------------------------------------------------------------------===//
409 // Direction
410 def MxMOVEM_MR : MxBead1Bit<0>;
411 def MxMOVEM_RM : MxBead1Bit<1>;
413 // Size
414 def MxMOVEM_W  : MxBead1Bit<0>;
415 def MxMOVEM_L  : MxBead1Bit<1>;
417 /// ---------------+-------------+-------------+---------
418 ///  F  E  D  C  B | A | 9  8  7 | 6 | 5  4  3 | 2  1  0
419 /// ---------------+---+---------+---+---------+---------
420 ///  0  1  0  0  1 | D | 0  0  1 | S |   MODE  |   REG
421 /// ---------------+---+---------+---+---------+---------
422 ///                  REGISTER LIST MASK
423 /// -----------------------------------------------------
424 /// D - direction(RM,MR)
425 /// S - size(W,L)
426 class MxMOVEMEncoding<MxEncEA EA, MxEncExt EXT, MxBead1Bit SIZE, MxBead1Bit DIR,
427                       MxBead16Imm IMM>
428     : MxEncoding<EA.Reg, EA.DA, EA.Mode, SIZE, MxBead3Bits<0b001>, DIR,
429                  MxBead1Bit<1>, MxBead4Bits<0b0100>, IMM,
430                  EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>;
432 let mayStore = 1 in
433 class MxMOVEM_MR<MxType TYPE, MxBead1Bit SIZE,
434                  MxOperand MEMOp, MxEncEA EA, MxEncExt EXT>
435     : MxInst<(outs), (ins MEMOp:$dst, MxMoveMask:$mask),
436              "movem."#TYPE.Prefix#"\t$mask, $dst", [],
437              MxMOVEMEncoding<EA, EXT, SIZE, MxMOVEM_MR, MxBead16Imm<1>>>;
439 let mayLoad = 1 in
440 class MxMOVEM_RM<MxType TYPE, MxBead1Bit SIZE,
441                  MxOperand MEMOp, MxEncEA EA, MxEncExt EXT>
442     : MxInst<(outs), (ins MxMoveMask:$mask, MEMOp:$src),
443              "movem."#TYPE.Prefix#"\t$src, $mask", [],
444              MxMOVEMEncoding<EA, EXT, SIZE, MxMOVEM_RM, MxBead16Imm<0>>>;
446 def MOVM32jm : MxMOVEM_MR<MxType32, MxMOVEM_L, MxType32.JOp, MxEncEAj_0, MxExtEmpty>;
447 def MOVM32pm : MxMOVEM_MR<MxType32, MxMOVEM_L, MxType32.POp, MxEncEAp_0, MxExtI16_0>;
449 def MOVM32mj : MxMOVEM_RM<MxType32, MxMOVEM_L, MxType32.JOp, MxEncEAj_1, MxExtEmpty>;
450 def MOVM32mp : MxMOVEM_RM<MxType32, MxMOVEM_L, MxType32.POp, MxEncEAp_1, MxExtI16_1>;
452 // Pseudo versions. These a required by virtual register spill/restore since
453 // the mask requires real register to encode. These instruction will be expanded
454 // into real MOVEM after RA finishes.
455 let mayStore = 1 in
456 class MxMOVEM_MR_Pseudo<MxType TYPE, MxOperand MEMOp>
457     : MxPseudo<(outs), (ins MEMOp:$dst, TYPE.ROp:$reg)>;
458 let mayLoad = 1 in
459 class MxMOVEM_RM_Pseudo<MxType TYPE, MxOperand MEMOp>
460     : MxPseudo<(outs TYPE.ROp:$dst), (ins MEMOp:$src)>;
462 // Mem <- Reg
463 def MOVM8jm_P  : MxMOVEM_MR_Pseudo<MxType8d,  MxType8.JOp>;
464 def MOVM16jm_P : MxMOVEM_MR_Pseudo<MxType16r, MxType16.JOp>;
465 def MOVM32jm_P : MxMOVEM_MR_Pseudo<MxType32r, MxType32.JOp>;
467 def MOVM8pm_P  : MxMOVEM_MR_Pseudo<MxType8d,  MxType8.POp>;
468 def MOVM16pm_P : MxMOVEM_MR_Pseudo<MxType16r, MxType16.POp>;
469 def MOVM32pm_P : MxMOVEM_MR_Pseudo<MxType32r, MxType32.POp>;
471 // Reg <- Mem
472 def MOVM8mj_P  : MxMOVEM_RM_Pseudo<MxType8d,  MxType8.JOp>;
473 def MOVM16mj_P : MxMOVEM_RM_Pseudo<MxType16r, MxType16.JOp>;
474 def MOVM32mj_P : MxMOVEM_RM_Pseudo<MxType32r, MxType32.JOp>;
476 def MOVM8mp_P  : MxMOVEM_RM_Pseudo<MxType8d,  MxType8.POp>;
477 def MOVM16mp_P : MxMOVEM_RM_Pseudo<MxType16r, MxType16.POp>;
478 def MOVM32mp_P : MxMOVEM_RM_Pseudo<MxType32r, MxType32.POp>;
481 //===----------------------------------------------------------------------===//
482 // MOVE to/from SR/CCR
484 // A special care must be taken working with to/from CCR since it is basically
485 // word-size SR register truncated for user mode thus it only supports word-size
486 // instructions. Plus the original M68000 does not support moves from CCR. So in
487 // order to use CCR effectively one MUST use proper byte-size pseudo instructi-
488 // ons that will be resolved sometime after RA pass.
489 //===----------------------------------------------------------------------===//
491 /// --------------------------------------------------
492 ///  F  E  D  C  B  A  9  8  7  6 | 5  4  3 | 2  1  0
493 /// --------------------------------------------------
494 ///                               | EFFECTIVE ADDRESS
495 ///  0  1  0  0  0  1  0  0  1  1 |   MODE  |   REG
496 /// --------------------------------------------------
497 let Defs = [CCR] in
498 class MxMoveToCCR<dag INS, MxEncEA EA, MxEncExt EXT>
499     : MxInst<(outs CCRC:$dst), INS, "move.w\t$src, $dst", [],
500              MxEncoding<EA.Reg, EA.DA, EA.Mode,
501                         MxBead4Bits<0b0011>, MxBead4Bits<0b0001>, MxBead2Bits<0b01>,
502                         EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>>;
504 class MxMoveToCCRPseudo<dag INS> : MxPseudo<(outs CCRC:$dst), INS>;
506 let mayLoad = 1 in {
507 def MOV16cp : MxMoveToCCR<(ins MxType16d.POp:$src), MxEncEAp_1, MxExtI16_1>;
508 def  MOV8cp : MxMoveToCCRPseudo<(ins MxType8d.POp:$src)>;
509 } // let mayLoad = 1
511 def MOV16cd : MxMoveToCCR<(ins MxType16d.ROp:$src), MxEncEAd_1, MxExtEmpty>;
512 def  MOV8cd : MxMoveToCCRPseudo<(ins MxType8d.ROp:$src)>;
514 /// Move from CCR
515 /// --------------------------------------------------
516 ///  F  E  D  C  B  A  9  8  7  6 | 5  4  3 | 2  1  0
517 /// --------------------------------------------------
518 ///                               | EFFECTIVE ADDRESS
519 ///  0  1  0  0  0  0  1  0  1  1 |   MODE  |   REG
520 /// --------------------------------------------------
521 let Uses = [CCR] in
522 class MxMoveFromCCR<dag OUTS, dag INS, MxEncEA EA, MxEncExt EXT>
523     : MxInst<OUTS, INS, "move.w\t$src, $dst", [],
524              MxEncoding<EA.Reg, EA.DA, EA.Mode,
525                         MxBead4Bits<0b1011>, MxBead4Bits<0b0000>, MxBead2Bits<0b01>,
526                         EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>>,
527       Requires<[ IsM68010 ]>;
529 class MxMoveFromCCRPseudo<dag INS> : MxPseudo<(outs), INS>;
531 let mayStore = 1 in {
532 def MOV16pc
533   : MxMoveFromCCR<(outs), (ins MxType16d.POp:$dst, CCRC:$src), MxEncEAp_0, MxExtI16_0>;
534 def MOV8pc : MxMoveFromCCRPseudo<(ins MxType8d.POp:$dst, CCRC:$src)>;
535 } // let mayStore = 1
537 def MOV16dc
538   : MxMoveFromCCR<(outs MxType16d.ROp:$dst), (ins CCRC:$src), MxEncEAd_0, MxExtEmpty>;
540 def MOV8dc : MxMoveFromCCRPseudo<(ins MxType8d.ROp:$dst, CCRC:$src)>;
543 //===----------------------------------------------------------------------===//
544 // LEA
545 //===----------------------------------------------------------------------===//
547 /// ----------------------------------------------------
548 ///  F  E  D  C | B  A  9 | 8  7  6 | 5  4  3 | 2  1  0
549 /// ----------------------------------------------------
550 ///  0  1  0  0 | DST REG | 1  1  1 |   MODE  |   REG
551 /// ----------------------------------------------------
552 class MxLEA<MxOperand SRCOpd, ComplexPattern SRCPat, MxEncEA EA, MxEncExt EXT>
553     : MxInst<(outs MxARD32:$dst), (ins SRCOpd:$src),
554              "lea\t$src, $dst", [(set i32:$dst, SRCPat:$src)],
555              MxEncoding<EA.Reg, EA.DA, EA.Mode,
556                         MxBead3Bits<0b111>, MxBeadReg<0>, MxBead4Bits<0x4>,
557                         EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>>;
559 def LEA32p : MxLEA<MxARID32, MxCP_ARID, MxEncEAp_1, MxExtI16_1>;
560 def LEA32f : MxLEA<MxARII32, MxCP_ARII, MxEncEAf_1, MxExtBrief_1>;
561 def LEA32q : MxLEA<MxPCD32,  MxCP_PCD,  MxEncEAq,   MxExtI16_1>;
562 def LEA32b : MxLEA<MxAL32,   MxCP_AL,   MxEncEAb,   MxExtI32_1>;
565 //===----------------------------------------------------------------------===//
566 // Pseudos
567 //===----------------------------------------------------------------------===//
569 /// Pushe/Pop to/from SP for simplicity
570 let Uses = [SP], Defs = [SP], hasSideEffects = 0 in {
572 // SP <- SP - <size>; (SP) <- Dn
573 let mayStore = 1 in {
574 def PUSH8d  : MxPseudo<(outs), (ins DR8:$reg)>;
575 def PUSH16d : MxPseudo<(outs), (ins DR16:$reg)>;
576 def PUSH32r : MxPseudo<(outs), (ins XR32:$reg)>;
577 } // let mayStore = 1
579 // Dn <- (SP); SP <- SP + <size>
580 let mayLoad = 1 in {
581 def POP8d  : MxPseudo<(outs DR8:$reg),  (ins)>;
582 def POP16d : MxPseudo<(outs DR16:$reg), (ins)>;
583 def POP32r : MxPseudo<(outs XR32:$reg), (ins)>;
584 } // let mayLoad = 1
586 } // let Uses/Defs = [SP], hasSideEffects = 0
589 let Defs = [CCR] in {
590 class MxPseudoMove_RR<MxType DST, MxType SRC, list<dag> PAT = []>
591     : MxPseudo<(outs DST.ROp:$dst), (ins SRC.ROp:$src), PAT>;
593 class MxPseudoMove_RM<MxType DST, MxOperand SRCOpd, list<dag> PAT = []>
594     : MxPseudo<(outs DST.ROp:$dst), (ins SRCOpd:$src), PAT>;
597 /// This group of Pseudos is analogues to the real x86 extending moves, but
598 /// since M68k does not have those we need to emulate. These instructions
599 /// will be expanded right after RA completed because we need to know precisely
600 /// what registers are allocated for the operands and if they overlap we just
601 /// extend the value if the registers are completely different we need to move
602 /// first.
603 foreach EXT = ["S", "Z"] in {
604   let hasSideEffects = 0 in {
606     def MOV#EXT#Xd16d8  : MxPseudoMove_RR<MxType16d,  MxType8d>;
607     def MOV#EXT#Xd32d8  : MxPseudoMove_RR<MxType32d,  MxType8d>;
608     def MOV#EXT#Xd32d16 : MxPseudoMove_RR<MxType32r, MxType16r>;
610     let mayLoad = 1 in {
612       def MOV#EXT#Xd16j8   : MxPseudoMove_RM<MxType16d,  MxType8.JOp>;
613       def MOV#EXT#Xd32j8   : MxPseudoMove_RM<MxType32d,  MxType8.JOp>;
614       def MOV#EXT#Xd32j16  : MxPseudoMove_RM<MxType32d, MxType16.JOp>;
616       def MOV#EXT#Xd16p8   : MxPseudoMove_RM<MxType16d,  MxType8.POp>;
617       def MOV#EXT#Xd32p8   : MxPseudoMove_RM<MxType32d,  MxType8.POp>;
618       def MOV#EXT#Xd32p16  : MxPseudoMove_RM<MxType32d, MxType16.POp>;
620       def MOV#EXT#Xd16f8   : MxPseudoMove_RM<MxType16d,  MxType8.FOp>;
621       def MOV#EXT#Xd32f8   : MxPseudoMove_RM<MxType32d,  MxType8.FOp>;
622       def MOV#EXT#Xd32f16  : MxPseudoMove_RM<MxType32d, MxType16.FOp>;
624     }
625   }
628 /// This group of instructions is similar to the group above but DOES NOT do
629 /// any value extension, they just load a smaller register into the lower part
630 /// of another register if operands' real registers are different or does
631 /// nothing if they are the same.
632 def MOVXd16d8  : MxPseudoMove_RR<MxType16d,  MxType8d>;
633 def MOVXd32d8  : MxPseudoMove_RR<MxType32d,  MxType8d>;
634 def MOVXd32d16 : MxPseudoMove_RR<MxType32r, MxType16r>;
636 //===----------------------------------------------------------------------===//
637 // Extend/Truncate Patterns
638 //===----------------------------------------------------------------------===//
640 // i16 <- sext i8
641 def: Pat<(i16 (sext i8:$src)),
642           (EXTRACT_SUBREG (MOVSXd32d8 MxDRD8:$src), MxSubRegIndex16Lo)>;
643 def: Pat<(MxSExtLoadi16i8 MxCP_ARI:$src),
644           (EXTRACT_SUBREG (MOVSXd32j8 MxARI8:$src), MxSubRegIndex16Lo)>;
645 def: Pat<(MxSExtLoadi16i8 MxCP_ARID:$src),
646           (EXTRACT_SUBREG (MOVSXd32p8 MxARID8:$src), MxSubRegIndex16Lo)>;
647 def: Pat<(MxSExtLoadi16i8 MxCP_ARII:$src),
648           (EXTRACT_SUBREG (MOVSXd32f8 MxARII8:$src), MxSubRegIndex16Lo)>;
650 // i32 <- sext i8
651 def: Pat<(i32 (sext i8:$src)), (MOVSXd32d8 MxDRD8:$src)>;
652 def: Pat<(MxSExtLoadi32i8 MxCP_ARI :$src), (MOVSXd32j8 MxARI8 :$src)>;
653 def: Pat<(MxSExtLoadi32i8 MxCP_ARID:$src), (MOVSXd32p8 MxARID8:$src)>;
654 def: Pat<(MxSExtLoadi32i8 MxCP_ARII:$src), (MOVSXd32f8 MxARII8:$src)>;
656 // i32 <- sext i16
657 def: Pat<(i32 (sext i16:$src)), (MOVSXd32d16 MxDRD16:$src)>;
658 def: Pat<(MxSExtLoadi32i16 MxCP_ARI :$src), (MOVSXd32j16 MxARI16 :$src)>;
659 def: Pat<(MxSExtLoadi32i16 MxCP_ARID:$src), (MOVSXd32p16 MxARID16:$src)>;
660 def: Pat<(MxSExtLoadi32i16 MxCP_ARII:$src), (MOVSXd32f16 MxARII16:$src)>;
662 // i16 <- zext i8
663 def: Pat<(i16 (zext i8:$src)),
664           (EXTRACT_SUBREG (MOVZXd32d8 MxDRD8:$src), MxSubRegIndex16Lo)>;
665 def: Pat<(MxZExtLoadi16i8 MxCP_ARI:$src),
666           (EXTRACT_SUBREG (MOVZXd32j8 MxARI8:$src), MxSubRegIndex16Lo)>;
667 def: Pat<(MxZExtLoadi16i8 MxCP_ARID:$src),
668           (EXTRACT_SUBREG (MOVZXd32p8 MxARID8:$src), MxSubRegIndex16Lo)>;
669 def: Pat<(MxZExtLoadi16i8 MxCP_ARII:$src),
670           (EXTRACT_SUBREG (MOVZXd32f8 MxARII8:$src), MxSubRegIndex16Lo)>;
672 // i32 <- zext i8
673 def: Pat<(i32 (zext i8:$src)), (MOVZXd32d8 MxDRD8:$src)>;
674 def: Pat<(MxZExtLoadi32i8 MxCP_ARI :$src), (MOVZXd32j8 MxARI8 :$src)>;
675 def: Pat<(MxZExtLoadi32i8 MxCP_ARID:$src), (MOVZXd32p8 MxARID8:$src)>;
676 def: Pat<(MxZExtLoadi32i8 MxCP_ARII:$src), (MOVZXd32f8 MxARII8:$src)>;
678 // i32 <- zext i16
679 def: Pat<(i32 (zext i16:$src)), (MOVZXd32d16 MxDRD16:$src)>;
680 def: Pat<(MxZExtLoadi32i16 MxCP_ARI :$src), (MOVZXd32j16 MxARI16 :$src)>;
681 def: Pat<(MxZExtLoadi32i16 MxCP_ARID:$src), (MOVZXd32p16 MxARID16:$src)>;
682 def: Pat<(MxZExtLoadi32i16 MxCP_ARII:$src), (MOVZXd32f16 MxARII16:$src)>;
684 // i16 <- anyext i8
685 def: Pat<(i16 (anyext i8:$src)),
686           (EXTRACT_SUBREG (MOVZXd32d8 MxDRD8:$src), MxSubRegIndex16Lo)>;
687 def: Pat<(MxExtLoadi16i8 MxCP_ARI:$src),
688           (EXTRACT_SUBREG (MOVZXd32j8 MxARI8:$src), MxSubRegIndex16Lo)>;
689 def: Pat<(MxExtLoadi16i8 MxCP_ARID:$src),
690           (EXTRACT_SUBREG (MOVZXd32p8 MxARID8:$src), MxSubRegIndex16Lo)>;
691 def: Pat<(MxExtLoadi16i8 MxCP_ARII:$src),
692           (EXTRACT_SUBREG (MOVZXd32f8 MxARII8:$src), MxSubRegIndex16Lo)>;
694 // i32 <- anyext i8
695 def: Pat<(i32 (anyext i8:$src)), (MOVZXd32d8 MxDRD8:$src)>;
696 def: Pat<(MxExtLoadi32i8 MxCP_ARI :$src), (MOVZXd32j8 MxARI8 :$src)>;
697 def: Pat<(MxExtLoadi32i8 MxCP_ARID:$src), (MOVZXd32p8 MxARID8:$src)>;
698 def: Pat<(MxExtLoadi32i8 MxCP_ARII:$src), (MOVZXd32f8 MxARII8:$src)>;
700 // i32 <- anyext i16
701 def: Pat<(i32 (anyext i16:$src)), (MOVZXd32d16 MxDRD16:$src)>;
702 def: Pat<(MxExtLoadi32i16 MxCP_ARI :$src), (MOVZXd32j16 MxARI16 :$src)>;
703 def: Pat<(MxExtLoadi32i16 MxCP_ARID:$src), (MOVZXd32p16 MxARID16:$src)>;
704 def: Pat<(MxExtLoadi32i16 MxCP_ARII:$src), (MOVZXd32f16 MxARII16:$src)>;
706 // trunc patterns
707 def : Pat<(i16 (trunc i32:$src)),
708           (EXTRACT_SUBREG MxXRD32:$src, MxSubRegIndex16Lo)>;
709 def : Pat<(i8  (trunc i32:$src)),
710           (EXTRACT_SUBREG MxXRD32:$src, MxSubRegIndex8Lo)>;
711 def : Pat<(i8  (trunc i16:$src)),
712           (EXTRACT_SUBREG MxXRD16:$src, MxSubRegIndex8Lo)>;