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