* config/rl78/rl78.c: Various whitespace and comment tweaks.
[official-gcc.git] / gcc / config / rl78 / rl78.md
bloba43b41b472f9a61e18473e4700686db194c61b13
1 ;;  Machine Description for Renesas RL78 processors
2 ;;  Copyright (C) 2011-2013 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)
10 ;; any later version.
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/>.
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)
36    (FP_REG 22)
37    (SP_REG 32)
38    (CC_REG 34)
39    (ES_REG 35)
40    (CS_REG 36)
42    (UNS_PROLOG  1)
43    (UNS_EPILOG  1)
44    (UNS_RETI    2)
45    (UNS_RETB    3)
47    (UNS_SET_RB  10)
48    (UNS_ES_ADDR 11)
50    (UNS_TRAMPOLINE_INIT         20)
51    (UNS_TRAMPOLINE_UNINIT       21)
52    (UNS_NONLOCAL_GOTO           22)
54    ])
56 (define_insn "nop"
57   [(const_int 0)]
58   ""
59   "nop"
60   )
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"
74   [(const_int 0)]
75   ""
76   "rl78_expand_prologue (); DONE;"
79 (define_expand "epilogue"
80   [(const_int 0)]
81   ""
82   "rl78_expand_epilogue (); DONE;"
85 (define_expand "sibcall_epilogue"
86   [(return)]
87   ""
88   "FAIL;"
91 (define_insn "rl78_return"
92   [(return)]
93   ""
94   "ret"
97 (define_insn "interrupt_return"
98   [(unspec_volatile [(return)] UNS_RETI) ]
99   ""
100   "reti"
103 (define_insn "brk_interrupt_return"
104   [(unspec_volatile [(return)] UNS_RETB) ]
105   ""
106   "retb"
109 (define_expand "eh_return"
110   [(match_operand:HI 0 "" "")]
111   ""
112   "rl78_expand_eh_epilogue (operands[0]);
113    emit_barrier ();
114    DONE;"
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"
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"
143 (define_insn "sel_rb"
144   [(unspec_volatile [(match_operand 0 "immediate_operand" "")] UNS_SET_RB)]
145   "!TARGET_G10"
146   "sel\trb%u0"
147   )
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   )
159 (define_insn "trampoline_uninit"
160   [(unspec_volatile [(const_int 0)] UNS_TRAMPOLINE_UNINIT)
161    ]
162   ""
163   "call !!___trampoline_uninit"
164   )
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   )
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
201   )
203 ;;======================================================================
205 ;; "macro" insns - cases where inline chunks of code are more
206 ;; efficient than anything else.
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;"
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")]
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")]
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;"
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")]
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")]
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   ""
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   ""
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   ""
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")]
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")]
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")]
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   )
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
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
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   )
437 (define_expand "es_addr"
438   [(unspec:SI [(reg:QI ES_REG)
439                (match_operand:HI 0 "" "")
440                ] UNS_ES_ADDR)]
441   ""
442   ""