1 ;; Machine Description for Renesas RL78 processors
2 ;; Copyright (C) 2011-2015 Free Software Foundation, Inc.
3 ;; Contributed by Red Hat.
5 ;; This file is part of GCC.
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)
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.
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/>.
50 (UNS_TRAMPOLINE_INIT 20)
51 (UNS_TRAMPOLINE_UNINIT 21)
52 (UNS_NONLOCAL_GOTO 22)
62 (define_mode_iterator QHI [QI HI])
64 (include "predicates.md")
65 (include "constraints.md")
66 (include "rl78-expand.md")
67 (include "rl78-virt.md")
68 (include "rl78-real.md")
71 ;; Function Prologue/Epilogue Instructions
73 (define_expand "prologue"
76 "rl78_expand_prologue (); DONE;"
79 (define_expand "epilogue"
82 "rl78_expand_epilogue (); DONE;"
85 (define_expand "sibcall_epilogue"
91 (define_insn "rl78_return"
97 (define_insn "interrupt_return"
98 [(unspec_volatile [(return)] UNS_RETI) ]
103 (define_insn "brk_interrupt_return"
104 [(unspec_volatile [(return)] UNS_RETB) ]
109 (define_expand "eh_return"
110 [(match_operand:HI 0 "")]
112 "rl78_expand_eh_epilogue (operands[0]);
117 ;; These are used only by prologue/epilogue so it's "safe" to pass
118 ;; virtual registers.
120 [(set (reg:HI SP_REG)
121 (plus:HI (reg:HI SP_REG)
123 (set (mem:HI (reg:HI SP_REG))
124 (match_operand:HI 0 "register_operand" "ABDT,vZint"))]
132 [(set (match_operand:HI 0 "register_operand" "=ABDT,vZint")
133 (mem:HI (reg:HI SP_REG)))
135 (plus:HI (reg:HI SP_REG)
143 (define_insn "sel_rb"
144 [(unspec_volatile [(match_operand 0 "immediate_operand" "")] UNS_SET_RB)]
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))
156 "call !!___trampoline_init ; %0 <= %1 %2"
159 (define_insn "trampoline_uninit"
160 [(unspec_volatile [(const_int 0)] UNS_TRAMPOLINE_UNINIT)
163 "call !!___trampoline_uninit"
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"
172 (unspec_volatile [(match_operand 0 "") ;; fp (ignore)
173 (match_operand 1 "") ;; target
174 (match_operand 2 "") ;; sp
175 (match_operand 3 "") ;; ?
176 ] UNS_NONLOCAL_GOTO))
179 "emit_jump_insn (gen_nonlocal_goto_insn (operands[0], operands[1], operands[2], operands[3]));
184 (define_insn "nonlocal_goto_insn"
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))
203 (define_expand "es_addr"
204 [(unspec:SI [(reg:QI ES_REG)
205 (match_operand:HI 0 "")
211 ;;======================================================================
213 ;; "macro" insns - cases where inline chunks of code are more
214 ;; efficient than anything else.
216 (define_expand "addsi3"
217 [(set (match_operand:SI 0 "nonimmediate_operand" "=&vm")
218 (plus:SI (match_operand:SI 1 "general_operand" "vim")
219 (match_operand 2 "general_operand" "vim")))
222 "emit_insn (gen_addsi3_internal_virt (operands[0], operands[1], operands[2]));
226 (define_insn "addsi3_internal_virt"
227 [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vm, vm")
228 (plus:SI (match_operand:SI 1 "general_operand" "0, vim, vim")
229 (match_operand 2 "general_operand" "vim,vim,vim")))
230 (clobber (reg:HI AX_REG))
231 (clobber (reg:HI BC_REG))
233 "rl78_virt_insns_ok ()"
235 [(set_attr "valloc" "macax")]
238 (define_insn "addsi3_internal_real"
239 [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vU, vU")
240 (plus:SI (match_operand:SI 1 "general_operand" "+0, viU, viU")
241 (match_operand 2 "general_operand" "viWabWhlWh1,viWabWhlWh1,viWabWhlWh1")))
242 (clobber (reg:HI AX_REG))
243 (clobber (reg:HI BC_REG))
245 "rl78_real_insns_ok ()"
247 movw ax,%h1 \;addw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;incw ax \;addw ax,%H2 \;movw %H0,ax
248 movw ax,%h1 \;addw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;incw ax \;addw ax,%H2 \;movw %H0,ax
249 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"
250 [(set_attr "valloc" "macax")]
253 (define_expand "subsi3"
254 [(set (match_operand:SI 0 "nonimmediate_operand")
255 (minus:SI (match_operand:SI 1 "general_operand")
256 (match_operand 2 "general_operand")))
259 "emit_insn (gen_subsi3_internal_virt (operands[0], operands[1], operands[2]));
263 (define_insn "subsi3_internal_virt"
264 [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vm, vm")
265 (minus:SI (match_operand:SI 1 "general_operand" "0, vim, vim")
266 (match_operand 2 "general_operand" "vim,vim,vim")))
267 (clobber (reg:HI AX_REG))
268 (clobber (reg:HI BC_REG))
270 "rl78_virt_insns_ok ()"
272 [(set_attr "valloc" "macax")]
275 (define_insn "subsi3_internal_real"
276 [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vU, vU")
277 (minus:SI (match_operand:SI 1 "general_operand" "+0, viU, viU")
278 (match_operand 2 "general_operand" "viWabWhlWh1,viWabWhlWh1,viWabWhlWh1")))
279 (clobber (reg:HI AX_REG))
280 (clobber (reg:HI BC_REG))
282 "rl78_real_insns_ok ()"
284 movw ax,%h1 \;subw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;decw ax \;subw ax,%H2 \;movw %H0,ax
285 movw ax,%h1 \;subw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;decw ax \;subw ax,%H2 \;movw %H0,ax
286 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"
287 [(set_attr "valloc" "macax")]
290 (define_expand "mulqi3"
291 [(set (match_operand:QI 0 "register_operand")
292 (mult:QI (match_operand:QI 1 "general_operand")
293 (match_operand:QI 2 "nonmemory_operand")))
295 "" ; mulu supported by all targets
299 (define_expand "mulhi3"
300 [(set (match_operand:HI 0 "register_operand")
301 (mult:HI (match_operand:HI 1 "general_operand")
302 (match_operand:HI 2 "nonmemory_operand")))
308 (define_expand "mulsi3"
309 [(set (match_operand:SI 0 "register_operand")
310 (mult:SI (match_operand:SI 1 "general_operand")
311 (match_operand:SI 2 "nonmemory_operand")))
317 (define_insn "*mulqi3_rl78"
318 [(set (match_operand:QI 0 "register_operand" "=&v")
319 (mult:QI (match_operand:QI 1 "general_operand" "viU")
320 (match_operand:QI 2 "general_operand" "vi")))
322 "" ; mulu supported by all targets
323 "; mulqi macro %0 = %1 * %2
330 ; end of mulqi macro"
331 ;; [(set_attr "valloc" "macax")]
334 (define_insn "*mulhi3_rl78"
335 [(set (match_operand:HI 0 "register_operand" "=&v")
336 (mult:HI (match_operand:HI 1 "general_operand" "viU")
337 (match_operand:HI 2 "general_operand" "vi")))
340 "; mulhi macro %0 = %1 * %2
343 mulhu ; bcax = bc * ax
345 ; end of mulhi macro"
346 ;; [(set_attr "valloc" "macax")]
349 (define_insn "*mulhi3_g13"
350 [(set (match_operand:HI 0 "register_operand" "=&v")
351 (mult:HI (match_operand:HI 1 "general_operand" "viU")
352 (match_operand:HI 2 "general_operand" "vi")))
355 "; mulhi macro %0 = %1 * %2
357 mov !0xf00e8, a ; MDUC
359 movw 0xffff0, ax ; MDAL
361 movw 0xffff2, ax ; MDAH
362 nop ; mdb = mdal * mdah
363 movw ax, 0xffff6 ; MDBL
365 ; end of mulhi macro"
366 ;; [(set_attr "valloc" "umul")]
369 ;; 0xFFFF0 is MACR(L). 0xFFFF2 is MACR(H) but we don't care about it
370 ;; because we're only using the lower 16 bits (which is the upper 16
371 ;; bits of the result).
372 (define_insn "mulsi3_rl78"
373 [(set (match_operand:SI 0 "register_operand" "=&v")
374 (mult:SI (match_operand:SI 1 "general_operand" "viU")
375 (match_operand:SI 2 "general_operand" "vi")))
378 "; mulsi macro %0 = %1 * %2
381 MULHU ; bcax = bc * ax
387 MACHU ; MACR += bc * ax
390 MACHU ; MACR += bc * ax
393 ; end of mulsi macro"
394 [(set_attr "valloc" "macax")]
397 ;; 0xFFFF0 is MDAL. 0xFFFF2 is MDAH.
398 ;; 0xFFFF6 is MDBL. 0xFFFF4 is MDBH.
399 ;; 0xF00E0 is MDCL. 0xF00E2 is MDCH.
401 ;; Warning: this matches the silicon not the documentation.
402 (define_insn "mulsi3_g13"
403 [(set (match_operand:SI 0 "register_operand" "=&v")
404 (mult:SI (match_operand:SI 1 "general_operand" "viU")
405 (match_operand:SI 2 "general_operand" "viU")))
408 "; mulsi macro %0 = %1 * %2
410 mov !0xf00e8, a ; MDUC
412 movw 0xffff0, ax ; MDAL
414 movw 0xffff2, ax ; MDAH
415 nop ; mdb = mdal * mdah
416 movw ax, 0xffff6 ; MDBL
420 mov !0xf00e8, a ; MDUC
421 movw ax, 0xffff4 ; MDBH
422 movw !0xf00e0, ax ; MDCL
424 movw !0xf00e2, ax ; MDCL
426 movw 0xffff0, ax ; MDAL
428 movw 0xffff2, ax ; MDAH
429 nop ; mdc += mdal * mdah
432 mov !0xf00e8, a ; MDUC
434 movw 0xffff0, ax ; MDAL
436 movw 0xffff2, ax ; MDAH
437 nop ; mdc += mdal * mdah
438 nop ; Additional nop for MAC
439 movw ax, !0xf00e0 ; MDCL
441 ; end of mulsi macro"
442 [(set_attr "valloc" "macax")]