xref: /netbsd-src/external/gpl3/gcc/dist/gcc/config/h8300/movepush.md (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1;; ----------------------------------------------------------------------
2;; MOVE INSTRUCTIONS
3;; ----------------------------------------------------------------------
4
5;; movqi
6
7(define_insn_and_split "*movqi"
8  [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
9	(match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
10  "!TARGET_H8300SX && h8300_move_ok (operands[0], operands[1])"
11  "#"
12  "&& reload_completed"
13  [(parallel [(set (match_dup 0) (match_dup 1))
14	      (clobber (reg:CC CC_REG))])])
15
16(define_insn "*movqi<cczn>"
17  [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
18	(match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))
19   (clobber (reg:CC CC_REG))]
20  "!TARGET_H8300SX && h8300_move_ok (operands[0], operands[1])"
21  "@
22   sub.b	%X0,%X0
23   mov.b	%R1,%X0
24   mov.b	%X1,%R0
25   mov.b	%R1,%X0
26   mov.b	%R1,%X0
27   mov.b	%X1,%R0"
28  [(set (attr "length") (symbol_ref "compute_mov_length (operands)"))])
29
30(define_insn_and_split "*movqi_h8sx"
31  [(set (match_operand:QI 0 "general_operand_dst" "=Z,rQ")
32	(match_operand:QI 1 "general_operand_src" "P4>X,rQi"))]
33  "TARGET_H8300SX"
34  "#"
35  "&& reload_completed"
36  [(parallel [(set (match_dup 0) (match_dup 1))
37	      (clobber (reg:CC CC_REG))])])
38
39(define_insn "*movqi_h8sx<cczn>"
40  [(set (match_operand:QI 0 "general_operand_dst" "=Z,rQ")
41	(match_operand:QI 1 "general_operand_src" "P4>X,rQi"))
42   (clobber (reg:CC CC_REG))]
43  "TARGET_H8300SX"
44  "@
45    mov.b	%X1:4,%X0
46    mov.b	%X1,%X0"
47  [(set_attr "length_table" "mov_imm4,movb")])
48
49(define_expand "mov<mode>"
50  [(set (match_operand:QHSIF 0 "general_operand_dst" "")
51	(match_operand:QHSIF 1 "general_operand_src" ""))]
52  ""
53  {
54    enum machine_mode mode = <MODE>mode;
55    if (!TARGET_H8300SX)
56      {
57	/* Other H8 chips, except the H8/SX family can only handle a
58	   single memory operand, which is checked by h8300_move_ok.
59
60	   We could perhaps have h8300_move_ok handle the H8/SX better
61	   and just remove the !TARGET_H8300SX conditional.  */
62	if (!h8300_move_ok (operands[0], operands[1]))
63	  operands[1] = copy_to_mode_reg (mode, operand1);
64      }
65  })
66
67(define_insn_and_split "movstrictqi"
68  [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "+r,r"))
69			 (match_operand:QI 1 "general_operand_src" "I,rmi>"))]
70  ""
71  "#"
72  "&& reload_completed"
73  [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
74	      (clobber (reg:CC CC_REG))])])
75
76
77(define_insn "*movstrictqi<cczn>"
78  [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "+r,r"))
79			 (match_operand:QI 1 "general_operand_src" "I,rmi>"))
80   (clobber (reg:CC CC_REG))]
81  ""
82  "@
83   sub.b	%X0,%X0
84   mov.b	%X1,%X0"
85  [(set_attr "length" "2,*")
86   (set_attr "length_table" "*,movb")])
87
88;; movhi
89
90(define_insn_and_split "*movhi"
91  [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
92	(match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
93  "!TARGET_H8300SX
94    && h8300_move_ok (operands[0], operands[1])"
95  "#"
96  "&& reload_completed"
97  [(parallel [(set (match_dup 0) (match_dup 1))
98	      (clobber (reg:CC CC_REG))])])
99
100(define_insn "*movhi<cczn>"
101  [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
102	(match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))
103   (clobber (reg:CC CC_REG))]
104  "!TARGET_H8300SX
105    && h8300_move_ok (operands[0], operands[1])"
106  "@
107   sub.w	%T0,%T0
108   mov.w	%T1,%T0
109   mov.w	%T1,%T0
110   mov.w	%T1,%T0
111   mov.w	%T1,%T0
112   mov.w	%T1,%T0"
113  [(set (attr "length") (symbol_ref "compute_mov_length (operands)"))])
114
115(define_insn_and_split "*movhi_h8sx"
116  [(set (match_operand:HI 0 "general_operand_dst" "=r,r,Z,Q,rQ")
117	(match_operand:HI 1 "general_operand_src" "I,P3>X,P4>X,IP8>X,rQi"))]
118  "TARGET_H8300SX"
119  "#"
120  "&& reload_completed"
121  [(parallel [(set (match_dup 0) (match_dup 1))
122	      (clobber (reg:CC CC_REG))])])
123
124(define_insn "*movhi_h8sx<cczn>"
125  [(set (match_operand:HI 0 "general_operand_dst" "=r,r,Z,Q,rQ")
126	(match_operand:HI 1 "general_operand_src" "I,P3>X,P4>X,IP8>X,rQi"))
127   (clobber (reg:CC CC_REG))]
128  "TARGET_H8300SX"
129  "@
130   sub.w	%T0,%T0
131   mov.w	%T1:3,%T0
132   mov.w	%T1:4,%T0
133   mov.w	%T1,%T0
134   mov.w	%T1,%T0"
135  [(set_attr "length_table" "*,*,mov_imm4,short_immediate,movw")
136   (set_attr "length" "2,2,*,*,*")])
137
138(define_insn_and_split "movstricthi"
139  [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "+r,r,r"))
140			 (match_operand:HI 1 "general_operand_src" "I,P3>X,rmi"))]
141  ""
142  "#"
143  "&& reload_completed"
144  [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
145	      (clobber (reg:CC CC_REG))])])
146
147(define_insn "*movstricthi<cczn>"
148  [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "+r,r,r"))
149			 (match_operand:HI 1 "general_operand_src" "I,P3>X,rmi"))
150   (clobber (reg:CC CC_REG))]
151  ""
152  "@
153   sub.w	%T0,%T0
154   mov.w	%T1,%T0
155   mov.w	%T1,%T0"
156  [(set_attr "length" "2,2,*")
157   (set_attr "length_table" "*,*,movw")])
158
159;; movsi
160(define_insn_and_split "*movsi"
161  [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m,*a,*a,r")
162	(match_operand:SI 1 "general_operand_src" "I,r,i,r,>,m,r,I,r,*a"))]
163  "(TARGET_H8300S || TARGET_H8300H) && !TARGET_H8300SX
164    && h8300_move_ok (operands[0], operands[1])"
165  "#"
166  "&& reload_completed"
167  [(parallel [(set (match_dup 0) (match_dup 1))
168	      (clobber (reg:CC CC_REG))])])
169
170(define_insn "*movsi_clobber_flags"
171  [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m,*a,*a, r")
172	(match_operand:SI 1 "general_operand_src" " I,r,i,r,>,m,r, I, r,*a"))
173   (clobber (reg:CC CC_REG))]
174  "(TARGET_H8300S || TARGET_H8300H) && !TARGET_H8300SX
175    && h8300_move_ok (operands[0], operands[1])"
176{
177  switch (which_alternative)
178    {
179    case 0:
180      return "sub.l	%S0,%S0";
181    case 7:
182      return "clrmac";
183    case 8:
184      return "clrmac\;ldmac %1,macl";
185    case 9:
186      return "stmac	macl,%0";
187    default:
188      if (GET_CODE (operands[1]) == CONST_INT)
189	{
190	  int val = INTVAL (operands[1]);
191
192	  /* Look for constants which can be made by adding an 8-bit
193	     number to zero in one of the two low bytes.  */
194	  if (val == (val & 0xff))
195	    {
196	      operands[1] = GEN_INT ((char) val & 0xff);
197	      return "sub.l\\t%S0,%S0\;add.b\\t%1,%w0";
198	    }
199
200	  if (val == (val & 0xff00))
201	    {
202	      operands[1] = GEN_INT ((char) (val >> 8) & 0xff);
203	      return "sub.l\\t%S0,%S0\;add.b\\t%1,%x0";
204	    }
205
206	  /* Look for constants that can be obtained by subs, inc, and
207	     dec to 0.  */
208	  switch (val & 0xffffffff)
209	    {
210	    case 0xffffffff:
211	      return "sub.l\\t%S0,%S0\;subs\\t#1,%S0";
212	    case 0xfffffffe:
213	      return "sub.l\\t%S0,%S0\;subs\\t#2,%S0";
214	    case 0xfffffffc:
215	      return "sub.l\\t%S0,%S0\;subs\\t#4,%S0";
216
217	    case 0x0000ffff:
218	      return "sub.l\\t%S0,%S0\;dec.w\\t#1,%f0";
219	    case 0x0000fffe:
220	      return "sub.l\\t%S0,%S0\;dec.w\\t#2,%f0";
221
222	    case 0xffff0000:
223	      return "sub.l\\t%S0,%S0\;dec.w\\t#1,%e0";
224	    case 0xfffe0000:
225	      return "sub.l\\t%S0,%S0\;dec.w\\t#2,%e0";
226
227	    case 0x00010000:
228	      return "sub.l\\t%S0,%S0\;inc.w\\t#1,%e0";
229	    case 0x00020000:
230	      return "sub.l\\t%S0,%S0\;inc.w\\t#2,%e0";
231	    }
232	}
233    }
234   return "mov.l	%S1,%S0";
235}
236  [(set (attr "length") (symbol_ref "compute_mov_length (operands)"))])
237
238(define_insn "*movsi_cczn"
239  [(set (reg:CCZN CC_REG)
240	(compare:CCZN
241	  (match_operand:SI 1 "general_operand_src" " I,r,i,r,>,m,r")
242	  (const_int 0)))
243   (set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m")
244	(match_dup 1))]
245  "(TARGET_H8300S || TARGET_H8300H) && !TARGET_H8300SX
246    && h8300_move_ok (operands[0], operands[1])"
247  "@
248   sub.l	%S0,%S0
249   mov.l	%S1,%S0
250   mov.l	%S1,%S0
251   mov.l	%S1,%S0
252   mov.l	%S1,%S0
253   mov.l	%S1,%S0
254   mov.l	%S1,%S0"
255  [(set (attr "length") (symbol_ref "compute_mov_length (operands)"))])
256
257(define_insn_and_split "*movsi_h8sx"
258  [(set (match_operand:SI 0 "general_operand_dst" "=r,r,Q,rQ,*a,*a,r")
259	(match_operand:SI 1 "general_operand_src" "I,P3>X,IP8>X,rQi,I,r,*a"))]
260  "TARGET_H8300SX"
261  "#"
262  "&& reload_completed"
263  [(parallel [(set (match_dup 0) (match_dup 1))
264	      (clobber (reg:CC CC_REG))])])
265
266(define_insn "*movsi_h8sx_clobber_flags"
267  [(set (match_operand:SI 0 "general_operand_dst" "=r,r,Q,rQ,*a,*a,r")
268	(match_operand:SI 1 "general_operand_src" "I,P3>X,IP8>X,rQi,I,r,*a"))
269   (clobber (reg:CC CC_REG))]
270  "TARGET_H8300SX"
271  "@
272   sub.l	%S0,%S0
273   mov.l	%S1:3,%S0
274   mov.l	%S1,%S0
275   mov.l	%S1,%S0
276   clrmac
277   clrmac\;ldmac	%1,macl
278   stmac	macl,%0"
279  [(set_attr "length_table" "*,*,short_immediate,movl,*,*,*")
280   (set_attr "length" "2,2,*,*,2,6,4")])
281
282(define_insn "*movsi_h8sx_ccnz"
283  [(set (reg:CCZN CC_REG)
284	(compare:CCZN
285	  (match_operand:SI 1 "general_operand_src" "I,P3>X,IP8>X,rQi")
286	  (const_int 0)))
287   (set (match_operand:SI 0 "general_operand_dst" "=r,r,Q,rQ")
288	(match_dup 1))]
289  "TARGET_H8300SX"
290  "@
291   sub.l	%S0,%S0
292   mov.l	%S1:3,%S0
293   mov.l	%S1,%S0
294   mov.l	%S1,%S0"
295  [(set_attr "length_table" "*,*,short_immediate,movl")
296   (set_attr "length" "2,2,*,*")])
297
298(define_insn_and_split "*movsf_h8sx"
299  [(set (match_operand:SF 0 "general_operand_dst" "=r,rQ")
300	(match_operand:SF 1 "general_operand_src" "G,rQi"))]
301  "TARGET_H8300SX"
302  "#"
303  "&& reload_completed"
304  [(parallel [(set (match_dup 0) (match_dup 1))
305	      (clobber (reg:CC CC_REG))])])
306
307(define_insn "*movsf_h8sx_clobber_flags"
308  [(set (match_operand:SF 0 "general_operand_dst" "=r,rQ")
309	(match_operand:SF 1 "general_operand_src" "G,rQi"))
310   (clobber (reg:CC CC_REG))]
311  "TARGET_H8300SX"
312  "@
313    sub.l	%S0,%S0
314    mov.l	%S1,%S0"
315  [(set_attr "length" "2,*")
316   (set_attr "length_table" "*,movl")])
317
318(define_insn_and_split "*movsf"
319  [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,m,<,r")
320	(match_operand:SF 1 "general_operand_src" "G,r,im,r,r,>"))]
321  "!TARGET_H8300SX
322    && (register_operand (operands[0], SFmode)
323	|| register_operand (operands[1], SFmode))"
324  "#"
325  "&& reload_completed"
326  [(parallel [(set (match_dup 0) (match_dup 1))
327	      (clobber (reg:CC CC_REG))])])
328
329(define_insn "*movsf_clobber_flags"
330  [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,m,<,r")
331	(match_operand:SF 1 "general_operand_src" "G,r,im,r,r,>"))
332   (clobber (reg:CC CC_REG))]
333  "!TARGET_H8300SX
334    && (register_operand (operands[0], SFmode)
335	|| register_operand (operands[1], SFmode))"
336  "@
337   sub.l	%S0,%S0
338   mov.l	%S1,%S0
339   mov.l	%S1,%S0
340   mov.l	%S1,%S0
341   mov.l	%S1,%S0
342   mov.l	%S1,%S0"
343  [(set (attr "length") (symbol_ref "compute_mov_length (operands)"))])
344
345;; ----------------------------------------------------------------------
346;; PUSH INSTRUCTIONS
347;; ----------------------------------------------------------------------
348
349(define_insn_and_split "*push1_<QHI:mode>"
350  [(set (mem:QHI
351	(pre_modify:P
352	  (reg:P SP_REG)
353	  (plus:P (reg:P SP_REG) (const_int -4))))
354	(match_operand:QHI 0 "register_no_sp_elim_operand" "r"))]
355  ""
356  "#"
357  "&& reload_completed"
358  [(parallel [(set (mem:QHI
359		     (pre_modify:P (reg:P SP_REG)
360				   (plus:P (reg:P SP_REG) (const_int -4))))
361		   (match_dup 0))
362	      (clobber (reg:CC CC_REG))])])
363
364(define_insn "*push1_<QHI:mode><cczn>"
365  [(set (mem:QHI
366	(pre_modify:P
367	  (reg:P SP_REG)
368	  (plus:P (reg:P SP_REG) (const_int -4))))
369	(match_operand:QHI 0 "register_no_sp_elim_operand" "r"))
370   (clobber (reg:CC CC_REG))]
371  ""
372  "mov.l\\t%S0,@-er7"
373  [(set_attr "length" "4")])
374
375