1 ;; libgcc routines for the Hitachi H8/300 CPU.
2 ;; Contributed by Steve Chamberlain <sac@cygnus.com>
3 ;; Optimizations by Toshiyasu Morita <toshiyasu.morita@hsa.hitachi.com>
5 /* Copyright
(C
) 1994, 2000, 2001, 2002 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
into combinations with other programs
,
15 and to distribute those combinations without any restriction coming
16 from the use of
this file.
(The General
Public License restrictions
17 do apply
in other respects
; for example, they cover modification of
18 the file
, and distribution when
not linked
into a combine
21 This file is distributed
in the hope that it will be useful
, but
22 WITHOUT ANY WARRANTY
; without even the implied warranty of
23 MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General
Public License for more details.
26 You should have received a copy of the GNU General
Public License
27 along with
this program
; see the file COPYING. If not, write to
28 the Free Software Foundation
, 59 Temple Place
- Suite
330,
29 Boston
, MA
02111-1307, USA.
*/
31 /* Assembler register definitions.
*/
74 #if defined
(__H8300H__
) || defined
(__H8300S__
)
93 #ifdef __NORMAL_MODE__
101 #ifdef __NORMAL_MODE__
132 #endif
/* L_cmpsi2
*/
158 #endif
/* L_ucmpsi2
*/
162 ;; HImode divides for the H8/300.
163 ;; We bunch all of this into one object file since there are several
164 ;; "supporting routines".
166 ; general purpose normalize routine
170 ; turns both into +ve numbers, and leaves what the answer sign
178 or A0H
,A0H
; is divisor > 0
180 not A0H
; no - then make it +ve
183 xor #
0x1,A2L
; and remember that in A2L
184 _lab1: or A1H
,A1H
; look at dividend
186 not A1H
; it is -ve, make it positive
189 xor #
0x1,A2L
; and toggle sign of result
191 ;; Basically the same, except that the sign of the divisor determines
195 or A0H
,A0H
; is divisor > 0
197 not A0H
; no - then make it +ve
200 xor #
0x1,A2L
; and remember that in A2L
201 _lab7: or A1H
,A1H
; look at dividend
203 not A1H
; it is -ve, make it positive
214 negans: or A2L
,A2L
; should answer be negative ?
216 not A0H
; yes, so make it so
241 ; D high 8 bits of denom
242 ; d low 8 bits of denom
243 ; N high 8 bits of num
244 ; n low 8 bits of num
245 ; M high 8 bits of mod
246 ; m low 8 bits of mod
247 ; Q high 8 bits of quot
248 ; q low 8 bits of quot
251 ; The H8/300 only has a 16/8 bit divide, so we look at the incoming and
252 ; see how to partition up the expression.
258 sub.w A3
,A3
; Nn Dd xP 00
264 ; we know that D == 0 and N is != 0
265 mov.b A0H
,A3L
; Nn Dd xP 0N
269 _lab6: mov.b A0L
,A3L
; n
273 mov.b #
0x0,A3H
; Qq 0m
276 ; D != 0 - which means the denominator is
277 ; loop around to get the result.
280 mov.b A0H
,A3L
; Nn Dd xP 0N
281 mov.b #
0x0,A0H
; high byte of answer has to be zero
283 div8: add.b A0L
,A0L
; n*=2
284 rotxl A3L
; Make remainder bigger
287 bhs setbit
; set a bit ?
288 add.w A1
,A3
; no : too far , Q+=N
294 setbit: inc A0L
; do insert bit
299 #endif
/* __H8300__
*/
300 #endif
/* L_divhi3
*/
304 ;; 4 byte integer divides for the H8/300.
306 ;; We have one routine which does all the work and lots of
307 ;; little ones which prepare the args and massage the sign.
308 ;; We bunch all of this into one object file since there are several
309 ;; "supporting routines".
314 ; Put abs SIs into r0/r1 and r2/r3, and leave a 1 in r6l with sign of rest.
315 ; This function is here to keep branch displacements small.
320 mov.b A0H
,A0H
; is the numerator -ve
321 stc ccr
,S2L
; keep the sign in bit 3 of S2L
335 mov.b A2H
,A2H
; is the denominator -ve
345 xor.b #
0x08,S2L
; toggle the result sign
349 ;; Basically the same, except that the sign of the divisor determines
352 mov.b A0H
,A0H
; is the numerator -ve
353 stc ccr
,S2L
; keep the sign in bit 3 of S2L
367 mov.b A2H
,A2H
; is the denominator -ve
380 #else
/* __H8300H__
*/
383 mov.l A0P
,A0P
; is the numerator -ve
384 stc ccr
,S2L
; keep the sign in bit 3 of S2L
387 neg.l A0P
; negate arg
390 mov.l A1P
,A1P
; is the denominator -ve
393 neg.l A1P
; negate arg
394 xor.b #
0x08,S2L
; toggle the result sign
399 ;; Basically the same, except that the sign of the divisor determines
402 mov.l A0P
,A0P
; is the numerator -ve
403 stc ccr
,S2L
; keep the sign in bit 3 of S2L
406 neg.l A0P
; negate arg
409 mov.l A1P
,A1P
; is the denominator -ve
412 neg.l A1P
; negate arg
420 ; denominator in A2/A3
440 ;; H8/300H and H8S version of ___udivsi3 is defined later in
482 ; examine what the sign should be
498 #else
/* __H8300H__
*/
510 ; takes A0/A1 numerator (A0P for H8/300H)
511 ; A2/A3 denominator (A1P for H8/300H)
512 ; returns A0/A1 quotient (A0P for H8/300H)
513 ; S0/S1 remainder (S0P for H8/300H)
519 sub.w S0
,S0
; zero play area
553 ; have to do the divide by shift and test
561 mov.b #
24,S2H
; only do 24 iterations
564 add.w A1
,A1
; double the answer guess
568 rotxl S1L
; double remainder
572 sub.w A3
,S1
; does it all fit
577 add.w A3
,S1
; no, restore mistake
591 #else
/* __H8300H__
*/
593 ;; This function also computes the remainder and stores it in er3.
596 mov.w A1E
,A1E
; denominator top word 0?
599 ; do it the easy way, see page 107 in manual
613 ; expects er1 >= 2^16
620 shlr.l er2
; make divisor < 2^16
624 shlr.l #
2,er2
; make divisor < 2^16
630 shlr.l #
2,er2
; make divisor < 2^16
644 ;; er0 contains shifted dividend
645 ;; er1 contains divisor
646 ;; er2 contains shifted divisor
647 ;; er3 contains dividend, later remainder
648 divxu.w r2
,er0
; r0 now contains the approximate quotient (AQ)
651 subs #
1,er0
; er0 = AQ - 1
653 mulxu.w r0
,er2
; er2 = upper (AQ - 1) * divisor
654 sub.w r2
,e3
; dividend - 65536 * er2
656 mulxu.w r0
,er2
; compute er3 = remainder (tentative)
657 sub.l er2
,er3
; er3 = dividend - (AQ - 1) * divisor
659 cmp.l er1
,er3
; is divisor < remainder?
662 sub.l er1
,er3
; correct the remainder
667 #endif
/* L_divsi3
*/
672 ; The H8/300 only has an 8*8->16 multiply.
673 ; The answer is the same as:
675 ; product = (srca.l * srcb.l) + ((srca.h * srcb.l) + (srcb.h * srca.l)) * 256
676 ; (we can ignore A1.h * A0.h cause that will all off the top)
686 mov.b A1L
,A2L
; A2l gets srcb.l
687 mulxu A0L
,A2
; A2 gets first sub product
689 mov.b A0H
,A3L
; prepare for
690 mulxu A1L
,A3
; second sub product
692 add.b A3L
,A2H
; sum first two terms
694 mov.b A1H
,A3L
; third sub product
697 add.b A3L
,A2H
; almost there
698 mov.w A2
,A0
; that is
702 #endif
/* L_mulhi3
*/
708 ;; I think that shift and add may be sufficient for this. Using the
709 ;; supplied 8x8->16 would need 10 ops of 14 cycles each + overhead. This way
710 ;; the inner loop uses maybe 20 cycles + overhead, but terminates
711 ;; quickly on small args.
769 #else
/* __H8300H__
*/
772 ; mulsi3 for H8/300H - based on Hitachi SH implementation
774 ; by Toshiyasu Morita
778 ; 16b * 16b = 372 states (worst case)
779 ; 32b * 32b = 724 states (worst case)
783 ; 16b * 16b = 48 states
784 ; 16b * 32b = 72 states
785 ; 32b * 32b = 92 states
790 mov.w r1
,r2
; ( 2 states) b * d
791 mulxu r0
,er2
; (22 states)
793 mov.w e0
,r3
; ( 2 states) a * d
794 beq L_skip1
; ( 4 states)
795 mulxu r1
,er3
; (22 states)
796 add.w r3
,e2
; ( 2 states)
799 mov.w e1
,r3
; ( 2 states) c * b
800 beq L_skip2
; ( 4 states)
801 mulxu r0
,er3
; (22 states)
802 add.w r3
,e2
; ( 2 states)
805 mov.l er2
,er0
; ( 2 states)
809 #endif
/* L_mulsi3
*/
810 #ifdef L_fixunssfsi_asm
811 /* For the h8300 we use asm to save some bytes
, to
812 allow more programs to fit
into the tiny address
813 space. For the H8
/300H and H8S
, the C version is good enough.
*/
815 /* We still treat NANs different than libgcc2.c
, but then
, the
816 behavior is undefined anyways.
*/
817 .
global ___fixunssfsi
837 #endif
/* L_fixunssfsi_asm
*/