]>
Commit | Line | Data |
---|---|---|
7857f134 | 1 | /* libgcc routines for M68HC11 & M68HC12. |
01beec65 | 2 | Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. |
385c9217 SC |
3 | |
4 | This file is part of GNU CC. | |
5 | ||
6 | GNU CC is free software; you can redistribute it and/or modify it | |
7 | under the terms of the GNU General Public License as published by the | |
8 | Free Software Foundation; either version 2, or (at your option) any | |
9 | later version. | |
10 | ||
11 | In addition to the permissions in the GNU General Public License, the | |
12 | Free Software Foundation gives you unlimited permission to link the | |
13 | compiled version of this file with other programs, and to distribute | |
14 | those programs without any restriction coming from the use of this | |
15 | file. (The General Public License restrictions do apply in other | |
16 | respects; for example, they cover modification of the file, and | |
17 | distribution when not linked into another program.) | |
18 | ||
19 | This file is distributed in the hope that it will be useful, but | |
20 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
22 | General Public License for more details. | |
23 | ||
24 | You should have received a copy of the GNU General Public License | |
25 | along with this program; see the file COPYING. If not, write to | |
26 | the Free Software Foundation, 59 Temple Place - Suite 330, | |
27 | Boston, MA 02111-1307, USA. */ | |
28 | ||
29 | /* As a special exception, if you link this library with other files, | |
30 | some of which are compiled with GCC, to produce an executable, | |
31 | this library does not by itself cause the resulting executable | |
32 | to be covered by the GNU General Public License. | |
33 | This exception does not however invalidate any other reasons why | |
34 | the executable file might be covered by the GNU General Public License. */ | |
35 | ||
36 | .file "larith.asm" | |
37 | ||
38 | .sect .text | |
39 | ||
40 | ||
41 | #define REG(NAME) \ | |
42 | NAME: .word 0; \ | |
43 | .type NAME,@object ; \ | |
44 | .size NAME,2 | |
45 | ||
46 | #ifdef L_regs_min | |
47 | /* Pseudo hard registers used by gcc. | |
48 | They must be located in page0. | |
49 | They will normally appear at the end of .page0 section. */ | |
01beec65 SC |
50 | #ifdef mc68hc12 |
51 | .sect .bss | |
52 | #else | |
385c9217 | 53 | .sect .page0 |
01beec65 | 54 | #endif |
c5c2ca16 | 55 | .globl _.tmp |
385c9217 SC |
56 | .globl _.z,_.xy |
57 | REG(_.tmp) | |
58 | REG(_.z) | |
59 | REG(_.xy) | |
385c9217 SC |
60 | |
61 | #endif | |
62 | ||
c5c2ca16 | 63 | #ifdef L_regs_frame |
01beec65 SC |
64 | #ifdef mc68hc12 |
65 | .sect .bss | |
66 | #else | |
385c9217 | 67 | .sect .page0 |
01beec65 | 68 | #endif |
c5c2ca16 SC |
69 | .globl _.frame |
70 | REG(_.frame) | |
71 | #endif | |
72 | ||
73 | #ifdef L_regs_d1_2 | |
74 | #ifdef mc68hc12 | |
75 | .sect .bss | |
76 | #else | |
77 | .sect .page0 | |
78 | #endif | |
79 | .globl _.d1,_.d2 | |
385c9217 SC |
80 | REG(_.d1) |
81 | REG(_.d2) | |
c5c2ca16 SC |
82 | #endif |
83 | ||
84 | #ifdef L_regs_d3_4 | |
85 | #ifdef mc68hc12 | |
86 | .sect .bss | |
87 | #else | |
88 | .sect .page0 | |
89 | #endif | |
90 | .globl _.d3,_.d4 | |
385c9217 SC |
91 | REG(_.d3) |
92 | REG(_.d4) | |
c5c2ca16 SC |
93 | #endif |
94 | ||
95 | #ifdef L_regs_d5_6 | |
96 | #ifdef mc68hc12 | |
97 | .sect .bss | |
98 | #else | |
99 | .sect .page0 | |
100 | #endif | |
101 | .globl _.d5,_.d6 | |
385c9217 SC |
102 | REG(_.d5) |
103 | REG(_.d6) | |
c5c2ca16 SC |
104 | #endif |
105 | ||
106 | #ifdef L_regs_d7_8 | |
107 | #ifdef mc68hc12 | |
108 | .sect .bss | |
109 | #else | |
110 | .sect .page0 | |
111 | #endif | |
112 | .globl _.d7,_.d8 | |
385c9217 SC |
113 | REG(_.d7) |
114 | REG(_.d8) | |
385c9217 SC |
115 | #endif |
116 | ||
c5c2ca16 | 117 | #ifdef L_regs_d9_16 |
385c9217 SC |
118 | /* Pseudo hard registers used by gcc. |
119 | They must be located in page0. | |
120 | They will normally appear at the end of .page0 section. */ | |
121 | .sect .page0 | |
122 | .globl _.d9,_.d10,_.d11,_.d12,_.d13,_.d14 | |
123 | .globl _.d15,_.d16 | |
124 | REG(_.d9) | |
125 | REG(_.d10) | |
126 | REG(_.d11) | |
127 | REG(_.d12) | |
128 | REG(_.d13) | |
129 | REG(_.d14) | |
130 | REG(_.d15) | |
131 | REG(_.d16) | |
132 | ||
133 | #endif | |
134 | ||
135 | #ifdef L_regs_d17_32 | |
136 | /* Pseudo hard registers used by gcc. | |
137 | They must be located in page0. | |
138 | They will normally appear at the end of .page0 section. */ | |
01beec65 SC |
139 | #ifdef mc68hc12 |
140 | .sect .bss | |
141 | #else | |
385c9217 | 142 | .sect .page0 |
01beec65 | 143 | #endif |
385c9217 SC |
144 | .globl _.d17,_.d18,_.d19,_.d20,_.d21,_.d22 |
145 | .globl _.d23,_.d24,_.d25,_.d26,_.d27,_.d28 | |
146 | .globl _.d29,_.d30,_.d31,_.d32 | |
147 | REG(_.d17) | |
148 | REG(_.d18) | |
149 | REG(_.d19) | |
150 | REG(_.d20) | |
151 | REG(_.d21) | |
152 | REG(_.d22) | |
153 | REG(_.d23) | |
154 | REG(_.d24) | |
155 | REG(_.d25) | |
156 | REG(_.d26) | |
157 | REG(_.d27) | |
158 | REG(_.d28) | |
159 | REG(_.d29) | |
160 | REG(_.d30) | |
161 | REG(_.d31) | |
162 | REG(_.d32) | |
163 | #endif | |
164 | ||
165 | #ifdef L_premain | |
166 | ;; | |
167 | ;; Specific initialization for 68hc11 before the main. | |
168 | ;; Nothing special for a generic routine; Just enable interrupts. | |
169 | ;; | |
170 | .sect .text | |
171 | .globl __premain | |
172 | __premain: | |
173 | clra | |
174 | tap ; Clear both I and X. | |
175 | rts | |
176 | #endif | |
177 | ||
178 | #ifdef L__exit | |
179 | ;; | |
180 | ;; Exit operation. Just loop forever and wait for interrupts. | |
181 | ;; (no other place to go) | |
182 | ;; | |
183 | .sect .text | |
184 | .globl _exit | |
185 | .globl exit | |
186 | .weak exit | |
187 | exit: | |
188 | _exit: | |
189 | fatal: | |
190 | cli | |
191 | wai | |
192 | bra fatal | |
193 | #endif | |
194 | ||
195 | #ifdef L_abort | |
196 | ;; | |
197 | ;; Abort operation. This is defined for the GCC testsuite. | |
198 | ;; | |
199 | .sect .text | |
200 | .globl abort | |
201 | abort: | |
202 | ldd #255 ; | |
01beec65 SC |
203 | #ifdef mc68hc12 |
204 | trap #0x30 | |
205 | #else | |
385c9217 SC |
206 | .byte 0xCD ; Generate an illegal instruction trap |
207 | .byte 0x03 ; The simulator catches this and stops. | |
01beec65 | 208 | #endif |
385c9217 SC |
209 | jmp _exit |
210 | #endif | |
211 | ||
212 | #ifdef L_cleanup | |
213 | ;; | |
214 | ;; Cleanup operation used by exit(). | |
215 | ;; | |
216 | .sect .text | |
217 | .globl _cleanup | |
218 | _cleanup: | |
219 | rts | |
220 | #endif | |
221 | ||
222 | ;----------------------------------------- | |
223 | ; required gcclib code | |
224 | ;----------------------------------------- | |
225 | #ifdef L_memcpy | |
226 | .sect .text | |
227 | .weak memcpy | |
228 | .globl memcpy | |
229 | .globl __memcpy | |
230 | ;;; | |
231 | ;;; void* memcpy(void*, const void*, size_t) | |
232 | ;;; | |
233 | ;;; D = dst Pmode | |
234 | ;;; 2,sp = src Pmode | |
235 | ;;; 4,sp = size HImode (size_t) | |
236 | ;;; | |
237 | __memcpy: | |
238 | memcpy: | |
01beec65 SC |
239 | #ifdef mc68hc12 |
240 | ldx 2,sp | |
241 | ldy 4,sp | |
242 | pshd | |
243 | xgdy | |
244 | lsrd | |
245 | bcc Start | |
246 | movb 1,x+,1,y+ | |
247 | Start: | |
248 | beq Done | |
249 | Loop: | |
250 | movw 2,x+,2,y+ | |
251 | dbne d,Loop | |
252 | Done: | |
253 | puld | |
254 | rts | |
255 | #else | |
385c9217 SC |
256 | xgdy |
257 | tsx | |
258 | ldd 4,x | |
259 | ldx 2,x ; SRC = X, DST = Y | |
260 | cpd #0 | |
261 | beq End | |
262 | pshy | |
263 | inca ; Correction for the deca below | |
264 | L0: | |
265 | psha ; Save high-counter part | |
266 | L1: | |
267 | ldaa 0,x ; Copy up to 256 bytes | |
268 | staa 0,y | |
269 | inx | |
270 | iny | |
271 | decb | |
272 | bne L1 | |
273 | pula | |
274 | deca | |
275 | bne L0 | |
276 | puly ; Restore Y to return the DST | |
277 | End: | |
278 | xgdy | |
279 | rts | |
280 | #endif | |
01beec65 | 281 | #endif |
385c9217 SC |
282 | |
283 | #ifdef L_memset | |
284 | .sect .text | |
285 | .globl memset | |
286 | .globl __memset | |
287 | ;;; | |
288 | ;;; void* memset(void*, int value, size_t) | |
289 | ;;; | |
290 | #ifndef __HAVE_SHORT_INT__ | |
291 | ;;; D = dst Pmode | |
292 | ;;; 2,sp = src SImode | |
293 | ;;; 6,sp = size HImode (size_t) | |
294 | val = 5 | |
295 | size = 6 | |
296 | #else | |
297 | ;;; D = dst Pmode | |
298 | ;;; 2,sp = src SImode | |
299 | ;;; 6,sp = size HImode (size_t) | |
300 | val = 3 | |
301 | size = 4 | |
302 | #endif | |
303 | __memset: | |
304 | memset: | |
01beec65 SC |
305 | #ifdef mc68hc12 |
306 | xgdx | |
307 | ldab val,sp | |
308 | ldy size,sp | |
309 | pshx | |
310 | beq End | |
311 | Loop: | |
312 | stab 1,x+ | |
313 | dbne y,Loop | |
314 | End: | |
315 | puld | |
316 | rts | |
317 | #else | |
385c9217 SC |
318 | xgdx |
319 | tsy | |
320 | ldab val,y | |
321 | ldy size,y ; DST = X, CNT = Y | |
322 | beq End | |
323 | pshx | |
324 | L0: | |
325 | stab 0,x ; Fill up to 256 bytes | |
326 | inx | |
327 | dey | |
328 | bne L0 | |
329 | pulx ; Restore X to return the DST | |
330 | End: | |
331 | xgdx | |
332 | rts | |
333 | #endif | |
01beec65 | 334 | #endif |
385c9217 SC |
335 | |
336 | #ifdef L_adddi3 | |
337 | .sect .text | |
338 | .globl ___adddi3 | |
339 | ||
340 | ___adddi3: | |
341 | tsx | |
385c9217 SC |
342 | pshb |
343 | psha | |
344 | ldd 8,x | |
01beec65 | 345 | addd 16,x |
385c9217 SC |
346 | pshb |
347 | psha | |
348 | ||
349 | ldd 6,x | |
01beec65 SC |
350 | adcb 15,x |
351 | adca 14,x | |
385c9217 SC |
352 | pshb |
353 | psha | |
354 | ||
355 | ldd 4,x | |
01beec65 SC |
356 | adcb 13,x |
357 | adca 12,x | |
385c9217 SC |
358 | pshb |
359 | psha | |
360 | ||
361 | ldd 2,x | |
01beec65 SC |
362 | adcb 11,x |
363 | adca 10,x | |
385c9217 SC |
364 | tsx |
365 | ldy 6,x | |
366 | ||
367 | std 0,y | |
368 | pulx | |
369 | stx 2,y | |
370 | pulx | |
371 | stx 4,y | |
372 | pulx | |
373 | stx 6,y | |
374 | pulx | |
375 | rts | |
376 | #endif | |
377 | ||
378 | #ifdef L_subdi3 | |
379 | .sect .text | |
380 | .globl ___subdi3 | |
381 | ||
382 | ___subdi3: | |
383 | tsx | |
385c9217 SC |
384 | pshb |
385 | psha | |
386 | ldd 8,x | |
01beec65 | 387 | subd 16,x |
385c9217 SC |
388 | pshb |
389 | psha | |
390 | ||
391 | ldd 6,x | |
01beec65 SC |
392 | sbcb 15,x |
393 | sbca 14,x | |
385c9217 SC |
394 | pshb |
395 | psha | |
396 | ||
397 | ldd 4,x | |
01beec65 SC |
398 | sbcb 13,x |
399 | sbca 12,x | |
385c9217 SC |
400 | pshb |
401 | psha | |
402 | ||
403 | ldd 2,x | |
01beec65 SC |
404 | sbcb 11,x |
405 | sbca 10,x | |
385c9217 SC |
406 | |
407 | tsx | |
408 | ldy 6,x | |
409 | ||
410 | std 0,y | |
411 | pulx | |
412 | stx 2,y | |
413 | pulx | |
414 | stx 4,y | |
415 | pulx | |
416 | stx 6,y | |
417 | pulx | |
418 | rts | |
419 | #endif | |
420 | ||
421 | #ifdef L_notdi2 | |
422 | .sect .text | |
423 | .globl ___notdi2 | |
424 | ||
425 | ___notdi2: | |
426 | tsy | |
427 | xgdx | |
428 | ldd 8,y | |
429 | coma | |
430 | comb | |
431 | std 6,x | |
432 | ||
433 | ldd 6,y | |
434 | coma | |
435 | comb | |
436 | std 4,x | |
437 | ||
438 | ldd 4,y | |
439 | coma | |
440 | comb | |
441 | std 2,x | |
442 | ||
443 | ldd 2,y | |
444 | coma | |
445 | comb | |
446 | std 0,x | |
447 | rts | |
448 | #endif | |
449 | ||
450 | #ifdef L_negsi2 | |
451 | .sect .text | |
452 | .globl ___negsi2 | |
453 | ||
454 | ___negsi2: | |
455 | comb | |
456 | coma | |
457 | addd #1 | |
458 | xgdx | |
459 | eorb #0xFF | |
460 | eora #0xFF | |
461 | adcb #0 | |
462 | adca #0 | |
463 | xgdx | |
464 | rts | |
465 | #endif | |
466 | ||
467 | #ifdef L_one_cmplsi2 | |
468 | .sect .text | |
469 | .globl ___one_cmplsi2 | |
470 | ||
471 | ___one_cmplsi2: | |
472 | comb | |
473 | coma | |
474 | xgdx | |
475 | comb | |
476 | coma | |
477 | xgdx | |
478 | rts | |
479 | #endif | |
480 | ||
481 | #ifdef L_ashlsi3 | |
482 | .sect .text | |
483 | .globl ___ashlsi3 | |
484 | ||
485 | ___ashlsi3: | |
486 | xgdy | |
487 | clra | |
488 | andb #0x1f | |
489 | xgdy | |
490 | beq Return | |
491 | Loop: | |
492 | lsld | |
493 | xgdx | |
494 | rolb | |
495 | rola | |
496 | xgdx | |
497 | dey | |
498 | bne Loop | |
499 | Return: | |
500 | rts | |
501 | #endif | |
502 | ||
503 | #ifdef L_ashrsi3 | |
504 | .sect .text | |
505 | .globl ___ashrsi3 | |
506 | ||
507 | ___ashrsi3: | |
508 | xgdy | |
509 | clra | |
510 | andb #0x1f | |
511 | xgdy | |
512 | beq Return | |
513 | Loop: | |
514 | xgdx | |
515 | asra | |
516 | rorb | |
517 | xgdx | |
518 | rora | |
519 | rorb | |
520 | dey | |
521 | bne Loop | |
522 | Return: | |
523 | rts | |
524 | #endif | |
525 | ||
526 | #ifdef L_lshrsi3 | |
527 | .sect .text | |
528 | .globl ___lshrsi3 | |
529 | ||
530 | ___lshrsi3: | |
531 | xgdy | |
532 | clra | |
533 | andb #0x1f | |
534 | xgdy | |
535 | beq Return | |
536 | Loop: | |
537 | xgdx | |
538 | lsrd | |
539 | xgdx | |
540 | rora | |
541 | rorb | |
542 | dey | |
543 | bne Loop | |
544 | Return: | |
545 | rts | |
546 | #endif | |
547 | ||
548 | #ifdef L_lshrhi3 | |
549 | .sect .text | |
550 | .globl ___lshrhi3 | |
551 | ||
552 | ___lshrhi3: | |
553 | cpx #16 | |
554 | bge Return_zero | |
555 | cpx #0 | |
556 | beq Return | |
557 | Loop: | |
558 | lsrd | |
559 | dex | |
560 | bne Loop | |
561 | Return: | |
562 | rts | |
563 | Return_zero: | |
564 | clra | |
565 | clrb | |
566 | rts | |
567 | #endif | |
568 | ||
569 | #ifdef L_lshlhi3 | |
570 | .sect .text | |
571 | .globl ___lshlhi3 | |
572 | ||
573 | ___lshlhi3: | |
574 | cpx #16 | |
575 | bge Return_zero | |
576 | cpx #0 | |
577 | beq Return | |
578 | Loop: | |
579 | lsld | |
580 | dex | |
581 | bne Loop | |
582 | Return: | |
583 | rts | |
584 | Return_zero: | |
585 | clra | |
586 | clrb | |
587 | rts | |
588 | #endif | |
589 | ||
590 | #ifdef L_ashrhi3 | |
591 | .sect .text | |
592 | .globl ___ashrhi3 | |
593 | ||
594 | ___ashrhi3: | |
595 | cpx #16 | |
596 | bge Return_minus_1_or_zero | |
597 | cpx #0 | |
598 | beq Return | |
599 | Loop: | |
600 | asra | |
601 | rorb | |
602 | dex | |
603 | bne Loop | |
604 | Return: | |
605 | rts | |
606 | Return_minus_1_or_zero: | |
607 | clrb | |
608 | tsta | |
609 | bpl Return_zero | |
610 | comb | |
611 | Return_zero: | |
612 | tba | |
613 | rts | |
614 | #endif | |
615 | ||
616 | #ifdef L_ashrqi3 | |
617 | .sect .text | |
618 | .globl ___ashrqi3 | |
619 | ||
620 | ___ashrqi3: | |
621 | cmpa #8 | |
622 | bge Return_minus_1_or_zero | |
623 | tsta | |
624 | beq Return | |
625 | Loop: | |
626 | asrb | |
627 | deca | |
628 | bne Loop | |
629 | Return: | |
630 | rts | |
631 | Return_minus_1_or_zero: | |
632 | clrb | |
633 | tstb | |
634 | bpl Return_zero | |
635 | coma | |
636 | Return_zero: | |
637 | tab | |
638 | rts | |
639 | #endif | |
640 | ||
641 | #ifdef L_lshlqi3 | |
642 | .sect .text | |
643 | .globl ___lshlqi3 | |
644 | ||
645 | ___lshlqi3: | |
646 | cmpa #8 | |
647 | bge Return_zero | |
648 | tsta | |
649 | beq Return | |
650 | Loop: | |
651 | lslb | |
652 | deca | |
653 | bne Loop | |
654 | Return: | |
655 | rts | |
656 | Return_zero: | |
657 | clrb | |
658 | rts | |
659 | #endif | |
660 | ||
661 | #ifdef L_divmodhi4 | |
3d0746ba SC |
662 | #ifndef mc68hc12 |
663 | /* 68HC12 signed divisions are generated inline (idivs). */ | |
664 | ||
385c9217 SC |
665 | .sect .text |
666 | .globl __divmodhi4 | |
667 | ||
668 | ; | |
669 | ;; D = numerator | |
670 | ;; X = denominator | |
671 | ;; | |
672 | ;; Result: D = D / X | |
673 | ;; X = D % X | |
674 | ;; | |
675 | __divmodhi4: | |
676 | tsta | |
677 | bpl Numerator_pos | |
678 | comb ; D = -D <=> D = (~D) + 1 | |
679 | coma | |
680 | xgdx | |
681 | inx | |
682 | tsta | |
683 | bpl Numerator_neg_denominator_pos | |
684 | Numerator_neg_denominator_neg: | |
685 | comb ; X = -X | |
686 | coma | |
687 | addd #1 | |
688 | xgdx | |
689 | idiv | |
690 | coma | |
691 | comb | |
692 | xgdx ; Remainder <= 0 and result >= 0 | |
693 | inx | |
694 | rts | |
695 | ||
696 | Numerator_pos_denominator_pos: | |
697 | xgdx | |
698 | idiv | |
699 | xgdx ; Both values are >= 0 | |
700 | rts | |
701 | ||
702 | Numerator_pos: | |
703 | xgdx | |
704 | tsta | |
705 | bpl Numerator_pos_denominator_pos | |
706 | Numerator_pos_denominator_neg: | |
707 | coma ; X = -X | |
708 | comb | |
709 | xgdx | |
710 | inx | |
711 | idiv | |
712 | xgdx ; Remainder >= 0 but result <= 0 | |
713 | coma | |
714 | comb | |
715 | addd #1 | |
716 | rts | |
717 | ||
718 | Numerator_neg_denominator_pos: | |
719 | xgdx | |
720 | idiv | |
721 | coma ; One value is > 0 and the other < 0 | |
722 | comb ; Change the sign of result and remainder | |
723 | xgdx | |
724 | inx | |
725 | coma | |
726 | comb | |
727 | addd #1 | |
728 | rts | |
3d0746ba | 729 | #endif /* !mc68hc12 */ |
385c9217 SC |
730 | #endif |
731 | ||
732 | #ifdef L_mulqi3 | |
733 | .sect .text | |
734 | .globl __mulqi3 | |
735 | ||
736 | ; | |
737 | ; short __mulqi3(signed char a, signed char b); | |
738 | ; | |
739 | ; signed char a -> register A | |
740 | ; signed char b -> register B | |
741 | ; | |
742 | ; returns the signed result of A * B in register D. | |
743 | ; | |
744 | __mulqi3: | |
745 | tsta | |
746 | bmi A_neg | |
747 | tstb | |
748 | bmi B_neg | |
749 | mul | |
750 | rts | |
751 | B_neg: | |
752 | negb | |
753 | bra A_or_B_neg | |
754 | A_neg: | |
755 | nega | |
756 | tstb | |
757 | bmi AB_neg | |
758 | A_or_B_neg: | |
759 | mul | |
760 | coma | |
761 | comb | |
762 | addd #1 | |
763 | rts | |
764 | AB_neg: | |
385c9217 SC |
765 | negb |
766 | mul | |
767 | rts | |
768 | #endif | |
769 | ||
770 | #ifdef L_mulhi3 | |
771 | .sect .text | |
772 | .globl ___mulhi3 | |
773 | ||
774 | ; | |
775 | ; | |
776 | ; unsigned short ___mulhi3(unsigned short a, unsigned short b) | |
777 | ; | |
778 | ; a = register D | |
779 | ; b = register X | |
780 | ; | |
781 | ___mulhi3: | |
01beec65 SC |
782 | #ifdef mc68hc12 |
783 | pshx ; Preserve X | |
784 | exg x,y | |
785 | emul | |
786 | exg x,y | |
787 | pulx | |
788 | #else | |
385c9217 SC |
789 | stx *_.tmp |
790 | pshb | |
791 | ldab *_.tmp+1 | |
792 | mul ; A.high * B.low | |
793 | ldaa *_.tmp | |
794 | stab *_.tmp | |
795 | pulb | |
796 | pshb | |
797 | mul ; A.low * B.high | |
798 | addb *_.tmp | |
799 | stab *_.tmp | |
800 | ldaa *_.tmp+1 | |
801 | pulb | |
802 | mul ; A.low * B.low | |
803 | adda *_.tmp | |
01beec65 | 804 | #endif |
385c9217 SC |
805 | rts |
806 | #endif | |
807 | ||
808 | #ifdef L_mulhi32 | |
809 | .sect .text | |
810 | .globl __mulhi32 | |
811 | ||
812 | ; | |
813 | ; | |
814 | ; unsigned long __mulhi32(unsigned short a, unsigned short b) | |
815 | ; | |
816 | ; a = register D | |
817 | ; b = value on stack | |
818 | ; | |
819 | ; +---------------+ | |
820 | ; | B low | <- 5,x | |
821 | ; +---------------+ | |
822 | ; | B high | <- 4,x | |
823 | ; +---------------+ | |
824 | ; | PC low | | |
825 | ; +---------------+ | |
826 | ; | PC high | | |
827 | ; +---------------+ | |
828 | ; | A low | | |
829 | ; +---------------+ | |
830 | ; | A high | | |
831 | ; +---------------+ <- 0,x | |
832 | ; | |
833 | ; | |
834 | ; <B-low> 5,x | |
835 | ; <B-high> 4,x | |
836 | ; <ret> 2,x | |
837 | ; <A-low> 1,x | |
838 | ; <A-high> 0,x | |
839 | ; | |
840 | __mulhi32: | |
01beec65 SC |
841 | #ifdef mc68hc12 |
842 | ldy 2,sp | |
843 | emul | |
844 | exg x,y | |
845 | #else | |
385c9217 SC |
846 | pshb |
847 | psha | |
848 | tsx | |
849 | ldab 4,x | |
850 | mul | |
851 | xgdy ; A.high * B.high | |
852 | ldab 5,x | |
853 | pula | |
854 | mul ; A.high * B.low | |
855 | std *_.tmp | |
856 | ldaa 1,x | |
857 | ldab 4,x | |
858 | mul ; A.low * B.high | |
859 | addd *_.tmp | |
860 | stab *_.tmp | |
861 | tab | |
862 | aby | |
863 | bcc N | |
864 | ldab #0xff | |
865 | aby | |
866 | iny | |
867 | N: | |
868 | ldab 5,x | |
869 | pula | |
870 | mul ; A.low * B.low | |
871 | adda *_.tmp | |
872 | bcc Ret | |
873 | iny | |
874 | Ret: | |
875 | pshy | |
876 | pulx | |
01beec65 | 877 | #endif |
385c9217 SC |
878 | rts |
879 | ||
880 | #endif | |
881 | ||
882 | #ifdef L_mulsi3 | |
883 | .sect .text | |
884 | .globl __mulsi3 | |
885 | ||
886 | ; | |
887 | ; <B-low> 8,y | |
888 | ; <B-high> 6,y | |
889 | ; <ret> 4,y | |
890 | ; <tmp> 2,y | |
891 | ; <A-low> 0,y | |
892 | ; | |
893 | ; D,X -> A | |
894 | ; Stack -> B | |
895 | ; | |
896 | ; The result is: | |
897 | ; | |
898 | ; (((A.low * B.high) + (A.high * B.low)) << 16) + (A.low * B.low) | |
899 | ; | |
900 | ; | |
901 | ; | |
902 | ||
3d0746ba SC |
903 | __mulsi3: |
904 | #ifdef mc68hc12 | |
905 | pshd ; Save A.low | |
906 | ldy 4,sp | |
907 | emul ; A.low * B.high | |
908 | ldy 6,sp | |
909 | exg x,d | |
910 | emul ; A.high * B.low | |
911 | leax d,x | |
912 | ldy 6,sp | |
913 | puld | |
914 | emul ; A.low * B.low | |
915 | exg d,y | |
916 | leax d,x | |
917 | exg d,y | |
918 | rts | |
919 | #else | |
385c9217 SC |
920 | B_low = 8 |
921 | B_high = 6 | |
922 | A_low = 0 | |
923 | A_high = 2 | |
385c9217 SC |
924 | pshx |
925 | pshb | |
926 | psha | |
927 | tsy | |
928 | ; | |
929 | ; If B.low is 0, optimize into: (A.low * B.high) << 16 | |
930 | ; | |
931 | ldd B_low,y | |
932 | beq B_low_zero | |
933 | ; | |
934 | ; If A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low) | |
935 | ; | |
936 | stx *_.tmp | |
937 | beq A_high_zero | |
938 | bsr ___mulhi3 ; A.high * B.low | |
939 | ; | |
940 | ; If A.low is 0, optimize into: (A.high * B.low) << 16 | |
941 | ; | |
942 | ldx A_low,y | |
943 | beq A_low_zero ; X = 0, D = A.high * B.low | |
944 | std 2,y | |
945 | ; | |
946 | ; If B.high is 0, we can avoid the (A.low * B.high) << 16 term. | |
947 | ; | |
948 | ldd B_high,y | |
949 | beq B_high_zero | |
950 | bsr ___mulhi3 ; A.low * B.high | |
951 | addd 2,y | |
952 | std 2,y | |
953 | ; | |
954 | ; Here, we know that A.low and B.low are not 0. | |
955 | ; | |
956 | B_high_zero: | |
957 | ldd B_low,y ; A.low is on the stack | |
958 | bsr __mulhi32 ; A.low * B.low | |
959 | xgdx | |
960 | tsy ; Y was clobbered, get it back | |
961 | addd 2,y | |
962 | A_low_zero: ; See A_low_zero_non_optimized below | |
963 | xgdx | |
964 | Return: | |
965 | ins | |
966 | ins | |
967 | ins | |
968 | ins | |
969 | rts | |
970 | ; | |
971 | ; | |
972 | ; A_low_zero_non_optimized: | |
973 | ; | |
974 | ; At this step, X = 0 and D = (A.high * B.low) | |
975 | ; Optimize into: (A.high * B.low) << 16 | |
976 | ; | |
977 | ; xgdx | |
978 | ; clra ; Since X was 0, clearing D is superfuous. | |
979 | ; clrb | |
980 | ; bra Return | |
981 | ; ---------------- | |
982 | ; B.low == 0, the result is: (A.low * B.high) << 16 | |
983 | ; | |
984 | ; At this step: | |
985 | ; D = B.low = 0 | |
986 | ; X = A.high ? | |
987 | ; A.low is at A_low,y ? | |
988 | ; B.low is at B_low,y ? | |
989 | ; | |
990 | B_low_zero: | |
991 | ldd A_low,y | |
992 | beq Zero1 | |
993 | ldx B_high,y | |
994 | beq Zero2 | |
995 | bsr ___mulhi3 | |
996 | Zero1: | |
997 | xgdx | |
998 | Zero2: | |
999 | clra | |
1000 | clrb | |
1001 | bra Return | |
1002 | ; ---------------- | |
1003 | ; A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low) | |
1004 | ; | |
1005 | ; At this step: | |
1006 | ; D = B.low != 0 | |
1007 | ; X = A.high = 0 | |
1008 | ; A.low is at A_low,y ? | |
1009 | ; B.low is at B_low,y ? | |
1010 | ; | |
1011 | A_high_zero: | |
1012 | ldd A_low,y ; A.low | |
1013 | beq Zero1 | |
1014 | ldx B_high,y ; B.high | |
1015 | beq A_low_B_low | |
1016 | bsr ___mulhi3 | |
1017 | std 2,y | |
1018 | bra B_high_zero ; Do the (A.low * B.low) and the add. | |
1019 | ||
1020 | ; ---------------- | |
1021 | ; A.high and B.high are 0 optimize into: (A.low * B.low) | |
1022 | ; | |
1023 | ; At this step: | |
1024 | ; D = B.high = 0 | |
1025 | ; X = A.low != 0 | |
1026 | ; A.low is at A_low,y != 0 | |
1027 | ; B.high is at B_high,y = 0 | |
1028 | ; | |
1029 | A_low_B_low: | |
1030 | ldd B_low,y ; A.low is on the stack | |
1031 | bsr __mulhi32 | |
1032 | bra Return | |
1033 | #endif | |
3d0746ba | 1034 | #endif |
385c9217 SC |
1035 | |
1036 | #ifdef L_map_data | |
1037 | ||
1038 | .sect .install3,"ax",@progbits | |
1039 | .globl __map_data_section | |
1040 | ||
1041 | __map_data_section: | |
1042 | ldd #__data_section_size | |
1043 | beq Done | |
1044 | ldx #__data_image | |
1045 | ldy #__data_section_start | |
1046 | Loop: | |
01beec65 SC |
1047 | #ifdef mc68hc12 |
1048 | movb 1,x+,1,y+ | |
1049 | dbne d,Loop | |
1050 | #else | |
385c9217 SC |
1051 | psha |
1052 | ldaa 0,x | |
1053 | staa 0,y | |
1054 | pula | |
1055 | inx | |
1056 | iny | |
1057 | subd #1 | |
1058 | bne Loop | |
01beec65 | 1059 | #endif |
385c9217 SC |
1060 | Done: |
1061 | ||
1062 | #endif | |
1063 | ||
1064 | #ifdef L_init_bss | |
1065 | ||
1066 | .sect .install3,"ax",@progbits | |
1067 | .globl __init_bss_section | |
1068 | ||
1069 | __init_bss_section: | |
1070 | ldd #__bss_size | |
1071 | beq Done | |
1072 | ldx #__bss_start | |
1073 | Loop: | |
01beec65 SC |
1074 | #ifdef mc68hc12 |
1075 | clr 1,x+ | |
1076 | dbne d,Loop | |
1077 | #else | |
385c9217 SC |
1078 | clr 0,x |
1079 | inx | |
1080 | subd #1 | |
1081 | bne Loop | |
01beec65 | 1082 | #endif |
385c9217 SC |
1083 | Done: |
1084 | ||
1085 | #endif | |
1086 | ||
1087 | ;----------------------------------------- | |
1088 | ; end required gcclib code | |
1089 | ;----------------------------------------- |