OSDN Git Service

2001-02-20 Joel Sherrill <joel@OARcorp.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / m68hc11 / larith.asm
1 /* libgcc routines for M68HC11 & M68HC12.
2    Copyright (C) 1999, 2000, 2001 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         pshb
356         psha
357         ldd     8,x
358         addd    16,x
359         pshb
360         psha
361
362         ldd     6,x
363         adcb    15,x
364         adca    14,x
365         pshb
366         psha
367
368         ldd     4,x
369         adcb    13,x
370         adca    12,x
371         pshb
372         psha
373         
374         ldd     2,x
375         adcb    11,x
376         adca    10,x
377         tsx
378         ldy     6,x
379
380         std     0,y
381         pulx
382         stx     2,y
383         pulx
384         stx     4,y
385         pulx
386         stx     6,y
387         pulx
388         rts
389 #endif
390
391 #ifdef L_subdi3
392         .sect .text
393         .globl ___subdi3
394
395 ___subdi3:
396         tsx
397         pshb
398         psha
399         ldd     8,x
400         subd    16,x
401         pshb
402         psha
403
404         ldd     6,x
405         sbcb    15,x
406         sbca    14,x
407         pshb
408         psha
409
410         ldd     4,x
411         sbcb    13,x
412         sbca    12,x
413         pshb
414         psha
415         
416         ldd     2,x
417         sbcb    11,x
418         sbca    10,x
419         
420         tsx
421         ldy     6,x
422
423         std     0,y
424         pulx
425         stx     2,y
426         pulx
427         stx     4,y
428         pulx
429         stx     6,y
430         pulx
431         rts
432 #endif
433         
434 #ifdef L_notdi2
435         .sect .text
436         .globl ___notdi2
437
438 ___notdi2:
439         tsy
440         xgdx
441         ldd     8,y
442         coma
443         comb
444         std     6,x
445         
446         ldd     6,y
447         coma
448         comb
449         std     4,x
450
451         ldd     4,y
452         coma
453         comb
454         std     2,x
455
456         ldd     2,y
457         coma
458         comb
459         std     0,x
460         rts
461 #endif
462         
463 #ifdef L_negsi2
464         .sect .text
465         .globl ___negsi2
466
467 ___negsi2:
468         comb
469         coma
470         addd    #1
471         xgdx
472         eorb    #0xFF
473         eora    #0xFF
474         adcb    #0
475         adca    #0
476         xgdx
477         rts
478 #endif
479
480 #ifdef L_one_cmplsi2
481         .sect .text
482         .globl ___one_cmplsi2
483
484 ___one_cmplsi2:
485         comb
486         coma
487         xgdx
488         comb
489         coma
490         xgdx
491         rts
492 #endif
493         
494 #ifdef L_ashlsi3
495         .sect .text
496         .globl ___ashlsi3
497
498 ___ashlsi3:
499         xgdy
500         clra
501         andb    #0x1f
502         xgdy
503         beq     Return
504 Loop:
505         lsld
506         xgdx
507         rolb
508         rola
509         xgdx
510         dey
511         bne     Loop
512 Return:
513         rts
514 #endif
515
516 #ifdef L_ashrsi3
517         .sect .text
518         .globl ___ashrsi3
519
520 ___ashrsi3:
521         xgdy
522         clra
523         andb    #0x1f
524         xgdy
525         beq     Return
526 Loop:
527         xgdx
528         asra
529         rorb
530         xgdx
531         rora
532         rorb
533         dey
534         bne     Loop
535 Return:
536         rts
537 #endif
538
539 #ifdef L_lshrsi3
540         .sect .text
541         .globl ___lshrsi3
542
543 ___lshrsi3:
544         xgdy
545         clra
546         andb    #0x1f
547         xgdy
548         beq     Return
549 Loop:
550         xgdx
551         lsrd
552         xgdx
553         rora
554         rorb
555         dey
556         bne     Loop
557 Return:
558         rts
559 #endif
560
561 #ifdef L_lshrhi3
562         .sect .text
563         .globl ___lshrhi3
564
565 ___lshrhi3:
566         cpx     #16
567         bge     Return_zero
568         cpx     #0
569         beq     Return
570 Loop:
571         lsrd
572         dex
573         bne     Loop
574 Return:
575         rts
576 Return_zero:
577         clra
578         clrb
579         rts
580 #endif
581         
582 #ifdef L_lshlhi3
583         .sect .text
584         .globl ___lshlhi3
585
586 ___lshlhi3:
587         cpx     #16
588         bge     Return_zero
589         cpx     #0
590         beq     Return
591 Loop:
592         lsld
593         dex
594         bne     Loop
595 Return:
596         rts
597 Return_zero:
598         clra
599         clrb
600         rts
601 #endif
602
603 #ifdef L_ashrhi3
604         .sect .text
605         .globl ___ashrhi3
606
607 ___ashrhi3:
608         cpx     #16
609         bge     Return_minus_1_or_zero
610         cpx     #0
611         beq     Return
612 Loop:
613         asra
614         rorb
615         dex
616         bne     Loop
617 Return:
618         rts
619 Return_minus_1_or_zero:
620         clrb
621         tsta
622         bpl     Return_zero
623         comb
624 Return_zero:
625         tba
626         rts
627 #endif
628         
629 #ifdef L_ashrqi3
630         .sect .text
631         .globl ___ashrqi3
632
633 ___ashrqi3:
634         cmpa    #8
635         bge     Return_minus_1_or_zero
636         tsta
637         beq     Return
638 Loop:
639         asrb
640         deca
641         bne     Loop
642 Return:
643         rts
644 Return_minus_1_or_zero:
645         clrb
646         tstb
647         bpl     Return_zero
648         coma
649 Return_zero:
650         tab
651         rts
652 #endif
653
654 #ifdef L_lshlqi3
655         .sect .text
656         .globl ___lshlqi3
657
658 ___lshlqi3:
659         cmpa    #8
660         bge     Return_zero
661         tsta
662         beq     Return
663 Loop:
664         lslb
665         deca
666         bne     Loop
667 Return:
668         rts
669 Return_zero:
670         clrb
671         rts
672 #endif
673
674 #ifdef L_divmodhi4
675 #ifndef mc68hc12
676 /* 68HC12 signed divisions are generated inline (idivs).  */
677
678         .sect .text
679         .globl __divmodhi4
680
681 ;
682 ;; D = numerator
683 ;; X = denominator
684 ;;
685 ;; Result:      D = D / X
686 ;;              X = D % X
687 ;; 
688 __divmodhi4:
689         tsta
690         bpl     Numerator_pos
691         comb                    ; D = -D <=> D = (~D) + 1
692         coma
693         xgdx
694         inx
695         tsta
696         bpl     Numerator_neg_denominator_pos
697 Numerator_neg_denominator_neg:
698         comb                    ; X = -X
699         coma
700         addd    #1
701         xgdx
702         idiv
703         coma
704         comb
705         xgdx                    ; Remainder <= 0 and result >= 0
706         inx
707         rts
708
709 Numerator_pos_denominator_pos:
710         xgdx
711         idiv
712         xgdx                    ; Both values are >= 0
713         rts
714         
715 Numerator_pos:
716         xgdx
717         tsta
718         bpl     Numerator_pos_denominator_pos
719 Numerator_pos_denominator_neg:
720         coma                    ; X = -X
721         comb
722         xgdx
723         inx
724         idiv
725         xgdx                    ; Remainder >= 0 but result <= 0
726         coma
727         comb
728         addd    #1
729         rts
730         
731 Numerator_neg_denominator_pos:
732         xgdx
733         idiv
734         coma                    ; One value is > 0 and the other < 0
735         comb                    ; Change the sign of result and remainder
736         xgdx
737         inx
738         coma
739         comb
740         addd    #1
741         rts
742 #endif /* !mc68hc12 */
743 #endif
744
745 #ifdef L_mulqi3
746        .sect .text
747        .globl __mulqi3
748
749 ;
750 ; short __mulqi3(signed char a, signed char b);
751 ;
752 ;       signed char a   -> register A
753 ;       signed char b   -> register B
754 ;
755 ; returns the signed result of A * B in register D.
756 ;
757 __mulqi3:
758         tsta
759         bmi     A_neg
760         tstb
761         bmi     B_neg
762         mul
763         rts
764 B_neg:
765         negb
766         bra     A_or_B_neg
767 A_neg:
768         nega
769         tstb
770         bmi     AB_neg
771 A_or_B_neg:
772         mul
773         coma
774         comb
775         addd    #1
776         rts
777 AB_neg:
778         negb
779         mul
780         rts
781 #endif
782         
783 #ifdef L_mulhi3
784         .sect .text
785         .globl ___mulhi3
786
787 ;
788 ;
789 ;  unsigned short ___mulhi3(unsigned short a, unsigned short b)
790 ;
791 ;       a = register D
792 ;       b = register X
793 ;
794 ___mulhi3:
795 #ifdef mc68hc12
796         pshx                    ; Preserve X
797         exg     x,y
798         emul
799         exg     x,y
800         pulx
801 #else
802         stx     *_.tmp
803         pshb
804         ldab    *_.tmp+1
805         mul                     ; A.high * B.low
806         ldaa    *_.tmp
807         stab    *_.tmp
808         pulb
809         pshb
810         mul                     ; A.low * B.high
811         addb    *_.tmp
812         stab    *_.tmp
813         ldaa    *_.tmp+1
814         pulb
815         mul                     ; A.low * B.low
816         adda    *_.tmp
817 #endif
818         rts
819 #endif
820
821 #ifdef L_mulhi32
822         .sect .text
823         .globl __mulhi32
824
825 ;
826 ;
827 ;  unsigned long __mulhi32(unsigned short a, unsigned short b)
828 ;
829 ;       a = register D
830 ;       b = value on stack
831 ;
832 ;       +---------------+
833 ;       |  B low        | <- 5,x
834 ;       +---------------+
835 ;       |  B high       | <- 4,x
836 ;       +---------------+
837 ;       |  PC low       |  
838 ;       +---------------+
839 ;       |  PC high      |  
840 ;       +---------------+
841 ;       |  A low        |
842 ;       +---------------+
843 ;       |  A high       |
844 ;       +---------------+  <- 0,x
845 ;
846 ;
847 ;      <B-low>    5,x
848 ;      <B-high>   4,x
849 ;      <ret>      2,x
850 ;      <A-low>    1,x
851 ;      <A-high>   0,x
852 ;
853 __mulhi32:
854 #ifdef mc68hc12
855         ldy     2,sp
856         emul
857         exg     x,y
858 #else
859         pshb
860         psha
861         tsx
862         ldab    4,x
863         mul
864         xgdy                    ; A.high * B.high
865         ldab    5,x
866         pula
867         mul                     ; A.high * B.low
868         std     *_.tmp
869         ldaa    1,x
870         ldab    4,x
871         mul                     ; A.low * B.high
872         addd    *_.tmp
873         stab    *_.tmp
874         tab
875         aby
876         bcc     N
877         ldab    #0xff
878         aby
879         iny
880 N:
881         ldab    5,x
882         pula
883         mul                     ; A.low * B.low
884         adda    *_.tmp
885         bcc     Ret
886         iny
887 Ret:
888         pshy
889         pulx
890 #endif
891         rts
892         
893 #endif
894
895 #ifdef L_mulsi3
896         .sect .text
897         .globl __mulsi3
898
899 ;
900 ;      <B-low>    8,y
901 ;      <B-high>   6,y
902 ;      <ret>      4,y
903 ;       <tmp>     2,y
904 ;      <A-low>    0,y
905 ;
906 ; D,X   -> A
907 ; Stack -> B
908 ;
909 ; The result is:
910 ;
911 ;       (((A.low * B.high) + (A.high * B.low)) << 16) + (A.low * B.low)
912 ;
913 ;
914 ;
915
916 __mulsi3:
917 #ifdef mc68hc12
918         pshd                            ; Save A.low
919         ldy     4,sp
920         emul                            ; A.low * B.high
921         ldy     6,sp
922         exg     x,d
923         emul                            ; A.high * B.low
924         leax    d,x
925         ldy     6,sp
926         puld
927         emul                            ; A.low * B.low
928         exg     d,y
929         leax    d,x
930         exg     d,y
931         rts
932 #else
933 B_low   =       8
934 B_high  =       6
935 A_low   =       0
936 A_high  =       2
937         pshx
938         pshb
939         psha
940         tsy
941 ;
942 ; If B.low is 0, optimize into: (A.low * B.high) << 16
943 ;
944         ldd     B_low,y
945         beq     B_low_zero
946 ;
947 ; If A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low)
948 ;
949         stx     *_.tmp
950         beq     A_high_zero
951         bsr     ___mulhi3               ; A.high * B.low
952 ;
953 ; If A.low is 0, optimize into: (A.high * B.low) << 16
954 ;
955         ldx     A_low,y
956         beq     A_low_zero              ; X = 0, D = A.high * B.low
957         std     2,y
958 ;
959 ; If B.high is 0, we can avoid the (A.low * B.high) << 16 term.
960 ;
961         ldd     B_high,y
962         beq     B_high_zero
963         bsr     ___mulhi3               ; A.low * B.high
964         addd    2,y
965         std     2,y
966 ;
967 ; Here, we know that A.low and B.low are not 0.
968 ;
969 B_high_zero:
970         ldd     B_low,y                 ; A.low is on the stack
971         bsr     __mulhi32               ; A.low * B.low
972         xgdx
973         tsy                             ; Y was clobbered, get it back
974         addd    2,y
975 A_low_zero:                             ; See A_low_zero_non_optimized below
976         xgdx
977 Return:
978         ins
979         ins
980         ins
981         ins
982         rts
983 ;
984
985 ; A_low_zero_non_optimized:
986 ;
987 ; At this step, X = 0 and D = (A.high * B.low)
988 ; Optimize into: (A.high * B.low) << 16
989 ;
990 ;       xgdx
991 ;       clra                    ; Since X was 0, clearing D is superfuous.
992 ;       clrb
993 ;       bra     Return
994 ; ----------------
995 ; B.low == 0, the result is:    (A.low * B.high) << 16
996 ;
997 ; At this step:
998 ;   D = B.low                           = 0 
999 ;   X = A.high                          ?
1000 ;       A.low is at A_low,y             ?
1001 ;       B.low is at B_low,y             ?
1002 ;
1003 B_low_zero:
1004         ldd     A_low,y
1005         beq     Zero1
1006         ldx     B_high,y
1007         beq     Zero2
1008         bsr     ___mulhi3
1009 Zero1:
1010         xgdx
1011 Zero2:
1012         clra
1013         clrb
1014         bra     Return
1015 ; ----------------
1016 ; A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low)
1017 ;
1018 ; At this step:
1019 ;   D = B.low                           != 0 
1020 ;   X = A.high                          = 0
1021 ;       A.low is at A_low,y             ?
1022 ;       B.low is at B_low,y             ?
1023 ;
1024 A_high_zero:
1025         ldd     A_low,y         ; A.low
1026         beq     Zero1
1027         ldx     B_high,y        ; B.high
1028         beq     A_low_B_low
1029         bsr     ___mulhi3
1030         std     2,y
1031         bra     B_high_zero     ; Do the (A.low * B.low) and the add.
1032
1033 ; ----------------
1034 ; A.high and B.high are 0 optimize into: (A.low * B.low)
1035 ;
1036 ; At this step:
1037 ;   D = B.high                          = 0 
1038 ;   X = A.low                           != 0
1039 ;       A.low is at A_low,y             != 0
1040 ;       B.high is at B_high,y           = 0
1041 ;
1042 A_low_B_low:
1043         ldd     B_low,y                 ; A.low is on the stack
1044         bsr     __mulhi32
1045         bra     Return
1046 #endif
1047 #endif
1048
1049 #ifdef L_map_data
1050
1051         .sect   .install2,"ax",@progbits
1052         .globl  __map_data_section
1053
1054 __map_data_section:
1055         ldd     #__data_section_size
1056         beq     Done
1057         ldx     #__data_image
1058         ldy     #__data_section_start
1059 Loop:
1060 #ifdef mc68hc12
1061         movb    1,x+,1,y+
1062         dbne    d,Loop
1063 #else
1064         psha
1065         ldaa    0,x
1066         staa    0,y
1067         pula
1068         inx
1069         iny
1070         subd    #1
1071         bne     Loop
1072 #endif
1073 Done:
1074
1075 #endif
1076
1077 #ifdef L_init_bss
1078
1079         .sect   .install2,"ax",@progbits
1080         .globl  __init_bss_section
1081
1082 __init_bss_section:
1083         ldd     #__bss_size
1084         beq     Done
1085         ldx     #__bss_start
1086 Loop:
1087 #ifdef mc68hc12
1088         clr     1,x+
1089         dbne    d,Loop
1090 #else
1091         clr     0,x
1092         inx
1093         subd    #1
1094         bne     Loop
1095 #endif
1096 Done:
1097
1098 #endif
1099
1100 #ifdef L_ctor
1101
1102 ; End of constructor table
1103         .sect   .install3,"ax",@progbits
1104         .globl  __do_global_ctors
1105
1106 __do_global_ctors:
1107         ; Start from the end - sizeof(void*)
1108         ldx     #__CTOR_END__-2
1109 ctors_loop:
1110         cpx     #__CTOR_LIST__
1111         blt     ctors_done
1112         pshx
1113         ldx     0,x
1114         jsr     0,x
1115         pulx
1116         dex
1117         dex
1118         bra     ctors_loop
1119 ctors_done:
1120
1121 #endif
1122
1123 #ifdef L_dtor
1124
1125         .sect   .fini3,"ax",@progbits
1126         .globl  __do_global_dtors
1127
1128 ;;
1129 ;; This piece of code is inserted in the _exit() code by the linker.
1130 ;;
1131 __do_global_dtors:
1132         pshb    ; Save exit code
1133         psha
1134         ldx     #__DTOR_LIST__
1135 dtors_loop:
1136         cpx     #__DTOR_END__
1137         bge     dtors_done
1138         pshx
1139         ldx     0,x
1140         jsr     0,x
1141         pulx
1142         inx
1143         inx
1144         bra     dtors_loop
1145 dtors_done:
1146         pula    ; Restore exit code
1147         pulb
1148
1149 #endif
1150
1151 ;-----------------------------------------
1152 ; end required gcclib code
1153 ;-----------------------------------------