Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
26731a9e
Commit
26731a9e
authored
Jul 11, 1994
by
Doug Evans
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial revision
From-SVN: r7726
parent
159c2aed
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
673 additions
and
0 deletions
+673
-0
gcc/config/h8300/lib1funcs.asm
+673
-0
No files found.
gcc/config/h8300/lib1funcs.asm
0 → 100644
View file @
26731a9e
;; libgcc1 routines for the Hitachi h8/300 cpu.
;; Contributed by Steve Chamberlain.
;; sac@cygnus.com
;; This file is in the public domain.
/*
Assembler
register
definitions
.
*/
#
define
A0
r0
#
define
A0L
r0l
#
define
A0H
r0h
#
define
A1
r1
#
define
A1L
r1l
#
define
A1H
r1h
#
define
A2
r2
#
define
A2L
r2l
#
define
A2H
r2h
#
define
A3
r3
#
define
A3L
r3l
#
define
A3H
r3h
#
define
S0
r4
#
define
S0L
r4l
#
define
S0H
r4h
#
define
S1
r5
#
define
S1L
r5l
#
define
S1H
r5h
#
define
S2
r6
#
define
S2L
r6l
#
define
S2H
r6h
#
ifdef
__H8300__
#
define
MOVP
mov
.
w
/*
pointers
are
16
bits
*/
#
define
ADDP
add
.
w
#
define
CMPP
cmp
.
w
#
define
PUSHP
push
#
define
POPP
pop
#
define
A0P
r0
#
define
A1P
r1
#
define
A2P
r2
#
define
A3P
r3
#
define
S0P
r4
#
define
S1P
r5
#
define
S2P
r6
#
endif
#
ifdef
__H8300H__
#
define
MOVP
mov
.
l
/*
pointers
are
32
bits
*/
#
define
ADDP
add
.
l
#
define
CMPP
cmp
.
l
#
define
PUSHP
push
.
l
#
define
POPP
pop
.
l
#
define
A0P
er0
#
define
A1P
er1
#
define
A2P
er2
#
define
A3P
er3
#
define
S0P
er4
#
define
S1P
er5
#
define
S2P
er6
#
define
A0E
e0
#
define
A1E
e1
#
define
A2E
e2
#
define
A3E
e3
#
endif
#
ifdef
L_cmpsi2
#
ifdef
__H8300__
.
section
.
text
.
align
2
.
global
___cmpsi2
___cmpsi2
:
cmp
.
w
A2
,
A0
bne
.
L2
cmp
.
w
A3
,
A1
bne
.
L2
mov
.
w
#
1
,
A0
rts
.
L2
:
cmp
.
w
A0
,
A2
bgt
.
L4
bne
.
L3
cmp
.
w
A1
,
A3
bls
.
L3
.
L4
:
sub
.
w
A0
,
A0
rts
.
L3
:
mov
.
w
#
2
,
A0
.
L5
:
rts
.
end
#
endif
#
endif
/*
L_cmpsi2
*/
#
ifdef
L_ucmpsi2
#
ifdef
__H8300__
.
section
.
text
.
align
2
.
global
___ucmpsi2
___ucmpsi2
:
cmp
.
w
A2
,
A0
bne
.
L2
cmp
.
w
A3
,
A1
bne
.
L2
mov
.
w
#
1
,
A0
rts
.
L2
:
cmp
.
w
A0
,
A2
bhi
.
L4
bne
.
L3
cmp
.
w
A1
,
A3
bls
.
L3
.
L4
:
sub
.
w
A0
,
A0
rts
.
L3
:
mov
.
w
#
2
,
A0
.
L5
:
rts
.
end
#
endif
#
endif
/*
L_ucmpsi2
*/
#
ifdef
L_divhi3
;; HImode divides for the H8/300.
;; We bunch all of this into one object file since there are several
;; "supporting routines".
; general purpose normalize routine
;
; divisor in A0
; dividend in A1
; turns both into +ve numbers, and leaves what the answer sign
; should be in A2L
#
ifdef
__H8300__
.
section
.
text
.
align
2
divnorm
:
mov
.
b
#
0x0
,
A2L
or
A0H
,
A0H
; is divisor > 0
bge
_lab1
not
A0H
; no - then make it +ve
not
A0L
adds
#
1
,
A0
xor
#
0x1
,
A2L
; and remember that in A2L
_lab1
:
or
A1H
,
A1H
; look at dividend
bge
_lab2
not
A1H
; it is -ve, make it positive
not
A1L
adds
#
1
,
A1
xor
#
0x1
,
A2L
; and toggle sign of result
_lab2
:
rts
; A0=A0/A1 signed
.
global
___divhi3
___divhi3
:
bsr
divnorm
bsr
___udivhi3
negans
:
or
A2L
,
A2L
; should answer be negative ?
beq
_lab4
not
A0H
; yes, so make it so
not
A0L
adds
#
1
,
A0
_lab4
:
rts
; A0=A0%A1 signed
.
global
___modhi3
___modhi3
:
bsr
divnorm
bsr
___udivhi3
mov
A3
,
A0
bra
negans
; A0=A0%A1 unsigned
.
global
___umodhi3
___umodhi3
:
bsr
___udivhi3
mov
A3
,
A0
rts
; A0=A0/A1 unsigned
; A3=A0%A1 unsigned
; A2H trashed
; D high 8 bits of denom
; d low 8 bits of denom
; N high 8 bits of num
; n low 8 bits of num
; M high 8 bits of mod
; m low 8 bits of mod
; Q high 8 bits of quot
; q low 8 bits of quot
; P preserve
; The h8 only has a 16/8 bit divide, so we look at the incoming and
; see how to partition up the expression.
.
global
___udivhi3
___udivhi3
:
; A0 A1 A2 A3
; Nn Dd P
sub
.
w
A3
,
A3
; Nn Dd xP 00
or
A1H
,
A1H
bne
divlongway
or
A0H
,
A0H
beq
_lab6
; we know that D == 0 and N is != 0
mov
.
b
A0H
,
A3L
; Nn Dd xP 0N
divxu
A1L
,
A3
; MQ
mov
.
b
A3L
,
A0H
; Q
; dealt with N, do n
_lab6
:
mov
.
b
A0L
,
A3L
; n
divxu
A1L
,
A3
; mq
mov
.
b
A3L
,
A0L
; Qq
mov
.
b
A3H
,
A3L
; m
mov
.
b
#
0x0
,
A3H
; Qq 0m
rts
; D != 0 - which means the denominator is
; loop around to get the result.
divlongway
:
mov
.
b
A0H
,
A3L
; Nn Dd xP 0N
mov
.
b
#
0x0
,
A0H
; high byte of answer has to be zero
mov
.
b
#
0x8
,
A2H
; 8
div8
:
add
.
b
A0L
,
A0L
; n*=2
rotxl
A3L
; Make remainder bigger
rotxl
A3H
sub
.
w
A1
,
A3
; Q-=N
bhs
setbit
; set a bit ?
add
.
w
A1
,
A3
; no : too far , Q+=N
dec
A2H
bne
div8
; next bit
rts
setbit
:
inc
A0L
; do insert bit
dec
A2H
bne
div8
; next bit
rts
#
endif
/*
__H8300__
*/
#
endif
/*
L_divhi3
*/
#
ifdef
L_divsi3
;; 4 byte integer divides for the H8/300.
;;
;; We have one routine which does all the work and lots of
;; little ones which prepare the args and massage the sign.
;; We bunch all of this into one object file since there are several
;; "supporting routines".
#
ifdef
__H8300H__
.
h8300h
#
endif
.
section
.
text
.
align
2
; Put abs SIs into r0/r1 and r2/r3, and leave a 1 in r6l with sign of rest.
; This function is here to keep branch displacements small.
#
ifdef
__H8300__
divnorm
:
mov
.
b
#
0
,
S2L
; keep the sign in S2
mov
.
b
A0H
,
A0H
; is the numerator -ve
bge
postive
; negate arg
not
A0H
not
A1H
not
A0L
not
A1L
add
#
1
,
A1L
addx
#
0
,
A1H
addx
#
0
,
A0H
addx
#
0
,
A0L
mov
.
b
#
1
,
S2L
; the sign will be -ve
postive
:
mov
.
b
A2H
,
A2H
; is the denominator -ve
bge
postive2
not
A2L
not
A2H
not
A3L
not
A3H
add
.
b
#
1
,
A3L
addx
#
0
,
A3H
addx
#
0
,
A2L
addx
#
0
,
A2H
xor
#
1
,
S2L
; toggle result sign
postive2
:
rts
#
else
/*
__H8300H__
*/
divnorm
:
mov
.
b
#
0
,
S2L
; keep the sign in S2
mov
.
l
A0P
,
A0P
; is the numerator -ve
bge
postive
neg
.
l
A0P
; negate arg
mov
.
b
#
1
,
S2L
; the sign will be -ve
postive
:
mov
.
l
A1P
,
A1P
; is the denominator -ve
bge
postive2
neg
.
l
A1P
; negate arg
xor
.
b
#
1
,
S2L
; toggle result sign
postive2
:
rts
#
endif
; numerator in A0/A1
; denominator in A2/A3
.
global
___modsi3
___modsi3
:
PUSHP
S2P
PUSHP
S0P
PUSHP
S1P
bsr
divnorm
bsr
divmodsi4
#
ifdef
__H8300__
mov
S0
,
A0
mov
S1
,
A1
#
else
mov
.
l
S0P
,
A0P
#
endif
bra
exitdiv
.
global
___udivsi3
___udivsi3
:
PUSHP
S2P
PUSHP
S0P
PUSHP
S1P
mov
.
b
#
0
,
S2L
; keep sign low
bsr
divmodsi4
bra
exitdiv
.
global
___umodsi3
___umodsi3
:
PUSHP
S2P
PUSHP
S0P
PUSHP
S1P
mov
.
b
#
0
,
S2L
; keep sign low
bsr
divmodsi4
#
ifdef
__H8300__
mov
S0
,
A0
mov
S1
,
A1
#
else
mov
.
l
S0P
,
A0P
#
endif
bra
exitdiv
.
global
___divsi3
___divsi3
:
PUSHP
S2P
PUSHP
S0P
PUSHP
S1P
jsr
divnorm
jsr
divmodsi4
; examine what the sign should be
exitdiv
:
POPP
S1P
POPP
S0P
or
S2L
,
S2L
beq
reti
; should be -ve
#
ifdef
__H8300__
not
A0H
not
A1H
not
A0L
not
A1L
add
#
1
,
A1L
addx
#
0
,
A1H
addx
#
0
,
A0H
addx
#
0
,
A0L
#
else
/*
__H8300H__
*/
neg
.
l
A0P
#
endif
reti
:
POPP
S2P
rts
; takes A0/A1 numerator (A0P for 300h)
; A2/A3 denominator (A1P for 300h)
; returns A0/A1 quotient (A0P for 300h)
; S0/S1 remainder (S0P for 300h)
; trashes S2
#
ifdef
__H8300__
divmodsi4
:
sub
.
w
S0
,
S0
; zero play area
mov
.
w
S0
,
S1
mov
.
b
A2H
,
S2H
or
A2L
,
S2H
or
A3H
,
S2H
bne
DenHighZero
mov
.
b
A0H
,
A0H
bne
NumByte0Zero
mov
.
b
A0L
,
A0L
bne
NumByte1Zero
mov
.
b
A1H
,
A1H
bne
NumByte2Zero
bra
NumByte3Zero
NumByte0Zero
:
mov
.
b
A0H
,
S1L
divxu
A3L
,
S1
mov
.
b
S1L
,
A0H
NumByte1Zero
:
mov
.
b
A0L
,
S1L
divxu
A3L
,
S1
mov
.
b
S1L
,
A0L
NumByte2Zero
:
mov
.
b
A1H
,
S1L
divxu
A3L
,
S1
mov
.
b
S1L
,
A1H
NumByte3Zero
:
mov
.
b
A1L
,
S1L
divxu
A3L
,
S1
mov
.
b
S1L
,
A1L
mov
.
b
S1H
,
S1L
mov
.
b
#
0x0
,
S1H
rts
; have to do the divide by shift and test
DenHighZero
:
mov
.
b
A0H
,
S1L
mov
.
b
A0L
,
A0H
mov
.
b
A1H
,
A0L
mov
.
b
A1L
,
A1H
mov
.
b
#
0
,
A1L
mov
.
b
#
24
,
S2H
; only do 24 iterations
nextbit
:
add
.
w
A1
,
A1
; double the answer guess
rotxl
A0L
rotxl
A0H
rotxl
S1L
; double remainder
rotxl
S1H
rotxl
S0L
rotxl
S0H
sub
.
w
A3
,
S1
; does it all fit
subx
A2L
,
S0L
subx
A2H
,
S0H
bhs
setone
add
.
w
A3
,
S1
; no, restore mistake
addx
A2L
,
S0L
addx
A2H
,
S0H
dec
S2H
bne
nextbit
rts
setone
:
inc
A1L
dec
S2H
bne
nextbit
rts
#
else
/*
__H8300H__
*/
divmodsi4
:
sub
.
l
S0P
,
S0P
; zero play area
mov
.
w
A1E
,
A1E
; denominator top word 0?
bne
DenHighZero
; do it the easy way, see page 107 in manual
mov
.
w
A0E
,
A2
extu
.
l
A2P
divxu
.
w
A1
,
A2P
mov
.
w
A2E
,
A0E
divxu
.
w
A1
,
A0P
mov
.
w
A0E
,
S0
mov
.
w
A2
,
A0E
extu
.
l
S0P
rts
DenHighZero
:
mov
.
w
A0E
,
A2
mov
.
b
A2H
,
S0L
mov
.
b
A2L
,
A2H
mov
.
b
A0H
,
A2L
mov
.
w
A2
,
A0E
mov
.
b
A0L
,
A0H
mov
.
b
#
0
,
A0L
mov
.
b
#
24
,
S2H
; only do 24 iterations
nextbit
:
shll
.
l
A0P
; double the answer guess
rotxl
.
l
S0P
; double remainder
sub
.
l
A1P
,
S0P
; does it all fit?
bhs
setone
add
.
l
A1P
,
S0P
; no, restore mistake
dec
S2H
bne
nextbit
rts
setone
:
inc
A0L
dec
S2H
bne
nextbit
rts
#
endif
#
endif
/*
L_divsi3
*/
#
ifdef
L_mulhi3
;; HImode multiply.
; The h8 only has an 8*8->16 multiply.
; The answer is the same as:
;
; product = (srca.l * srcb.l) + ((srca.h * srcb.l) + (srcb.h * srca.l)) * 256
; (we can ignore A1.h * A0.h cause that will all off the top)
; A0 in
; A1 in
; A0 answer
#
ifdef
__H8300__
.
section
.
text
.
align
2
.
global
___mulhi3
___mulhi3
:
mov
.
b
A1L
,
A2L
; A2l gets srcb.l
mulxu
A0L
,
A2
; A2 gets first sub product
mov
.
b
A0H
,
A3L
; prepare for
mulxu
A1L
,
A3
; second sub product
add
.
b
A3L
,
A2H
; sum first two terms
mov
.
b
A1H
,
A3L
; third sub product
mulxu
A0L
,
A3
add
.
b
A3L
,
A2H
; almost there
mov
.
w
A2
,
A0
; that is
rts
#
endif
#
endif
/*
L_mulhi3
*/
#
ifdef
L_mulsi3
;; SImode multiply.
;;
;; I think that shift and add may be sufficient for this. Using the
;; supplied 8x8->16 would need 10 ops of 14 cycles each + overhead. This way
;; the inner loop uses maybe 20 cycles + overhead, but terminates
;; quickly on small args.
;;
;; A0/A1 src_a
;; A2/A3 src_b
;;
;; while (a)
;; {
;; if (a & 1)
;; r += b;
;; a >>= 1;
;; b <<= 1;
;; }
.
section
.
text
.
align
2
#
ifdef
__H8300__
.
global
___mulsi3
___mulsi3
:
PUSHP
S0P
PUSHP
S1P
PUSHP
S2P
sub
.
w
S0
,
S0
sub
.
w
S1
,
S1
; while (a)
_top
:
mov
.
w
A0
,
A0
bne
_more
mov
.
w
A1
,
A1
beq
_done
_more
:
; if (a & 1)
bld
#
0
,
A1L
bcc
_nobit
; r += b
add
.
w
A3
,
S1
addx
A2L
,
S0L
addx
A2H
,
S0H
_nobit
:
; a >>= 1
shlr
A0H
rotxr
A0L
rotxr
A1H
rotxr
A1L
; b <<= 1
add
.
w
A3
,
A3
addx
A2L
,
A2L
addx
A2H
,
A2H
bra
_top
_done
:
mov
.
w
S0
,
A0
mov
.
w
S1
,
A1
POPP
S2P
POPP
S1P
POPP
S0P
rts
#
else
/*
__H8300H__
*/
.
h8300h
.
global
___mulsi3
___mulsi3
:
sub
.
l
A2P
,
A2P
; while (a)
_top
:
mov
.
l
A0P
,
A0P
beq
_done
; if (a & 1)
bld
#
0
,
A0L
bcc
_nobit
; r += b
add
.
l
A1P
,
A2P
_nobit
:
; a >>= 1
shlr
.
l
A0P
; b <<= 1
shll
.
l
A1P
bra
_top
_done
:
mov
.
l
A2P
,
A0P
rts
#
endif
#
endif
/*
L_mulsi3
*/
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment