Archival checkin (semi-working code).
This commit is contained in:
2
mach/powerpc/libem/.distr
Normal file
2
mach/powerpc/libem/.distr
Normal file
@@ -0,0 +1,2 @@
|
||||
LIST
|
||||
libem_s.a
|
||||
35
mach/powerpc/libem/aar4.s
Normal file
35
mach/powerpc/libem/aar4.s
Normal file
@@ -0,0 +1,35 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
! Index into a bounds-checked array.
|
||||
!
|
||||
! On entry:
|
||||
! r3 = ptr to descriptor
|
||||
! r4 = index
|
||||
! r5 = address of array
|
||||
|
||||
.define .aar4
|
||||
.aar4:
|
||||
addis r0, r0, <.trap_earray
|
||||
ori r0, r0, >.trap_earray
|
||||
mtspr ctr, r0 ! load CTR with trap address
|
||||
|
||||
lwz r0, 0(r3)
|
||||
subf. r4, r0, r4 ! adjust range
|
||||
bcctr IFTRUE, LT, 0 ! check lower bound
|
||||
|
||||
lwz r0, 4(r3)
|
||||
cmpl cr0, 0, r4, r3
|
||||
bcctr IFFALSE, LT, 0 ! check upper bound
|
||||
|
||||
lwz r0, 8(r3)
|
||||
mullw r4, r4, r0 ! scale index
|
||||
add r3, r4, r5 ! calculate element address
|
||||
|
||||
bclr ALWAYS, 0, 0
|
||||
20
mach/powerpc/libem/cfi8.s
Normal file
20
mach/powerpc/libem/cfi8.s
Normal file
@@ -0,0 +1,20 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
! Converts a 64-bit double into a 32-bit integer.
|
||||
!
|
||||
! Stack: ( double -- int )
|
||||
|
||||
.define .cfi8
|
||||
.cfi8:
|
||||
lfd f0, 0(sp)
|
||||
fctiwz f0, f0
|
||||
stfd f0, 0(sp)
|
||||
addi sp, sp, 4
|
||||
bclr ALWAYS, 0, 0 ! ...and return
|
||||
44
mach/powerpc/libem/cfu8.s
Normal file
44
mach/powerpc/libem/cfu8.s
Normal file
@@ -0,0 +1,44 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
! Converts a 64-bit double into a 32-bit unsigned integer.
|
||||
!
|
||||
! Stack: ( double -- uint )
|
||||
|
||||
.define .cfu8
|
||||
.cfu8:
|
||||
la(r3, .fd_00000000)
|
||||
lfd f0, 0(r3) ! f0 = 0.0
|
||||
|
||||
lfd f1, 0(sp) ! value to be converted
|
||||
|
||||
la(r3, .fd_FFFFFFFF)
|
||||
lfd f3, 0(r3) ! f3 = 0xFFFFFFFF
|
||||
|
||||
la(r3, .fd_80000000)
|
||||
lfd f4, 0(r3) ! f4 = 0x80000000
|
||||
|
||||
fsel f2, f1, f1, f0
|
||||
fsub f5, f3, f1
|
||||
fsel f2, f5, f2, f3
|
||||
fsub f5, f2, f4
|
||||
fcmpu cr0, f2, f4
|
||||
fsel f2, f5, f5, f2
|
||||
fctiwz f2, f2
|
||||
|
||||
stfd f2, 0(sp)
|
||||
addi sp, sp, 4
|
||||
|
||||
bclr IFTRUE, LT, 0
|
||||
|
||||
lwz r3, 0(sp)
|
||||
xoris r3, r3, 0x8000
|
||||
stw r3, 0(sp)
|
||||
|
||||
bclr ALWAYS, 0, 0
|
||||
37
mach/powerpc/libem/cif8.s
Normal file
37
mach/powerpc/libem/cif8.s
Normal file
@@ -0,0 +1,37 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
! Converts a 32-bit integer into a 64-bit double.
|
||||
!
|
||||
! Stack: ( int -- double )
|
||||
|
||||
.define .cif8
|
||||
.cif8:
|
||||
addi sp, sp, -4 ! make space for the double
|
||||
|
||||
lwz r3, 4(sp)
|
||||
xoris r3, r3, 0x8000
|
||||
stw r3, 4(sp) ! flip sign of integer value
|
||||
|
||||
addis r3, r0, 0x4330
|
||||
stw r3, 0(sp) ! set high word to construct a double
|
||||
|
||||
lfd f0, 0(sp) ! load value
|
||||
|
||||
la (r3, pivot)
|
||||
lfd f1, 0(r3) ! load pivot value
|
||||
fsub f0, f0, f1 ! adjust
|
||||
|
||||
stfd f0, 0(sp) ! save value again...
|
||||
bclr ALWAYS, 0, 0 ! ...and return
|
||||
|
||||
.sect .rom
|
||||
pivot:
|
||||
.data4 0x43300000
|
||||
.data4 0x80000000
|
||||
44
mach/powerpc/libem/csa.s
Normal file
44
mach/powerpc/libem/csa.s
Normal file
@@ -0,0 +1,44 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
! this is not a subroutine, but just a
|
||||
! piece of code that computes the jump-
|
||||
! address and jumps to it.
|
||||
! traps if resulting address is zero
|
||||
!
|
||||
! On entry: r3 = address of CSA table
|
||||
! r4 = value
|
||||
|
||||
.define .csa
|
||||
.csa:
|
||||
lwz r5, 0(r3) ! load default
|
||||
mtspr ctr, r5
|
||||
|
||||
lwz r5, 4(r3) ! fetch lower bound
|
||||
subf. r4, r5, r4 ! adjust value
|
||||
bcctr IFTRUE, LT, 0 ! jump to default if out of range
|
||||
|
||||
lwz r5, 8(r3) ! fetch range
|
||||
cmp cr0, 0, r4, r5
|
||||
bcctr IFTRUE, GT, 0 ! jump to default if out of range
|
||||
|
||||
addi r3, r3, 12 ! skip header
|
||||
rlwinm r4, r4, 2, 0, 31-2 ! scale value (<<2)
|
||||
b 1f
|
||||
1:
|
||||
lwzx r5, r3, r4 ! load target
|
||||
b 1f
|
||||
1:
|
||||
mtspr ctr, r5
|
||||
|
||||
or. r5, r5, r5 ! test it
|
||||
b 1f
|
||||
1:
|
||||
bcctr IFFALSE, EQ, 0 ! jump to target if non-zero
|
||||
b .trap_ecase ! otherwise trap
|
||||
39
mach/powerpc/libem/csb.s
Normal file
39
mach/powerpc/libem/csb.s
Normal file
@@ -0,0 +1,39 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
! this is not a subroutine, but just a
|
||||
! piece of code that computes the jump-
|
||||
! address and jumps to it.
|
||||
! traps if resulting address is zero
|
||||
!
|
||||
! On entry: r3 = address of CSB table
|
||||
! r4 = value
|
||||
|
||||
.define .csb
|
||||
.csb:
|
||||
lwz r5, 0(r3) ! load default
|
||||
mtspr ctr, r5
|
||||
|
||||
lwz r6, 4(r3) ! fetch count
|
||||
|
||||
1:
|
||||
or. r6, r6, r6 ! test count
|
||||
bcctr IFTRUE, EQ, 0 ! exit if zero
|
||||
addi r6, r6, -1 ! otherwise decrement
|
||||
|
||||
lwzu r7, 8(r3) ! fetch target index, increment pointer
|
||||
cmp cr0, 0, r4, r7 ! compare with value
|
||||
bc IFFALSE, EQ, 1b ! if not equal, go again
|
||||
|
||||
lwz r7, 4(r3) ! fetch target address
|
||||
mtspr ctr, r7
|
||||
|
||||
or. r7, r7, r7 ! test it
|
||||
bcctr IFFALSE, EQ, 0 ! jump to target if non-zero
|
||||
b .trap_ecase ! otherwise trap
|
||||
33
mach/powerpc/libem/cuf8.s
Normal file
33
mach/powerpc/libem/cuf8.s
Normal file
@@ -0,0 +1,33 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
! Converts a 32-bit unsigned integer into a 64-bit double.
|
||||
!
|
||||
! Stack: ( uint -- double )
|
||||
|
||||
.define .cuf8
|
||||
.cuf8:
|
||||
addi sp, sp, -4 ! make space for the double
|
||||
|
||||
addis r3, r0, 0x4330
|
||||
stw r3, 0(sp) ! set high word to construct a double
|
||||
|
||||
lfd f0, 0(sp) ! load value
|
||||
|
||||
la (r3, pivot)
|
||||
lfd f1, 0(r3) ! load pivot value
|
||||
fsub f0, f0, f1 ! adjust
|
||||
|
||||
stfd f0, 0(sp) ! save value again...
|
||||
bclr ALWAYS, 0, 0 ! ...and return
|
||||
|
||||
.sect .rom
|
||||
pivot:
|
||||
.data4 0x43300000
|
||||
.data4 0x00000000
|
||||
17
mach/powerpc/libem/fd_00000000.s
Normal file
17
mach/powerpc/libem/fd_00000000.s
Normal file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .rom
|
||||
|
||||
! Contains a handy double-precision zero. (Also works as a single-precision
|
||||
! zero.)
|
||||
|
||||
.define .fd_00000000, .fs_00000000
|
||||
.fd_00000000:
|
||||
.fs_00000000:
|
||||
.data4 0x00000000
|
||||
.data4 0x00000000
|
||||
15
mach/powerpc/libem/fd_80000000.s
Normal file
15
mach/powerpc/libem/fd_80000000.s
Normal file
@@ -0,0 +1,15 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .rom
|
||||
|
||||
! Contains a handy double-precision 0x80000000.
|
||||
|
||||
.define .fd_80000000
|
||||
.fd_80000000:
|
||||
!float 2.147483648e+9 sz 8
|
||||
.data1 0101,0340,00,00,00,00,00,00
|
||||
15
mach/powerpc/libem/fd_FFFFFFFF.s
Normal file
15
mach/powerpc/libem/fd_FFFFFFFF.s
Normal file
@@ -0,0 +1,15 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .rom
|
||||
|
||||
! Contains a handy double-precision 0xFFFFFFFF.
|
||||
|
||||
.define .fd_FFFFFFFF
|
||||
.fd_FFFFFFFF:
|
||||
!float 4.294967295e+9 sz 8
|
||||
.data1 0101,0357,0377,0377,0377,0340,00,00
|
||||
46
mach/powerpc/libem/fef8.c
Normal file
46
mach/powerpc/libem/fef8.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* $Source$
|
||||
* $State$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
/* no headers allowed! */
|
||||
|
||||
/* Given a double, calculates the mantissa and exponent.
|
||||
*
|
||||
* This function is intended to be called internally by the code generator,
|
||||
* so the calling convention is odd.
|
||||
*/
|
||||
|
||||
int __fef8(double* fp)
|
||||
{
|
||||
double f = *fp;
|
||||
int exponent, sign;
|
||||
|
||||
if (f == 0.0)
|
||||
return 0;
|
||||
|
||||
if (f < 0.0)
|
||||
{
|
||||
sign = -1;
|
||||
f = -f;
|
||||
}
|
||||
else
|
||||
sign = 0;
|
||||
|
||||
exponent = 0;
|
||||
while (f >= 1.0)
|
||||
{
|
||||
f /= 2.0;
|
||||
exponent++;
|
||||
}
|
||||
|
||||
while (f < 0.5)
|
||||
{
|
||||
f *= 2.0;
|
||||
exponent--;
|
||||
}
|
||||
|
||||
*fp = (sign) ? -f : f;
|
||||
return exponent;
|
||||
}
|
||||
38
mach/powerpc/libem/fif8.s
Normal file
38
mach/powerpc/libem/fif8.s
Normal file
@@ -0,0 +1,38 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
! Multiplies two floats, and returns the fraction and integer.
|
||||
|
||||
.define .fif8
|
||||
.fif8:
|
||||
lfd f0, 8(sp)
|
||||
lfd f1, 0(sp)
|
||||
fmul f0, f0, f1
|
||||
fabs f1, f0 ! f0 = result
|
||||
|
||||
! The following chunk does f1 = floor(f1). See page 158 of the book.
|
||||
|
||||
mtfsfi cr7, 3 ! set rounding mode to -inf.
|
||||
mtfsb0 23
|
||||
fctid f2, f1
|
||||
fcfid f2, f2
|
||||
mcrfs cr7, cr5
|
||||
bc IFFALSE, 31, toobig
|
||||
fmr f1, f2
|
||||
toobig:
|
||||
|
||||
fabs f2, f1 ! f2 = fabs(f1)
|
||||
fsub f2, f2, f1
|
||||
stfd f2, 8(sp)
|
||||
|
||||
fneg f2, f1
|
||||
fsel f2, f0, f1, f2
|
||||
stfd f2, 0(sp)
|
||||
|
||||
bclr ALWAYS, 0, 0
|
||||
54
mach/powerpc/libem/los.s
Normal file
54
mach/powerpc/libem/los.s
Normal file
@@ -0,0 +1,54 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
! Loads a variable-sized structure onto the stack.
|
||||
!
|
||||
! r3 = size
|
||||
! r4 = address
|
||||
|
||||
.define .los
|
||||
.los:
|
||||
! These sizes are handled specially.
|
||||
|
||||
cmpi cr0, 0, r3, 1
|
||||
bc IFFALSE, GT, size1
|
||||
|
||||
cmpi cr0, 0, r3, 2
|
||||
bc IFFALSE, GT, size2
|
||||
|
||||
cmpi cr0, 0, r3, 4
|
||||
bc IFFALSE, GT, size4
|
||||
|
||||
! Variable-sized structure.
|
||||
|
||||
addi r3, r3, 3
|
||||
andi. r3, r3, ~3 ! align size
|
||||
|
||||
add r4, r4, r3 ! adjust address to top of block
|
||||
|
||||
srawi r3, r3, 2 ! convert size to the number of words
|
||||
mtspr ctr, r3
|
||||
|
||||
1:
|
||||
lwzu r5, -4(r4)
|
||||
stwu r5, -4(sp)
|
||||
bc DNZ, 0, 1b ! decrement CTR, jump if non-zero
|
||||
bclr ALWAYS, 0, 0
|
||||
|
||||
size1:
|
||||
lbz r3, 0(r4)
|
||||
b 1f
|
||||
size2:
|
||||
lhz r3, 0(r4)
|
||||
b 1f
|
||||
size4:
|
||||
lwz r3, 0(r4)
|
||||
1:
|
||||
stwu r3, -4(sp)
|
||||
bclr ALWAYS, 0, 0
|
||||
30
mach/powerpc/libem/pmfile
Normal file
30
mach/powerpc/libem/pmfile
Normal file
@@ -0,0 +1,30 @@
|
||||
-- $Source$
|
||||
-- $State$
|
||||
-- $Revision$
|
||||
|
||||
local d = ROOTDIR.."mach/powerpc/libem/"
|
||||
|
||||
libem_powerpc = acklibrary {
|
||||
outputs = {"%U%/libem-%PLATFORM%.a"},
|
||||
|
||||
ACKINCLUDES = {PARENT, d},
|
||||
|
||||
ackfile (d.."ret.s"),
|
||||
ackfile (d.."tge.s"),
|
||||
ackfile (d.."csa.s"),
|
||||
ackfile (d.."csb.s"),
|
||||
ackfile (d.."los.s"),
|
||||
ackfile (d.."sts.s"),
|
||||
ackfile (d.."aar4.s"),
|
||||
ackfile (d.."fef8.c"),
|
||||
ackfile (d.."fif8.s"),
|
||||
ackfile (d.."cif8.s"),
|
||||
ackfile (d.."cuf8.s"),
|
||||
ackfile (d.."cfi8.s"),
|
||||
ackfile (d.."cfu8.s"),
|
||||
ackfile (d.."fd_00000000.s"),
|
||||
ackfile (d.."fd_80000000.s"),
|
||||
ackfile (d.."fd_FFFFFFFF.s"),
|
||||
|
||||
install = pm.install("%BINDIR%lib/%PLATFORM%/libem.a"),
|
||||
}
|
||||
23
mach/powerpc/libem/powerpc.h
Normal file
23
mach/powerpc/libem/powerpc.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
! Declare segments (the order is important).
|
||||
|
||||
.sect .text
|
||||
.sect .rom
|
||||
.sect .data
|
||||
.sect .bss
|
||||
|
||||
#define IFFALSE 4
|
||||
#define IFTRUE 12
|
||||
#define ALWAYS 20
|
||||
#define DNZ 16
|
||||
|
||||
#define LT 0
|
||||
#define GT 1
|
||||
#define EQ 2
|
||||
#define OV 3
|
||||
|
||||
#define la(reg, val) addis reg, r0, <val; ori reg, reg, >val
|
||||
19
mach/powerpc/libem/ret.s
Normal file
19
mach/powerpc/libem/ret.s
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
! Standard boilerplate for returning from functions.
|
||||
|
||||
.define .ret
|
||||
.ret:
|
||||
lwz r0, 4(fp)
|
||||
mtspr lr, r0
|
||||
lwz r0, 0(fp) ! our stack frame becomes invalid as soon as...
|
||||
addi sp, fp, 8 ! ...we change sp
|
||||
or fp, r0, r0
|
||||
bclr ALWAYS, 0, 0
|
||||
57
mach/powerpc/libem/sts.s
Normal file
57
mach/powerpc/libem/sts.s
Normal file
@@ -0,0 +1,57 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
! Stores a variable-sized structure from the stack.
|
||||
!
|
||||
! r3 = size
|
||||
! r4 = address
|
||||
|
||||
.define .sts
|
||||
.sts:
|
||||
! These sizes are handled specially.
|
||||
|
||||
lwz r5, 0(sp)
|
||||
|
||||
cmpi cr0, 0, r3, 1
|
||||
bc IFFALSE, GT, size1
|
||||
|
||||
cmpi cr0, 0, r3, 2
|
||||
bc IFFALSE, GT, size2
|
||||
|
||||
cmpi cr0, 0, r3, 4
|
||||
bc IFFALSE, GT, size4
|
||||
|
||||
! Variable-sized structure.
|
||||
|
||||
addi r3, r3, 3
|
||||
andi. r3, r3, ~3 ! align size
|
||||
|
||||
srawi r3, r3, 2 ! convert size to the number of words
|
||||
mtspr ctr, r3
|
||||
|
||||
1:
|
||||
lwz r5, 0(sp)
|
||||
addi sp, sp, 4
|
||||
stw r5, 0(r4)
|
||||
addi r4, r4, 4
|
||||
|
||||
bc DNZ, 0, 1b ! decrement CTR, jump if non-zero
|
||||
bclr ALWAYS, 0, 0
|
||||
|
||||
size1:
|
||||
stb r5, 0(r4)
|
||||
b 1f
|
||||
size2:
|
||||
sth r5, 0(r4)
|
||||
b 1f
|
||||
size4:
|
||||
stw r5, 0(r4)
|
||||
1:
|
||||
addi sp, sp, 4
|
||||
bclr ALWAYS, 0, 0
|
||||
46
mach/powerpc/libem/tge.s
Normal file
46
mach/powerpc/libem/tge.s
Normal file
@@ -0,0 +1,46 @@
|
||||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .rom
|
||||
|
||||
! Lookup table for tge.
|
||||
|
||||
.define .teq_table
|
||||
.teq_table:
|
||||
.data4 1 ! . .
|
||||
.data4 0 ! . G
|
||||
.data4 0 ! L .
|
||||
|
||||
.define .tne_table
|
||||
.tne_table:
|
||||
.data4 0 ! . .
|
||||
.data4 1 ! . G
|
||||
.data4 1 ! L .
|
||||
|
||||
.define .tgt_table
|
||||
.tgt_table:
|
||||
.data4 0 ! . .
|
||||
.data4 1 ! . G
|
||||
.data4 0 ! L .
|
||||
|
||||
.define .tge_table
|
||||
.tge_table:
|
||||
.data4 1 ! . .
|
||||
.data4 1 ! . G
|
||||
.data4 0 ! L .
|
||||
|
||||
.define .tlt_table
|
||||
.tlt_table:
|
||||
.data4 0 ! . .
|
||||
.data4 0 ! . G
|
||||
.data4 1 ! L .
|
||||
|
||||
.define .tle_table
|
||||
.tle_table:
|
||||
.data4 1 ! . .
|
||||
.data4 0 ! . G
|
||||
.data4 1 ! L .
|
||||
Reference in New Issue
Block a user