1 ;; libgcc1 routines for the Hitachi h8/300 cpu.
2 ;; Contributed by Steve Chamberlain.
5 /* Copyright (C) 1994 Free Software Foundation, Inc.
7 This file is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
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 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 /* As a special exception, if you link this library with other files,
31 some of which are compiled with GCC, to produce an executable,
32 this library does not by itself cause the resulting executable
33 to be covered by the GNU General Public License.
34 This exception does not however invalidate any other reasons why
35 the executable file might be covered by the GNU General Public License. */
37 /* Assembler register definitions. */
68 #define MOVP mov.w /* pointers are 16 bits */
84 #define MOVP mov.l /* pointers are 32 bits */
131 #endif /* L_cmpsi2 */
160 #endif /* L_ucmpsi2 */
164 ;; HImode divides for the H8/300.
165 ;; We bunch all of this into one object file since there are several
166 ;; "supporting routines".
168 ; general purpose normalize routine
172 ; turns both into +ve numbers, and leaves what the answer sign
180 or A0H,A0H ; is divisor > 0
182 not A0H ; no - then make it +ve
185 xor #0x1,A2L ; and remember that in A2L
186 _lab1: or A1H,A1H ; look at dividend
188 not A1H ; it is -ve, make it positive
191 xor #0x1,A2L; and toggle sign of result
200 negans: or A2L,A2L ; should answer be negative ?
202 not A0H ; yes, so make it so
227 ; D high 8 bits of denom
228 ; d low 8 bits of denom
229 ; N high 8 bits of num
230 ; n low 8 bits of num
231 ; M high 8 bits of mod
232 ; m low 8 bits of mod
233 ; Q high 8 bits of quot
234 ; q low 8 bits of quot
237 ; The h8 only has a 16/8 bit divide, so we look at the incoming and
238 ; see how to partition up the expression.
244 sub.w A3,A3 ; Nn Dd xP 00
250 ; we know that D == 0 and N is != 0
251 mov.b A0H,A3L ; Nn Dd xP 0N
255 _lab6: mov.b A0L,A3L ; n
259 mov.b #0x0,A3H ; Qq 0m
262 ; D != 0 - which means the denominator is
263 ; loop around to get the result.
266 mov.b A0H,A3L ; Nn Dd xP 0N
267 mov.b #0x0,A0H ; high byte of answer has to be zero
269 div8: add.b A0L,A0L ; n*=2
270 rotxl A3L ; Make remainder bigger
273 bhs setbit ; set a bit ?
274 add.w A1,A3 ; no : too far , Q+=N
280 setbit: inc A0L ; do insert bit
285 #endif /* __H8300__ */
286 #endif /* L_divhi3 */
290 ;; 4 byte integer divides for the H8/300.
292 ;; We have one routine which does all the work and lots of
293 ;; little ones which prepare the args and massage the sign.
294 ;; We bunch all of this into one object file since there are several
295 ;; "supporting routines".
304 ; Put abs SIs into r0/r1 and r2/r3, and leave a 1 in r6l with sign of rest.
305 ; This function is here to keep branch displacements small.
310 mov.b #0,S2L ; keep the sign in S2
311 mov.b A0H,A0H ; is the numerator -ve
325 mov.b #1,S2L ; the sign will be -ve
327 mov.b A2H,A2H ; is the denominator -ve
337 xor #1,S2L ; toggle result sign
341 #else /* __H8300H__ */
344 mov.b #0,S2L ; keep the sign in S2
345 mov.l A0P,A0P ; is the numerator -ve
348 neg.l A0P ; negate arg
349 mov.b #1,S2L ; the sign will be -ve
352 mov.l A1P,A1P ; is the denominator -ve
355 neg.l A1P ; negate arg
356 xor.b #1,S2L ; toggle result sign
364 ; denominator in A2/A3
386 mov.b #0,S2L ; keep sign low
395 mov.b #0,S2L ; keep sign low
413 ; examine what the sign should be
432 #else /* __H8300H__ */
440 ; takes A0/A1 numerator (A0P for 300h)
441 ; A2/A3 denominator (A1P for 300h)
442 ; returns A0/A1 quotient (A0P for 300h)
443 ; S0/S1 remainder (S0P for 300h)
449 sub.w S0,S0 ; zero play area
483 ; have to do the divide by shift and test
491 mov.b #24,S2H ; only do 24 iterations
494 add.w A1,A1 ; double the answer guess
498 rotxl S1L ; double remainder
502 sub.w A3,S1 ; does it all fit
507 add.w A3,S1 ; no, restore mistake
521 #else /* __H8300H__ */
524 sub.l S0P,S0P ; zero play area
525 mov.w A1E,A1E ; denominator top word 0?
528 ; do it the easy way, see page 107 in manual
547 mov.b #24,S2H ; only do 24 iterations
550 shll.l A0P ; double the answer guess
551 rotxl.l S0P ; double remainder
552 sub.l A1P,S0P ; does it all fit?
555 add.l A1P,S0P ; no, restore mistake
567 #endif /* L_divsi3 */
572 ; The h8 only has an 8*8->16 multiply.
573 ; The answer is the same as:
575 ; product = (srca.l * srcb.l) + ((srca.h * srcb.l) + (srcb.h * srca.l)) * 256
576 ; (we can ignore A1.h * A0.h cause that will all off the top)
586 mov.b A1L,A2L ; A2l gets srcb.l
587 mulxu A0L,A2 ; A2 gets first sub product
589 mov.b A0H,A3L ; prepare for
590 mulxu A1L,A3 ; second sub product
592 add.b A3L,A2H ; sum first two terms
594 mov.b A1H,A3L ; third sub product
597 add.b A3L,A2H ; almost there
598 mov.w A2,A0 ; that is
602 #endif /* L_mulhi3 */
608 ;; I think that shift and add may be sufficient for this. Using the
609 ;; supplied 8x8->16 would need 10 ops of 14 cycles each + overhead. This way
610 ;; the inner loop uses maybe 20 cycles + overhead, but terminates
611 ;; quickly on small args.
671 #else /* __H8300H__ */
703 #endif /* L_mulsi3 */