* config/rl78/rl78.c (rl78_addsi3_internal): New function.
[official-gcc.git] / gcc / config / rl78 / rl78.md
blob735c19f81eedcda32af6adc80bbf300ef587e579
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)
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 "") ;; target
174                           (match_operand 2 "") ;; sp
175                           (match_operand 3 "") ;; ?
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 (define_expand "es_addr"
204   [(unspec:SI [(reg:QI ES_REG)
205                (match_operand:HI 0 "")
206                ] UNS_ES_ADDR)]
207   ""
208   ""
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")))
220    ]
221   ""
222   "emit_insn (gen_addsi3_internal_virt (operands[0], operands[1], operands[2]));
223    DONE;"
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))
232    ]
233   "rl78_virt_insns_ok ()"
234   ""
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))
244    ]
245   "rl78_real_insns_ok ()"
246   { return rl78_addsi3_internal (operands, which_alternative); }
247   [(set_attr "valloc" "macax")]
250 (define_expand "subsi3"
251   [(set (match_operand:SI           0 "nonimmediate_operand")
252         (minus:SI (match_operand:SI 1 "general_operand")
253                   (match_operand    2 "general_operand")))
254    ]
255   ""
256   "emit_insn (gen_subsi3_internal_virt (operands[0], operands[1], operands[2]));
257   DONE;"
260 (define_insn "subsi3_internal_virt"
261   [(set (match_operand:SI           0 "nonimmediate_operand" "=v,&vm, vm")
262         (minus:SI (match_operand:SI 1 "general_operand"      "0, vim, vim")
263                   (match_operand    2 "general_operand"      "vim,vim,vim")))
264    (clobber (reg:HI AX_REG))
265    (clobber (reg:HI BC_REG))
266    ]
267   "rl78_virt_insns_ok ()"
268   ""
269   [(set_attr "valloc" "macax")]
272 (define_insn "subsi3_internal_real"
273   [(set (match_operand:SI           0 "nonimmediate_operand" "=v,&vU, vU")
274         (minus:SI (match_operand:SI 1 "general_operand"      "+0, viU, viU")
275                   (match_operand    2 "general_operand"      "viWabWhlWh1,viWabWhlWh1,viWabWhlWh1")))
276    (clobber (reg:HI AX_REG))
277    (clobber (reg:HI BC_REG))
278    ]
279   "rl78_real_insns_ok ()"
280   "@
281    movw ax,%h1 \;subw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;decw ax \;subw ax,%H2 \;movw %H0,ax
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 bc,  ax \;movw ax,%H1 \;sknc \;decw ax \;subw ax,%H2 \;movw %H0,ax \;movw ax,bc \;movw %h0, ax"
284   [(set_attr "valloc" "macax")]
287 (define_expand "mulqi3"
288   [(parallel
289     [(set (match_operand:QI            0 "register_operand")
290            (mult:QI  (match_operand:QI 1 "general_operand")
291                      (match_operand:QI 2 "nonmemory_operand")))
292       (clobber (reg:HI AX_REG))
293     ])
294   ]
295   "" ; mulu supported by all targets
296   ""
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")))
303    ]
304   "! RL78_MUL_NONE"
305   {
306     if (RL78_MUL_G14)
307       emit_insn (gen_mulhi3_g14 (operands[0], operands[1], operands[2]));
308     else /* RL78_MUL_G13 */
309       emit_insn (gen_mulhi3_g13 (operands[0], operands[1], operands[2]));
310     DONE;
311   }
314 (define_expand "mulsi3"
315   [(set (match_operand:SI          0 "register_operand")
316         (mult:SI (match_operand:SI 1 "general_operand")
317                  (match_operand:SI 2 "nonmemory_operand")))
318    ]
319   "! RL78_MUL_NONE"
320   {
321     if (RL78_MUL_G14)
322       emit_insn (gen_mulsi3_g14 (operands[0], operands[1], operands[2]));
323     else /* RL78_MUL_G13 */
324       emit_insn (gen_mulsi3_g13 (operands[0], operands[1], operands[2]));
325     DONE;
326   }
329 (define_insn "*mulqi3_rl78"
330   [(set (match_operand:QI          0 "register_operand" "=&v")
331         (mult:QI (match_operand:QI 1 "general_operand" "viU")
332                  (match_operand:QI 2 "general_operand" "vi")))
333    (clobber (reg:HI AX_REG))
334   ]
335   "" ; mulu supported by all targets
336   "; mulqi macro %0 = %1 * %2
337         mov    a, %h1
338         mov    x, a
339         mov    a, %h2
340         mulu   x ; ax = a * x
341         mov    a, x
342         mov    %h0, a
343         ; end of mulqi macro"
344   [(set_attr "valloc" "macax")]
347 (define_insn "mulhi3_g14"
348   [(set (match_operand:HI          0 "register_operand" "=&v")
349         (mult:HI (match_operand:HI 1 "general_operand" "viU")
350                  (match_operand:HI 2 "general_operand" "vi")))
351    (clobber (reg:HI AX_REG))
352    (clobber (reg:HI BC_REG))
353   ]
354   "RL78_MUL_G14"
355   "; G14 mulhi macro %0 = %1 * %2
356         movw    ax, %h1
357         movw    bc, %h2
358         mulhu   ; bcax = bc * ax
359         movw    %h0, ax
360         ; end of mulhi macro"
361   [(set_attr "valloc" "macax")]
364 (define_insn "mulhi3_g13"
365   [(set (match_operand:HI          0 "register_operand" "=&v")
366         (mult:HI (match_operand:HI 1 "general_operand" "viU")
367                  (match_operand:HI 2 "general_operand" "vi")))
368    (clobber (reg:HI AX_REG))
369   ]
370   "RL78_MUL_G13"
371   "; G13 mulhi macro %0 = %1 * %2
372         mov     a, #0x00
373         mov     !0xf00e8, a     ; MDUC
374         movw    ax, %h1
375         movw    0xffff0, ax     ; MDAL
376         movw    ax, %h2
377         movw    0xffff2, ax     ; MDAH
378         nop     ; mdb = mdal * mdah
379         movw    ax, 0xffff6     ; MDBL
380         movw    %h0, ax
381         ; end of mulhi macro"
382   [(set_attr "valloc" "macax")]
385 ;; 0xFFFF0 is MACR(L).  0xFFFF2 is MACR(H) but we don't care about it
386 ;; because we're only using the lower 16 bits (which is the upper 16
387 ;; bits of the result).
388 (define_insn "mulsi3_g14"
389   [(set (match_operand:SI          0 "register_operand" "=&v")
390         (mult:SI (match_operand:SI 1 "general_operand" "viU")
391                  (match_operand:SI 2 "general_operand" "vi")))
392    (clobber (reg:HI AX_REG))
393    (clobber (reg:HI BC_REG))
394   ]
395   "RL78_MUL_G14"
396   "; G14 mulsi macro %0 = %1 * %2
397         movw    ax, %h1
398         movw    bc, %h2
399         MULHU   ; bcax = bc * ax
400         movw    %h0, ax
401         movw    ax, bc
402         movw    0xffff0, ax
403         movw    ax, %H1
404         movw    bc, %h2
405         MACHU   ; MACR += bc * ax
406         movw    ax, %h1
407         movw    bc, %H2
408         MACHU   ; MACR += bc * ax
409         movw    ax, 0xffff0
410         movw    %H0, ax
411         ; end of mulsi macro"
412   [(set_attr "valloc" "macax")]
413   )
415 ;; 0xFFFF0 is MDAL.  0xFFFF2 is MDAH.
416 ;; 0xFFFF6 is MDBL.  0xFFFF4 is MDBH.
417 ;; 0xF00E0 is MDCL.  0xF00E2 is MDCH.
418 ;; 0xF00E8 is MDUC.
419 ;; Warning: this matches the silicon not the documentation.
420 (define_insn "mulsi3_g13"
421   [(set (match_operand:SI          0 "register_operand" "=&v")
422         (mult:SI (match_operand:SI 1 "general_operand" "viU")
423                  (match_operand:SI 2 "general_operand" "viU")))
424    (clobber (reg:HI AX_REG))
425    (clobber (reg:HI BC_REG))
426   ]
427   "RL78_MUL_G13"
428   "; G13 mulsi macro %0 = %1 * %2
429         mov     a, #0x00
430         mov     !0xf00e8, a     ; MDUC
431         movw    ax, %h1
432         movw    0xffff0, ax     ; MDAL
433         movw    ax, %h2
434         movw    0xffff2, ax     ; MDAH
435         nop     ; mdb = mdal * mdah
436         movw    ax, 0xffff6     ; MDBL
437         movw    %h0, ax
439         mov     a, #0x40
440         mov     !0xf00e8, a     ; MDUC
441         movw    ax, 0xffff4     ; MDBH
442         movw    !0xf00e0, ax    ; MDCL
443         movw    ax, #0
444         movw    !0xf00e2, ax    ; MDCL
445         movw    ax, %H1
446         movw    0xffff0, ax     ; MDAL
447         movw    ax, %h2
448         movw    0xffff2, ax     ; MDAH
449         nop     ; mdc += mdal * mdah
451         mov     a, #0x40
452         mov     !0xf00e8, a     ; MDUC
453         movw    ax, %h1
454         movw    0xffff0, ax     ; MDAL
455         movw    ax, %H2
456         movw    0xffff2, ax     ; MDAH
457         nop     ; mdc += mdal * mdah
458         nop     ; Additional nop for MAC
459         movw    ax, !0xf00e0    ; MDCL
460         movw    %H0, ax
461         ; end of mulsi macro"
462   [(set_attr "valloc" "macax")]
465 (define_expand "udivmodhi4"
466   [(parallel
467     [(set (match_operand:HI          0 "register_operand")
468           (udiv:HI (match_operand:HI 1 "register_operand")
469                    (match_operand:HI 2 "register_operand")))
470      (set (match_operand:HI          3 "register_operand")
471           (umod:HI (match_dup 1) (match_dup 2)))
472      (clobber (reg:HI AX_REG))
473      (clobber (reg:HI DE_REG))
474     ])
475    ]
476   "RL78_MUL_G14"
477   ""
480 (define_insn "*udivmodhi4_g14"
481   [(set (match_operand:HI          0 "register_operand" "=v")
482         (udiv:HI (match_operand:HI 1 "register_operand" "v")
483                  (match_operand:HI 2 "register_operand" "v")))
484    (set (match_operand:HI          3 "register_operand" "=v")
485         (umod:HI (match_dup 1) (match_dup 2)))
486    (clobber (reg:HI AX_REG))
487    (clobber (reg:HI DE_REG))
488   ]
489   "RL78_MUL_G14"
490   {
491     if (find_reg_note (insn, REG_UNUSED, operands[3]))
492       return "; G14 udivhi macro %0 = %1 / %2 \n\
493         movw    ax, %h1 \n\
494         movw    de, %h2 \n\
495         push    psw     ; Save the current interrupt status \n\
496         di              ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\
497         divhu           ; ax = ax / de \n\
498         pop     psw     ; Restore saved interrupt status \n\
499         movw    %h0, ax \n\
500         ; end of udivhi macro";
501     else if (find_reg_note (insn, REG_UNUSED, operands[0]))
502       return "; G14 umodhi macro %3 = %1 %% %2 \n\
503         movw    ax, %h1 \n\
504         movw    de, %h2 \n\
505         push    psw     ; Save the current interrupt status \n\
506         di              ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\
507         divhu           ; de = ax %% de \n\
508         pop     psw     ; Restore saved interrupt status \n\
509         movw    ax, de \n\
510         movw    %h3, ax \n\
511         ; end of umodhi macro";
512     else
513       return "; G14 udivmodhi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\
514         movw    ax, %h1 \n\
515         movw    de, %h2 \n\
516         push    psw     ; Save the current interrupt status \n\
517         di              ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\
518         divhu           ; ax = ax / de, de = ax %% de \n\
519         pop     psw     ; Restore saved interrupt status \n\
520         movw    %h0, ax \n\
521         movw    ax, de \n\
522         movw    %h3, ax \n\
523         ; end of udivmodhi macro";
524   }
525   [(set_attr "valloc" "divhi")]
528 (define_expand "udivmodsi4"
529   [(parallel
530     [(set (match_operand:SI          0 "register_operand")
531           (udiv:SI (match_operand:SI 1 "register_operand")
532                    (match_operand:SI 2 "register_operand")))
533      (set (match_operand:SI          3 "register_operand")
534           (umod:SI (match_dup 1) (match_dup 2)))
535     ])
536    ]
537   "! RL78_MUL_NONE && ! optimize_size"
538   {
539     if (RL78_MUL_G14)
540       emit_insn (gen_udivmodsi4_g14 (operands[0], operands[1], operands[2], operands[3]));
541     else /* RL78_MUL_G13 */
542       emit_insn (gen_udivmodsi4_g13 (operands[0], operands[1], operands[2], operands[3]));
543     DONE;
544   }
547 (define_insn "udivmodsi4_g14"
548   [(set (match_operand:SI          0 "register_operand" "=v")
549         (udiv:SI (match_operand:SI 1 "register_operand" "v")
550                  (match_operand:SI 2 "register_operand" "v")))
551    (set (match_operand:SI          3 "register_operand" "=v")
552         (umod:SI (match_dup 1) (match_dup 2)))
553    (clobber (reg:HI AX_REG))
554    (clobber (reg:HI BC_REG))
555    (clobber (reg:HI DE_REG))
556    (clobber (reg:HI HL_REG))
557   ]
558   "RL78_MUL_G14"
559   {
560     if (find_reg_note (insn, REG_UNUSED, operands[3]))
561       return "; G14 udivsi macro %0 = %1 / %2 \n\
562         movw    ax, %h1 \n\
563         movw    bc, %H1 \n\
564         movw    de, %h2 \n\
565         movw    hl, %H2 \n\
566         push    psw     ; Save the current interrupt status \n\
567         di              ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\
568         divwu           ; bcax = bcax / hlde \n\
569         pop     psw     ; Restore saved interrupt status \n\
570         movw    %h0, ax \n\
571         movw    ax, bc \n\
572         movw    %H0, ax \n\
573         ; end of udivsi macro";
574     else if (find_reg_note (insn, REG_UNUSED, operands[0]))
575       return "; G14 umodsi macro %3 = %1 %% %2 \n\
576         movw    ax, %h1 \n\
577         movw    bc, %H1 \n\
578         movw    de, %h2 \n\
579         movw    hl, %H2 \n\
580         push    psw     ; Save the current interrupt status \n\
581         di              ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\
582         divwu           ; hlde = bcax %% hlde \n\
583         pop     psw     ; Restore saved interrupt status \n\
584         movw    ax, de \n\
585         movw    %h3, ax \n\
586         movw    ax, hl \n\
587         movw    %H3, ax \n\
588         ; end of umodsi macro";
589     else
590       return "; G14 udivmodsi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\
591         movw    ax, %h1 \n\
592         movw    bc, %H1 \n\
593         movw    de, %h2 \n\
594         movw    hl, %H2 \n\
595         push    psw     ; Save the current interrupt status \n\
596         di              ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\
597         divwu           ; bcax = bcax / hlde, hlde = bcax %% hlde \n\
598         pop     psw     ; Restore saved interrupt status \n\
599         movw    %h0, ax \n\
600         movw    ax, bc \n\
601         movw    %H0, ax \n\
602         movw    ax, de \n\
603         movw    %h3, ax \n\
604         movw    ax, hl \n\
605         movw    %H3, ax \n\
606         ; end of udivmodsi macro";
607   }
608   [(set_attr "valloc" "divsi")]
611 ;; Warning: these values match the silicon not the documentation.
612 ;; 0xFFFF0 is MDAL.  0xFFFF2 is MDAH.
613 ;; 0xFFFF6 is MDBL.  0xFFFF4 is MDBH.
614 ;; 0xF00E0 is MDCL.  0xF00E2 is MDCH.
615 ;; 0xF00E8 is MDUC.
617 (define_insn "udivmodsi4_g13"
618   [(set (match_operand:SI          0 "register_operand" "=v")
619         (udiv:SI (match_operand:SI 1 "register_operand" "v")
620                  (match_operand:SI 2 "register_operand" "v")))
621    (set (match_operand:SI          3 "register_operand" "=v")
622         (umod:SI (match_dup 1) (match_dup 2)))
623    (clobber (reg:HI AX_REG))
624   ]
625   "RL78_MUL_G13"
626   {
627     if (find_reg_note (insn, REG_UNUSED, operands[3]))
628       return "; G13 udivsi macro %0 = %1 / %2 \n\
629         mov     a, #0xC0        ; Set DIVMODE=1 and MACMODE=1 \n\
630         mov     !0xf00e8, a     ; This preps the peripheral for division without interrupt generation \n\
631         movw    ax, %H1         \n\
632         movw    0xffff2, ax     ; MDAH \n\
633         movw    ax, %h1         \n\
634         movw    0xffff0, ax     ; MDAL \n\
635         movw    ax, %H2         \n\
636         movw    0xffff4, ax     ; MDBH \n\
637         movw    ax, %h2         \n\
638         movw    0xffff6, ax     ; MDBL \n\
639         mov     a, #0xC1        ; Set the DIVST bit in MDUC \n\
640         mov     !0xf00e8, a     ; This starts the division op \n\
641 1:      mov     a, !0xf00e8     ; Wait 16 clocks or until DIVST is clear \n\
642         bt      a.0, $1b        \n\
643         movw    ax, 0xffff0     ; Read the quotient \n\
644         movw    %h0, ax         \n\
645         movw    ax, 0xffff2     \n\
646         movw    %H0, ax         \n\
647         ; end of udivsi macro";
648     else if (find_reg_note (insn, REG_UNUSED, operands[0]))
649       return "; G13 umodsi macro %3 = %1 %% %2 \n\
650         mov     a, #0xC0        ; Set DIVMODE=1 and MACMODE=1 \n\
651         mov     !0xf00e8, a     ; This preps the peripheral for division without interrupt generation \n\
652         movw    ax, %H1         \n\
653         movw    0xffff2, ax     ; MDAH \n\
654         movw    ax, %h1         \n\
655         movw    0xffff0, ax     ; MDAL \n\
656         movw    ax, %H2         \n\
657         movw    0xffff4, ax     ; MDBH \n\
658         movw    ax, %h2         \n\
659         movw    0xffff6, ax     ; MDBL \n\
660         mov     a, #0xC1        ; Set the DIVST bit in MDUC \n\
661         mov     !0xf00e8, a     ; This starts the division op \n\
662 1:      mov     a, !0xf00e8     ; Wait 16 clocks or until DIVST is clear \n\
663         bt      a.0, $1b        \n\
664         movw    ax, !0xf00e0    ; Read the remainder \n\
665         movw    %h3, ax         \n\
666         movw    ax, !0xf00e2    \n\
667         movw    %H3, ax         \n\
668         ; end of umodsi macro";
669     else
670       return "; G13 udivmodsi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\
671         mov     a, #0xC0        ; Set DIVMODE=1 and MACMODE=1 \n\
672         mov     !0xf00e8, a     ; This preps the peripheral for division without interrupt generation \n\
673         movw    ax, %H1         \n\
674         movw    0xffff2, ax     ; MDAH \n\
675         movw    ax, %h1         \n\
676         movw    0xffff0, ax     ; MDAL \n\
677         movw    ax, %H2         \n\
678         movw    0xffff4, ax     ; MDBH \n\
679         movw    ax, %h2         \n\
680         movw    0xffff6, ax     ; MDBL \n\
681         mov     a, #0xC1        ; Set the DIVST bit in MDUC \n\
682         mov     !0xf00e8, a     ; This starts the division op \n\
683 1:      mov     a, !0xf00e8     ; Wait 16 clocks or until DIVST is clear \n\
684         bt      a.0, $1b        \n\
685         movw    ax, 0xffff0     ; Read the quotient \n\
686         movw    %h0, ax         \n\
687         movw    ax, 0xffff2     \n\
688         movw    %H0, ax         \n\
689         movw    ax, !0xf00e0    ; Read the remainder \n\
690         movw    %h3, ax         \n\
691         movw    ax, !0xf00e2    \n\
692         movw    %H3, ax         \n\
693         ; end of udivmodsi macro";
694       }
695   [(set_attr "valloc" "macax")]