]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/rl78/rl78.md
Update copyright years in gcc/
[thirdparty/gcc.git] / gcc / config / rl78 / rl78.md
1 ;; Machine Description for Renesas RL78 processors
2 ;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
3 ;; Contributed by Red Hat.
4
5 ;; This file is part of GCC.
6
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
11
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
20 \f
21 (define_constants
22 [
23 (AX_REG 0)
24 (X_REG 0)
25 (A_REG 1)
26 (BC_REG 2)
27 (C_REG 2)
28 (B_REG 3)
29 (DE_REG 4)
30 (E_REG 4)
31 (D_REG 5)
32 (HL_REG 6)
33 (L_REG 6)
34 (H_REG 7)
35
36 (FP_REG 22)
37 (SP_REG 32)
38 (CC_REG 34)
39 (ES_REG 35)
40 (CS_REG 36)
41
42 (UNS_PROLOG 1)
43 (UNS_EPILOG 1)
44 (UNS_RETI 2)
45 (UNS_RETB 3)
46
47 (UNS_SET_RB 10)
48 (UNS_ES_ADDR 11)
49
50 (UNS_TRAMPOLINE_INIT 20)
51 (UNS_TRAMPOLINE_UNINIT 21)
52 (UNS_NONLOCAL_GOTO 22)
53
54 ])
55
56 (define_insn "nop"
57 [(const_int 0)]
58 ""
59 "nop"
60 )
61
62 (define_mode_iterator QHI [QI HI])
63
64 (include "predicates.md")
65 (include "constraints.md")
66 (include "rl78-expand.md")
67 (include "rl78-virt.md")
68 (include "rl78-real.md")
69
70
71 ;; Function Prologue/Epilogue Instructions
72
73 (define_expand "prologue"
74 [(const_int 0)]
75 ""
76 "rl78_expand_prologue (); DONE;"
77 )
78
79 (define_expand "epilogue"
80 [(const_int 0)]
81 ""
82 "rl78_expand_epilogue (); DONE;"
83 )
84
85 (define_expand "sibcall_epilogue"
86 [(return)]
87 ""
88 "FAIL;"
89 )
90
91 (define_insn "rl78_return"
92 [(return)]
93 ""
94 "ret"
95 )
96
97 (define_insn "interrupt_return"
98 [(unspec_volatile [(return)] UNS_RETI) ]
99 ""
100 "reti"
101 )
102
103 (define_insn "brk_interrupt_return"
104 [(unspec_volatile [(return)] UNS_RETB) ]
105 ""
106 "retb"
107 )
108
109 (define_expand "eh_return"
110 [(match_operand:HI 0 "" "")]
111 ""
112 "rl78_expand_eh_epilogue (operands[0]);
113 emit_barrier ();
114 DONE;"
115 )
116
117 ;; These are used only by prologue/epilogue so it's "safe" to pass
118 ;; virtual registers.
119 (define_insn "push"
120 [(set (reg:HI SP_REG)
121 (plus:HI (reg:HI SP_REG)
122 (const_int -2)))
123 (set (mem:HI (reg:HI SP_REG))
124 (match_operand:HI 0 "register_operand" "ABDT,vZint"))]
125 ""
126 "@
127 push\t%v0
128 push\t%v0 ; %0"
129 )
130
131 (define_insn "pop"
132 [(set (match_operand:HI 0 "register_operand" "=ABDT,vZint")
133 (mem:HI (reg:HI SP_REG)))
134 (set (reg:HI SP_REG)
135 (plus:HI (reg:HI SP_REG)
136 (const_int 2)))]
137 ""
138 "@
139 pop\t%v0
140 pop\t%v0 ; %0"
141 )
142
143 (define_insn "sel_rb"
144 [(unspec_volatile [(match_operand 0 "immediate_operand" "")] UNS_SET_RB)]
145 "!TARGET_G10"
146 "sel\trb%u0"
147 )
148
149 (define_insn "trampoline_init"
150 [(set (match_operand 0 "register_operand" "=Z08W")
151 (unspec_volatile [(match_operand 1 "register_operand" "Z08W")
152 (match_operand 2 "register_operand" "Z10W")
153 ] UNS_TRAMPOLINE_INIT))
154 ]
155 ""
156 "call !!___trampoline_init ; %0 <= %1 %2"
157 )
158
159 (define_insn "trampoline_uninit"
160 [(unspec_volatile [(const_int 0)] UNS_TRAMPOLINE_UNINIT)
161 ]
162 ""
163 "call !!___trampoline_uninit"
164 )
165
166 ;; GCC restores $fp *before* using it to access values on the *old*
167 ;; frame. So, we do it ourselves, to ensure this is not the case.
168 ;; Note that while %1 is usually a label_ref, we allow for a
169 ;; non-immediate as well.
170 (define_expand "nonlocal_goto"
171 [(set (pc)
172 (unspec_volatile [(match_operand 0 "" "") ;; fp (ignore)
173 (match_operand 1 "" "vi") ;; target
174 (match_operand 2 "" "vi") ;; sp
175 (match_operand 3 "" "vi") ;; ?
176 ] UNS_NONLOCAL_GOTO))
177 ]
178 ""
179 "emit_jump_insn (gen_nonlocal_goto_insn (operands[0], operands[1], operands[2], operands[3]));
180 emit_barrier ();
181 DONE;"
182 )
183
184 (define_insn "nonlocal_goto_insn"
185 [(set (pc)
186 (unspec_volatile [(match_operand 0 "" "") ;; fp (ignore)
187 (match_operand 1 "" "vi") ;; target
188 (match_operand 2 "" "vi") ;; sp
189 (match_operand 3 "" "vi") ;; ?
190 ] UNS_NONLOCAL_GOTO))
191 ]
192 ""
193 "; nonlocal goto
194 movw ax, %3
195 movw r22, ax
196 movw ax, %2
197 movw sp, ax
198 movw ax, %1
199 br ax
200 "
201 )
202
203 ;;======================================================================
204 ;;
205 ;; "macro" insns - cases where inline chunks of code are more
206 ;; efficient than anything else.
207
208 (define_expand "addsi3"
209 [(set (match_operand:SI 0 "nonimmediate_operand" "=&vm")
210 (plus:SI (match_operand:SI 1 "general_operand" "vim")
211 (match_operand 2 "general_operand" "vim")))
212 ]
213 ""
214 "emit_insn (gen_addsi3_internal_virt (operands[0], operands[1], operands[2]));
215 DONE;"
216 )
217
218 (define_insn "addsi3_internal_virt"
219 [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vm, vm")
220 (plus:SI (match_operand:SI 1 "general_operand" "0, vim, vim")
221 (match_operand 2 "general_operand" "vim,vim,vim")))
222 (clobber (reg:HI AX_REG))
223 (clobber (reg:HI BC_REG))
224 ]
225 "rl78_virt_insns_ok ()"
226 ""
227 [(set_attr "valloc" "macax")]
228 )
229
230 (define_insn "addsi3_internal_real"
231 [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vU, vU")
232 (plus:SI (match_operand:SI 1 "general_operand" "+0, viU, viU")
233 (match_operand 2 "general_operand" "viWabWhlWh1,viWabWhlWh1,viWabWhlWh1")))
234 (clobber (reg:HI AX_REG))
235 (clobber (reg:HI BC_REG))
236 ]
237 "rl78_real_insns_ok ()"
238 "@
239 movw ax,%h1 \;addw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;incw ax \;addw ax,%H2 \;movw %H0,ax
240 movw ax,%h1 \;addw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;incw ax \;addw ax,%H2 \;movw %H0,ax
241 movw ax,%h1 \;addw ax,%h2 \;movw bc, ax \;movw ax,%H1 \;sknc \;incw ax \;addw ax,%H2 \;movw %H0,ax \;movw ax,bc \;movw %h0, ax"
242 [(set_attr "valloc" "macax")]
243 )
244
245 (define_expand "subsi3"
246 [(set (match_operand:SI 0 "nonimmediate_operand" "=&vm")
247 (minus:SI (match_operand:SI 1 "general_operand" "vim")
248 (match_operand 2 "general_operand" "vim")))
249 ]
250 ""
251 "emit_insn (gen_subsi3_internal_virt (operands[0], operands[1], operands[2]));
252 DONE;"
253 )
254
255 (define_insn "subsi3_internal_virt"
256 [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vm, vm")
257 (minus:SI (match_operand:SI 1 "general_operand" "0, vim, vim")
258 (match_operand 2 "general_operand" "vim,vim,vim")))
259 (clobber (reg:HI AX_REG))
260 (clobber (reg:HI BC_REG))
261 ]
262 "rl78_virt_insns_ok ()"
263 ""
264 [(set_attr "valloc" "macax")]
265 )
266
267 (define_insn "subsi3_internal_real"
268 [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vU, vU")
269 (minus:SI (match_operand:SI 1 "general_operand" "+0, viU, viU")
270 (match_operand 2 "general_operand" "viWabWhlWh1,viWabWhlWh1,viWabWhlWh1")))
271 (clobber (reg:HI AX_REG))
272 (clobber (reg:HI BC_REG))
273 ]
274 "rl78_real_insns_ok ()"
275 "@
276 movw ax,%h1 \;subw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;decw ax \;subw ax,%H2 \;movw %H0,ax
277 movw ax,%h1 \;subw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;decw ax \;subw ax,%H2 \;movw %H0,ax
278 movw ax,%h1 \;subw ax,%h2 \;movw bc, ax \;movw ax,%H1 \;sknc \;decw ax \;subw ax,%H2 \;movw %H0,ax \;movw ax,bc \;movw %h0, ax"
279 [(set_attr "valloc" "macax")]
280 )
281
282 (define_expand "mulqi3"
283 [(set (match_operand:QI 0 "register_operand" "")
284 (mult:QI (match_operand:QI 1 "general_operand" "")
285 (match_operand:QI 2 "nonmemory_operand" "")))
286 ]
287 "" ; mulu supported by all targets
288 ""
289 )
290
291 (define_expand "mulhi3"
292 [(set (match_operand:HI 0 "register_operand" "")
293 (mult:HI (match_operand:HI 1 "general_operand" "")
294 (match_operand:HI 2 "nonmemory_operand" "")))
295 ]
296 "! RL78_MUL_NONE"
297 ""
298 )
299
300 (define_expand "mulsi3"
301 [(set (match_operand:SI 0 "register_operand" "=&v")
302 (mult:SI (match_operand:SI 1 "general_operand" "+vim")
303 (match_operand:SI 2 "nonmemory_operand" "vi")))
304 ]
305 "! RL78_MUL_NONE"
306 ""
307 )
308
309 (define_insn "*mulqi3_rl78"
310 [(set (match_operand:QI 0 "register_operand" "=&v")
311 (mult:QI (match_operand:QI 1 "general_operand" "+viU")
312 (match_operand:QI 2 "general_operand" "vi")))
313 ]
314 "" ; mulu supported by all targets
315 "; mulqi macro %0 = %1 * %2
316 mov a, %h1
317 mov x, a
318 mov a, %h2
319 mulu x ; ax = a * x
320 mov a, x
321 mov %h0, a
322 ; end of mulqi macro"
323 ;; [(set_attr "valloc" "macax")]
324 )
325
326 (define_insn "*mulhi3_rl78"
327 [(set (match_operand:HI 0 "register_operand" "=&v")
328 (mult:HI (match_operand:HI 1 "general_operand" "+viU")
329 (match_operand:HI 2 "general_operand" "vi")))
330 ]
331 "RL78_MUL_RL78"
332 "; mulhi macro %0 = %1 * %2
333 movw ax, %h1
334 movw bc, %h2
335 mulhu ; bcax = bc * ax
336 movw %h0, ax
337 ; end of mulhi macro"
338 ;; [(set_attr "valloc" "macax")]
339 )
340
341 (define_insn "*mulhi3_g13"
342 [(set (match_operand:HI 0 "register_operand" "=&v")
343 (mult:HI (match_operand:HI 1 "general_operand" "+viU")
344 (match_operand:HI 2 "general_operand" "vi")))
345 ]
346 "RL78_MUL_G13"
347 "; mulhi macro %0 = %1 * %2
348 mov a, #0x00
349 mov !0xf00e8, a ; MDUC
350 movw ax, %h1
351 movw 0xffff0, ax ; MDAL
352 movw ax, %h2
353 movw 0xffff2, ax ; MDAH
354 nop ; mdb = mdal * mdah
355 movw ax, 0xffff6 ; MDBL
356 movw %h0, ax
357 ; end of mulhi macro"
358 ;; [(set_attr "valloc" "umul")]
359 )
360
361 ;; 0xFFFF0 is MACR(L). 0xFFFF2 is MACR(H) but we don't care about it
362 ;; because we're only using the lower 16 bits (which is the upper 16
363 ;; bits of the result).
364 (define_insn "mulsi3_rl78"
365 [(set (match_operand:SI 0 "register_operand" "=&v")
366 (mult:SI (match_operand:SI 1 "general_operand" "+viU")
367 (match_operand:SI 2 "general_operand" "vi")))
368 ]
369 "RL78_MUL_RL78"
370 "; mulsi macro %0 = %1 * %2
371 movw ax, %h1
372 movw bc, %h2
373 MULHU ; bcax = bc * ax
374 movw %h0, ax
375 movw ax, bc
376 movw 0xffff0, ax
377 movw ax, %H1
378 movw bc, %h2
379 MACHU ; MACR += bc * ax
380 movw ax, %h1
381 movw bc, %H2
382 MACHU ; MACR += bc * ax
383 movw ax, 0xffff0
384 movw %H0, ax
385 ; end of mulsi macro"
386 [(set_attr "valloc" "macax")]
387 )
388
389 ;; 0xFFFF0 is MDAL. 0xFFFF2 is MDAH.
390 ;; 0xFFFF6 is MDBL. 0xFFFF4 is MDBH.
391 ;; 0xF00E0 is MDCL. 0xF00E2 is MDCH.
392 ;; 0xF00E8 is MDUC.
393 ;; Warning: this matches the silicon not the documentation.
394 (define_insn "mulsi3_g13"
395 [(set (match_operand:SI 0 "register_operand" "=&v")
396 (mult:SI (match_operand:SI 1 "general_operand" "viU")
397 (match_operand:SI 2 "general_operand" "viU")))
398 ]
399 "RL78_MUL_G13"
400 "; mulsi macro %0 = %1 * %2
401 mov a, #0x00
402 mov !0xf00e8, a ; MDUC
403 movw ax, %h1
404 movw 0xffff0, ax ; MDAL
405 movw ax, %h2
406 movw 0xffff2, ax ; MDAH
407 nop ; mdb = mdal * mdah
408 movw ax, 0xffff6 ; MDBL
409 movw %h0, ax
410
411 mov a, #0x40
412 mov !0xf00e8, a ; MDUC
413 movw ax, 0xffff4 ; MDBH
414 movw !0xf00e0, ax ; MDCL
415 movw ax, #0
416 movw !0xf00e2, ax ; MDCL
417 movw ax, %H1
418 movw 0xffff0, ax ; MDAL
419 movw ax, %h2
420 movw 0xffff2, ax ; MDAH
421 nop ; mdc += mdal * mdah
422
423 mov a, #0x40
424 mov !0xf00e8, a ; MDUC
425 movw ax, %h1
426 movw 0xffff0, ax ; MDAL
427 movw ax, %H2
428 movw 0xffff2, ax ; MDAH
429 nop ; mdc += mdal * mdah
430 nop ; Additional nop for MAC
431 movw ax, !0xf00e0 ; MDCL
432 movw %H0, ax
433 ; end of mulsi macro"
434 [(set_attr "valloc" "macax")]
435 )
436
437 (define_expand "es_addr"
438 [(unspec:SI [(reg:QI ES_REG)
439 (match_operand:HI 0 "" "")
440 ] UNS_ES_ADDR)]
441 ""
442 ""
443 )