]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rl78/rl78.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / rl78 / rl78.md
CommitLineData
78e515f7 1;; Machine Description for Renesas RL78 processors
f1717362 2;; Copyright (C) 2011-2016 Free Software Foundation, Inc.
78e515f7 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)
3f3556f1 38 (CC_REG 34)
78e515f7 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)
563dc27b 48 (UNS_ES_ADDR 11)
78e515f7 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
edf1f7ba 91(define_insn "rl78_return"
78e515f7 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"
d1dc25ff 110 [(match_operand:HI 0 "")]
78e515f7 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)]
1d701d79 145 "!TARGET_G10"
78e515f7 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)
d1dc25ff 172 (unspec_volatile [(match_operand 0 "") ;; fp (ignore)
173 (match_operand 1 "") ;; target
174 (match_operand 2 "") ;; sp
175 (match_operand 3 "") ;; ?
78e515f7 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
d1dc25ff 203(define_expand "es_addr"
204 [(unspec:SI [(reg:QI ES_REG)
205 (match_operand:HI 0 "")
206 ] UNS_ES_ADDR)]
207 ""
208 ""
209)
210
78e515f7 211;;======================================================================
212;;
213;; "macro" insns - cases where inline chunks of code are more
214;; efficient than anything else.
215
216(define_expand "addsi3"
3f3556f1 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")))
78e515f7 220 ]
221 ""
3f3556f1 222 "emit_insn (gen_addsi3_internal_virt (operands[0], operands[1], operands[2]));
223 DONE;"
78e515f7 224)
225
3f3556f1 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))
78e515f7 232 ]
3f3556f1 233 "rl78_virt_insns_ok ()"
78e515f7 234 ""
3f3556f1 235 [(set_attr "valloc" "macax")]
236)
237
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 ()"
95328f38 246 { return rl78_addsi3_internal (operands, which_alternative); }
3f3556f1 247 [(set_attr "valloc" "macax")]
248)
249
250(define_expand "subsi3"
d1dc25ff 251 [(set (match_operand:SI 0 "nonimmediate_operand")
252 (minus:SI (match_operand:SI 1 "general_operand")
253 (match_operand 2 "general_operand")))
3f3556f1 254 ]
255 ""
256 "emit_insn (gen_subsi3_internal_virt (operands[0], operands[1], operands[2]));
257 DONE;"
258)
259
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")]
270)
271
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"
78e515f7 284 [(set_attr "valloc" "macax")]
285)
286
789a3e1c 287(define_expand "mulqi3"
e98e1692 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 ]
789a3e1c 295 "" ; mulu supported by all targets
296 ""
297)
298
299(define_expand "mulhi3"
d1dc25ff 300 [(set (match_operand:HI 0 "register_operand")
301 (mult:HI (match_operand:HI 1 "general_operand")
302 (match_operand:HI 2 "nonmemory_operand")))
789a3e1c 303 ]
304 "! RL78_MUL_NONE"
e98e1692 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 }
789a3e1c 312)
313
78e515f7 314(define_expand "mulsi3"
d1dc25ff 315 [(set (match_operand:SI 0 "register_operand")
316 (mult:SI (match_operand:SI 1 "general_operand")
317 (match_operand:SI 2 "nonmemory_operand")))
78e515f7 318 ]
319 "! RL78_MUL_NONE"
e98e1692 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 }
78e515f7 327)
328
789a3e1c 329(define_insn "*mulqi3_rl78"
330 [(set (match_operand:QI 0 "register_operand" "=&v")
d1dc25ff 331 (mult:QI (match_operand:QI 1 "general_operand" "viU")
789a3e1c 332 (match_operand:QI 2 "general_operand" "vi")))
e98e1692 333 (clobber (reg:HI AX_REG))
334 ]
789a3e1c 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"
e98e1692 344 [(set_attr "valloc" "macax")]
789a3e1c 345)
346
e98e1692 347(define_insn "mulhi3_g14"
789a3e1c 348 [(set (match_operand:HI 0 "register_operand" "=&v")
d1dc25ff 349 (mult:HI (match_operand:HI 1 "general_operand" "viU")
789a3e1c 350 (match_operand:HI 2 "general_operand" "vi")))
e98e1692 351 (clobber (reg:HI AX_REG))
352 (clobber (reg:HI BC_REG))
353 ]
354 "RL78_MUL_G14"
355 "; G14 mulhi macro %0 = %1 * %2
789a3e1c 356 movw ax, %h1
357 movw bc, %h2
358 mulhu ; bcax = bc * ax
359 movw %h0, ax
360 ; end of mulhi macro"
e98e1692 361 [(set_attr "valloc" "macax")]
789a3e1c 362)
363
e98e1692 364(define_insn "mulhi3_g13"
789a3e1c 365 [(set (match_operand:HI 0 "register_operand" "=&v")
d1dc25ff 366 (mult:HI (match_operand:HI 1 "general_operand" "viU")
789a3e1c 367 (match_operand:HI 2 "general_operand" "vi")))
e98e1692 368 (clobber (reg:HI AX_REG))
369 ]
789a3e1c 370 "RL78_MUL_G13"
e98e1692 371 "; G13 mulhi macro %0 = %1 * %2
789a3e1c 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"
e98e1692 382 [(set_attr "valloc" "macax")]
789a3e1c 383)
384
78e515f7 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).
e98e1692 388(define_insn "mulsi3_g14"
78e515f7 389 [(set (match_operand:SI 0 "register_operand" "=&v")
d1dc25ff 390 (mult:SI (match_operand:SI 1 "general_operand" "viU")
3f3556f1 391 (match_operand:SI 2 "general_operand" "vi")))
e98e1692 392 (clobber (reg:HI AX_REG))
393 (clobber (reg:HI BC_REG))
394 ]
395 "RL78_MUL_G14"
396 "; G14 mulsi macro %0 = %1 * %2
78e515f7 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 )
414
415;; 0xFFFF0 is MDAL. 0xFFFF2 is MDAH.
50008a8e 416;; 0xFFFF6 is MDBL. 0xFFFF4 is MDBH.
78e515f7 417;; 0xF00E0 is MDCL. 0xF00E2 is MDCH.
418;; 0xF00E8 is MDUC.
50008a8e 419;; Warning: this matches the silicon not the documentation.
78e515f7 420(define_insn "mulsi3_g13"
421 [(set (match_operand:SI 0 "register_operand" "=&v")
3f3556f1 422 (mult:SI (match_operand:SI 1 "general_operand" "viU")
423 (match_operand:SI 2 "general_operand" "viU")))
e98e1692 424 (clobber (reg:HI AX_REG))
425 (clobber (reg:HI BC_REG))
426 ]
78e515f7 427 "RL78_MUL_G13"
e98e1692 428 "; G13 mulsi macro %0 = %1 * %2
78e515f7 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
50008a8e 436 movw ax, 0xffff6 ; MDBL
78e515f7 437 movw %h0, ax
438
439 mov a, #0x40
440 mov !0xf00e8, a ; MDUC
50008a8e 441 movw ax, 0xffff4 ; MDBH
78e515f7 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
450
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
57518f85 458 nop ; Additional nop for MAC
78e515f7 459 movw ax, !0xf00e0 ; MDCL
460 movw %H0, ax
461 ; end of mulsi macro"
462 [(set_attr "valloc" "macax")]
563dc27b 463)
e98e1692 464
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 ""
478)
479
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")]
526)
527
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 }
545)
546
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")]
609)
610
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.
616
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\
6411: 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\
6621: 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\
6831: 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")]
696)