PR target/81369
[official-gcc.git] / gcc / config / rl78 / rl78.md
blob722d98439b2b4344b6c10873f52dd65c8c4fda11
1 ;;  Machine Description for Renesas RL78 processors
2 ;;  Copyright (C) 2011-2017 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")
70 (define_attr "is_g13_muldiv_insn" "yes,no" (const_string "no"))
72 ;; Function Prologue/Epilogue Instructions
74 (define_expand "prologue"
75   [(const_int 0)]
76   ""
77   "rl78_expand_prologue (); DONE;"
80 (define_expand "epilogue"
81   [(const_int 0)]
82   ""
83   "rl78_expand_epilogue (); DONE;"
86 (define_expand "sibcall_epilogue"
87   [(return)]
88   ""
89   "FAIL;"
92 (define_insn "rl78_return"
93   [(return)]
94   ""
95   "ret"
98 (define_insn "interrupt_return"
99   [(unspec_volatile [(return)] UNS_RETI) ]
100   ""
101   "reti"
104 (define_insn "brk_interrupt_return"
105   [(unspec_volatile [(return)] UNS_RETB) ]
106   ""
107   "retb"
110 (define_expand "eh_return"
111   [(match_operand:HI 0 "")]
112   ""
113   "rl78_expand_eh_epilogue (operands[0]);
114    emit_barrier ();
115    DONE;"
118 ;; These are used only by prologue/epilogue so it's "safe" to pass
119 ;; virtual registers.
120 (define_insn "push"
121   [(set (reg:HI SP_REG)
122         (plus:HI (reg:HI SP_REG)
123                   (const_int -2)))
124    (set (mem:HI (reg:HI SP_REG))
125         (match_operand:HI 0 "register_operand" "ABDT,vZint"))]
126   ""
127   "@
128    push\t%v0
129    push\t%v0 ; %0"
132 (define_insn "pop"
133   [(set (match_operand:HI 0 "register_operand" "=ABDT,vZint")
134         (mem:HI (reg:HI SP_REG)))
135    (set (reg:HI SP_REG)
136         (plus:HI (reg:HI SP_REG)
137                     (const_int 2)))]
138   ""
139   "@
140    pop\t%v0
141    pop\t%v0 ; %0"
144 (define_insn "sel_rb"
145   [(unspec_volatile [(match_operand 0 "immediate_operand" "")] UNS_SET_RB)]
146   "!TARGET_G10"
147   "sel\trb%u0"
148   )
150 (define_insn "trampoline_init"
151   [(set (match_operand 0 "register_operand" "=Z08W")
152         (unspec_volatile [(match_operand 1 "register_operand" "Z08W")
153                           (match_operand 2 "register_operand" "Z10W")
154                           ] UNS_TRAMPOLINE_INIT))
155    ]
156   ""
157   "call !!___trampoline_init ; %0 <= %1 %2"
158   )
160 (define_insn "trampoline_uninit"
161   [(unspec_volatile [(const_int 0)] UNS_TRAMPOLINE_UNINIT)
162    ]
163   ""
164   "call !!___trampoline_uninit"
165   )
167 ;; GCC restores $fp *before* using it to access values on the *old*
168 ;; frame.  So, we do it ourselves, to ensure this is not the case.
169 ;; Note that while %1 is usually a label_ref, we allow for a
170 ;; non-immediate as well.
171 (define_expand "nonlocal_goto"
172   [(set (pc)
173         (unspec_volatile [(match_operand 0 "") ;; fp (ignore)
174                           (match_operand 1 "") ;; target
175                           (match_operand 2 "") ;; sp
176                           (match_operand 3 "") ;; ?
177                           ] UNS_NONLOCAL_GOTO))
178    ]
179   ""
180   "emit_jump_insn (gen_nonlocal_goto_insn (operands[0], operands[1], operands[2], operands[3]));
181    emit_barrier ();
182    DONE;"
183   )
185 (define_insn "nonlocal_goto_insn"
186   [(set (pc)
187         (unspec_volatile [(match_operand 0 "" "") ;; fp (ignore)
188                           (match_operand 1 "" "vi") ;; target
189                           (match_operand 2 "" "vi") ;; sp
190                           (match_operand 3 "" "vi") ;; ?
191                           ] UNS_NONLOCAL_GOTO))
192    ]
193   ""
194   "; nonlocal goto
195         movw    ax, %3
196         movw    r22, ax
197         movw    ax, %2
198         movw    sp, ax
199         movw    ax, %1
200         br      ax
202   )
204 (define_expand "es_addr"
205   [(unspec:SI [(reg:QI ES_REG)
206                (match_operand:HI 0 "")
207                ] UNS_ES_ADDR)]
208   ""
209   ""
212 ;;======================================================================
214 ;; "macro" insns - cases where inline chunks of code are more
215 ;; efficient than anything else.
217 (define_expand "addsi3"
218   [(set (match_operand:SI          0 "nonimmediate_operand" "=&vm")
219         (plus:SI (match_operand:SI 1 "general_operand"      "vim")
220                  (match_operand    2 "general_operand"      "vim")))
221    ]
222   ""
223   "emit_insn (gen_addsi3_internal_virt (operands[0], operands[1], operands[2]));
224    DONE;"
227 (define_insn "addsi3_internal_virt"
228   [(set (match_operand:SI          0 "nonimmediate_operand" "=v,&vm, vm")
229         (plus:SI (match_operand:SI 1 "general_operand"      "0, vim, vim")
230                  (match_operand    2 "general_operand"      "vim,vim,vim")))
231    (clobber (reg:HI AX_REG))
232    (clobber (reg:HI BC_REG))
233    ]
234   "rl78_virt_insns_ok ()"
235   ""
236   [(set_attr "valloc" "macax")]
239 (define_insn "addsi3_internal_real"
240   [(set (match_operand:SI          0 "nonimmediate_operand" "=v,&vU, vU")
241         (plus:SI (match_operand:SI 1 "general_operand"      "+0, viU, viU")
242                  (match_operand    2 "general_operand"      "viWabWhlWh1,viWabWhlWh1,viWabWhlWh1")))
243    (clobber (reg:HI AX_REG))
244    (clobber (reg:HI BC_REG))
245    ]
246   "rl78_real_insns_ok ()"
247   { return rl78_addsi3_internal (operands, which_alternative); }
248   [(set_attr "valloc" "macax")]
251 (define_expand "subsi3"
252   [(set (match_operand:SI           0 "nonimmediate_operand")
253         (minus:SI (match_operand:SI 1 "general_operand")
254                   (match_operand    2 "general_operand")))
255    ]
256   ""
257   "emit_insn (gen_subsi3_internal_virt (operands[0], operands[1], operands[2]));
258   DONE;"
261 (define_insn "subsi3_internal_virt"
262   [(set (match_operand:SI           0 "nonimmediate_operand" "=v,&vm, vm")
263         (minus:SI (match_operand:SI 1 "general_operand"      "0, vim, vim")
264                   (match_operand    2 "general_operand"      "vim,vim,vim")))
265    (clobber (reg:HI AX_REG))
266    (clobber (reg:HI BC_REG))
267    ]
268   "rl78_virt_insns_ok ()"
269   ""
270   [(set_attr "valloc" "macax")]
273 (define_insn "subsi3_internal_real"
274   [(set (match_operand:SI           0 "nonimmediate_operand" "=v,&vU, vU")
275         (minus:SI (match_operand:SI 1 "general_operand"      "+0, viU, viU")
276                   (match_operand    2 "general_operand"      "viWabWhlWh1,viWabWhlWh1,viWabWhlWh1")))
277    (clobber (reg:HI AX_REG))
278    (clobber (reg:HI BC_REG))
279    ]
280   "rl78_real_insns_ok ()"
281   "@
282    movw ax,%h1 \;subw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;decw ax \;subw ax,%H2 \;movw %H0,ax
283    movw ax,%h1 \;subw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;decw ax \;subw ax,%H2 \;movw %H0,ax
284    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"
285   [(set_attr "valloc" "macax")]
288 (define_expand "mulqi3"
289   [(parallel
290     [(set (match_operand:QI            0 "register_operand")
291            (mult:QI  (match_operand:QI 1 "general_operand")
292                      (match_operand:QI 2 "nonmemory_operand")))
293       (clobber (reg:HI AX_REG))
294     ])
295   ]
296   "" ; mulu supported by all targets
297   ""
300 (define_expand "mulhi3"
301   [(set (match_operand:HI          0 "register_operand")
302         (mult:HI (match_operand:HI 1 "general_operand")
303                  (match_operand:HI 2 "nonmemory_operand")))
304    ]
305   "! RL78_MUL_NONE"
306   {
307     if (RL78_MUL_G14)
308       emit_insn (gen_mulhi3_g14 (operands[0], operands[1], operands[2]));
309     else /* RL78_MUL_G13 */
310       emit_insn (gen_mulhi3_g13 (operands[0], operands[1], operands[2]));
311     DONE;
312   }
315 (define_expand "mulsi3"
316   [(set (match_operand:SI          0 "register_operand")
317         (mult:SI (match_operand:SI 1 "general_operand")
318                  (match_operand:SI 2 "nonmemory_operand")))
319    ]
320   "! RL78_MUL_NONE"
321   {
322     if (RL78_MUL_G14)
323       emit_insn (gen_mulsi3_g14 (operands[0], operands[1], operands[2]));
324     else /* RL78_MUL_G13 */
325       emit_insn (gen_mulsi3_g13 (operands[0], operands[1], operands[2]));
326     DONE;
327   }
330 (define_insn "*mulqi3_rl78"
331   [(set (match_operand:QI          0 "register_operand" "=&v")
332         (mult:QI (match_operand:QI 1 "general_operand" "viU")
333                  (match_operand:QI 2 "general_operand" "vi")))
334    (clobber (reg:HI AX_REG))
335   ]
336   "" ; mulu supported by all targets
337   "; mulqi macro %0 = %1 * %2
338         mov    a, %h1
339         mov    x, a
340         mov    a, %h2
341         mulu   x ; ax = a * x
342         mov    a, x
343         mov    %h0, a
344         ; end of mulqi macro"
345   [(set_attr "valloc" "macax")]
348 (define_insn "mulhi3_g14"
349   [(set (match_operand:HI          0 "register_operand" "=&v")
350         (mult:HI (match_operand:HI 1 "general_operand" "viU")
351                  (match_operand:HI 2 "general_operand" "vi")))
352    (clobber (reg:HI AX_REG))
353    (clobber (reg:HI BC_REG))
354   ]
355   "RL78_MUL_G14"
356   "; G14 mulhi macro %0 = %1 * %2
357         movw    ax, %h1
358         movw    bc, %h2
359         mulhu   ; bcax = bc * ax
360         movw    %h0, ax
361         ; end of mulhi macro"
362   [(set_attr "valloc" "macax")]
365 (define_insn "mulhi3_g13"
366   [(set (match_operand:HI          0 "register_operand" "=&v")
367         (mult:HI (match_operand:HI 1 "general_operand" "viU")
368                  (match_operand:HI 2 "general_operand" "vi")))
369    (clobber (reg:HI AX_REG))
370   ]
371   "RL78_MUL_G13"
372   "; G13 mulhi macro %0 = %1 * %2
373         mov     a, #0x00
374         mov     !0xf00e8, a     ; MDUC
375         movw    ax, %h1
376         movw    0xffff0, ax     ; MDAL
377         movw    ax, %h2
378         movw    0xffff2, ax     ; MDAH
379         nop     ; mdb = mdal * mdah
380         movw    ax, 0xffff6     ; MDBL
381         movw    %h0, ax
382         ; end of mulhi macro"
383   [(set_attr "valloc" "macax")
384    (set_attr "is_g13_muldiv_insn" "yes")]
387 ;; 0xFFFF0 is MACR(L).  0xFFFF2 is MACR(H) but we don't care about it
388 ;; because we're only using the lower 16 bits (which is the upper 16
389 ;; bits of the result).
390 (define_insn "mulsi3_g14"
391   [(set (match_operand:SI          0 "register_operand" "=&v")
392         (mult:SI (match_operand:SI 1 "general_operand" "viU")
393                  (match_operand:SI 2 "general_operand" "vi")))
394    (clobber (reg:HI AX_REG))
395    (clobber (reg:HI BC_REG))
396   ]
397   "RL78_MUL_G14"
398   "; G14 mulsi macro %0 = %1 * %2
399         movw    ax, %h1
400         movw    bc, %h2
401         MULHU   ; bcax = bc * ax
402         movw    %h0, ax
403         movw    ax, bc
404         movw    0xffff0, ax
405         movw    ax, %H1
406         movw    bc, %h2
407         MACHU   ; MACR += bc * ax
408         movw    ax, %h1
409         movw    bc, %H2
410         MACHU   ; MACR += bc * ax
411         movw    ax, 0xffff0
412         movw    %H0, ax
413         ; end of mulsi macro"
414   [(set_attr "valloc" "macax")]
415   )
417 ;; 0xFFFF0 is MDAL.  0xFFFF2 is MDAH.
418 ;; 0xFFFF6 is MDBL.  0xFFFF4 is MDBH.
419 ;; 0xF00E0 is MDCL.  0xF00E2 is MDCH.
420 ;; 0xF00E8 is MDUC.
421 ;; Warning: this matches the silicon not the documentation.
422 (define_insn "mulsi3_g13"
423   [(set (match_operand:SI          0 "register_operand" "=&v")
424         (mult:SI (match_operand:SI 1 "general_operand" "viU")
425                  (match_operand:SI 2 "general_operand" "viU")))
426    (clobber (reg:HI AX_REG))
427    (clobber (reg:HI BC_REG))
428   ]
429   "RL78_MUL_G13"
430   "; G13 mulsi macro %0 = %1 * %2
431         mov     a, #0x00
432         mov     !0xf00e8, a     ; MDUC
433         movw    ax, %h1
434         movw    0xffff0, ax     ; MDAL
435         movw    ax, %h2
436         movw    0xffff2, ax     ; MDAH
437         nop     ; mdb = mdal * mdah
438         movw    ax, 0xffff6     ; MDBL
439         movw    %h0, ax
441         mov     a, #0x40
442         mov     !0xf00e8, a     ; MDUC
443         movw    ax, 0xffff4     ; MDBH
444         movw    !0xf00e0, ax    ; MDCL
445         movw    ax, #0
446         movw    !0xf00e2, ax    ; MDCL
447         movw    ax, %H1
448         movw    0xffff0, ax     ; MDAL
449         movw    ax, %h2
450         movw    0xffff2, ax     ; MDAH
451         nop     ; mdc += mdal * mdah
453         mov     a, #0x40
454         mov     !0xf00e8, a     ; MDUC
455         movw    ax, %h1
456         movw    0xffff0, ax     ; MDAL
457         movw    ax, %H2
458         movw    0xffff2, ax     ; MDAH
459         nop     ; mdc += mdal * mdah
460         nop     ; Additional nop for MAC
461         movw    ax, !0xf00e0    ; MDCL
462         movw    %H0, ax
463         ; end of mulsi macro"
464   [(set_attr "valloc" "macax")
465    (set_attr "is_g13_muldiv_insn" "yes")]
468 (define_expand "udivmodhi4"
469   [(parallel
470     [(set (match_operand:HI          0 "register_operand")
471           (udiv:HI (match_operand:HI 1 "register_operand")
472                    (match_operand:HI 2 "register_operand")))
473      (set (match_operand:HI          3 "register_operand")
474           (umod:HI (match_dup 1) (match_dup 2)))
475      (clobber (reg:HI AX_REG))
476      (clobber (reg:HI DE_REG))
477     ])
478    ]
479   "RL78_MUL_G14"
480   ""
483 (define_insn "*udivmodhi4_g14"
484   [(set (match_operand:HI          0 "register_operand" "=v")
485         (udiv:HI (match_operand:HI 1 "register_operand" "v")
486                  (match_operand:HI 2 "register_operand" "v")))
487    (set (match_operand:HI          3 "register_operand" "=v")
488         (umod:HI (match_dup 1) (match_dup 2)))
489    (clobber (reg:HI AX_REG))
490    (clobber (reg:HI DE_REG))
491   ]
492   "RL78_MUL_G14"
493   {
494     if (find_reg_note (insn, REG_UNUSED, operands[3]))
495       return "; G14 udivhi macro %0 = %1 / %2 \n\
496         movw    ax, %h1 \n\
497         movw    de, %h2 \n\
498         push    psw     ; Save the current interrupt status \n\
499         di              ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\
500         divhu           ; ax = ax / de \n\
501         pop     psw     ; Restore saved interrupt status \n\
502         movw    %h0, ax \n\
503         ; end of udivhi macro";
504     else if (find_reg_note (insn, REG_UNUSED, operands[0]))
505       return "; G14 umodhi macro %3 = %1 %% %2 \n\
506         movw    ax, %h1 \n\
507         movw    de, %h2 \n\
508         push    psw     ; Save the current interrupt status \n\
509         di              ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\
510         divhu           ; de = ax %% de \n\
511         pop     psw     ; Restore saved interrupt status \n\
512         movw    ax, de \n\
513         movw    %h3, ax \n\
514         ; end of umodhi macro";
515     else
516       return "; G14 udivmodhi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\
517         movw    ax, %h1 \n\
518         movw    de, %h2 \n\
519         push    psw     ; Save the current interrupt status \n\
520         di              ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\
521         divhu           ; ax = ax / de, de = ax %% de \n\
522         pop     psw     ; Restore saved interrupt status \n\
523         movw    %h0, ax \n\
524         movw    ax, de \n\
525         movw    %h3, ax \n\
526         ; end of udivmodhi macro";
527   }
528   [(set_attr "valloc" "divhi")]
531 (define_expand "udivmodsi4"
532   [(parallel
533     [(set (match_operand:SI          0 "register_operand")
534           (udiv:SI (match_operand:SI 1 "register_operand")
535                    (match_operand:SI 2 "register_operand")))
536      (set (match_operand:SI          3 "register_operand")
537           (umod:SI (match_dup 1) (match_dup 2)))
538     ])
539    ]
540   "! RL78_MUL_NONE && ! optimize_size"
541   {
542     if (RL78_MUL_G14)
543       emit_insn (gen_udivmodsi4_g14 (operands[0], operands[1], operands[2], operands[3]));
544     else /* RL78_MUL_G13 */
545       emit_insn (gen_udivmodsi4_g13 (operands[0], operands[1], operands[2], operands[3]));
546     DONE;
547   }
550 (define_insn "udivmodsi4_g14"
551   [(set (match_operand:SI          0 "register_operand" "=v")
552         (udiv:SI (match_operand:SI 1 "register_operand" "v")
553                  (match_operand:SI 2 "register_operand" "v")))
554    (set (match_operand:SI          3 "register_operand" "=v")
555         (umod:SI (match_dup 1) (match_dup 2)))
556    (clobber (reg:HI AX_REG))
557    (clobber (reg:HI BC_REG))
558    (clobber (reg:HI DE_REG))
559    (clobber (reg:HI HL_REG))
560   ]
561   "RL78_MUL_G14"
562   {
563     if (find_reg_note (insn, REG_UNUSED, operands[3]))
564       return "; G14 udivsi macro %0 = %1 / %2 \n\
565         movw    ax, %h1 \n\
566         movw    bc, %H1 \n\
567         movw    de, %h2 \n\
568         movw    hl, %H2 \n\
569         push    psw     ; Save the current interrupt status \n\
570         di              ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\
571         divwu           ; bcax = bcax / hlde \n\
572         pop     psw     ; Restore saved interrupt status \n\
573         movw    %h0, ax \n\
574         movw    ax, bc \n\
575         movw    %H0, ax \n\
576         ; end of udivsi macro";
577     else if (find_reg_note (insn, REG_UNUSED, operands[0]))
578       return "; G14 umodsi macro %3 = %1 %% %2 \n\
579         movw    ax, %h1 \n\
580         movw    bc, %H1 \n\
581         movw    de, %h2 \n\
582         movw    hl, %H2 \n\
583         push    psw     ; Save the current interrupt status \n\
584         di              ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\
585         divwu           ; hlde = bcax %% hlde \n\
586         pop     psw     ; Restore saved interrupt status \n\
587         movw    ax, de \n\
588         movw    %h3, ax \n\
589         movw    ax, hl \n\
590         movw    %H3, ax \n\
591         ; end of umodsi macro";
592     else
593       return "; G14 udivmodsi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\
594         movw    ax, %h1 \n\
595         movw    bc, %H1 \n\
596         movw    de, %h2 \n\
597         movw    hl, %H2 \n\
598         push    psw     ; Save the current interrupt status \n\
599         di              ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\
600         divwu           ; bcax = bcax / hlde, hlde = bcax %% hlde \n\
601         pop     psw     ; Restore saved interrupt status \n\
602         movw    %h0, ax \n\
603         movw    ax, bc \n\
604         movw    %H0, ax \n\
605         movw    ax, de \n\
606         movw    %h3, ax \n\
607         movw    ax, hl \n\
608         movw    %H3, ax \n\
609         ; end of udivmodsi macro";
610   }
611   [(set_attr "valloc" "divsi")]
614 ;; Warning: these values match the silicon not the documentation.
615 ;; 0xFFFF0 is MDAL.  0xFFFF2 is MDAH.
616 ;; 0xFFFF6 is MDBL.  0xFFFF4 is MDBH.
617 ;; 0xF00E0 is MDCL.  0xF00E2 is MDCH.
618 ;; 0xF00E8 is MDUC.
620 (define_insn "udivmodsi4_g13"
621   [(set (match_operand:SI          0 "register_operand" "=v")
622         (udiv:SI (match_operand:SI 1 "register_operand" "v")
623                  (match_operand:SI 2 "register_operand" "v")))
624    (set (match_operand:SI          3 "register_operand" "=v")
625         (umod:SI (match_dup 1) (match_dup 2)))
626    (clobber (reg:HI AX_REG))
627   ]
628   "RL78_MUL_G13"
629   {
630     if (find_reg_note (insn, REG_UNUSED, operands[3]))
631       return "; G13 udivsi macro %0 = %1 / %2 \n\
632         mov     a, #0xC0        ; Set DIVMODE=1 and MACMODE=1 \n\
633         mov     !0xf00e8, a     ; This preps the peripheral for division without interrupt generation \n\
634         movw    ax, %H1         \n\
635         movw    0xffff2, ax     ; MDAH \n\
636         movw    ax, %h1         \n\
637         movw    0xffff0, ax     ; MDAL \n\
638         movw    ax, %H2         \n\
639         movw    0xffff4, ax     ; MDBH \n\
640         movw    ax, %h2         \n\
641         movw    0xffff6, ax     ; MDBL \n\
642         mov     a, #0xC1        ; Set the DIVST bit in MDUC \n\
643         mov     !0xf00e8, a     ; This starts the division op \n\
644 1:      mov     a, !0xf00e8     ; Wait 16 clocks or until DIVST is clear \n\
645         bt      a.0, $1b        \n\
646         movw    ax, 0xffff0     ; Read the quotient \n\
647         movw    %h0, ax         \n\
648         movw    ax, 0xffff2     \n\
649         movw    %H0, ax         \n\
650         ; end of udivsi macro";
651     else if (find_reg_note (insn, REG_UNUSED, operands[0]))
652       return "; G13 umodsi macro %3 = %1 %% %2 \n\
653         mov     a, #0xC0        ; Set DIVMODE=1 and MACMODE=1 \n\
654         mov     !0xf00e8, a     ; This preps the peripheral for division without interrupt generation \n\
655         movw    ax, %H1         \n\
656         movw    0xffff2, ax     ; MDAH \n\
657         movw    ax, %h1         \n\
658         movw    0xffff0, ax     ; MDAL \n\
659         movw    ax, %H2         \n\
660         movw    0xffff4, ax     ; MDBH \n\
661         movw    ax, %h2         \n\
662         movw    0xffff6, ax     ; MDBL \n\
663         mov     a, #0xC1        ; Set the DIVST bit in MDUC \n\
664         mov     !0xf00e8, a     ; This starts the division op \n\
665 1:      mov     a, !0xf00e8     ; Wait 16 clocks or until DIVST is clear \n\
666         bt      a.0, $1b        \n\
667         movw    ax, !0xf00e0    ; Read the remainder \n\
668         movw    %h3, ax         \n\
669         movw    ax, !0xf00e2    \n\
670         movw    %H3, ax         \n\
671         ; end of umodsi macro";
672     else
673       return "; G13 udivmodsi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\
674         mov     a, #0xC0        ; Set DIVMODE=1 and MACMODE=1 \n\
675         mov     !0xf00e8, a     ; This preps the peripheral for division without interrupt generation \n\
676         movw    ax, %H1         \n\
677         movw    0xffff2, ax     ; MDAH \n\
678         movw    ax, %h1         \n\
679         movw    0xffff0, ax     ; MDAL \n\
680         movw    ax, %H2         \n\
681         movw    0xffff4, ax     ; MDBH \n\
682         movw    ax, %h2         \n\
683         movw    0xffff6, ax     ; MDBL \n\
684         mov     a, #0xC1        ; Set the DIVST bit in MDUC \n\
685         mov     !0xf00e8, a     ; This starts the division op \n\
686 1:      mov     a, !0xf00e8     ; Wait 16 clocks or until DIVST is clear \n\
687         bt      a.0, $1b        \n\
688         movw    ax, 0xffff0     ; Read the quotient \n\
689         movw    %h0, ax         \n\
690         movw    ax, 0xffff2     \n\
691         movw    %H0, ax         \n\
692         movw    ax, !0xf00e0    ; Read the remainder \n\
693         movw    %h3, ax         \n\
694         movw    ax, !0xf00e2    \n\
695         movw    %H3, ax         \n\
696         ; end of udivmodsi macro";
697       }
698   [(set_attr "valloc" "macax")
699    (set_attr "is_g13_muldiv_insn" "yes")]