mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 01:40:39 +08:00
cmpsi2.S: Use function start and end macros.
* config/rl78/cmpsi2.S: Use function start and end macros. (__gcc_bcmp): New function. * config/rl78/lshrsi3.S: Use function start and end macros. * config/rl78/mulsi3.S: Add support for G10. (__mulqi3): New function for G10. * config/rl78/signbit.S: Use function start and end macros. * config/rl78/t-rl78 (LIB2ADD): Add bit-count.S, fpbit-sf.S and fpmath-sf.S. (LIB2FUNCS_EXCLUDE): Define. (LIB2FUNCS_ST): Define. * config/rl78/trampoline.S: Use function start and end macros. * config/rl78/vregs.h (START_FUNC): New macro. (START_ANOTHER_FUNC): New macro. (END_FUNC): New macro. (END_ANOTHER_FUNC): New macro. * config/rl78/bit-count.S: New file. Contains assembler implementations of the bit counting functions: ___clzhi2, __clzsi2, ctzhi2, ctzsi2, ffshi2, ffssi2, __partityhi2, __paritysi2, __popcounthi2 and __popcountsi2. * config/rl78/fpbit-sf.S: New file. Contains assembler implementationas of the math functions: __negsf2, __cmpsf2, __eqsf2, __nesf2, __lesf2, __ltsf2, __gesf2, gtsf2, __unordsf2, __fixsfsi, __fixunssfsi, __floatsisf and __floatunssisf. * config/rl78/fpmath-sf.S: New file. Contains assembler implementations of the math functions: __subsf3, __addsf3, __mulsf3 and __divsf3 From-SVN: r220162
This commit is contained in:
parent
506f03c370
commit
8410904a77
@ -1,3 +1,32 @@
|
||||
2015-01-27 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* config/rl78/cmpsi2.S: Use function start and end macros.
|
||||
(__gcc_bcmp): New function.
|
||||
* config/rl78/lshrsi3.S: Use function start and end macros.
|
||||
* config/rl78/mulsi3.S: Add support for G10.
|
||||
(__mulqi3): New function for G10.
|
||||
* config/rl78/signbit.S: Use function start and end macros.
|
||||
* config/rl78/t-rl78 (LIB2ADD): Add bit-count.S, fpbit-sf.S and
|
||||
fpmath-sf.S.
|
||||
(LIB2FUNCS_EXCLUDE): Define.
|
||||
(LIB2FUNCS_ST): Define.
|
||||
* config/rl78/trampoline.S: Use function start and end macros.
|
||||
* config/rl78/vregs.h (START_FUNC): New macro.
|
||||
(START_ANOTHER_FUNC): New macro.
|
||||
(END_FUNC): New macro.
|
||||
(END_ANOTHER_FUNC): New macro.
|
||||
* config/rl78/bit-count.S: New file. Contains assembler
|
||||
implementations of the bit counting functions: ___clzhi2,
|
||||
__clzsi2, ctzhi2, ctzsi2, ffshi2, ffssi2, __partityhi2,
|
||||
__paritysi2, __popcounthi2 and __popcountsi2.
|
||||
* config/rl78/fpbit-sf.S: New file. Contains assembler
|
||||
implementationas of the math functions: __negsf2, __cmpsf2,
|
||||
__eqsf2, __nesf2, __lesf2, __ltsf2, __gesf2, gtsf2, __unordsf2,
|
||||
__fixsfsi, __fixunssfsi, __floatsisf and __floatunssisf.
|
||||
* config/rl78/fpmath-sf.S: New file. Contains assembler
|
||||
implementations of the math functions: __subsf3, __addsf3,
|
||||
__mulsf3 and __divsf3
|
||||
|
||||
2015-01-27 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
* config.host (i[34567]86-*-solaris2*, x86_64-*-solaris2.1[0-9]*):
|
||||
|
213
libgcc/config/rl78/bit-count.S
Normal file
213
libgcc/config/rl78/bit-count.S
Normal file
@ -0,0 +1,213 @@
|
||||
; Copyright (C) 2012-2014 Free Software Foundation, Inc.
|
||||
; Contributed by Red Hat.
|
||||
;
|
||||
; This file is free software; you can redistribute it and/or modify it
|
||||
; under the terms of the GNU General Public License as published by the
|
||||
; Free Software Foundation; either version 3, or (at your option) any
|
||||
; later version.
|
||||
;
|
||||
; This file is distributed in the hope that it will be useful, but
|
||||
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; General Public License for more details.
|
||||
;
|
||||
; Under Section 7 of GPL version 3, you are granted additional
|
||||
; permissions described in the GCC Runtime Library Exception, version
|
||||
; 3.1, as published by the Free Software Foundation.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License and
|
||||
; a copy of the GCC Runtime Library Exception along with this program;
|
||||
; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
; <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "vregs.h"
|
||||
|
||||
START_FUNC ___clzhi2
|
||||
;; Argument is in [SP+4], return in R8.
|
||||
movw ax, [SP+4]
|
||||
|
||||
.global __clzhi2_internal
|
||||
__clzhi2_internal:
|
||||
movw r8, #16
|
||||
cmpw ax, #0
|
||||
bz $clzhi2_is_zero
|
||||
mov e, #0xff
|
||||
1:
|
||||
inc e
|
||||
shlw ax, 1
|
||||
bnc $1b
|
||||
mov a, e
|
||||
mov r8, a
|
||||
clzhi2_is_zero:
|
||||
ret
|
||||
END_FUNC ___clzhi2
|
||||
|
||||
|
||||
START_FUNC ___clzsi2
|
||||
;; Argument is in [SP+6]:[SP+4], return in R8.
|
||||
movw ax, [SP+6]
|
||||
cmpw ax, #0
|
||||
bnz $__clzhi2_internal
|
||||
movw ax, [SP+4]
|
||||
call !__clzhi2_internal
|
||||
movw ax, r8
|
||||
addw ax, #16
|
||||
movw r8, ax
|
||||
ret
|
||||
END_FUNC ___clzsi2
|
||||
|
||||
|
||||
START_FUNC ___ctzhi2
|
||||
;; Argument is in [SP+4], return in R8.
|
||||
movw ax, [SP+4]
|
||||
|
||||
.global __ctzhi2_internal
|
||||
__ctzhi2_internal:
|
||||
movw r8, #16
|
||||
cmpw ax, #0
|
||||
bz $ctzhi2_is_zero
|
||||
mov e, #0xff
|
||||
1:
|
||||
inc e
|
||||
shrw ax, 1
|
||||
bnc $1b
|
||||
mov a, e
|
||||
mov r8, a
|
||||
ctzhi2_is_zero:
|
||||
ret
|
||||
END_FUNC ___ctzhi2
|
||||
|
||||
|
||||
START_FUNC ___ctzsi2
|
||||
;; Argument is in [SP+6]:[SP+4], return in R8.
|
||||
movw ax, [SP+4]
|
||||
cmpw ax, #0
|
||||
bnz $__ctzhi2_internal
|
||||
movw ax, [SP+6]
|
||||
call !__ctzhi2_internal
|
||||
movw ax, r8
|
||||
addw ax, #16
|
||||
movw r8, ax
|
||||
ret
|
||||
END_FUNC ___ctzsi2
|
||||
|
||||
|
||||
START_FUNC ___ffshi2
|
||||
;; Argument is in [SP+4], return in R8.
|
||||
movw ax, [SP+4]
|
||||
|
||||
.global __ffshi2_internal
|
||||
__ffshi2_internal:
|
||||
movw r8, #0
|
||||
cmpw ax, #0
|
||||
bz $ffshi2_is_zero
|
||||
mov e, #0
|
||||
1:
|
||||
inc e
|
||||
shrw ax, 1
|
||||
bnc $1b
|
||||
mov a, e
|
||||
mov r8, a
|
||||
ffshi2_is_zero:
|
||||
ret
|
||||
END_FUNC ___ffshi2
|
||||
|
||||
|
||||
START_FUNC ___ffssi2
|
||||
;; Argument is in [SP+6]:[SP+4], return in R8.
|
||||
movw ax, [SP+4]
|
||||
cmpw ax, #0
|
||||
bnz $__ffshi2_internal
|
||||
movw ax, [SP+6]
|
||||
cmpw ax, #0
|
||||
bz $1f
|
||||
call !__ffshi2_internal
|
||||
movw ax, r8
|
||||
addw ax, #16
|
||||
1:
|
||||
movw r8, ax
|
||||
ret
|
||||
END_FUNC ___ffssi2
|
||||
|
||||
|
||||
START_FUNC ___parityqi_internal
|
||||
mov1 cy, a.0
|
||||
xor1 cy, a.1
|
||||
xor1 cy, a.2
|
||||
xor1 cy, a.3
|
||||
xor1 cy, a.4
|
||||
xor1 cy, a.5
|
||||
xor1 cy, a.6
|
||||
xor1 cy, a.7
|
||||
movw ax, #0
|
||||
bnc $1f
|
||||
incw ax
|
||||
1:
|
||||
movw r8, ax
|
||||
ret
|
||||
END_FUNC ___parityqi_internal
|
||||
|
||||
|
||||
START_FUNC ___parityhi2
|
||||
;; Argument is in [SP+4], return in R8.
|
||||
movw ax, [SP+4]
|
||||
xor a, x
|
||||
br $___parityqi_internal
|
||||
END_FUNC ___parityhi2
|
||||
|
||||
|
||||
START_FUNC ___paritysi2
|
||||
;; Argument is in [SP+6]:[SP+4], return in R8.
|
||||
movw ax, [SP+4]
|
||||
xor a, x
|
||||
mov b, a
|
||||
movw ax, [SP+6]
|
||||
xor a, x
|
||||
xor a, b
|
||||
br $___parityqi_internal
|
||||
END_FUNC ___paritysi2
|
||||
|
||||
|
||||
|
||||
START_FUNC ___popcounthi2
|
||||
;; Argument is in [SP+4], return in R8.
|
||||
mov d, #2
|
||||
br $___popcountqi_internal
|
||||
END_FUNC ___popcounthi2
|
||||
|
||||
|
||||
START_FUNC ___popcountsi2
|
||||
;; Argument is in [SP+6]:[SP+4], return in R8.
|
||||
mov d, #4
|
||||
br $___popcountqi_internal
|
||||
END_FUNC ___popcountsi2
|
||||
|
||||
|
||||
START_FUNC ___popcountqi_internal
|
||||
;; There are D bytes starting at [HL]
|
||||
;; store count in R8.
|
||||
|
||||
movw ax, sp
|
||||
addw ax, #4
|
||||
movw hl, ax
|
||||
mov a, #0
|
||||
1:
|
||||
xch a, b
|
||||
mov a, [hl]
|
||||
xch a, b
|
||||
mov e, #8
|
||||
2:
|
||||
shl b,1
|
||||
addc a, #0
|
||||
dec e
|
||||
bnz $2b
|
||||
|
||||
incw hl
|
||||
dec d
|
||||
bnz $1b
|
||||
|
||||
mov x, a
|
||||
mov a, #0
|
||||
movw r8, ax
|
||||
ret
|
||||
END_FUNC ___popcountqi_internal
|
@ -31,9 +31,8 @@
|
||||
;; If A is less than B it returns 0. If A is greater
|
||||
;; than B it returns 2. If they are equal it returns 1.
|
||||
|
||||
.global ___cmpsi2
|
||||
.type ___cmpsi2, @function
|
||||
___cmpsi2:
|
||||
START_FUNC ___cmpsi2
|
||||
|
||||
;; A is at [sp+4]
|
||||
;; B is at [sp+8]
|
||||
;; Result put in R8
|
||||
@ -88,18 +87,18 @@ ___cmpsi2:
|
||||
movw r8, ax
|
||||
ret
|
||||
|
||||
.size ___cmpsi2, . - ___cmpsi2
|
||||
|
||||
|
||||
END_FUNC ___cmpsi2
|
||||
|
||||
;; ------------------------------------------------------
|
||||
|
||||
;; int __ucmpsi2 (unsigned long A, unsigned long B)
|
||||
;;
|
||||
;; Performs an unsigned comparison of A and B.
|
||||
;; If A is less than B it returns 0. If A is greater
|
||||
;; than B it returns 2. If they are equal it returns 1.
|
||||
|
||||
.global ___ucmpsi2
|
||||
.type ___ucmpsi2, @function
|
||||
___ucmpsi2:
|
||||
START_FUNC ___ucmpsi2
|
||||
|
||||
;; A is at [sp+4]
|
||||
;; B is at [sp+8]
|
||||
;; Result put in R8..R9
|
||||
@ -117,5 +116,57 @@ ___ucmpsi2:
|
||||
br !!.Lless_than_or_greater_than
|
||||
br !!.Lcompare_bottom_words
|
||||
|
||||
.size ___ucmpsi2, . - ___ucmpsi2
|
||||
|
||||
END_FUNC ___ucmpsi2
|
||||
|
||||
;; ------------------------------------------------------
|
||||
|
||||
;; signed int __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
|
||||
;; Result is negative if S1 is less than S2,
|
||||
;; positive if S1 is greater, 0 if S1 and S2 are equal.
|
||||
|
||||
START_FUNC __gcc_bcmp
|
||||
|
||||
;; S1 is at [sp+4]
|
||||
;; S2 is at [sp+6]
|
||||
;; SIZE is at [sp+8]
|
||||
;; Result in r8/r9
|
||||
|
||||
movw r10, #0
|
||||
1:
|
||||
;; Compare R10 against the SIZE parameter
|
||||
movw ax, [sp+8]
|
||||
subw ax, r10
|
||||
sknz
|
||||
br !!1f
|
||||
|
||||
;; Load S2[r10] into R8
|
||||
movw ax, [sp+6]
|
||||
addw ax, r10
|
||||
movw hl, ax
|
||||
mov a, [hl]
|
||||
mov r8, a
|
||||
|
||||
;; Load S1[r10] into A
|
||||
movw ax, [sp+4]
|
||||
addw ax, r10
|
||||
movw hl, ax
|
||||
mov a, [hl]
|
||||
|
||||
;; Increment offset
|
||||
incw r10
|
||||
|
||||
;; Compare loaded bytes
|
||||
cmp a, r8
|
||||
sknz
|
||||
br !!1b
|
||||
|
||||
;; They differ. Subtract *S2 from *S1 and return as the result.
|
||||
mov x, a
|
||||
mov a, #0
|
||||
mov r9, #0
|
||||
subw ax, r8
|
||||
1:
|
||||
movw r8, ax
|
||||
ret
|
||||
|
||||
END_FUNC __gcc_bcmp
|
||||
|
608
libgcc/config/rl78/fpbit-sf.S
Normal file
608
libgcc/config/rl78/fpbit-sf.S
Normal file
@ -0,0 +1,608 @@
|
||||
; SF format is:
|
||||
;
|
||||
; [sign] 1.[23bits] E[8bits(n-127)]
|
||||
;
|
||||
; SEEEEEEE Emmmmmmm mmmmmmmm mmmmmmmm
|
||||
;
|
||||
; [A+0] mmmmmmmm
|
||||
; [A+1] mmmmmmmm
|
||||
; [A+2] Emmmmmmm
|
||||
; [A+3] SEEEEEEE
|
||||
;
|
||||
; Special values (xxx != 0):
|
||||
;
|
||||
; s1111111 10000000 00000000 00000000 infinity
|
||||
; s1111111 1xxxxxxx xxxxxxxx xxxxxxxx NaN
|
||||
; s0000000 00000000 00000000 00000000 zero
|
||||
; s0000000 0xxxxxxx xxxxxxxx xxxxxxxx denormals
|
||||
;
|
||||
; Note that CMPtype is "signed char" for rl78
|
||||
;
|
||||
|
||||
#include "vregs.h"
|
||||
|
||||
#define Z PSW.6
|
||||
|
||||
START_FUNC ___negsf2
|
||||
|
||||
;; Negate the floating point value.
|
||||
;; Input at [SP+4]..[SP+7].
|
||||
;; Output to R8..R11.
|
||||
|
||||
movw ax, [SP+4]
|
||||
movw r8, ax
|
||||
movw ax, [SP+6]
|
||||
xor a, #0x80
|
||||
movw r10, ax
|
||||
ret
|
||||
|
||||
END_FUNC ___negsf2
|
||||
|
||||
;; ------------------internal functions used by later code --------------
|
||||
|
||||
START_FUNC __int_isnan
|
||||
|
||||
;; [HL] points to value, returns Z if it's a NaN
|
||||
|
||||
mov a, [hl+2]
|
||||
and a, #0x80
|
||||
mov x, a
|
||||
mov a, [hl+3]
|
||||
and a, #0x7f
|
||||
cmpw ax, #0x7f80
|
||||
skz
|
||||
ret ; return NZ if not NaN
|
||||
mov a, [hl+2]
|
||||
and a, #0x7f
|
||||
or a, [hl+1]
|
||||
or a, [hl]
|
||||
bnz $1f
|
||||
clr1 Z ; Z, normal
|
||||
ret
|
||||
1:
|
||||
set1 Z ; nan
|
||||
ret
|
||||
|
||||
END_FUNC __int_isnan
|
||||
|
||||
START_FUNC __int_eithernan
|
||||
|
||||
;; call from toplevel functions, returns Z if either number is a NaN,
|
||||
;; or NZ if both are OK.
|
||||
|
||||
movw ax, sp
|
||||
addw ax, #8
|
||||
movw hl, ax
|
||||
call $!__int_isnan
|
||||
bz $1f
|
||||
|
||||
movw ax, sp
|
||||
addw ax, #12
|
||||
movw hl, ax
|
||||
call $!__int_isnan
|
||||
1:
|
||||
ret
|
||||
|
||||
END_FUNC __int_eithernan
|
||||
|
||||
START_FUNC __int_iszero
|
||||
|
||||
;; [HL] points to value, returns Z if it's zero
|
||||
|
||||
mov a, [hl+3]
|
||||
and a, #0x7f
|
||||
or a, [hl+2]
|
||||
or a, [hl+1]
|
||||
or a, [hl]
|
||||
ret
|
||||
|
||||
END_FUNC __int_iszero
|
||||
|
||||
START_FUNC __int_cmpsf
|
||||
|
||||
;; This is always called from some other function here,
|
||||
;; so the stack offsets are adjusted accordingly.
|
||||
|
||||
;; X [SP+8] <=> Y [SP+12] : <a> <=> 0
|
||||
|
||||
movw ax, sp
|
||||
addw ax, #8
|
||||
movw hl, ax
|
||||
call $!__int_iszero
|
||||
bnz $1f
|
||||
|
||||
movw ax, sp
|
||||
addw ax, #12
|
||||
movw hl, ax
|
||||
call $!__int_iszero
|
||||
bnz $2f
|
||||
;; At this point, both args are zero.
|
||||
mov a, #0
|
||||
ret
|
||||
|
||||
2:
|
||||
movw ax, sp
|
||||
addw ax, #8
|
||||
movw hl, ax
|
||||
1:
|
||||
;; At least one arg is non-zero so we can just compare magnitudes.
|
||||
;; Args are [HL] and [HL+4].
|
||||
|
||||
mov a, [HL+3]
|
||||
xor a, [HL+7]
|
||||
mov1 cy, a.7
|
||||
bnc $1f
|
||||
|
||||
mov a, [HL+3]
|
||||
sar a, 7
|
||||
or a, #1
|
||||
ret
|
||||
|
||||
1: ;; Signs the same, compare magnitude. It's safe to lump
|
||||
;; the sign bits, exponent, and mantissa together here, since they're
|
||||
;; stored in the right sequence.
|
||||
movw ax, [HL+2]
|
||||
cmpw ax, [HL+6]
|
||||
bc $ybig_cmpsf ; branch if X < Y
|
||||
bnz $xbig_cmpsf ; branch if X > Y
|
||||
|
||||
movw ax, [HL]
|
||||
cmpw ax, [HL+4]
|
||||
bc $ybig_cmpsf ; branch if X < Y
|
||||
bnz $xbig_cmpsf ; branch if X > Y
|
||||
|
||||
mov a, #0
|
||||
ret
|
||||
|
||||
xbig_cmpsf: ; |X| > |Y| so return A = 1 if pos, 0xff if neg
|
||||
mov a, [HL+3]
|
||||
sar a, 7
|
||||
or a, #1
|
||||
ret
|
||||
ybig_cmpsf: ; |X| < |Y| so return A = 0xff if pos, 1 if neg
|
||||
mov a, [HL+3]
|
||||
xor a, #0x80
|
||||
sar a, 7
|
||||
or a, #1
|
||||
ret
|
||||
|
||||
END_FUNC __int_cmpsf
|
||||
|
||||
;; ----------------------------------------------------------
|
||||
|
||||
START_FUNC ___cmpsf2
|
||||
;; This functions calculates "A <=> B". That is, if A is less than B
|
||||
;; they return -1, if A is greater than B, they return 1, and if A
|
||||
;; and B are equal they return 0. If either argument is NaN the
|
||||
;; behaviour is undefined.
|
||||
|
||||
;; Input at [SP+4]..[SP+7].
|
||||
;; Output to R8..R9.
|
||||
|
||||
call $!__int_eithernan
|
||||
bnz $1f
|
||||
movw r8, #1
|
||||
ret
|
||||
1:
|
||||
call $!__int_cmpsf
|
||||
mov r8, a
|
||||
sar a, 7
|
||||
mov r9, a
|
||||
ret
|
||||
|
||||
END_FUNC ___cmpsf2
|
||||
|
||||
;; ----------------------------------------------------------
|
||||
|
||||
;; These functions are all basically the same as ___cmpsf2
|
||||
;; except that they define how they handle NaNs.
|
||||
|
||||
START_FUNC ___eqsf2
|
||||
;; Returns zero iff neither argument is NaN
|
||||
;; and both arguments are equal.
|
||||
START_ANOTHER_FUNC ___nesf2
|
||||
;; Returns non-zero iff either argument is NaN or the arguments are
|
||||
;; unequal. Effectively __nesf2 is the same as __eqsf2
|
||||
START_ANOTHER_FUNC ___lesf2
|
||||
;; Returns a value less than or equal to zero if neither
|
||||
;; argument is NaN, and the first is less than or equal to the second.
|
||||
START_ANOTHER_FUNC ___ltsf2
|
||||
;; Returns a value less than zero if neither argument is
|
||||
;; NaN, and the first is strictly less than the second.
|
||||
|
||||
;; Input at [SP+4]..[SP+7].
|
||||
;; Output to R8.
|
||||
|
||||
mov r8, #1
|
||||
|
||||
;;; Fall through
|
||||
|
||||
START_ANOTHER_FUNC __int_cmp_common
|
||||
|
||||
call $!__int_eithernan
|
||||
sknz
|
||||
;; return value (pre-filled-in below) for "either is nan"
|
||||
ret
|
||||
|
||||
call $!__int_cmpsf
|
||||
mov r8, a
|
||||
ret
|
||||
|
||||
END_ANOTHER_FUNC __int_cmp_common
|
||||
END_ANOTHER_FUNC ___ltsf2
|
||||
END_ANOTHER_FUNC ___lesf2
|
||||
END_ANOTHER_FUNC ___nesf2
|
||||
END_FUNC ___eqsf2
|
||||
|
||||
START_FUNC ___gesf2
|
||||
;; Returns a value greater than or equal to zero if neither argument
|
||||
;; is a NaN and the first is greater than or equal to the second.
|
||||
START_ANOTHER_FUNC ___gtsf2
|
||||
;; Returns a value greater than zero if neither argument
|
||||
;; is NaN, and the first is strictly greater than the second.
|
||||
|
||||
mov r8, #0xffff
|
||||
br $__int_cmp_common
|
||||
|
||||
END_ANOTHER_FUNC ___gtsf2
|
||||
END_FUNC ___gesf2
|
||||
|
||||
;; ----------------------------------------------------------
|
||||
|
||||
START_FUNC ___unordsf2
|
||||
;; Returns a nonzero value if either argument is NaN, otherwise 0.
|
||||
|
||||
call $!__int_eithernan
|
||||
movw r8, #0
|
||||
sknz ; this is from the call, not the movw
|
||||
movw r8, #1
|
||||
ret
|
||||
|
||||
END_FUNC ___unordsf2
|
||||
|
||||
;; ----------------------------------------------------------
|
||||
|
||||
START_FUNC ___fixsfsi
|
||||
;; Converts its floating point argument into a signed long,
|
||||
;; rounding toward zero.
|
||||
;; The behaviour with NaNs and Infinities is not well defined.
|
||||
;; We choose to return 0 for NaNs, -INTMAX for -inf and INTMAX for +inf.
|
||||
;; This matches the behaviour of the C function in libgcc2.c.
|
||||
|
||||
;; Input at [SP+4]..[SP+7], result is in (lsb) R8..R11 (msb).
|
||||
|
||||
;; Special case handling for infinities as __fixunssfsi
|
||||
;; will not give us the values that we want.
|
||||
movw ax, sp
|
||||
addw ax, #4
|
||||
movw hl, ax
|
||||
call !!__int_isinf
|
||||
bnz $1f
|
||||
mov a, [SP+7]
|
||||
bt a.7, $2f
|
||||
;; +inf
|
||||
movw r8, #-1
|
||||
movw r10, #0x7fff
|
||||
ret
|
||||
;; -inf
|
||||
2: mov r8, #0
|
||||
mov r10, #0x8000
|
||||
ret
|
||||
|
||||
;; Load the value into r10:r11:X:A
|
||||
1: movw ax, [SP+4]
|
||||
movw r10, ax
|
||||
movw ax, [SP+6]
|
||||
|
||||
;; If the value is positive we can just use __fixunssfsi
|
||||
bf a.7, $__int_fixunssfsi
|
||||
|
||||
;; Otherwise we negate the value, call __fixunssfsi and
|
||||
;; then negate its result.
|
||||
clr1 a.7
|
||||
call $!__int_fixunssfsi
|
||||
|
||||
movw ax, #0
|
||||
subw ax, r8
|
||||
movw r8, ax
|
||||
movw ax, #0
|
||||
sknc
|
||||
decw ax
|
||||
subw ax, r10
|
||||
movw r10, ax
|
||||
|
||||
;; Check for a positive result (which should only happen when
|
||||
;; __fixunssfsi returns UINTMAX or 0). In such cases just return 0.
|
||||
mov a, r11
|
||||
bt a.7, $1f
|
||||
movw r10,#0x0
|
||||
movw r8, #0x0
|
||||
|
||||
1: ret
|
||||
|
||||
END_FUNC ___fixsfsi
|
||||
|
||||
START_FUNC ___fixunssfsi
|
||||
;; Converts its floating point argument into an unsigned long
|
||||
;; rounding towards zero. Negative arguments all become zero.
|
||||
;; We choose to return 0 for NaNs and -inf, but UINTMAX for +inf.
|
||||
;; This matches the behaviour of the C function in libgcc2.c.
|
||||
|
||||
;; Input at [SP+4]..[SP+7], result is in (lsb) R8..R11 (msb)
|
||||
|
||||
;; Get the input value.
|
||||
movw ax, [SP+4]
|
||||
movw r10, ax
|
||||
movw ax, [SP+6]
|
||||
|
||||
;; Fall through into the internal function.
|
||||
|
||||
.global __int_fixunssfsi
|
||||
__int_fixunssfsi:
|
||||
;; Input in (lsb) r10.r11.x.a (msb).
|
||||
|
||||
;; Test for a negative input. We shift the other bits at the
|
||||
;; same time so that A ends up holding the whole exponent:
|
||||
;;
|
||||
;; before:
|
||||
;; SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM
|
||||
;; A X R11 R10
|
||||
;;
|
||||
;; after:
|
||||
;; EEEEEEEE MMMMMMM0 MMMMMMMM MMMMMMMM
|
||||
;; A X R11 R10
|
||||
shlw ax, 1
|
||||
bnc $1f
|
||||
|
||||
;; Return zero.
|
||||
2: movw r8, #0
|
||||
movw r10, #0
|
||||
ret
|
||||
|
||||
;; An exponent of -1 is either a NaN or infinity.
|
||||
1: cmp a, #-1
|
||||
bnz $3f
|
||||
;; For NaN we return 0. For infinity we return UINTMAX.
|
||||
mov a, x
|
||||
or a, r10
|
||||
or a, r11
|
||||
cmp0 a
|
||||
bnz $2b
|
||||
|
||||
6: movw r8, #-1 ; -1 => UINT_MAX
|
||||
movw r10, #-1
|
||||
ret
|
||||
|
||||
;; If the exponent is negative the value is < 1 and so the
|
||||
;; converted value is 0. Note we must allow for the bias
|
||||
;; applied to the exponent. Thus a value of 127 in the
|
||||
;; EEEEEEEE bits actually represents an exponent of 0, whilst
|
||||
;; a value less than 127 actually represents a negative exponent.
|
||||
;; Also if the EEEEEEEE bits are all zero then this represents
|
||||
;; either a denormal value or 0.0. Either way for these values
|
||||
;; we return 0.
|
||||
3: sub a, #127
|
||||
bc $2b
|
||||
|
||||
;; A now holds the bias adjusted exponent, which is known to be >= 0.
|
||||
;; If the exponent is > 31 then the conversion will overflow.
|
||||
cmp a, #32
|
||||
bnc $6b
|
||||
4:
|
||||
;; Save the exponent in H. We increment it by one because we want
|
||||
;; to be sure that the loop below will always execute at least once.
|
||||
inc a
|
||||
mov h, a
|
||||
|
||||
;; Get the top 24 bits of the mantissa into A:X:R10
|
||||
;; Include the implicit 1-bit that is inherent in the IEEE fp format.
|
||||
;;
|
||||
;; before:
|
||||
;; EEEEEEEE MMMMMMM0 MMMMMMMM MMMMMMMM
|
||||
;; H X R11 R10
|
||||
;; after:
|
||||
;; EEEEEEEE 1MMMMMMM MMMMMMMM MMMMMMMM
|
||||
;; H A X R10
|
||||
|
||||
mov a, r11
|
||||
xch a, x
|
||||
shr a, 1
|
||||
set1 a.7
|
||||
|
||||
;; Clear B:C:R12:R13
|
||||
movw bc, #0
|
||||
movw r12, #0
|
||||
|
||||
;; Shift bits from the mantissa (A:X:R10) into (B:C:R12:R13),
|
||||
;; decrementing the exponent as we go.
|
||||
|
||||
;; before:
|
||||
;; MMMMMMMM MMMMMMMM MMMMMMMM xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
|
||||
;; A X R10 B C R12 R13
|
||||
;; first iter:
|
||||
;; MMMMMMMM MMMMMMMM MMMMMMM0 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxM
|
||||
;; A X R10 B C R12 R13
|
||||
;; second iter:
|
||||
;; MMMMMMMM MMMMMMMM MMMMMM00 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxMM
|
||||
;; A X R10 B C R12 R13
|
||||
;; etc.
|
||||
5:
|
||||
xch a, r10
|
||||
shl a, 1
|
||||
xch a, r10
|
||||
|
||||
rolwc ax, 1
|
||||
|
||||
xch a, r13
|
||||
rolc a, 1
|
||||
xch a, r13
|
||||
|
||||
xch a, r12
|
||||
rolc a, 1
|
||||
xch a, r12
|
||||
|
||||
rolwc bc, 1
|
||||
|
||||
dec h
|
||||
bnz $5b
|
||||
|
||||
;; Result is currently in (lsb) r13.r12. c. b. (msb),
|
||||
;; Move it into (lsb) r8. r9. r10. r11 (msb).
|
||||
|
||||
mov a, r13
|
||||
mov r8, a
|
||||
|
||||
mov a, r12
|
||||
mov r9, a
|
||||
|
||||
mov a, c
|
||||
mov r10, a
|
||||
|
||||
mov a, b
|
||||
mov r11, a
|
||||
|
||||
ret
|
||||
|
||||
END_FUNC ___fixunssfsi
|
||||
|
||||
;; ------------------------------------------------------------------------
|
||||
|
||||
START_FUNC ___floatsisf
|
||||
;; Converts its signed long argument into a floating point.
|
||||
;; Argument in [SP+4]..[SP+7]. Result in R8..R11.
|
||||
|
||||
;; Get the argument.
|
||||
movw ax, [SP+4]
|
||||
movw bc, ax
|
||||
movw ax, [SP+6]
|
||||
|
||||
;; Test the sign bit. If the value is positive then drop into
|
||||
;; the unsigned conversion routine.
|
||||
bf a.7, $2f
|
||||
|
||||
;; If negative convert to positive ...
|
||||
movw hl, ax
|
||||
movw ax, #0
|
||||
subw ax, bc
|
||||
movw bc, ax
|
||||
movw ax, #0
|
||||
sknc
|
||||
decw ax
|
||||
subw ax, hl
|
||||
|
||||
;; If the result is negative then the input was 0x80000000 and
|
||||
;; we want to return -0.0, which will not happen if we call
|
||||
;; __int_floatunsisf.
|
||||
bt a.7, $1f
|
||||
|
||||
;; Call the unsigned conversion routine.
|
||||
call $!__int_floatunsisf
|
||||
|
||||
;; Negate the result.
|
||||
set1 r11.7
|
||||
|
||||
;; Done.
|
||||
ret
|
||||
|
||||
1: ;; Return -0.0 aka 0xcf000000
|
||||
|
||||
clrb a
|
||||
mov r8, a
|
||||
mov r9, a
|
||||
mov r10, a
|
||||
mov a, #0xcf
|
||||
mov r11, a
|
||||
ret
|
||||
|
||||
START_ANOTHER_FUNC ___floatunsisf
|
||||
;; Converts its unsigned long argument into a floating point.
|
||||
;; Argument in [SP+4]..[SP+7]. Result in R8..R11.
|
||||
|
||||
;; Get the argument.
|
||||
movw ax, [SP+4]
|
||||
movw bc, ax
|
||||
movw ax, [SP+6]
|
||||
|
||||
2: ;; Internal entry point from __floatsisf
|
||||
;; Input in AX (high) and BC (low)
|
||||
.global __int_floatunsisf
|
||||
__int_floatunsisf:
|
||||
|
||||
;; Special case handling for zero.
|
||||
cmpw ax, #0
|
||||
bnz $1f
|
||||
movw ax, bc
|
||||
cmpw ax, #0
|
||||
movw ax, #0
|
||||
bnz $1f
|
||||
|
||||
;; Return 0.0
|
||||
movw r8, ax
|
||||
movw r10, ax
|
||||
ret
|
||||
|
||||
1: ;; Pre-load the loop count/exponent.
|
||||
;; Exponents are biased by 0x80 and we start the loop knowing that
|
||||
;; we are going to skip the highest set bit. Hence the highest value
|
||||
;; that we can get for the exponent is 0x1e (bits from input) + 0x80 = 0x9e.
|
||||
mov h, #0x9e
|
||||
|
||||
;; Move bits off the top of AX:BC until we hit a 1 bit.
|
||||
;; Decrement the count of remaining bits as we go.
|
||||
|
||||
2: shlw bc, 1
|
||||
rolwc ax, 1
|
||||
bc $3f
|
||||
dec h
|
||||
br $2b
|
||||
|
||||
;; Ignore the first one bit - it is implicit in the IEEE format.
|
||||
;; The count of remaining bits is the exponent.
|
||||
|
||||
;; Assemble the final floating point value. We have...
|
||||
;; before:
|
||||
;; EEEEEEEE MMMMMMMM MMMMMMMM MMMMMMMM xxxxxxxx
|
||||
;; H A X B C
|
||||
;; after:
|
||||
;; 0EEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM
|
||||
;; R11 R10 R9 R8
|
||||
|
||||
|
||||
3: shrw ax, 1
|
||||
mov r10, a
|
||||
mov a, x
|
||||
mov r9, a
|
||||
|
||||
mov a, b
|
||||
rorc a, 1
|
||||
|
||||
;; If the bottom bit of B was set before we shifted it out then we
|
||||
;; need to round the result up. Unless none of the bits in C are set.
|
||||
;; In this case we are exactly half-way between two values, and we
|
||||
;; round towards an even value. We round up by increasing the
|
||||
;; mantissa by 1. If this results in a zero mantissa we have to
|
||||
;; increment the exponent. We round down by ignoring the dropped bits.
|
||||
|
||||
bnc $4f
|
||||
cmp0 c
|
||||
sknz
|
||||
bf a.0, $4f
|
||||
|
||||
5: ;; Round the mantissa up by 1.
|
||||
add a, #1
|
||||
addc r9, #0
|
||||
addc r10, #0
|
||||
bf r10.7, $4f
|
||||
inc h
|
||||
clr1 r10.7
|
||||
|
||||
4: mov r8, a
|
||||
mov a, h
|
||||
shr a, 1
|
||||
mov r11, a
|
||||
sknc
|
||||
set1 r10.7
|
||||
ret
|
||||
|
||||
END_ANOTHER_FUNC ___floatunsisf
|
||||
END_FUNC ___floatsisf
|
1030
libgcc/config/rl78/fpmath-sf.S
Normal file
1030
libgcc/config/rl78/fpmath-sf.S
Normal file
File diff suppressed because it is too large
Load Diff
@ -22,11 +22,7 @@
|
||||
|
||||
#include "vregs.h"
|
||||
|
||||
.text
|
||||
.global ___lshrsi3
|
||||
.type ___lshrsi3, @function
|
||||
___lshrsi3:
|
||||
|
||||
START_FUNC ___lshrsi3
|
||||
;; input:
|
||||
;;
|
||||
;; [zero]
|
||||
@ -46,7 +42,6 @@ ___lshrsi3:
|
||||
;; B - count
|
||||
|
||||
mov a, [sp+8] ; A now contains the count
|
||||
|
||||
cmp a, #0x20
|
||||
bc $.Lcount_is_normal
|
||||
|
||||
@ -113,4 +108,4 @@ ___lshrsi3:
|
||||
|
||||
br $.Lloop_top
|
||||
|
||||
.size ___lshrsi3, .-___lshrsi3
|
||||
END_FUNC ___lshrsi3
|
||||
|
@ -33,6 +33,18 @@
|
||||
; DE count (resL-tmp)
|
||||
; HL [sp+4]
|
||||
|
||||
; Register use (G10):
|
||||
;
|
||||
; AX op2L
|
||||
; BC op2H
|
||||
; DE count
|
||||
; HL [sp+4]
|
||||
; r8/r9 res32L
|
||||
; r10/r11 (resH)
|
||||
; r12/r13 (resL-tmp)
|
||||
; r16/r17 res32H
|
||||
; r18/r19 op1
|
||||
|
||||
START_FUNC ___mulsi3
|
||||
;; A is at [sp+4]
|
||||
;; B is at [sp+8]
|
||||
@ -159,7 +171,7 @@ START_FUNC ___mulsi3
|
||||
sknc
|
||||
incw ax
|
||||
addw ax, r_2
|
||||
.Lmul_hisi_no_add:
|
||||
.Lmul_hisi_no_add:
|
||||
sel rb1
|
||||
shlw bc, 1
|
||||
sel rb0
|
||||
@ -267,3 +279,45 @@ START_FUNC ___mulhi3
|
||||
.Lmul_hi_done:
|
||||
ret
|
||||
END_FUNC ___mulhi3
|
||||
|
||||
;;; --------------------------------------
|
||||
#ifdef __RL78_G10__
|
||||
START_FUNC ___mulqi3
|
||||
|
||||
mov a, [sp+4]
|
||||
mov r9, a
|
||||
mov a, [sp+6]
|
||||
mov r10, a
|
||||
mov a, #9
|
||||
mov r11, a
|
||||
clrb a
|
||||
mov r8, a
|
||||
.L2:
|
||||
cmp0 r10
|
||||
skz
|
||||
dec r11
|
||||
sknz
|
||||
ret
|
||||
mov a, r10
|
||||
and a, #1
|
||||
mov r12, a
|
||||
cmp0 r12
|
||||
sknz
|
||||
br !!.L3
|
||||
mov a, r9
|
||||
mov l, a
|
||||
mov a, r8
|
||||
add a, l
|
||||
mov r8, a
|
||||
.L3:
|
||||
mov a, r9
|
||||
add a, a
|
||||
mov r9, a
|
||||
mov a, r10
|
||||
shr a, 1
|
||||
mov r10, a
|
||||
br !!.L2
|
||||
|
||||
END_FUNC ___mulqi3
|
||||
#endif
|
||||
|
||||
|
@ -37,11 +37,9 @@
|
||||
|
||||
.text
|
||||
|
||||
.global _signbit
|
||||
_signbit:
|
||||
.global _signbitf
|
||||
_signbitf:
|
||||
;; X is at [sp+4]
|
||||
START_FUNC _signbit
|
||||
START_ANOTHER_FUNC _signbitf
|
||||
;; X is at [sp+4]..[SP+7]
|
||||
;; result is in R8..R9
|
||||
|
||||
movw r8, #0
|
||||
@ -50,12 +48,12 @@ _signbitf:
|
||||
sknc
|
||||
movw r8, #1
|
||||
ret
|
||||
.size _signbit, . - _signbit
|
||||
.size _signbitf, . - _signbitf
|
||||
END_ANOTHER_FUNC _signbitf
|
||||
END_FUNC _signbit
|
||||
|
||||
.global _signbitl
|
||||
_signbitl:
|
||||
;; X is at [sp+4]
|
||||
|
||||
START_FUNC _signbitl
|
||||
;; X is at [sp+4]..[SP+7]
|
||||
;; result is in R8..R9
|
||||
|
||||
movw r8, #0
|
||||
@ -64,4 +62,4 @@ _signbitl:
|
||||
sknc
|
||||
movw r8, #1
|
||||
ret
|
||||
.size _signbitl, . - _signbitl
|
||||
END_FUNC _signbitl
|
||||
|
@ -20,8 +20,6 @@
|
||||
|
||||
LIB2ADD = \
|
||||
$(srcdir)/config/rl78/trampoline.S \
|
||||
$(srcdir)/config/rl78/lib2div.c \
|
||||
$(srcdir)/config/rl78/lib2mul.c \
|
||||
$(srcdir)/config/rl78/lib2shift.c \
|
||||
$(srcdir)/config/rl78/lshrsi3.S \
|
||||
$(srcdir)/config/rl78/mulsi3.S \
|
||||
@ -29,6 +27,22 @@ LIB2ADD = \
|
||||
$(srcdir)/config/rl78/divmodhi.S \
|
||||
$(srcdir)/config/rl78/divmodqi.S \
|
||||
$(srcdir)/config/rl78/signbit.S \
|
||||
$(srcdir)/config/rl78/bit-count.S \
|
||||
$(srcdir)/config/rl78/fpbit-sf.S \
|
||||
$(srcdir)/config/rl78/fpmath-sf.S \
|
||||
$(srcdir)/config/rl78/cmpsi2.S
|
||||
|
||||
LIB2FUNCS_EXCLUDE = _clzhi2 _clzsi2 _ctzhi2 _ctzsi2 \
|
||||
_popcounthi2 _popcountsi2 \
|
||||
_parityhi2 _paritysi2 _ffssi2 _ffshi2 \
|
||||
_negate_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \
|
||||
_lt_sf _le_sf _unord_sf \
|
||||
_si_to_sf _usi_to_sf \
|
||||
_sf_to_si _sf_to_usi \
|
||||
_fixunssfsi _fixsfsi \
|
||||
_addsub_sf _mul_sf _div_sf
|
||||
|
||||
# Remove __gcc_bcmp from LIB2FUNCS_ST
|
||||
LIB2FUNCS_ST = _eprintf
|
||||
|
||||
HOST_LIBGCC2_CFLAGS += -Os -ffunction-sections -fdata-sections
|
||||
|
@ -80,14 +80,10 @@ trampoline_array_end:
|
||||
pointer in R10, allocate a trampoline and return its address in
|
||||
R8. */
|
||||
|
||||
.text
|
||||
.global ___trampoline_init
|
||||
.type ___trampoline_init, @function
|
||||
___trampoline_init:
|
||||
|
||||
START_FUNC ___trampoline_init
|
||||
movw hl, #trampoline_array
|
||||
1:
|
||||
movw ax, [hl + TO_ADDR]
|
||||
|
||||
1: movw ax, [hl + TO_ADDR]
|
||||
cmpw ax, #0
|
||||
bz $2f
|
||||
|
||||
@ -107,30 +103,27 @@ ___trampoline_init:
|
||||
|
||||
movw ax, [hl + TO_STUB]
|
||||
movw r8, ax
|
||||
|
||||
ret
|
||||
.size ___trampoline_init, . - ___trampoline_init
|
||||
END_FUNC ___trampoline_init
|
||||
|
||||
.global ___trampoline_uninit
|
||||
.type ___trampoline_uninit, @function
|
||||
___trampoline_uninit:
|
||||
|
||||
START_FUNC ___trampoline_uninit
|
||||
movw hl, #trampoline_array
|
||||
movw ax, sp
|
||||
movw bc, ax
|
||||
1:
|
||||
movw ax, [hl + TO_FRAME]
|
||||
|
||||
1: movw ax, [hl + TO_FRAME]
|
||||
cmpw ax, bc
|
||||
bc $2f
|
||||
|
||||
clrw ax
|
||||
movw [hl + TO_ADDR], ax
|
||||
|
||||
2:
|
||||
movw ax, hl
|
||||
2: movw ax, hl
|
||||
addw ax, #TO_SIZE
|
||||
movw hl, ax
|
||||
cmpw ax, #trampoline_array_end
|
||||
bnz $1b
|
||||
|
||||
ret
|
||||
.size ___trampoline_uninit, . - ___trampoline_uninit
|
||||
END_FUNC ___trampoline_uninit
|
||||
|
@ -55,17 +55,25 @@ r23 = 0xffeef
|
||||
|
||||
#endif
|
||||
|
||||
/* Start a function in its own section, so that it
|
||||
can be subject to linker garbage collection. */
|
||||
.macro START_FUNC name
|
||||
.pushsection .text.\name,"ax",@progbits
|
||||
.macro START_ANOTHER_FUNC name
|
||||
.global \name
|
||||
.type \name , @function
|
||||
\name:
|
||||
.endm
|
||||
|
||||
/* Start a function in its own section, so that it
|
||||
can be subject to linker garbage collection. */
|
||||
.macro START_FUNC name
|
||||
.pushsection .text.\name,"ax",@progbits
|
||||
START_ANOTHER_FUNC \name
|
||||
.endm
|
||||
|
||||
.macro END_ANOTHER_FUNC name
|
||||
.size \name , . - \name
|
||||
.endm
|
||||
|
||||
/* End the function. Set the size. */
|
||||
.macro END_FUNC name
|
||||
.size \name , . - \name
|
||||
END_ANOTHER_FUNC \name
|
||||
.popsection
|
||||
.endm
|
||||
|
Loading…
x
Reference in New Issue
Block a user