]>
Commit | Line | Data |
---|---|---|
85b8555e | 1 | ;; Machine Description for Renesas RL78 processors |
a5544970 | 2 | ;; Copyright (C) 2011-2019 Free Software Foundation, Inc. |
85b8555e DD |
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) | |
3e3d9d17 | 38 | (CC_REG 34) |
85b8555e DD |
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) | |
2e7c3f21 | 48 | (UNS_ES_ADDR 11) |
85b8555e DD |
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 | ||
035b8879 | 70 | (define_attr "is_g13_muldiv_insn" "yes,no" (const_string "no")) |
85b8555e DD |
71 | |
72 | ;; Function Prologue/Epilogue Instructions | |
73 | ||
74 | (define_expand "prologue" | |
75 | [(const_int 0)] | |
76 | "" | |
77 | "rl78_expand_prologue (); DONE;" | |
78 | ) | |
79 | ||
80 | (define_expand "epilogue" | |
81 | [(const_int 0)] | |
82 | "" | |
83 | "rl78_expand_epilogue (); DONE;" | |
84 | ) | |
85 | ||
86 | (define_expand "sibcall_epilogue" | |
87 | [(return)] | |
88 | "" | |
89 | "FAIL;" | |
90 | ) | |
91 | ||
794f3386 | 92 | (define_insn "rl78_return" |
85b8555e DD |
93 | [(return)] |
94 | "" | |
95 | "ret" | |
96 | ) | |
97 | ||
98 | (define_insn "interrupt_return" | |
99 | [(unspec_volatile [(return)] UNS_RETI) ] | |
100 | "" | |
101 | "reti" | |
102 | ) | |
103 | ||
104 | (define_insn "brk_interrupt_return" | |
105 | [(unspec_volatile [(return)] UNS_RETB) ] | |
106 | "" | |
107 | "retb" | |
108 | ) | |
109 | ||
110 | (define_expand "eh_return" | |
93684323 | 111 | [(match_operand:HI 0 "")] |
85b8555e DD |
112 | "" |
113 | "rl78_expand_eh_epilogue (operands[0]); | |
114 | emit_barrier (); | |
115 | DONE;" | |
116 | ) | |
117 | ||
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" | |
130 | ) | |
131 | ||
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" | |
142 | ) | |
143 | ||
144 | (define_insn "sel_rb" | |
145 | [(unspec_volatile [(match_operand 0 "immediate_operand" "")] UNS_SET_RB)] | |
6fcd3a13 | 146 | "!TARGET_G10" |
85b8555e DD |
147 | "sel\trb%u0" |
148 | ) | |
149 | ||
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 | ) | |
159 | ||
160 | (define_insn "trampoline_uninit" | |
161 | [(unspec_volatile [(const_int 0)] UNS_TRAMPOLINE_UNINIT) | |
162 | ] | |
163 | "" | |
164 | "call !!___trampoline_uninit" | |
165 | ) | |
166 | ||
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) | |
93684323 NC |
173 | (unspec_volatile [(match_operand 0 "") ;; fp (ignore) |
174 | (match_operand 1 "") ;; target | |
175 | (match_operand 2 "") ;; sp | |
176 | (match_operand 3 "") ;; ? | |
85b8555e DD |
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 | ) | |
184 | ||
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 | |
201 | " | |
202 | ) | |
203 | ||
93684323 NC |
204 | (define_expand "es_addr" |
205 | [(unspec:SI [(reg:QI ES_REG) | |
206 | (match_operand:HI 0 "") | |
207 | ] UNS_ES_ADDR)] | |
208 | "" | |
209 | "" | |
210 | ) | |
211 | ||
85b8555e DD |
212 | ;;====================================================================== |
213 | ;; | |
214 | ;; "macro" insns - cases where inline chunks of code are more | |
215 | ;; efficient than anything else. | |
216 | ||
217 | (define_expand "addsi3" | |
3e3d9d17 DD |
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"))) | |
85b8555e DD |
221 | ] |
222 | "" | |
3e3d9d17 DD |
223 | "emit_insn (gen_addsi3_internal_virt (operands[0], operands[1], operands[2])); |
224 | DONE;" | |
85b8555e DD |
225 | ) |
226 | ||
a0bf6cf7 SP |
227 | (define_expand "adddi3" |
228 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
229 | (plus:DI (match_operand:DI 1 "general_operand" "") | |
230 | (match_operand:DI 2 "general_operand" ""))) | |
231 | ] | |
232 | "" | |
233 | "rl78_emit_libcall (\"__adddi3\", PLUS, DImode, DImode, 3, operands); | |
234 | DONE;" | |
235 | ) | |
236 | ||
3e3d9d17 DD |
237 | (define_insn "addsi3_internal_virt" |
238 | [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vm, vm") | |
239 | (plus:SI (match_operand:SI 1 "general_operand" "0, vim, vim") | |
240 | (match_operand 2 "general_operand" "vim,vim,vim"))) | |
241 | (clobber (reg:HI AX_REG)) | |
242 | (clobber (reg:HI BC_REG)) | |
85b8555e | 243 | ] |
3e3d9d17 | 244 | "rl78_virt_insns_ok ()" |
85b8555e | 245 | "" |
3e3d9d17 DD |
246 | [(set_attr "valloc" "macax")] |
247 | ) | |
248 | ||
249 | (define_insn "addsi3_internal_real" | |
250 | [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vU, vU") | |
251 | (plus:SI (match_operand:SI 1 "general_operand" "+0, viU, viU") | |
252 | (match_operand 2 "general_operand" "viWabWhlWh1,viWabWhlWh1,viWabWhlWh1"))) | |
253 | (clobber (reg:HI AX_REG)) | |
254 | (clobber (reg:HI BC_REG)) | |
255 | ] | |
256 | "rl78_real_insns_ok ()" | |
f87a37c6 | 257 | { return rl78_addsi3_internal (operands, which_alternative); } |
3e3d9d17 DD |
258 | [(set_attr "valloc" "macax")] |
259 | ) | |
260 | ||
261 | (define_expand "subsi3" | |
93684323 NC |
262 | [(set (match_operand:SI 0 "nonimmediate_operand") |
263 | (minus:SI (match_operand:SI 1 "general_operand") | |
264 | (match_operand 2 "general_operand"))) | |
3e3d9d17 DD |
265 | ] |
266 | "" | |
267 | "emit_insn (gen_subsi3_internal_virt (operands[0], operands[1], operands[2])); | |
268 | DONE;" | |
269 | ) | |
270 | ||
5feee954 SP |
271 | (define_expand "subdi3" |
272 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
273 | (minus:DI (match_operand:DI 1 "general_operand" "") | |
274 | (match_operand:DI 2 "general_operand" ""))) | |
275 | ] | |
276 | "" | |
277 | "rl78_emit_libcall (\"__subdi3\", MINUS, DImode, DImode, 3, operands); | |
278 | DONE;" | |
279 | ) | |
280 | ||
3e3d9d17 DD |
281 | (define_insn "subsi3_internal_virt" |
282 | [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vm, vm") | |
283 | (minus:SI (match_operand:SI 1 "general_operand" "0, vim, vim") | |
284 | (match_operand 2 "general_operand" "vim,vim,vim"))) | |
285 | (clobber (reg:HI AX_REG)) | |
286 | (clobber (reg:HI BC_REG)) | |
287 | ] | |
288 | "rl78_virt_insns_ok ()" | |
289 | "" | |
290 | [(set_attr "valloc" "macax")] | |
291 | ) | |
292 | ||
293 | (define_insn "subsi3_internal_real" | |
294 | [(set (match_operand:SI 0 "nonimmediate_operand" "=v,&vU, vU") | |
295 | (minus:SI (match_operand:SI 1 "general_operand" "+0, viU, viU") | |
296 | (match_operand 2 "general_operand" "viWabWhlWh1,viWabWhlWh1,viWabWhlWh1"))) | |
297 | (clobber (reg:HI AX_REG)) | |
298 | (clobber (reg:HI BC_REG)) | |
299 | ] | |
300 | "rl78_real_insns_ok ()" | |
301 | "@ | |
302 | movw ax,%h1 \;subw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;decw ax \;subw ax,%H2 \;movw %H0,ax | |
303 | movw ax,%h1 \;subw ax,%h2 \;movw %h0, ax \;movw ax,%H1 \;sknc \;decw ax \;subw ax,%H2 \;movw %H0,ax | |
304 | 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" | |
85b8555e DD |
305 | [(set_attr "valloc" "macax")] |
306 | ) | |
307 | ||
e571fa59 | 308 | (define_expand "mulqi3" |
72ed1126 NC |
309 | [(parallel |
310 | [(set (match_operand:QI 0 "register_operand") | |
311 | (mult:QI (match_operand:QI 1 "general_operand") | |
312 | (match_operand:QI 2 "nonmemory_operand"))) | |
313 | (clobber (reg:HI AX_REG)) | |
314 | ]) | |
315 | ] | |
e571fa59 KP |
316 | "" ; mulu supported by all targets |
317 | "" | |
318 | ) | |
319 | ||
320 | (define_expand "mulhi3" | |
93684323 NC |
321 | [(set (match_operand:HI 0 "register_operand") |
322 | (mult:HI (match_operand:HI 1 "general_operand") | |
323 | (match_operand:HI 2 "nonmemory_operand"))) | |
e571fa59 KP |
324 | ] |
325 | "! RL78_MUL_NONE" | |
72ed1126 NC |
326 | { |
327 | if (RL78_MUL_G14) | |
328 | emit_insn (gen_mulhi3_g14 (operands[0], operands[1], operands[2])); | |
329 | else /* RL78_MUL_G13 */ | |
330 | emit_insn (gen_mulhi3_g13 (operands[0], operands[1], operands[2])); | |
331 | DONE; | |
332 | } | |
e571fa59 KP |
333 | ) |
334 | ||
85b8555e | 335 | (define_expand "mulsi3" |
93684323 NC |
336 | [(set (match_operand:SI 0 "register_operand") |
337 | (mult:SI (match_operand:SI 1 "general_operand") | |
338 | (match_operand:SI 2 "nonmemory_operand"))) | |
85b8555e DD |
339 | ] |
340 | "! RL78_MUL_NONE" | |
72ed1126 NC |
341 | { |
342 | if (RL78_MUL_G14) | |
343 | emit_insn (gen_mulsi3_g14 (operands[0], operands[1], operands[2])); | |
344 | else /* RL78_MUL_G13 */ | |
345 | emit_insn (gen_mulsi3_g13 (operands[0], operands[1], operands[2])); | |
346 | DONE; | |
347 | } | |
85b8555e DD |
348 | ) |
349 | ||
e571fa59 KP |
350 | (define_insn "*mulqi3_rl78" |
351 | [(set (match_operand:QI 0 "register_operand" "=&v") | |
93684323 | 352 | (mult:QI (match_operand:QI 1 "general_operand" "viU") |
e571fa59 | 353 | (match_operand:QI 2 "general_operand" "vi"))) |
72ed1126 NC |
354 | (clobber (reg:HI AX_REG)) |
355 | ] | |
e571fa59 KP |
356 | "" ; mulu supported by all targets |
357 | "; mulqi macro %0 = %1 * %2 | |
358 | mov a, %h1 | |
359 | mov x, a | |
360 | mov a, %h2 | |
361 | mulu x ; ax = a * x | |
362 | mov a, x | |
363 | mov %h0, a | |
364 | ; end of mulqi macro" | |
72ed1126 | 365 | [(set_attr "valloc" "macax")] |
e571fa59 KP |
366 | ) |
367 | ||
72ed1126 | 368 | (define_insn "mulhi3_g14" |
e571fa59 | 369 | [(set (match_operand:HI 0 "register_operand" "=&v") |
93684323 | 370 | (mult:HI (match_operand:HI 1 "general_operand" "viU") |
e571fa59 | 371 | (match_operand:HI 2 "general_operand" "vi"))) |
72ed1126 NC |
372 | (clobber (reg:HI AX_REG)) |
373 | (clobber (reg:HI BC_REG)) | |
374 | ] | |
375 | "RL78_MUL_G14" | |
376 | "; G14 mulhi macro %0 = %1 * %2 | |
e571fa59 KP |
377 | movw ax, %h1 |
378 | movw bc, %h2 | |
379 | mulhu ; bcax = bc * ax | |
380 | movw %h0, ax | |
381 | ; end of mulhi macro" | |
72ed1126 | 382 | [(set_attr "valloc" "macax")] |
e571fa59 KP |
383 | ) |
384 | ||
72ed1126 | 385 | (define_insn "mulhi3_g13" |
e571fa59 | 386 | [(set (match_operand:HI 0 "register_operand" "=&v") |
93684323 | 387 | (mult:HI (match_operand:HI 1 "general_operand" "viU") |
e571fa59 | 388 | (match_operand:HI 2 "general_operand" "vi"))) |
72ed1126 NC |
389 | (clobber (reg:HI AX_REG)) |
390 | ] | |
e571fa59 | 391 | "RL78_MUL_G13" |
72ed1126 | 392 | "; G13 mulhi macro %0 = %1 * %2 |
e571fa59 KP |
393 | mov a, #0x00 |
394 | mov !0xf00e8, a ; MDUC | |
395 | movw ax, %h1 | |
396 | movw 0xffff0, ax ; MDAL | |
397 | movw ax, %h2 | |
398 | movw 0xffff2, ax ; MDAH | |
399 | nop ; mdb = mdal * mdah | |
400 | movw ax, 0xffff6 ; MDBL | |
401 | movw %h0, ax | |
402 | ; end of mulhi macro" | |
035b8879 KP |
403 | [(set_attr "valloc" "macax") |
404 | (set_attr "is_g13_muldiv_insn" "yes")] | |
e571fa59 KP |
405 | ) |
406 | ||
85b8555e DD |
407 | ;; 0xFFFF0 is MACR(L). 0xFFFF2 is MACR(H) but we don't care about it |
408 | ;; because we're only using the lower 16 bits (which is the upper 16 | |
409 | ;; bits of the result). | |
72ed1126 | 410 | (define_insn "mulsi3_g14" |
85b8555e | 411 | [(set (match_operand:SI 0 "register_operand" "=&v") |
93684323 | 412 | (mult:SI (match_operand:SI 1 "general_operand" "viU") |
3e3d9d17 | 413 | (match_operand:SI 2 "general_operand" "vi"))) |
72ed1126 NC |
414 | (clobber (reg:HI AX_REG)) |
415 | (clobber (reg:HI BC_REG)) | |
416 | ] | |
417 | "RL78_MUL_G14" | |
418 | "; G14 mulsi macro %0 = %1 * %2 | |
85b8555e DD |
419 | movw ax, %h1 |
420 | movw bc, %h2 | |
421 | MULHU ; bcax = bc * ax | |
422 | movw %h0, ax | |
423 | movw ax, bc | |
424 | movw 0xffff0, ax | |
425 | movw ax, %H1 | |
426 | movw bc, %h2 | |
427 | MACHU ; MACR += bc * ax | |
428 | movw ax, %h1 | |
429 | movw bc, %H2 | |
430 | MACHU ; MACR += bc * ax | |
431 | movw ax, 0xffff0 | |
432 | movw %H0, ax | |
433 | ; end of mulsi macro" | |
434 | [(set_attr "valloc" "macax")] | |
435 | ) | |
436 | ||
437 | ;; 0xFFFF0 is MDAL. 0xFFFF2 is MDAH. | |
83ffd964 | 438 | ;; 0xFFFF6 is MDBL. 0xFFFF4 is MDBH. |
85b8555e DD |
439 | ;; 0xF00E0 is MDCL. 0xF00E2 is MDCH. |
440 | ;; 0xF00E8 is MDUC. | |
83ffd964 | 441 | ;; Warning: this matches the silicon not the documentation. |
85b8555e DD |
442 | (define_insn "mulsi3_g13" |
443 | [(set (match_operand:SI 0 "register_operand" "=&v") | |
3e3d9d17 DD |
444 | (mult:SI (match_operand:SI 1 "general_operand" "viU") |
445 | (match_operand:SI 2 "general_operand" "viU"))) | |
72ed1126 NC |
446 | (clobber (reg:HI AX_REG)) |
447 | (clobber (reg:HI BC_REG)) | |
448 | ] | |
85b8555e | 449 | "RL78_MUL_G13" |
72ed1126 | 450 | "; G13 mulsi macro %0 = %1 * %2 |
85b8555e DD |
451 | mov a, #0x00 |
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 ; mdb = mdal * mdah | |
83ffd964 | 458 | movw ax, 0xffff6 ; MDBL |
85b8555e DD |
459 | movw %h0, ax |
460 | ||
461 | mov a, #0x40 | |
462 | mov !0xf00e8, a ; MDUC | |
83ffd964 | 463 | movw ax, 0xffff4 ; MDBH |
85b8555e DD |
464 | movw !0xf00e0, ax ; MDCL |
465 | movw ax, #0 | |
466 | movw !0xf00e2, ax ; MDCL | |
467 | movw ax, %H1 | |
468 | movw 0xffff0, ax ; MDAL | |
469 | movw ax, %h2 | |
470 | movw 0xffff2, ax ; MDAH | |
471 | nop ; mdc += mdal * mdah | |
472 | ||
473 | mov a, #0x40 | |
474 | mov !0xf00e8, a ; MDUC | |
475 | movw ax, %h1 | |
476 | movw 0xffff0, ax ; MDAL | |
477 | movw ax, %H2 | |
478 | movw 0xffff2, ax ; MDAH | |
479 | nop ; mdc += mdal * mdah | |
bad4df9b | 480 | nop ; Additional nop for MAC |
85b8555e DD |
481 | movw ax, !0xf00e0 ; MDCL |
482 | movw %H0, ax | |
483 | ; end of mulsi macro" | |
035b8879 KP |
484 | [(set_attr "valloc" "macax") |
485 | (set_attr "is_g13_muldiv_insn" "yes")] | |
2e7c3f21 | 486 | ) |
72ed1126 NC |
487 | |
488 | (define_expand "udivmodhi4" | |
489 | [(parallel | |
490 | [(set (match_operand:HI 0 "register_operand") | |
491 | (udiv:HI (match_operand:HI 1 "register_operand") | |
492 | (match_operand:HI 2 "register_operand"))) | |
493 | (set (match_operand:HI 3 "register_operand") | |
494 | (umod:HI (match_dup 1) (match_dup 2))) | |
495 | (clobber (reg:HI AX_REG)) | |
496 | (clobber (reg:HI DE_REG)) | |
497 | ]) | |
498 | ] | |
499 | "RL78_MUL_G14" | |
500 | "" | |
501 | ) | |
502 | ||
503 | (define_insn "*udivmodhi4_g14" | |
504 | [(set (match_operand:HI 0 "register_operand" "=v") | |
505 | (udiv:HI (match_operand:HI 1 "register_operand" "v") | |
506 | (match_operand:HI 2 "register_operand" "v"))) | |
507 | (set (match_operand:HI 3 "register_operand" "=v") | |
508 | (umod:HI (match_dup 1) (match_dup 2))) | |
509 | (clobber (reg:HI AX_REG)) | |
510 | (clobber (reg:HI DE_REG)) | |
511 | ] | |
512 | "RL78_MUL_G14" | |
513 | { | |
514 | if (find_reg_note (insn, REG_UNUSED, operands[3])) | |
515 | return "; G14 udivhi macro %0 = %1 / %2 \n\ | |
516 | movw ax, %h1 \n\ | |
517 | movw de, %h2 \n\ | |
518 | push psw ; Save the current interrupt status \n\ | |
519 | di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ | |
520 | divhu ; ax = ax / de \n\ | |
521 | pop psw ; Restore saved interrupt status \n\ | |
522 | movw %h0, ax \n\ | |
523 | ; end of udivhi macro"; | |
524 | else if (find_reg_note (insn, REG_UNUSED, operands[0])) | |
525 | return "; G14 umodhi macro %3 = %1 %% %2 \n\ | |
526 | movw ax, %h1 \n\ | |
527 | movw de, %h2 \n\ | |
528 | push psw ; Save the current interrupt status \n\ | |
529 | di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ | |
530 | divhu ; de = ax %% de \n\ | |
531 | pop psw ; Restore saved interrupt status \n\ | |
532 | movw ax, de \n\ | |
533 | movw %h3, ax \n\ | |
534 | ; end of umodhi macro"; | |
535 | else | |
536 | return "; G14 udivmodhi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\ | |
537 | movw ax, %h1 \n\ | |
538 | movw de, %h2 \n\ | |
539 | push psw ; Save the current interrupt status \n\ | |
540 | di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ | |
541 | divhu ; ax = ax / de, de = ax %% de \n\ | |
542 | pop psw ; Restore saved interrupt status \n\ | |
543 | movw %h0, ax \n\ | |
544 | movw ax, de \n\ | |
545 | movw %h3, ax \n\ | |
546 | ; end of udivmodhi macro"; | |
547 | } | |
548 | [(set_attr "valloc" "divhi")] | |
549 | ) | |
550 | ||
551 | (define_expand "udivmodsi4" | |
552 | [(parallel | |
553 | [(set (match_operand:SI 0 "register_operand") | |
554 | (udiv:SI (match_operand:SI 1 "register_operand") | |
555 | (match_operand:SI 2 "register_operand"))) | |
556 | (set (match_operand:SI 3 "register_operand") | |
557 | (umod:SI (match_dup 1) (match_dup 2))) | |
558 | ]) | |
559 | ] | |
560 | "! RL78_MUL_NONE && ! optimize_size" | |
561 | { | |
562 | if (RL78_MUL_G14) | |
563 | emit_insn (gen_udivmodsi4_g14 (operands[0], operands[1], operands[2], operands[3])); | |
564 | else /* RL78_MUL_G13 */ | |
565 | emit_insn (gen_udivmodsi4_g13 (operands[0], operands[1], operands[2], operands[3])); | |
566 | DONE; | |
567 | } | |
568 | ) | |
569 | ||
570 | (define_insn "udivmodsi4_g14" | |
571 | [(set (match_operand:SI 0 "register_operand" "=v") | |
572 | (udiv:SI (match_operand:SI 1 "register_operand" "v") | |
573 | (match_operand:SI 2 "register_operand" "v"))) | |
574 | (set (match_operand:SI 3 "register_operand" "=v") | |
575 | (umod:SI (match_dup 1) (match_dup 2))) | |
576 | (clobber (reg:HI AX_REG)) | |
577 | (clobber (reg:HI BC_REG)) | |
578 | (clobber (reg:HI DE_REG)) | |
579 | (clobber (reg:HI HL_REG)) | |
580 | ] | |
581 | "RL78_MUL_G14" | |
582 | { | |
583 | if (find_reg_note (insn, REG_UNUSED, operands[3])) | |
584 | return "; G14 udivsi macro %0 = %1 / %2 \n\ | |
585 | movw ax, %h1 \n\ | |
586 | movw bc, %H1 \n\ | |
587 | movw de, %h2 \n\ | |
588 | movw hl, %H2 \n\ | |
589 | push psw ; Save the current interrupt status \n\ | |
590 | di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ | |
591 | divwu ; bcax = bcax / hlde \n\ | |
592 | pop psw ; Restore saved interrupt status \n\ | |
593 | movw %h0, ax \n\ | |
594 | movw ax, bc \n\ | |
595 | movw %H0, ax \n\ | |
596 | ; end of udivsi macro"; | |
597 | else if (find_reg_note (insn, REG_UNUSED, operands[0])) | |
598 | return "; G14 umodsi macro %3 = %1 %% %2 \n\ | |
599 | movw ax, %h1 \n\ | |
600 | movw bc, %H1 \n\ | |
601 | movw de, %h2 \n\ | |
602 | movw hl, %H2 \n\ | |
603 | push psw ; Save the current interrupt status \n\ | |
604 | di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ | |
605 | divwu ; hlde = bcax %% hlde \n\ | |
606 | pop psw ; Restore saved interrupt status \n\ | |
607 | movw ax, de \n\ | |
608 | movw %h3, ax \n\ | |
609 | movw ax, hl \n\ | |
610 | movw %H3, ax \n\ | |
611 | ; end of umodsi macro"; | |
612 | else | |
613 | return "; G14 udivmodsi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\ | |
614 | movw ax, %h1 \n\ | |
615 | movw bc, %H1 \n\ | |
616 | movw de, %h2 \n\ | |
617 | movw hl, %H2 \n\ | |
618 | push psw ; Save the current interrupt status \n\ | |
619 | di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ | |
620 | divwu ; bcax = bcax / hlde, hlde = bcax %% hlde \n\ | |
621 | pop psw ; Restore saved interrupt status \n\ | |
622 | movw %h0, ax \n\ | |
623 | movw ax, bc \n\ | |
624 | movw %H0, ax \n\ | |
625 | movw ax, de \n\ | |
626 | movw %h3, ax \n\ | |
627 | movw ax, hl \n\ | |
628 | movw %H3, ax \n\ | |
629 | ; end of udivmodsi macro"; | |
630 | } | |
631 | [(set_attr "valloc" "divsi")] | |
632 | ) | |
633 | ||
634 | ;; Warning: these values match the silicon not the documentation. | |
635 | ;; 0xFFFF0 is MDAL. 0xFFFF2 is MDAH. | |
636 | ;; 0xFFFF6 is MDBL. 0xFFFF4 is MDBH. | |
637 | ;; 0xF00E0 is MDCL. 0xF00E2 is MDCH. | |
638 | ;; 0xF00E8 is MDUC. | |
639 | ||
640 | (define_insn "udivmodsi4_g13" | |
641 | [(set (match_operand:SI 0 "register_operand" "=v") | |
642 | (udiv:SI (match_operand:SI 1 "register_operand" "v") | |
643 | (match_operand:SI 2 "register_operand" "v"))) | |
644 | (set (match_operand:SI 3 "register_operand" "=v") | |
645 | (umod:SI (match_dup 1) (match_dup 2))) | |
646 | (clobber (reg:HI AX_REG)) | |
647 | ] | |
648 | "RL78_MUL_G13" | |
649 | { | |
650 | if (find_reg_note (insn, REG_UNUSED, operands[3])) | |
651 | return "; G13 udivsi macro %0 = %1 / %2 \n\ | |
652 | mov a, #0xC0 ; Set DIVMODE=1 and MACMODE=1 \n\ | |
653 | mov !0xf00e8, a ; This preps the peripheral for division without interrupt generation \n\ | |
654 | movw ax, %H1 \n\ | |
655 | movw 0xffff2, ax ; MDAH \n\ | |
656 | movw ax, %h1 \n\ | |
657 | movw 0xffff0, ax ; MDAL \n\ | |
658 | movw ax, %H2 \n\ | |
659 | movw 0xffff4, ax ; MDBH \n\ | |
660 | movw ax, %h2 \n\ | |
661 | movw 0xffff6, ax ; MDBL \n\ | |
662 | mov a, #0xC1 ; Set the DIVST bit in MDUC \n\ | |
663 | mov !0xf00e8, a ; This starts the division op \n\ | |
664 | 1: mov a, !0xf00e8 ; Wait 16 clocks or until DIVST is clear \n\ | |
665 | bt a.0, $1b \n\ | |
666 | movw ax, 0xffff0 ; Read the quotient \n\ | |
667 | movw %h0, ax \n\ | |
668 | movw ax, 0xffff2 \n\ | |
669 | movw %H0, ax \n\ | |
670 | ; end of udivsi macro"; | |
671 | else if (find_reg_note (insn, REG_UNUSED, operands[0])) | |
672 | return "; G13 umodsi macro %3 = %1 %% %2 \n\ | |
673 | mov a, #0xC0 ; Set DIVMODE=1 and MACMODE=1 \n\ | |
674 | mov !0xf00e8, a ; This preps the peripheral for division without interrupt generation \n\ | |
675 | movw ax, %H1 \n\ | |
676 | movw 0xffff2, ax ; MDAH \n\ | |
677 | movw ax, %h1 \n\ | |
678 | movw 0xffff0, ax ; MDAL \n\ | |
679 | movw ax, %H2 \n\ | |
680 | movw 0xffff4, ax ; MDBH \n\ | |
681 | movw ax, %h2 \n\ | |
682 | movw 0xffff6, ax ; MDBL \n\ | |
683 | mov a, #0xC1 ; Set the DIVST bit in MDUC \n\ | |
684 | mov !0xf00e8, a ; This starts the division op \n\ | |
685 | 1: mov a, !0xf00e8 ; Wait 16 clocks or until DIVST is clear \n\ | |
686 | bt a.0, $1b \n\ | |
687 | movw ax, !0xf00e0 ; Read the remainder \n\ | |
688 | movw %h3, ax \n\ | |
689 | movw ax, !0xf00e2 \n\ | |
690 | movw %H3, ax \n\ | |
691 | ; end of umodsi macro"; | |
692 | else | |
693 | return "; G13 udivmodsi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\ | |
694 | mov a, #0xC0 ; Set DIVMODE=1 and MACMODE=1 \n\ | |
695 | mov !0xf00e8, a ; This preps the peripheral for division without interrupt generation \n\ | |
696 | movw ax, %H1 \n\ | |
697 | movw 0xffff2, ax ; MDAH \n\ | |
698 | movw ax, %h1 \n\ | |
699 | movw 0xffff0, ax ; MDAL \n\ | |
700 | movw ax, %H2 \n\ | |
701 | movw 0xffff4, ax ; MDBH \n\ | |
702 | movw ax, %h2 \n\ | |
703 | movw 0xffff6, ax ; MDBL \n\ | |
704 | mov a, #0xC1 ; Set the DIVST bit in MDUC \n\ | |
705 | mov !0xf00e8, a ; This starts the division op \n\ | |
706 | 1: mov a, !0xf00e8 ; Wait 16 clocks or until DIVST is clear \n\ | |
707 | bt a.0, $1b \n\ | |
708 | movw ax, 0xffff0 ; Read the quotient \n\ | |
709 | movw %h0, ax \n\ | |
710 | movw ax, 0xffff2 \n\ | |
711 | movw %H0, ax \n\ | |
712 | movw ax, !0xf00e0 ; Read the remainder \n\ | |
713 | movw %h3, ax \n\ | |
714 | movw ax, !0xf00e2 \n\ | |
715 | movw %H3, ax \n\ | |
716 | ; end of udivmodsi macro"; | |
717 | } | |
035b8879 KP |
718 | [(set_attr "valloc" "macax") |
719 | (set_attr "is_g13_muldiv_insn" "yes")] | |
72ed1126 | 720 | ) |
5dd16013 | 721 | |
10cd6ec5 SP |
722 | (define_expand "movdi" |
723 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
724 | (match_operand:DI 1 "general_operand" ""))] | |
725 | "" | |
726 | "rl78_split_movdi(operands, DImode); | |
727 | DONE;" | |
728 | ) | |
729 | ||
65e3761d SP |
730 | (define_expand "movdf" |
731 | [(set (match_operand:DF 0 "nonimmediate_operand" "") | |
732 | (match_operand:DF 1 "general_operand" ""))] | |
733 | "" | |
734 | "rl78_split_movdi(operands, DFmode); | |
735 | DONE;" | |
736 | ) | |
737 | ||
99cc06ea SP |
738 | (define_expand "umindi3" |
739 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
740 | (umin:DI (match_operand:DI 1 "general_operand" "") | |
741 | (match_operand:DI 2 "general_operand" ""))) | |
742 | ] | |
743 | "optimize_size" | |
744 | "rl78_emit_libcall (\"__umindi3\", UMIN, DImode, DImode, 3, operands); | |
745 | DONE;" | |
746 | ) | |
747 | ||
5dd16013 SP |
748 | (define_expand "umaxdi3" |
749 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
750 | (umax:DI (match_operand:DI 1 "general_operand" "") | |
751 | (match_operand:DI 2 "general_operand" ""))) | |
752 | ] | |
753 | "optimize_size" | |
754 | "rl78_emit_libcall (\"__umaxdi3\", UMAX, DImode, DImode, 3, operands); | |
755 | DONE;" | |
756 | ) | |
d975e494 | 757 | |
6e9007a0 SP |
758 | (define_expand "smindi3" |
759 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
760 | (smin:DI (match_operand:DI 1 "general_operand" "") | |
761 | (match_operand:DI 2 "general_operand" ""))) | |
762 | ] | |
763 | "optimize_size" | |
764 | "rl78_emit_libcall (\"__smindi3\", SMIN, DImode, DImode, 3, operands); | |
765 | DONE;" | |
766 | ) | |
767 | ||
d975e494 SP |
768 | (define_expand "smaxdi3" |
769 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
770 | (smax:DI (match_operand:DI 1 "general_operand" "") | |
771 | (match_operand:DI 2 "general_operand" ""))) | |
772 | ] | |
773 | "optimize_size" | |
774 | "rl78_emit_libcall (\"__smaxdi3\", SMAX, DImode, DImode, 3, operands); | |
775 | DONE;" | |
776 | ) | |
bc8b0d04 SP |
777 | |
778 | (define_expand "anddi3" | |
779 | [(set (match_operand:DI 0 "nonimmediate_operand" "") | |
780 | (and:DI (match_operand:DI 1 "general_operand" "") | |
781 | (match_operand:DI 2 "general_operand" ""))) | |
782 | ] | |
783 | "optimize_size" | |
784 | "rl78_emit_libcall (\"__anddi3\", AND, DImode, DImode, 3, operands); | |
785 | DONE;" | |
786 | ) |