1 ;; libgcc1 routines for the Hitachi H8/300 CPU.
2 ;; Contributed by Steve Chamberlain <sac@cygnus.com>
4 /* Copyright (C) 1994, 2000 Free Software Foundation, Inc.
6 This file 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 into combinations with other programs,
14 and to distribute those combinations without any restriction coming
15 from the use of this file. (The General Public License restrictions
16 do apply in other respects; for example, they cover modification of
17 the file, and distribution when not linked into a combine
20 This file is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; 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 /* Assembler register definitions. */
61 #define MOVP mov.w /* pointers are 16 bits */
76 #if defined (__H8300H__) || defined (__H8300S__)
77 #define MOVP mov.l /* pointers are 32 bits */
132 #endif /* L_cmpsi2 */
161 #endif /* L_ucmpsi2 */
165 ;; HImode divides for the H8/300.
166 ;; We bunch all of this into one object file since there are several
167 ;; "supporting routines".
169 ; general purpose normalize routine
173 ; turns both into +ve numbers, and leaves what the answer sign
181 or A0H,A0H ; is divisor > 0
183 not A0H ; no - then make it +ve
186 xor #0x1,A2L ; and remember that in A2L
187 _lab1: or A1H,A1H ; look at dividend
189 not A1H ; it is -ve, make it positive
192 xor #0x1,A2L; and toggle sign of result
194 ;; Basically the same, except that the sign of the divisor determines
198 or A0H,A0H ; is divisor > 0
200 not A0H ; no - then make it +ve
203 xor #0x1,A2L ; and remember that in A2L
204 _lab7: or A1H,A1H ; look at dividend
206 not A1H ; it is -ve, make it positive
217 negans: or A2L,A2L ; should answer be negative ?
219 not A0H ; yes, so make it so
244 ; D high 8 bits of denom
245 ; d low 8 bits of denom
246 ; N high 8 bits of num
247 ; n low 8 bits of num
248 ; M high 8 bits of mod
249 ; m low 8 bits of mod
250 ; Q high 8 bits of quot
251 ; q low 8 bits of quot
254 ; The h8 only has a 16/8 bit divide, so we look at the incoming and
255 ; see how to partition up the expression.
261 sub.w A3,A3 ; Nn Dd xP 00
267 ; we know that D == 0 and N is != 0
268 mov.b A0H,A3L ; Nn Dd xP 0N
272 _lab6: mov.b A0L,A3L ; n
276 mov.b #0x0,A3H ; Qq 0m
279 ; D != 0 - which means the denominator is
280 ; loop around to get the result.
283 mov.b A0H,A3L ; Nn Dd xP 0N
284 mov.b #0x0,A0H ; high byte of answer has to be zero
286 div8: add.b A0L,A0L ; n*=2
287 rotxl A3L ; Make remainder bigger
290 bhs setbit ; set a bit ?
291 add.w A1,A3 ; no : too far , Q+=N
297 setbit: inc A0L ; do insert bit
302 #endif /* __H8300__ */
303 #endif /* L_divhi3 */
307 ;; 4 byte integer divides for the H8/300.
309 ;; We have one routine which does all the work and lots of
310 ;; little ones which prepare the args and massage the sign.
311 ;; We bunch all of this into one object file since there are several
312 ;; "supporting routines".
317 ; Put abs SIs into r0/r1 and r2/r3, and leave a 1 in r6l with sign of rest.
318 ; This function is here to keep branch displacements small.
323 mov.b #0,S2L ; keep the sign in S2
324 mov.b A0H,A0H ; is the numerator -ve
338 mov.b #1,S2L ; the sign will be -ve
340 mov.b A2H,A2H ; is the denominator -ve
350 xor #1,S2L ; toggle result sign
354 ;; Basically the same, except that the sign of the divisor determines
357 mov.b #0,S2L ; keep the sign in S2
358 mov.b A0H,A0H ; is the numerator -ve
372 mov.b #1,S2L ; the sign will be -ve
374 mov.b A2H,A2H ; is the denominator -ve
387 #else /* __H8300H__ */
390 mov.b #0,S2L ; keep the sign in S2
391 mov.l A0P,A0P ; is the numerator -ve
394 neg.l A0P ; negate arg
395 mov.b #1,S2L ; the sign will be -ve
398 mov.l A1P,A1P ; is the denominator -ve
401 neg.l A1P ; negate arg
402 xor.b #1,S2L ; toggle result sign
407 ;; Basically the same, except that the sign of the divisor determines
410 mov.b #0,S2L ; keep the sign in S2
411 mov.l A0P,A0P ; is the numerator -ve
414 neg.l A0P ; negate arg
415 mov.b #1,S2L ; the sign will be -ve
418 mov.l A1P,A1P ; is the denominator -ve
421 neg.l A1P ; negate arg
429 ; denominator in A2/A3
451 mov.b #0,S2L ; keep sign low
460 mov.b #0,S2L ; keep sign low
478 ; examine what the sign should be
497 #else /* __H8300H__ */
505 ; takes A0/A1 numerator (A0P for 300h)
506 ; A2/A3 denominator (A1P for 300h)
507 ; returns A0/A1 quotient (A0P for 300h)
508 ; S0/S1 remainder (S0P for 300h)
514 sub.w S0,S0 ; zero play area
548 ; have to do the divide by shift and test
556 mov.b #24,S2H ; only do 24 iterations
559 add.w A1,A1 ; double the answer guess
563 rotxl S1L ; double remainder
567 sub.w A3,S1 ; does it all fit
572 add.w A3,S1 ; no, restore mistake
586 #else /* __H8300H__ */
589 sub.l S0P,S0P ; zero play area
590 mov.w A1E,A1E ; denominator top word 0?
593 ; do it the easy way, see page 107 in manual
612 mov.b #24,S2H ; only do 24 iterations
615 shll.l A0P ; double the answer guess
616 rotxl.l S0P ; double remainder
617 sub.l A1P,S0P ; does it all fit?
620 add.l A1P,S0P ; no, restore mistake
632 #endif /* L_divsi3 */
637 ; The h8 only has an 8*8->16 multiply.
638 ; The answer is the same as:
640 ; product = (srca.l * srcb.l) + ((srca.h * srcb.l) + (srcb.h * srca.l)) * 256
641 ; (we can ignore A1.h * A0.h cause that will all off the top)
651 mov.b A1L,A2L ; A2l gets srcb.l
652 mulxu A0L,A2 ; A2 gets first sub product
654 mov.b A0H,A3L ; prepare for
655 mulxu A1L,A3 ; second sub product
657 add.b A3L,A2H ; sum first two terms
659 mov.b A1H,A3L ; third sub product
662 add.b A3L,A2H ; almost there
663 mov.w A2,A0 ; that is
667 #endif /* L_mulhi3 */
673 ;; I think that shift and add may be sufficient for this. Using the
674 ;; supplied 8x8->16 would need 10 ops of 14 cycles each + overhead. This way
675 ;; the inner loop uses maybe 20 cycles + overhead, but terminates
676 ;; quickly on small args.
736 #else /* __H8300H__ */
766 #endif /* L_mulsi3 */