OSDN Git Service

* config/m68hc11/larith.asm (__map_data_section): Fix condition
[pf3gnuchains/gcc-fork.git] / gcc / config / m68hc11 / larith.asm
1 /* libgcc routines for M68HC11 & M68HC12.
2    Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
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.  */
50 #ifdef mc68hc12
51         .sect .bss
52 #else
53         .sect .page0
54 #endif
55         .globl _.tmp
56         .globl _.z,_.xy
57 REG(_.tmp)
58 REG(_.z)
59 REG(_.xy)
60
61 #endif
62
63 #ifdef L_regs_frame
64 #ifdef mc68hc12
65         .sect .bss
66 #else
67         .sect .page0
68 #endif
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
80 REG(_.d1)
81 REG(_.d2)
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
91 REG(_.d3)
92 REG(_.d4)
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
102 REG(_.d5)
103 REG(_.d6)
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
113 REG(_.d7)
114 REG(_.d8)
115 #endif
116
117 #ifdef L_regs_d9_16
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.  */
139 #ifdef mc68hc12
140         .sect .bss
141 #else
142         .sect .page0
143 #endif
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 ;; This operation is split in several pieces collected together by
183 ;; the linker script.  This allows to support destructors at the
184 ;; exit stage while not impacting program sizes when there is no
185 ;; destructors.
186 ;;
187 ;; _exit:
188 ;;    *(.fini0)         /* Beginning of finish code (_exit symbol).  */
189 ;;    *(.fini1)         /* Place holder for applications.  */
190 ;;    *(.fini2)         /* C++ destructors.  */
191 ;;    *(.fini3)         /* Place holder for applications.  */
192 ;;    *(.fini4)         /* Runtime exit.  */
193 ;;
194         .sect .fini0,"ax",@progbits
195         .globl _exit
196         .globl exit
197         .weak  exit
198 exit:
199 _exit:
200
201         .sect .fini4,"ax",@progbits
202 fatal:
203         cli
204         wai
205         bra fatal
206 #endif
207
208 #ifdef L_abort
209 ;;
210 ;; Abort operation.  This is defined for the GCC testsuite.
211 ;;
212         .sect .text
213         .globl abort
214 abort:
215         ldd     #255            ; 
216 #ifdef mc68hc12
217         trap    #0x30
218 #else
219         .byte 0xCD              ; Generate an illegal instruction trap
220         .byte 0x03              ; The simulator catches this and stops.
221 #endif
222         jmp _exit
223 #endif
224         
225 #ifdef L_cleanup
226 ;;
227 ;; Cleanup operation used by exit().
228 ;;
229         .sect .text
230         .globl _cleanup
231 _cleanup:
232         rts
233 #endif
234
235 ;-----------------------------------------
236 ; required gcclib code
237 ;-----------------------------------------
238 #ifdef L_memcpy
239         .sect .text
240         .weak memcpy
241         .globl memcpy
242         .globl __memcpy
243 ;;;
244 ;;; void* memcpy(void*, const void*, size_t)
245 ;;; 
246 ;;; D    = dst  Pmode
247 ;;; 2,sp = src  Pmode
248 ;;; 4,sp = size HImode (size_t)
249 ;;; 
250 __memcpy:
251 memcpy:
252 #ifdef mc68hc12
253         ldx     2,sp
254         ldy     4,sp
255         pshd
256         xgdy
257         lsrd
258         bcc     Start
259         movb    1,x+,1,y+
260 Start:
261         beq     Done
262 Loop:
263         movw    2,x+,2,y+
264         dbne    d,Loop
265 Done:
266         puld
267         rts
268 #else
269         xgdy
270         tsx
271         ldd     4,x
272         ldx     2,x             ; SRC = X, DST = Y
273         cpd     #0
274         beq     End
275         pshy
276         inca                    ; Correction for the deca below
277 L0:
278         psha                    ; Save high-counter part
279 L1:
280         ldaa    0,x             ; Copy up to 256 bytes
281         staa    0,y
282         inx
283         iny
284         decb
285         bne     L1
286         pula
287         deca
288         bne     L0
289         puly                    ; Restore Y to return the DST
290 End:
291         xgdy
292         rts
293 #endif
294 #endif
295
296 #ifdef L_memset
297         .sect .text
298         .globl memset
299         .globl __memset
300 ;;;
301 ;;; void* memset(void*, int value, size_t)
302 ;;; 
303 #ifndef __HAVE_SHORT_INT__
304 ;;; D    = dst  Pmode
305 ;;; 2,sp = src  SImode
306 ;;; 6,sp = size HImode (size_t)
307         val  = 5
308         size = 6
309 #else
310 ;;; D    = dst  Pmode
311 ;;; 2,sp = src  SImode
312 ;;; 6,sp = size HImode (size_t)
313         val  = 3
314         size = 4
315 #endif
316 __memset:
317 memset:
318 #ifdef mc68hc12
319         xgdx
320         ldab    val,sp
321         ldy     size,sp
322         pshx
323         beq     End
324 Loop:
325         stab    1,x+
326         dbne    y,Loop
327 End:
328         puld
329         rts
330 #else
331         xgdx
332         tsy
333         ldab    val,y
334         ldy     size,y          ; DST = X, CNT = Y
335         beq     End
336         pshx
337 L0:
338         stab    0,x             ; Fill up to 256 bytes
339         inx
340         dey
341         bne     L0
342         pulx                    ; Restore X to return the DST
343 End:
344         xgdx
345         rts
346 #endif
347 #endif
348                 
349 #ifdef L_adddi3
350         .sect .text
351         .globl ___adddi3
352
353 ___adddi3:
354         tsx
355         xgdy
356         ldd     8,x             ; Add LSB
357         addd    16,x
358         std     6,y             ; Save (carry preserved)
359
360         ldd     6,x
361         adcb    15,x
362         adca    14,x
363         std     4,y
364
365         ldd     4,x
366         adcb    13,x
367         adca    12,x
368         std     2,y
369         
370         ldd     2,x
371         adcb    11,x            ; Add MSB
372         adca    10,x
373         std     0,y
374
375         xgdy
376         rts
377 #endif
378
379 #ifdef L_subdi3
380         .sect .text
381         .globl ___subdi3
382
383 ___subdi3:
384         tsx
385         xgdy
386         ldd     8,x             ; Subtract LSB
387         subd    16,x
388         std     6,y             ; Save, borrow preserved
389
390         ldd     6,x
391         sbcb    15,x
392         sbca    14,x
393         std     4,y
394
395         ldd     4,x
396         sbcb    13,x
397         sbca    12,x
398         std     2,y
399         
400         ldd     2,x             ; Subtract MSB
401         sbcb    11,x
402         sbca    10,x
403         std     0,y
404
405         xgdy                    ;
406         rts
407 #endif
408         
409 #ifdef L_notdi2
410         .sect .text
411         .globl ___notdi2
412
413 ___notdi2:
414         tsy
415         xgdx
416         ldd     8,y
417         coma
418         comb
419         std     6,x
420         
421         ldd     6,y
422         coma
423         comb
424         std     4,x
425
426         ldd     4,y
427         coma
428         comb
429         std     2,x
430
431         ldd     2,y
432         coma
433         comb
434         std     0,x
435         xgdx
436         rts
437 #endif
438         
439 #ifdef L_negsi2
440         .sect .text
441         .globl ___negsi2
442
443 ___negsi2:
444         comb
445         coma
446         xgdx
447         comb
448         coma
449         inx
450         xgdx
451         bne     done
452         inx
453 done:
454         rts
455 #endif
456
457 #ifdef L_one_cmplsi2
458         .sect .text
459         .globl ___one_cmplsi2
460
461 ___one_cmplsi2:
462         comb
463         coma
464         xgdx
465         comb
466         coma
467         xgdx
468         rts
469 #endif
470         
471 #ifdef L_ashlsi3
472         .sect .text
473         .globl ___ashlsi3
474
475 ___ashlsi3:
476         xgdy
477         clra
478         andb    #0x1f
479         xgdy
480         beq     Return
481 Loop:
482         lsld
483         xgdx
484         rolb
485         rola
486         xgdx
487         dey
488         bne     Loop
489 Return:
490         rts
491 #endif
492
493 #ifdef L_ashrsi3
494         .sect .text
495         .globl ___ashrsi3
496
497 ___ashrsi3:
498         xgdy
499         clra
500         andb    #0x1f
501         xgdy
502         beq     Return
503 Loop:
504         xgdx
505         asra
506         rorb
507         xgdx
508         rora
509         rorb
510         dey
511         bne     Loop
512 Return:
513         rts
514 #endif
515
516 #ifdef L_lshrsi3
517         .sect .text
518         .globl ___lshrsi3
519
520 ___lshrsi3:
521         xgdy
522         clra
523         andb    #0x1f
524         xgdy
525         beq     Return
526 Loop:
527         xgdx
528         lsrd
529         xgdx
530         rora
531         rorb
532         dey
533         bne     Loop
534 Return:
535         rts
536 #endif
537
538 #ifdef L_lshrhi3
539         .sect .text
540         .globl ___lshrhi3
541
542 ___lshrhi3:
543         cpx     #16
544         bge     Return_zero
545         cpx     #0
546         beq     Return
547 Loop:
548         lsrd
549         dex
550         bne     Loop
551 Return:
552         rts
553 Return_zero:
554         clra
555         clrb
556         rts
557 #endif
558         
559 #ifdef L_lshlhi3
560         .sect .text
561         .globl ___lshlhi3
562
563 ___lshlhi3:
564         cpx     #16
565         bge     Return_zero
566         cpx     #0
567         beq     Return
568 Loop:
569         lsld
570         dex
571         bne     Loop
572 Return:
573         rts
574 Return_zero:
575         clra
576         clrb
577         rts
578 #endif
579
580 #ifdef L_ashrhi3
581         .sect .text
582         .globl ___ashrhi3
583
584 ___ashrhi3:
585         cpx     #16
586         bge     Return_minus_1_or_zero
587         cpx     #0
588         beq     Return
589 Loop:
590         asra
591         rorb
592         dex
593         bne     Loop
594 Return:
595         rts
596 Return_minus_1_or_zero:
597         clrb
598         tsta
599         bpl     Return_zero
600         comb
601 Return_zero:
602         tba
603         rts
604 #endif
605         
606 #ifdef L_ashrqi3
607         .sect .text
608         .globl ___ashrqi3
609
610 ___ashrqi3:
611         cmpa    #8
612         bge     Return_minus_1_or_zero
613         tsta
614         beq     Return
615 Loop:
616         asrb
617         deca
618         bne     Loop
619 Return:
620         rts
621 Return_minus_1_or_zero:
622         clrb
623         tstb
624         bpl     Return_zero
625         coma
626 Return_zero:
627         tab
628         rts
629 #endif
630
631 #ifdef L_lshlqi3
632         .sect .text
633         .globl ___lshlqi3
634
635 ___lshlqi3:
636         cmpa    #8
637         bge     Return_zero
638         tsta
639         beq     Return
640 Loop:
641         lslb
642         deca
643         bne     Loop
644 Return:
645         rts
646 Return_zero:
647         clrb
648         rts
649 #endif
650
651 #ifdef L_divmodhi4
652 #ifndef mc68hc12
653 /* 68HC12 signed divisions are generated inline (idivs).  */
654
655         .sect .text
656         .globl __divmodhi4
657
658 ;
659 ;; D = numerator
660 ;; X = denominator
661 ;;
662 ;; Result:      D = D / X
663 ;;              X = D % X
664 ;; 
665 __divmodhi4:
666         tsta
667         bpl     Numerator_pos
668         comb                    ; D = -D <=> D = (~D) + 1
669         coma
670         xgdx
671         inx
672         tsta
673         bpl     Numerator_neg_denominator_pos
674 Numerator_neg_denominator_neg:
675         comb                    ; X = -X
676         coma
677         addd    #1
678         xgdx
679         idiv
680         coma
681         comb
682         xgdx                    ; Remainder <= 0 and result >= 0
683         inx
684         rts
685
686 Numerator_pos_denominator_pos:
687         xgdx
688         idiv
689         xgdx                    ; Both values are >= 0
690         rts
691         
692 Numerator_pos:
693         xgdx
694         tsta
695         bpl     Numerator_pos_denominator_pos
696 Numerator_pos_denominator_neg:
697         coma                    ; X = -X
698         comb
699         xgdx
700         inx
701         idiv
702         xgdx                    ; Remainder >= 0 but result <= 0
703         coma
704         comb
705         addd    #1
706         rts
707         
708 Numerator_neg_denominator_pos:
709         xgdx
710         idiv
711         coma                    ; One value is > 0 and the other < 0
712         comb                    ; Change the sign of result and remainder
713         xgdx
714         inx
715         coma
716         comb
717         addd    #1
718         rts
719 #endif /* !mc68hc12 */
720 #endif
721
722 #ifdef L_mulqi3
723        .sect .text
724        .globl __mulqi3
725
726 ;
727 ; short __mulqi3(signed char a, signed char b);
728 ;
729 ;       signed char a   -> register A
730 ;       signed char b   -> register B
731 ;
732 ; returns the signed result of A * B in register D.
733 ;
734 __mulqi3:
735         tsta
736         bmi     A_neg
737         tstb
738         bmi     B_neg
739         mul
740         rts
741 B_neg:
742         negb
743         bra     A_or_B_neg
744 A_neg:
745         nega
746         tstb
747         bmi     AB_neg
748 A_or_B_neg:
749         mul
750         coma
751         comb
752         addd    #1
753         rts
754 AB_neg:
755         negb
756         mul
757         rts
758 #endif
759         
760 #ifdef L_mulhi3
761         .sect .text
762         .globl ___mulhi3
763
764 ;
765 ;
766 ;  unsigned short ___mulhi3(unsigned short a, unsigned short b)
767 ;
768 ;       a = register D
769 ;       b = register X
770 ;
771 ___mulhi3:
772 #ifdef mc68hc12
773         pshx                    ; Preserve X
774         exg     x,y
775         emul
776         exg     x,y
777         pulx
778         rts
779 #else
780 #ifdef NO_TMP
781         ;
782         ; 16 bit multiplication without temp memory location.
783         ; (smaller but slower)
784         ;
785         pshx                    ; (4)
786         ins                     ; (3)
787         pshb                    ; (3)
788         psha                    ; (3)
789         pshx                    ; (4)
790         pula                    ; (4)
791         pulx                    ; (5)
792         mul                     ; (10) B.high * A.low
793         xgdx                    ; (3)
794         mul                     ; (10) B.low * A.high
795         abx                     ; (3)
796         pula                    ; (4)
797         pulb                    ; (4)
798         mul                     ; (10) B.low * A.low
799         pshx                    ; (4) 
800         tsx                     ; (3)
801         adda    1,x             ; (4)
802         pulx                    ; (5)
803         rts                     ; (5) 20 bytes
804                                 ; ---
805                                 ; 91 cycles
806 #else
807         stx     _.tmp           ; (4/5)
808         pshb                    ; (3)
809         ldab    _.tmp+1         ; (3/4)
810         mul                     ; (10) B.high * A.low
811         xgdx                    ; (3)
812         pulb                    ; (4)
813         stab    _.tmp           ; (3/4)
814         mul                     ; (10) B.low * A.high
815         abx                     ; (3)
816         ldd     _.tmp           ; (4/5)
817         mul                     ; (10) B.low * A.low
818         stx     _.tmp           ; (4) 
819         adda    _.tmp+1         ; (4/5)
820         rts                     ; (5) 20/26 bytes
821                                 ; ---
822                                 ; 70/76 cycles
823
824 #ifdef OLD_MUL
825         stx     *_.tmp          ; (4)
826         pshb                    ; (3)
827         ldab    *_.tmp+1        ; (3)
828         mul                     ; (10) A.high * B.low
829         ldaa    *_.tmp          ; (3)
830         stab    *_.tmp          ; (3)
831         pulb                    ; (4)
832         pshb                    ; (4)
833         mul                     ; (10) A.low * B.high
834         addb    *_.tmp          ; (4)
835         stab    *_.tmp          ; (3)
836         ldaa    *_.tmp+1        ; (3)
837         pulb                    ; (4)
838         mul                     ; (10) A.low * B.low
839         adda    *_.tmp          ; (4)
840         rts                     ; (5) 24/32 bytes
841                                 ; 77/85 cycles
842 #endif
843 #endif
844 #endif
845 #endif
846
847 #ifdef L_mulhi32
848         .sect .text
849         .globl __mulhi32
850
851 ;
852 ;
853 ;  unsigned long __mulhi32(unsigned short a, unsigned short b)
854 ;
855 ;       a = register D
856 ;       b = value on stack
857 ;
858 ;       +---------------+
859 ;       |  B low        | <- 7,x
860 ;       +---------------+
861 ;       |  B high       | <- 6,x
862 ;       +---------------+
863 ;       |  PC low       |  
864 ;       +---------------+
865 ;       |  PC high      |  
866 ;       +---------------+
867 ;       |  Tmp low      |
868 ;       +---------------+
869 ;       |  Tmp high     |
870 ;       +---------------+
871 ;       |  A low        |
872 ;       +---------------+
873 ;       |  A high       |
874 ;       +---------------+  <- 0,x
875 ;
876 ;
877 ;      <B-low>    5,x
878 ;      <B-high>   4,x
879 ;      <ret>      2,x
880 ;      <A-low>    1,x
881 ;      <A-high>   0,x
882 ;
883 __mulhi32:
884 #ifdef mc68hc12
885         ldy     2,sp
886         emul
887         exg     x,y
888         rts
889 #else
890         pshx                    ; Room for temp value
891         pshb
892         psha
893         tsx
894         ldab    6,x
895         mul
896         xgdy                    ; A.high * B.high
897         ldab    7,x
898         pula
899         mul                     ; A.high * B.low
900         std     2,x
901         ldaa    1,x
902         ldab    6,x
903         mul                     ; A.low * B.high
904         addd    2,x
905         stab    2,x
906         tab
907         aby
908         bcc     N
909         ldab    #0xff
910         aby
911         iny
912 N:
913         ldab    7,x
914         pula
915         mul                     ; A.low * B.low
916         adda    2,x
917         pulx                    ; Drop temp location
918         pshy                    ; Put high part in X
919         pulx
920         bcc     Ret
921         inx
922 Ret:
923         rts
924 #endif  
925 #endif
926
927 #ifdef L_mulsi3
928         .sect .text
929         .globl __mulsi3
930
931 ;
932 ;      <B-low>    8,y
933 ;      <B-high>   6,y
934 ;      <ret>      4,y
935 ;       <tmp>     2,y
936 ;      <A-low>    0,y
937 ;
938 ; D,X   -> A
939 ; Stack -> B
940 ;
941 ; The result is:
942 ;
943 ;       (((A.low * B.high) + (A.high * B.low)) << 16) + (A.low * B.low)
944 ;
945 ;
946 ;
947
948 __mulsi3:
949 #ifdef mc68hc12
950         pshd                            ; Save A.low
951         ldy     4,sp
952         emul                            ; A.low * B.high
953         ldy     6,sp
954         exg     x,d
955         emul                            ; A.high * B.low
956         leax    d,x
957         ldy     6,sp
958         puld
959         emul                            ; A.low * B.low
960         exg     d,y
961         leax    d,x
962         exg     d,y
963         rts
964 #else
965 B_low   =       8
966 B_high  =       6
967 A_low   =       0
968 A_high  =       2
969         pshx
970         pshb
971         psha
972         tsy
973 ;
974 ; If B.low is 0, optimize into: (A.low * B.high) << 16
975 ;
976         ldd     B_low,y
977         beq     B_low_zero
978 ;
979 ; If A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low)
980 ;
981         cpx     #0
982         beq     A_high_zero
983         bsr     ___mulhi3               ; A.high * B.low
984 ;
985 ; If A.low is 0, optimize into: (A.high * B.low) << 16
986 ;
987         ldx     A_low,y
988         beq     A_low_zero              ; X = 0, D = A.high * B.low
989         std     2,y
990 ;
991 ; If B.high is 0, we can avoid the (A.low * B.high) << 16 term.
992 ;
993         ldd     B_high,y
994         beq     B_high_zero
995         bsr     ___mulhi3               ; A.low * B.high
996         addd    2,y
997         std     2,y
998 ;
999 ; Here, we know that A.low and B.low are not 0.
1000 ;
1001 B_high_zero:
1002         ldd     B_low,y                 ; A.low is on the stack
1003         bsr     __mulhi32               ; A.low * B.low
1004         xgdx
1005         tsy                             ; Y was clobbered, get it back
1006         addd    2,y
1007 A_low_zero:                             ; See A_low_zero_non_optimized below
1008         xgdx
1009 Return:
1010         ins
1011         ins
1012         ins
1013         ins
1014         rts
1015 ;
1016
1017 ; A_low_zero_non_optimized:
1018 ;
1019 ; At this step, X = 0 and D = (A.high * B.low)
1020 ; Optimize into: (A.high * B.low) << 16
1021 ;
1022 ;       xgdx
1023 ;       clra                    ; Since X was 0, clearing D is superfuous.
1024 ;       clrb
1025 ;       bra     Return
1026 ; ----------------
1027 ; B.low == 0, the result is:    (A.low * B.high) << 16
1028 ;
1029 ; At this step:
1030 ;   D = B.low                           = 0 
1031 ;   X = A.high                          ?
1032 ;       A.low is at A_low,y             ?
1033 ;       B.low is at B_low,y             ?
1034 ;
1035 B_low_zero:
1036         ldd     A_low,y
1037         beq     Zero1
1038         ldx     B_high,y
1039         beq     Zero2
1040         bsr     ___mulhi3
1041 Zero1:
1042         xgdx
1043 Zero2:
1044         clra
1045         clrb
1046         bra     Return
1047 ; ----------------
1048 ; A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low)
1049 ;
1050 ; At this step:
1051 ;   D = B.low                           != 0 
1052 ;   X = A.high                          = 0
1053 ;       A.low is at A_low,y             ?
1054 ;       B.low is at B_low,y             ?
1055 ;
1056 A_high_zero:
1057         ldd     A_low,y         ; A.low
1058         beq     Zero1
1059         ldx     B_high,y        ; B.high
1060         beq     A_low_B_low
1061         bsr     ___mulhi3
1062         std     2,y
1063         bra     B_high_zero     ; Do the (A.low * B.low) and the add.
1064
1065 ; ----------------
1066 ; A.high and B.high are 0 optimize into: (A.low * B.low)
1067 ;
1068 ; At this step:
1069 ;   D = B.high                          = 0 
1070 ;   X = A.low                           != 0
1071 ;       A.low is at A_low,y             != 0
1072 ;       B.high is at B_high,y           = 0
1073 ;
1074 A_low_B_low:
1075         ldd     B_low,y                 ; A.low is on the stack
1076         bsr     __mulhi32
1077         bra     Return
1078 #endif
1079 #endif
1080
1081 #ifdef L_map_data
1082
1083         .sect   .install2,"ax",@progbits
1084         .globl  __map_data_section
1085         .globl __data_image
1086 #ifdef mc68hc12
1087         .globl __data_section_size
1088 #endif
1089 __map_data_section:
1090 #ifdef mc68hc12
1091         ldx     #__data_image
1092         ldy     #__data_section_start
1093         ldd     #__data_section_size
1094         beq     Done
1095 Loop:
1096         movb    1,x+,1,y+
1097         dbne    d,Loop
1098 #else
1099         ldx     #__data_image
1100         ldy     #__data_section_start
1101         bra     Start_map
1102 Loop:
1103         ldaa    0,x
1104         staa    0,y
1105         inx
1106         iny
1107 Start_map:
1108         cpx     #__data_image_end
1109         blo     Loop
1110 #endif
1111 Done:
1112
1113 #endif
1114
1115 #ifdef L_init_bss
1116
1117         .sect   .install2,"ax",@progbits
1118         .globl  __init_bss_section
1119
1120 __init_bss_section:
1121         ldd     #__bss_size
1122         beq     Done
1123         ldx     #__bss_start
1124 Loop:
1125 #ifdef mc68hc12
1126         clr     1,x+
1127         dbne    d,Loop
1128 #else
1129         clr     0,x
1130         inx
1131         subd    #1
1132         bne     Loop
1133 #endif
1134 Done:
1135
1136 #endif
1137
1138 #ifdef L_ctor
1139
1140 ; End of constructor table
1141         .sect   .install3,"ax",@progbits
1142         .globl  __do_global_ctors
1143
1144 __do_global_ctors:
1145         ; Start from the end - sizeof(void*)
1146         ldx     #__CTOR_END__-2
1147 ctors_loop:
1148         cpx     #__CTOR_LIST__
1149         blo     ctors_done
1150         pshx
1151         ldx     0,x
1152         jsr     0,x
1153         pulx
1154         dex
1155         dex
1156         bra     ctors_loop
1157 ctors_done:
1158
1159 #endif
1160
1161 #ifdef L_dtor
1162
1163         .sect   .fini3,"ax",@progbits
1164         .globl  __do_global_dtors
1165
1166 ;;
1167 ;; This piece of code is inserted in the _exit() code by the linker.
1168 ;;
1169 __do_global_dtors:
1170         pshb    ; Save exit code
1171         psha
1172         ldx     #__DTOR_LIST__
1173 dtors_loop:
1174         cpx     #__DTOR_END__
1175         bhs     dtors_done
1176         pshx
1177         ldx     0,x
1178         jsr     0,x
1179         pulx
1180         inx
1181         inx
1182         bra     dtors_loop
1183 dtors_done:
1184         pula    ; Restore exit code
1185         pulb
1186
1187 #endif
1188
1189 ;-----------------------------------------
1190 ; end required gcclib code
1191 ;-----------------------------------------