2 ; Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
3 ; Contributed by Red Hat, Inc and Ubicom, Inc.
5 ; This file is part of GCC.
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 2, or (at your option)
12 ; In addition to the permissions in the GNU General Public License, the
13 ; Free Software Foundation gives you unlimited permission to link the
14 ; compiled version of this file with other programs, and to distribute
15 ; those programs without any restriction coming from the use of this
16 ; file. (The General Public License restrictions do apply in other
17 ; respects; for example, they cover modification of the file, and
18 ; distribution when not linked into another program.)
20 ; GCC is distributed in the hope that it will be useful,
21 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 ; GNU General Public License for more details.
25 ; You should have received a copy of the GNU General Public License
26 ; along with GCC; see the file COPYING. If not, write to
27 ; the Free Software Foundation, 59 Temple Place - Suite 330,
28 ; Boston, MA 02111-1307, USA. */
30 /*******************************************************
31 load byte from arbitrary memory
32 address passed in first bank register, result in W
34 *******************************************************/
41 #if defined (L_indcall)
42 /* __indcall - given register containing an address, call the function
46 .sect .pram.libgcc,"ax"
48 .func _indcall,__indcall
53 1: pop callh ; Get the call target
55 ret ; Transfer to new function
61 #if defined (L_mulhi3)
62 .sect .pram.libgcc,"ax"
64 .func _mulhi3, __mulhi3
67 mov w, 2(SP) ; First upper half partial product
70 mov w, 1(SP) ; Second upper half partial product
73 mov w, 2(SP) ; Lower half partial product
79 mov w, #2 ; Adjust the stack leaving the result to
80 add spl, w ; be popped off later.
85 #endif /* defined (L_mulhi3) */
87 #if defined (L_mulsi3)
88 /*******************************************************
89 Multiplication 32 x 32
90 *******************************************************/
92 .sect .text.libgcc,"ax"
94 .func _mulsi3, __mulsi3
97 clr $80 ; Assume zero result
106 snz ; Any more significant bits to multiply?
110 sb 4(sp), 0 ; Check LSB of multiplier
111 page 1f ; zero => scale multiplicand & multiplier
114 mov w, 8(sp) ; Accumulate product
122 1: clrb status, 0 ; scale multiplier down
141 #endif /* defined (L_mulsi3) */
143 #if defined (L_muldi3)
144 /*******************************************************
145 Multiplication 64 x 64
146 *******************************************************/
148 .sect .text.libgcc,"ax"
150 .func _muldi3, __muldi3
153 clr $80 ; Assume zero result
170 snz ; Any more significant bits to multiply?
174 sb 8(sp), 0 ; Check LSB of multiplier
175 page 1f ; zero => scale multiplicand & multiplier
178 mov w, 16(sp) ; Accumulate product
195 1: clrb status, 0 ; scale multiplier down
222 #endif /* defined (L_muldi3) */
224 #if defined (L_divmodhi4)
235 #define arg1_sign $86
238 .sect .text.libgcc,"ax"
240 .func _divmodhi4, __divmodhi4
267 1: page __udivmodhi4 ; Do the unsigned div/mod
303 #endif /* defined (L_divmodhi4) */
305 #if defined (L_udivmodhi4)
318 .sect .text.libgcc,"ax"
320 .func _udivmodhi4, __udivmodhi4
370 #endif /* defined (L_udivmodhi4) */
372 #if defined (L_divmodsi4)
398 #define arg1_sign $8c
401 .sect .text.libgcc,"ax"
403 .func _divmodsi4, __divmodsi4
442 1: page __udivmodsi4 ; Do the unsigned div/mod.
503 #endif /* defined (L_divmodsi4) */
505 #if defined (L_udivmodsi4)
531 .sect .text.libgcc,"ax"
533 .func _udivmodsi4, __udivmodsi4
616 #endif /* defined (L_udivmodsi4) */
618 #if defined (L_divmoddi4)
665 .sect .text.libgcc,"ax"
667 .func _divmoddi4, __divmoddi4
670 rl w, arg2s ; Use MULH to track sign bits.
732 1: page __udivmoddi4 ; Do the unsigned div/mod.
735 sb MULH, 0 ; Look at the save sign bit for arg 1.
833 #endif /* defined (L_divmoddi4) */
835 #if defined (L_udivmoddi4)
881 .sect .text.libgcc,"ax"
883 .func _udivmoddi4, __udivmoddi4
1022 #endif /* defined (L_udivmoddi4) */
1028 #if defined(L_cmphi2)
1034 .sect .text.libgcc,"ax"
1038 .func _cmphi2, __cmphi2
1062 add pcl,w ; carry of arg1 - arg2
1063 retw GT ; [000] arg1 > arg2
1064 retw LT ; [001] arg1 < arg2
1065 retw GT ; [010] arg1 > arg2
1066 retw GT ; [011] arg1 > arg2
1067 retw LT ; [100] arg1 < arg2
1068 retw LT ; [101] arg1 < arg2
1069 retw GT ; [110] arg1 > arg2
1070 retw LT ; [111] arg1 < arg2
1085 #endif /* L_cmphi2 */
1087 #if defined(L_cmpqi2)
1091 .sect .text.libgcc,"ax"
1093 .func _cmpqi2, __cmpqi2
1120 #endif /* L_cmpqi2 */
1122 #if defined(L_cmpsi2)
1132 .sect .text.libgcc,"ax"
1134 .func _cmpsi2, __cmpsi2
1189 #endif /* L_cmpsi2 */
1191 #if defined(L_cmpdi2)
1201 #define arg2z 16(sp)
1202 #define arg2y 15(sp)
1203 #define arg2x 14(sp)
1204 #define arg2w 13(sp)
1205 #define arg2v 12(sp)
1206 #define arg2u 11(sp)
1207 #define arg2t 10(sp)
1210 .sect .text.libgcc,"ax"
1212 .func _cmpdi2, __cmpdi2
1303 #endif /* L_cmpdi2 */
1305 #if defined(L_cmpdi2_dp)
1306 .sect .text.libgcc,"ax"
1308 .func _cmpdi2_dp, __cmpdi2_dp
1323 #endif /* L_cmpdi2_dp */
1325 #if defined(L_fp_pop_args_ret)
1326 .sect .pram.libgcc,"ax"
1327 .global __fp_pop_args_ret
1328 .global __pop_args_ret
1329 .global __pop2_args_ret
1330 .func __fp_pop2_args_ret, __fp_pop2_args_ret
1344 #endif /* L_fp_pop_args_ret */
1346 #if defined(L__pop2_args_ret)
1347 .sect .pram.libgcc,"ax"
1348 .global __pop2_args_ret
1349 .func __pop2_args_ret, __pop2_args_ret
1359 #endif /* L__pop2_args_ret */
1361 #if defined(L_leaf_fp_pop_args_ret)
1362 .sect .pram.libgcc,"ax"
1363 .global __leaf_fp_pop_args_ret, __leaf_fp_pop2_args_ret
1364 .func __leaf_fp2_pop_args_ret, __leaf_fp_pop2_args_ret
1366 __leaf_fp_pop2_args_ret:
1368 __leaf_fp_pop_args_ret:
1375 #endif /* L_leaf_fp_pop_args_ret */
1377 #if defined(L_movmemhi_countqi)
1378 .sect .pram.libgcc,"ax"
1379 .global __movmemhi_countqi
1380 .func _movmemhi_countqi, __movmemhi_countqi
1383 push dph ; Save our pointer regs
1388 mov w, 5(SP) ; Get our dest pointer
1392 mov w, 7(SP) ; And our source pointer
1397 1: push (IP) ; *dest++ = *src++
1401 decsz 9(SP) ; Loop until completed
1405 pop ipl ; Restore our pointer regs
1410 mov w, #5 ; Tidy up our stack args
1417 #if defined(L_movmemhi_counthi)
1418 .sect .text.libgcc,"ax"
1419 .global __movmemhi_counthi
1420 .func _movmemhi_counthi, __movmemhi_counthi
1423 push dph ; Save our pointer regs
1428 mov w, 5(SP) ; Get our dest pointer
1432 mov w, 7(SP) ; And our source pointer
1437 test 10(SP) ; If we have a nonzero LSB then adjust the
1438 sz ; MSB of the loop count to allow us to use
1439 inc 9(SP) ; skip tricks!
1441 1: push (IP) ; *dest++ = *src++
1445 decsnz 10(SP) ; Loop until completed - note the skip trick
1446 decsz 9(SP) ; on the MSB!
1450 pop ipl ; Restore our pointer regs
1455 mov w, #6 ; Tidy up our stacked args.
1463 .sect .text.libgcc,"ax"
1479 page __exit ; Never return
1486 .sect .text.libgcc,"ax"
1501 /* Dummy entrypoint to suppress problems with glue code. */
1502 .sect .text.libgcc,"ax"
1506 ;; write (fil,buf,len) - say that write succeeds....
1510 movb $81, 6(SP) ; Return length written