1 /* libgcc1 routines for M68HC11 & M68HC12.
2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
4 This file is part of GNU CC.
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
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.)
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.
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. */
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. */
43 .type NAME,@object ; \
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. */
65 /* Pseudo hard registers used by gcc.
66 They must be located in page0.
67 They will normally appear at the end of .page0 section. */
73 .globl _.d1,_.d2,_.d3,_.d4,_.d5,_.d6
87 /* Pseudo hard registers used by gcc.
88 They must be located in page0.
89 They will normally appear at the end of .page0 section. */
91 .globl _.d9,_.d10,_.d11,_.d12,_.d13,_.d14
105 /* Pseudo hard registers used by gcc.
106 They must be located in page0.
107 They will normally appear at the end of .page0 section. */
113 .globl _.d17,_.d18,_.d19,_.d20,_.d21,_.d22
114 .globl _.d23,_.d24,_.d25,_.d26,_.d27,_.d28
115 .globl _.d29,_.d30,_.d31,_.d32
136 ;; Specific initialization for 68hc11 before the main.
137 ;; Nothing special for a generic routine; Just enable interrupts.
143 tap ; Clear both I and X.
149 ;; Exit operation. Just loop forever and wait for interrupts.
150 ;; (no other place to go)
166 ;; Abort operation. This is defined for the GCC testsuite.
175 .byte 0xCD ; Generate an illegal instruction trap
176 .byte 0x03 ; The simulator catches this and stops.
183 ;; Cleanup operation used by exit().
191 ;-----------------------------------------
192 ; required gcclib code
193 ;-----------------------------------------
200 ;;; void* memcpy(void*, const void*, size_t)
204 ;;; 4,sp = size HImode (size_t)
228 ldx 2,x ; SRC = X, DST = Y
232 inca ; Correction for the deca below
234 psha ; Save high-counter part
236 ldaa 0,x ; Copy up to 256 bytes
245 puly ; Restore Y to return the DST
257 ;;; void* memset(void*, int value, size_t)
259 #ifndef __HAVE_SHORT_INT__
261 ;;; 2,sp = src SImode
262 ;;; 6,sp = size HImode (size_t)
267 ;;; 2,sp = src SImode
268 ;;; 6,sp = size HImode (size_t)
290 ldy size,y ; DST = X, CNT = Y
294 stab 0,x ; Fill up to 256 bytes
298 pulx ; Restore X to return the DST
438 .globl ___one_cmplsi2
565 bge Return_minus_1_or_zero
575 Return_minus_1_or_zero:
591 bge Return_minus_1_or_zero
600 Return_minus_1_or_zero:
632 /* 68HC12 signed divisions are generated inline (idivs). */
647 comb ; D = -D <=> D = (~D) + 1
652 bpl Numerator_neg_denominator_pos
653 Numerator_neg_denominator_neg:
661 xgdx ; Remainder <= 0 and result >= 0
665 Numerator_pos_denominator_pos:
668 xgdx ; Both values are >= 0
674 bpl Numerator_pos_denominator_pos
675 Numerator_pos_denominator_neg:
681 xgdx ; Remainder >= 0 but result <= 0
687 Numerator_neg_denominator_pos:
690 coma ; One value is > 0 and the other < 0
691 comb ; Change the sign of result and remainder
698 #endif /* !mc68hc12 */
706 ; short __mulqi3(signed char a, signed char b);
708 ; signed char a -> register A
709 ; signed char b -> register B
711 ; returns the signed result of A * B in register D.
745 ; unsigned short ___mulhi3(unsigned short a, unsigned short b)
783 ; unsigned long __mulhi32(unsigned short a, unsigned short b)
800 ; +---------------+ <- 0,x
820 xgdy ; A.high * B.high
867 ; (((A.low * B.high) + (A.high * B.low)) << 16) + (A.low * B.low)
876 emul ; A.low * B.high
879 emul ; A.high * B.low
898 ; If B.low is 0, optimize into: (A.low * B.high) << 16
903 ; If A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low)
907 bsr ___mulhi3 ; A.high * B.low
909 ; If A.low is 0, optimize into: (A.high * B.low) << 16
912 beq A_low_zero ; X = 0, D = A.high * B.low
915 ; If B.high is 0, we can avoid the (A.low * B.high) << 16 term.
919 bsr ___mulhi3 ; A.low * B.high
923 ; Here, we know that A.low and B.low are not 0.
926 ldd B_low,y ; A.low is on the stack
927 bsr __mulhi32 ; A.low * B.low
929 tsy ; Y was clobbered, get it back
931 A_low_zero: ; See A_low_zero_non_optimized below
941 ; A_low_zero_non_optimized:
943 ; At this step, X = 0 and D = (A.high * B.low)
944 ; Optimize into: (A.high * B.low) << 16
947 ; clra ; Since X was 0, clearing D is superfuous.
951 ; B.low == 0, the result is: (A.low * B.high) << 16
956 ; A.low is at A_low,y ?
957 ; B.low is at B_low,y ?
972 ; A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low)
977 ; A.low is at A_low,y ?
978 ; B.low is at B_low,y ?
983 ldx B_high,y ; B.high
987 bra B_high_zero ; Do the (A.low * B.low) and the add.
990 ; A.high and B.high are 0 optimize into: (A.low * B.low)
995 ; A.low is at A_low,y != 0
996 ; B.high is at B_high,y = 0
999 ldd B_low,y ; A.low is on the stack
1007 .sect .install3,"ax",@progbits
1008 .globl __map_data_section
1011 ldd #__data_section_size
1014 ldy #__data_section_start
1035 .sect .install3,"ax",@progbits
1036 .globl __init_bss_section
1056 ;-----------------------------------------
1057 ; end required gcclib code
1058 ;-----------------------------------------