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