commit
34c4cfee8f
|
@ -8,6 +8,7 @@ vars.plats = {
|
|||
"cpm",
|
||||
"linux386",
|
||||
"linux68k",
|
||||
"linuxppc",
|
||||
"pc86",
|
||||
"rpi",
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
program hilo(input, output);
|
||||
|
||||
type
|
||||
string = array [0..255] of char;
|
||||
string = packed array [0..255] of char;
|
||||
charstar = packed array [0..0] of char;
|
||||
|
||||
var
|
||||
playing : Boolean;
|
||||
|
@ -34,18 +35,18 @@ function random(range : integer) : integer;
|
|||
that conflicts with a Pascal keyword. Luckily there's a private function
|
||||
uread() in the ACK Pascal library that we can use instead. }
|
||||
|
||||
function uread(fd : integer; var buffer : char; count : integer) : integer;
|
||||
function uread(fd : integer; var buffer : charstar; count : integer) : integer;
|
||||
extern;
|
||||
|
||||
function readchar : char;
|
||||
var
|
||||
c : char;
|
||||
c : charstar;
|
||||
dummy : integer;
|
||||
|
||||
begin
|
||||
c := chr(0);
|
||||
c[0] := chr(0);
|
||||
dummy := uread(0, c, 1);
|
||||
readchar := c;
|
||||
readchar := c[0];
|
||||
end;
|
||||
|
||||
procedure readstring(var buffer : string; var length : integer);
|
||||
|
|
2
h/out.h
2
h/out.h
|
@ -66,7 +66,7 @@ struct outname {
|
|||
#define RELO2 2 /* 2 bytes */
|
||||
#define RELO4 3 /* 4 bytes */
|
||||
#define RELOPPC 4 /* PowerPC 26-bit address */
|
||||
#define RELOH2 5 /* write top 2 bytes of 4 byte word */
|
||||
/* relo 5 is unused */
|
||||
#define RELOVC4 6 /* VideoCore IV address in 32-bit instruction */
|
||||
|
||||
#define RELPC 0x2000 /* pc relative */
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
%token <y_word> OP_TO_RA_RB
|
||||
%token <y_word> OP_TO_RA_SI
|
||||
|
||||
%token <y_word> OP_la
|
||||
%token <y_word> OP_LI32
|
||||
|
||||
/* Other token types */
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
|
||||
/* Special instructions */
|
||||
|
||||
0, OP_la, 0, "la",
|
||||
0, OP_LI32, 0, "li32",
|
||||
|
||||
/* Branch processor instructions (page 20) */
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ operation
|
|||
| OP_LEV u7 { emit4($1 | ($2<<5)); }
|
||||
| OP_LIA lia { emit4($1 | $2); }
|
||||
| OP_LIL lil { emit4($1 | $2); }
|
||||
| OP_LI32 li32 /* emitted in subrule */
|
||||
;
|
||||
|
||||
c
|
||||
|
@ -66,26 +67,12 @@ c
|
|||
;
|
||||
|
||||
e16
|
||||
: '<' expr
|
||||
: absexp
|
||||
{
|
||||
DOTVAL += 2;
|
||||
newrelo($2.typ, RELOH2 | FIXUPFLAGS);
|
||||
DOTVAL -= 2;
|
||||
$$ = ($2.val >> 16) & 0xFFFF;
|
||||
}
|
||||
| '>' expr
|
||||
{
|
||||
DOTVAL += 2;
|
||||
newrelo($2.typ, RELO2 | FIXUPFLAGS);
|
||||
DOTVAL -= 2;
|
||||
$$ = $2.val & 0xFFFF;
|
||||
}
|
||||
| expr
|
||||
{
|
||||
DOTVAL += 2;
|
||||
newrelo($1.typ, RELO2 | FIXUPFLAGS);
|
||||
DOTVAL -= 2;
|
||||
$$ = $1.val & 0xFFFF;
|
||||
/* Allow signed or unsigned 16-bit values. */
|
||||
if (($1 < -0x8000) || ($1 > 0xffff))
|
||||
serror("16-bit value out of range");
|
||||
$$ = (uint16_t) $1;
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -206,6 +193,15 @@ bda
|
|||
}
|
||||
;
|
||||
|
||||
li32
|
||||
: GPR ',' expr
|
||||
{
|
||||
newrelo($3.typ, RELOPPC | FIXUPFLAGS);
|
||||
emit4((15<<26) | ($1<<21) | (0<<16) | ($3.val >> 16)); /* addis */
|
||||
emit4((24<<26) | ($1<<21) | ($1<<16) | ($3.val & 0xffff)); /* ori */
|
||||
}
|
||||
;
|
||||
|
||||
lil
|
||||
: expr
|
||||
{
|
||||
|
|
|
@ -13,11 +13,14 @@
|
|||
! r3 = ptr to descriptor
|
||||
! r4 = index
|
||||
! r5 = address of array
|
||||
! Yields:
|
||||
! r3 = address of element
|
||||
! r0 = size of element (used by .lar4, .sar4)
|
||||
! Preserves r10 for .lar4, .sar4
|
||||
|
||||
.define .aar4
|
||||
.aar4:
|
||||
addis r0, r0, <.trap_earray
|
||||
ori r0, r0, >.trap_earray
|
||||
li32 r0, .trap_earray
|
||||
mtspr ctr, r0 ! load CTR with trap address
|
||||
|
||||
lwz r0, 0(r3)
|
||||
|
|
13
mach/powerpc/libem/build.lua
Normal file
13
mach/powerpc/libem/build.lua
Normal file
|
@ -0,0 +1,13 @@
|
|||
for _, plat in ipairs(vars.plats) do
|
||||
acklibrary {
|
||||
name = "lib_"..plat,
|
||||
srcs = {
|
||||
"./*.s",
|
||||
},
|
||||
vars = { plat = plat },
|
||||
deps = {
|
||||
"h+emheaders"
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
@ -13,15 +13,15 @@
|
|||
|
||||
.define .cfu8
|
||||
.cfu8:
|
||||
la(r3, .fd_00000000)
|
||||
li32 r3, .fd_00000000
|
||||
lfd f0, 0(r3) ! f0 = 0.0
|
||||
|
||||
lfd f1, 0(sp) ! value to be converted
|
||||
|
||||
la(r3, .fd_FFFFFFFF)
|
||||
li32 r3, .fd_FFFFFFFF
|
||||
lfd f3, 0(r3) ! f3 = 0xFFFFFFFF
|
||||
|
||||
la(r3, .fd_80000000)
|
||||
li32 r3, .fd_80000000
|
||||
lfd f4, 0(r3) ! f4 = 0x80000000
|
||||
|
||||
fsel f2, f1, f1, f0
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
lfd f0, 0(sp) ! load value
|
||||
|
||||
la (r3, pivot)
|
||||
li32 r3, pivot
|
||||
lfd f1, 0(r3) ! load pivot value
|
||||
fsub f0, f0, f1 ! adjust
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
lfd f0, 0(sp) ! load value
|
||||
|
||||
la (r3, pivot)
|
||||
li32 r3, pivot
|
||||
lfd f1, 0(r3) ! load pivot value
|
||||
fsub f0, f0, f1 ! adjust
|
||||
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* $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;
|
||||
}
|
58
mach/powerpc/libem/fef8.s
Normal file
58
mach/powerpc/libem/fef8.s
Normal file
|
@ -0,0 +1,58 @@
|
|||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
! Split a double-precision float into fraction and exponent, like
|
||||
! frexp(3) in C. On entry:
|
||||
! r3 = float, high word (bits 0..31)
|
||||
! r4 = float, low word (bits 32..63)
|
||||
! Yields:
|
||||
! r3 = fraction, high word (bits 0..31)
|
||||
! r4 = fraction, low word (bits 32..63)
|
||||
! r5 = exponent
|
||||
! Kills: cr0 f0 f1 r6 r7
|
||||
|
||||
.define .fef8
|
||||
.fef8:
|
||||
! IEEE double-precision format:
|
||||
! sign exponent fraction
|
||||
! 0 1..11 12..63
|
||||
rlwinm r6, r3, 12, 21, 31 ! r6 = IEEE exponent
|
||||
addis r7, r0, 0x7ff0 ! r7 = exponent mask
|
||||
addi r5, r6, -1022 ! r5 = true exponent
|
||||
cmpi cr0, 0, r6, 2047
|
||||
bclr IFTRUE, EQ, 0 ! return if infinity or NaN
|
||||
cmpi cr0, 0, r6, 0
|
||||
bc IFFALSE, EQ, 1f ! jump if normalized number
|
||||
|
||||
! Got denormalized number or zero, probably zero.
|
||||
rlwinm r6, r3, 0, 12, 31
|
||||
addi r5, r0, 0 ! r5 = true exponent = 0
|
||||
or. r6, r6, r4 ! r6 = high|low fraction
|
||||
bclr IFTRUE, EQ, 0 ! return if zero
|
||||
|
||||
! Got denormalized number, not zero.
|
||||
stwu r4, -4(sp)
|
||||
stwu r3, -4(sp)
|
||||
li32 r6, _2_64
|
||||
lfd f0, 0(sp)
|
||||
lfd f1, 0(r6)
|
||||
fmul f0, f0, f1 ! multiply it by 2**64
|
||||
stfd f0, 0(sp)
|
||||
lwz r3, 0(sp)
|
||||
lwz r4, 4(sp)
|
||||
rlwinm r6, r3, 12, 21, 31 ! r6 = IEEE exponent
|
||||
addi sp, sp, 8
|
||||
addi r5, r6, -1022 - 64 ! r5 = true exponent
|
||||
1:
|
||||
! Put fraction in [0.5, 1) or (-1, -0.5] by setting its
|
||||
! exponent to true 0, IEEE 1022.
|
||||
andc r3, r3, r7 ! clear old exponent
|
||||
oris r3, r3, 1022 << 4 ! set new exponent
|
||||
bclr ALWAYS, 0, 0
|
||||
|
||||
.sect .rom
|
||||
_2_64:
|
||||
! (double) 2**64
|
||||
.data4 0x43f00000
|
||||
.data4 0x00000000
|
|
@ -1,38 +1,71 @@
|
|||
#
|
||||
! $Source$
|
||||
! $State$
|
||||
! $Revision$
|
||||
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
! Multiplies two floats, and returns the fraction and integer.
|
||||
! Multiplies two double-precision floats, then splits the product into
|
||||
! integer and fraction, like modf(3) in C. On entry:
|
||||
! f1 = float
|
||||
! f2 = other float
|
||||
! Yields:
|
||||
! f1 = fraction
|
||||
! f2 = integer
|
||||
! Kills: cr0 f1 f2 r3 r4 r5 r6
|
||||
|
||||
.define .fif8
|
||||
.fif8:
|
||||
lfd f0, 8(sp)
|
||||
lfd f1, 0(sp)
|
||||
fmul f0, f0, f1
|
||||
fabs f1, f0 ! f0 = result
|
||||
fmul f1, f1, f2
|
||||
stfdu f1, -8(sp) ! push f1 = product
|
||||
lwz r3, 0(sp) ! r3 = high word
|
||||
lwz r4, 4(sp) ! r4 = low word
|
||||
|
||||
! The following chunk does f1 = floor(f1). See page 158 of the book.
|
||||
! IEEE double-precision format:
|
||||
! sign exponent fraction
|
||||
! 0 1..11 12..63
|
||||
! Subtract 1023 from the IEEE exponent. If the result is from
|
||||
! 0 to 51, then the IEEE fraction has that many integer bits.
|
||||
! (IEEE has an implicit 1 before its fraction. If the IEEE
|
||||
! fraction has 0 integer bits, we still have an integer.)
|
||||
rlwinm r5, r3, 12, 21, 31 ! r5 = IEEE exponent
|
||||
addic. r5, r5, -1023 ! r5 = nr of integer bits
|
||||
bc IFTRUE, LT, no_int
|
||||
cmpi cr0, 0, r5, 21
|
||||
bc IFTRUE, LT, small_int
|
||||
cmpi cr0, 0, r5, 52
|
||||
bc IFTRUE, LT, big_int
|
||||
|
||||
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:
|
||||
! f1 is an integer without fraction. Jump to calculate
|
||||
! fraction f1 = f2 - f1. It will be zero (or perhaps NaN).
|
||||
fmr f2, f1
|
||||
b subtract
|
||||
|
||||
fabs f2, f1 ! f2 = fabs(f1)
|
||||
fsub f2, f2, f1
|
||||
stfd f2, 8(sp)
|
||||
no_int:
|
||||
! f1 is a fraction without integer.
|
||||
fsub f2, f1, f1 ! integer = zero
|
||||
b done
|
||||
|
||||
fneg f2, f1
|
||||
fsel f2, f0, f1, f2
|
||||
stfd f2, 0(sp)
|
||||
small_int:
|
||||
! f1 has r5 = 0 to 20 integer bits in the IEEE fraction.
|
||||
! High word has 20 - r5 fraction bits.
|
||||
addi r6, r0, 20
|
||||
subf r6, r5, r6
|
||||
srw r3, r3, r6
|
||||
addi r4, r0, 0 ! clear low word
|
||||
slw r3, r3, r6 ! clear fraction in high word
|
||||
b move_int
|
||||
|
||||
big_int:
|
||||
! f1 has r5 = 21 to 51 to integer bits.
|
||||
! Low word has 52 - r5 fraction bits.
|
||||
addi r6, r0, 52
|
||||
subf r6, r5, r6
|
||||
srw r4, r4, r6
|
||||
slw r4, r4, r6 ! clear fraction in low word
|
||||
move_int:
|
||||
stw r3, 0(sp)
|
||||
stw r4, 4(sp)
|
||||
lfd f2, 0(sp) ! f2 = integer
|
||||
subtract:
|
||||
fsub f1, f1, f2 ! fraction = value - integer
|
||||
done:
|
||||
addi sp, sp, 8 ! restore stack pointer
|
||||
bclr ALWAYS, 0, 0
|
||||
|
|
43
mach/powerpc/libem/lar4.s
Normal file
43
mach/powerpc/libem/lar4.s
Normal file
|
@ -0,0 +1,43 @@
|
|||
#
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
! Load from bounds-checked array.
|
||||
!
|
||||
! On entry:
|
||||
! r3 = ptr to descriptor
|
||||
! r4 = index
|
||||
! r5 = address of array
|
||||
|
||||
.define .lar4
|
||||
.lar4:
|
||||
mfspr r10, lr
|
||||
bl .aar4
|
||||
mtspr lr, r10
|
||||
! r3 = ptr to element
|
||||
! r0 = size of element
|
||||
|
||||
cmpi cr0, 0, r0, 1
|
||||
bc IFFALSE, EQ, 1f
|
||||
! Load 1 byte.
|
||||
lbz r4, 0(r3)
|
||||
stwu r4, -4(sp)
|
||||
bclr ALWAYS, 0, 0
|
||||
1:
|
||||
cmpi cr0, 0, r0, 2
|
||||
bc IFFALSE, EQ, 2f
|
||||
! Load 2 bytes.
|
||||
lhz r4, 0(r3)
|
||||
stwu r4, -4(sp)
|
||||
bclr ALWAYS, 0, 0
|
||||
2:
|
||||
! Load r0 bytes, where r0 must be a positive multiple of 4.
|
||||
subf sp, r0, sp ! move stack pointer down
|
||||
or r5, r0, r0 ! index r5 = length r0
|
||||
3:
|
||||
addic. r5, r5, -4 ! r5 -= 4
|
||||
lwzx r4, r5, r3
|
||||
stwx r4, r5, sp
|
||||
bc IFTRUE, GT, 3b ! loop if r5 > 0
|
||||
bclr ALWAYS, 0, 0
|
|
@ -20,4 +20,3 @@
|
|||
#define EQ 2
|
||||
#define OV 3
|
||||
|
||||
#define la(reg, val) addis reg, r0, <val; ori reg, reg, >val
|
||||
|
|
45
mach/powerpc/libem/sar4.s
Normal file
45
mach/powerpc/libem/sar4.s
Normal file
|
@ -0,0 +1,45 @@
|
|||
#
|
||||
#include "powerpc.h"
|
||||
|
||||
.sect .text
|
||||
|
||||
! Store to bounds-checked array.
|
||||
!
|
||||
! On entry:
|
||||
! r3 = ptr to descriptor
|
||||
! r4 = index
|
||||
! r5 = address of array
|
||||
|
||||
.define .sar4
|
||||
.sar4:
|
||||
mfspr r10, lr
|
||||
bl .aar4
|
||||
mtspr lr, r10
|
||||
! r3 = ptr to element
|
||||
! r0 = size of element
|
||||
|
||||
cmpi cr0, 0, r0, 1
|
||||
bc IFFALSE, EQ, 1f
|
||||
! Store 1 byte.
|
||||
lwz r4, 0(sp)
|
||||
addi sp, sp, 4
|
||||
stb r4, 0(r3)
|
||||
bclr ALWAYS, 0, 0
|
||||
1:
|
||||
cmpi cr0, 0, r0, 2
|
||||
bc IFFALSE, EQ, 2f
|
||||
! Store 2 bytes.
|
||||
lwz r4, 0(sp)
|
||||
addi sp, sp, 4
|
||||
sth r4, 0(r3)
|
||||
bclr ALWAYS, 0, 0
|
||||
2:
|
||||
! Store r0 bytes, where r0 must be a positive multiple of 4.
|
||||
or r5, r0, r0 ! index r5 = length r0
|
||||
3:
|
||||
addic. r5, r5, -4 ! r5 -= 4
|
||||
lwzx r4, r5, sp
|
||||
stwx r4, r5, r3
|
||||
bc IFTRUE, GT, 3b ! loop if r5 > 0
|
||||
add sp, r0, sp ! move stack pointer up
|
||||
bclr ALWAYS, 0, 0
|
8
mach/powerpc/libend/build.lua
Normal file
8
mach/powerpc/libend/build.lua
Normal file
|
@ -0,0 +1,8 @@
|
|||
for _, plat in ipairs(vars.plats) do
|
||||
acklibrary {
|
||||
name = "lib_"..plat,
|
||||
srcs = { "./*.s" },
|
||||
vars = { plat = plat },
|
||||
}
|
||||
end
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -909,23 +909,6 @@ normalfailed: if (stackpad!=tokpatlen) {
|
|||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_NOFRAMEPOINTER
|
||||
case DO_STACKADJUST: {
|
||||
result_t result;
|
||||
int nodeno;
|
||||
|
||||
DEBUG("STACKADJUST");
|
||||
/* The offset is an expression, which we need to evaluate. */
|
||||
|
||||
getint(nodeno,codep);
|
||||
compute(&enodes[nodeno], &result);
|
||||
assert(result.e_typ==EV_INT);
|
||||
|
||||
if (toplevel)
|
||||
stackoffset += result.e_v.e_con;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,9 +20,6 @@ extern rl_p curreglist; /* side effect of findcoerc() */
|
|||
#ifndef NDEBUG
|
||||
extern int Debug; /* on/off debug printout */
|
||||
#endif
|
||||
#ifdef USE_NOFRAMEPOINTER
|
||||
extern int stackoffset; /* offset from localbase to sp */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Next descriptions are external declarations for tables created
|
||||
|
|
|
@ -42,6 +42,13 @@ begtext:
|
|||
|
||||
b __m_a_i_n
|
||||
|
||||
! Define symbols at the beginning of our various segments, so that we can find
|
||||
! them. (Except .text, which has already been done.)
|
||||
|
||||
.sect .data; begdata:
|
||||
.sect .rom; begrom:
|
||||
.sect .bss; begbss:
|
||||
|
||||
! Some magic data. All EM systems need these.
|
||||
|
||||
.define _errno
|
||||
|
@ -50,7 +57,3 @@ begtext:
|
|||
.define .trppc, .ignmask
|
||||
.comm .trppc, 4 ! ptr to user trap handler
|
||||
.comm .ignmask, 4 ! user trap ignore mask
|
||||
|
||||
.define .linenumber, .filename
|
||||
.comm .linenumber, 4 ! current linenumber (used for debugging)
|
||||
.comm .filename, 4 ! ptr to current filename (used for debugging)
|
||||
|
|
25
plat/linuxppc/build-pkg.lua
Normal file
25
plat/linuxppc/build-pkg.lua
Normal file
|
@ -0,0 +1,25 @@
|
|||
include("plat/build.lua")
|
||||
|
||||
ackfile {
|
||||
name = "boot",
|
||||
srcs = { "./boot.s" },
|
||||
vars = { plat = "linuxppc" }
|
||||
}
|
||||
|
||||
build_plat_libs {
|
||||
name = "libs",
|
||||
arch = "powerpc",
|
||||
plat = "linuxppc",
|
||||
}
|
||||
|
||||
installable {
|
||||
name = "pkg",
|
||||
map = {
|
||||
"+tools",
|
||||
"+libs",
|
||||
"./include+pkg",
|
||||
["$(PLATIND)/linuxppc/boot.o"] = "+boot",
|
||||
["$(PLATIND)/linuxppc/libsys.a"] = "./libsys+lib",
|
||||
}
|
||||
}
|
||||
|
21
plat/linuxppc/build-tools.lua
Normal file
21
plat/linuxppc/build-tools.lua
Normal file
|
@ -0,0 +1,21 @@
|
|||
include("plat/build.lua")
|
||||
|
||||
build_as {
|
||||
name = "as",
|
||||
arch = "powerpc",
|
||||
}
|
||||
|
||||
build_ncg {
|
||||
name = "ncg",
|
||||
arch = "powerpc",
|
||||
}
|
||||
|
||||
return installable {
|
||||
name = "tools",
|
||||
map = {
|
||||
["$(PLATDEP)/linuxppc/as"] = "+as",
|
||||
["$(PLATDEP)/linuxppc/ncg"] = "+ncg",
|
||||
["$(PLATIND)/descr/linuxppc"] = "./descr",
|
||||
"util/opt+pkg",
|
||||
}
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
# $Source: /cvsroot/tack/Ack/plat/linux386/descr,v $
|
||||
# $State: Exp $
|
||||
# $Revision: 1.1 $
|
||||
# plat/linuxppc/descr
|
||||
|
||||
var w=4
|
||||
var wa=4
|
||||
|
@ -19,8 +17,8 @@ var xa={x}
|
|||
var ARCH=powerpc
|
||||
var PLATFORM=linuxppc
|
||||
var PLATFORMDIR={EM}/share/ack/{PLATFORM}
|
||||
var CPP_F=-D__unix -D__POWERPC
|
||||
var ALIGN=-a0:4 -a1:4 -a2:4 -a3:4 -b0:0x80000054
|
||||
var CPP_F=-D__unix
|
||||
var ALIGN=-a0:4 -a1:4 -a2:4 -a3:4 -b0:0x10000054
|
||||
var C_LIB={PLATFORMDIR}/libc-ansi.a
|
||||
# bitfields reversed for compatibility with (g)cc.
|
||||
var CC_ALIGN=-Vr
|
||||
|
@ -35,25 +33,26 @@ var C_INCLUDES=-I{PLATFORMDIR}/include -I{EM}/share/ack/include/ansi
|
|||
name be
|
||||
from .m.g
|
||||
to .s
|
||||
program {EM}/lib/ack/{ARCH}/ncg
|
||||
program {EM}/lib/ack/{PLATFORM}/ncg
|
||||
mapflag -gdb GF=-gdb
|
||||
args {GF?} <
|
||||
stdout
|
||||
need .e
|
||||
end
|
||||
name asopt
|
||||
from .s
|
||||
to .so
|
||||
program {EM}/lib/ack/{ARCH}/top
|
||||
args
|
||||
optimizer
|
||||
stdin
|
||||
stdout
|
||||
end
|
||||
# FIXME(dtrg): not working yet
|
||||
#name asopt
|
||||
# from .s
|
||||
# to .so
|
||||
# program {EM}/lib/ack/{PLATFORM}/top
|
||||
# args
|
||||
# optimizer
|
||||
# stdin
|
||||
# stdout
|
||||
#end
|
||||
name as
|
||||
from .s.so
|
||||
to .o
|
||||
program {EM}/lib/ack/{ARCH}/as
|
||||
program {EM}/lib/ack/{PLATFORM}/as
|
||||
args - -o > <
|
||||
prep cond
|
||||
end
|
||||
|
@ -64,8 +63,9 @@ name led
|
|||
mapflag -l* LNAME={PLATFORMDIR}/lib*
|
||||
mapflag -fp FLOATS={EM}/{LIB}fp
|
||||
args {ALIGN} {SEPID?} \
|
||||
{PLATFORMDIR}/boot.o \
|
||||
({RTS}:.ocm.b.c={PLATFORMDIR}/c-ansi.o) \
|
||||
(.e:{HEAD}={PLATFORMDIR}/boot.o) \
|
||||
({RTS}:.ocm.b={PLATFORMDIR}/c-ansi.o) \
|
||||
({RTS}:.c={PLATFORMDIR}/c-ansi.o) \
|
||||
({RTS}:.mod={PLATFORMDIR}/modula2.o) \
|
||||
({RTS}:.p={PLATFORMDIR}/pascal.o) \
|
||||
-o > < \
|
||||
|
@ -74,10 +74,10 @@ name led
|
|||
(.mod:{TAIL}={PLATFORMDIR}/libmodula2.a) \
|
||||
(.ocm:{TAIL}={PLATFORMDIR}/liboccam.a) \
|
||||
(.ocm.b.mod.c.p:{TAIL}={PLATFORMDIR}/libc.a) \
|
||||
{PLATFORMDIR}/liblinux.a \
|
||||
{PLATFORMDIR}/libem.a \
|
||||
{FLOATS?} \
|
||||
(.e:{TAIL}={PLATFORMDIR}/libem.a \
|
||||
{PLATFORMDIR}/libsys.a \
|
||||
{PLATFORMDIR}/libend.a
|
||||
{PLATFORMDIR}/libend.a)
|
||||
linker
|
||||
end
|
||||
name cv
|
||||
|
|
24
plat/linuxppc/include/build.lua
Normal file
24
plat/linuxppc/include/build.lua
Normal file
|
@ -0,0 +1,24 @@
|
|||
include("plat/build.lua")
|
||||
|
||||
headermap = {}
|
||||
packagemap = {}
|
||||
|
||||
local function addheader(h)
|
||||
headermap[h] = "./"..h
|
||||
packagemap["$(PLATIND)/linuxppc/include/"..h] = "./"..h
|
||||
end
|
||||
|
||||
addheader("ack/config.h")
|
||||
addheader("sys/ioctl.h")
|
||||
addheader("unistd.h")
|
||||
|
||||
acklibrary {
|
||||
name = "headers",
|
||||
hdrs = headermap
|
||||
}
|
||||
|
||||
installable {
|
||||
name = "pkg",
|
||||
map = packagemap
|
||||
}
|
||||
|
|
@ -42,8 +42,7 @@ __syscall:
|
|||
bc IFTRUE, GT, 2f
|
||||
|
||||
3:
|
||||
addis r4, r0, <_errno
|
||||
ori r4, r4, >_errno
|
||||
li32 r4, _errno
|
||||
stw r3, 0(r4)
|
||||
addi r3, r0, -1
|
||||
bclr ALWAYS, 0, 0
|
||||
|
|
16
plat/linuxppc/libsys/build.lua
Normal file
16
plat/linuxppc/libsys/build.lua
Normal file
|
@ -0,0 +1,16 @@
|
|||
acklibrary {
|
||||
name = "lib",
|
||||
srcs = {
|
||||
"./*.s",
|
||||
"plat/linux/libsys/*.c",
|
||||
"plat/linux/libsys/*.s",
|
||||
},
|
||||
deps = {
|
||||
"lang/cem/libcc.ansi/headers+headers",
|
||||
"plat/linuxppc/include+headers",
|
||||
},
|
||||
vars = {
|
||||
plat = "linuxppc"
|
||||
}
|
||||
}
|
||||
|
|
@ -65,15 +65,13 @@ EUNIMPL = 63 ! unimplemented em-instruction called
|
|||
|
||||
addi r4, r0, 1
|
||||
rlwnm r4, r4, r3, 0, 31 ! calculate trap bit
|
||||
addis r5, r0, <.ignmask
|
||||
ori r5, r5, >.ignmask
|
||||
li32 r5, .ignmask
|
||||
lwz r5, 0(r5) ! load ignore mask
|
||||
and. r4, r4, r5 ! compare
|
||||
bclr IFFALSE, EQ, 0 ! return if non-zero
|
||||
|
||||
1:
|
||||
addis r4, r0, <.trppc
|
||||
ori r4, r4, >.trppc
|
||||
li32 r4, .trppc
|
||||
lwz r5, 0(r4) ! load user trap routine
|
||||
or. r5, r5, r5 ! test
|
||||
bc IFTRUE, EQ, fatal ! if no user trap routine, bail out
|
||||
|
@ -94,8 +92,7 @@ EUNIMPL = 63 ! unimplemented em-instruction called
|
|||
|
||||
fatal:
|
||||
addi r3, r0, 1
|
||||
addis r4, r0, <message
|
||||
ori r4, r4, >message
|
||||
li32 r4, message
|
||||
addi r5, r0, 6
|
||||
addi r0, r0, 4 ! write()
|
||||
sc 0
|
||||
|
|
|
@ -140,9 +140,6 @@ showrelo()
|
|||
case RELOPPC:
|
||||
printf("\tPowerPC 26-bit address\n");
|
||||
break;
|
||||
case RELOH2:
|
||||
printf("\ttop 2 bytes of a 4 byte word\n");
|
||||
break;
|
||||
case RELOVC4:
|
||||
printf("\tVideoCore IV address in 32-bit instruction\n");
|
||||
break;
|
||||
|
|
|
@ -158,12 +158,11 @@ struct outrelo {
|
|||
/*
|
||||
* relocation type bits
|
||||
*/
|
||||
#define RELSZ 0x0fffi /* relocation length */
|
||||
#define RELSZ 0x0fff /* relocation length */
|
||||
#define RELO1 0x01 /* 1 byte */
|
||||
#define RELO2 0x02 /* 2 bytes */
|
||||
#define RELO4 0x03 /* 4 bytes */
|
||||
#define RELOPPC 0x04 /* 26-bit PowerPC address */
|
||||
#define RELOH2 0x05 /* write top 2 bytes of 4 byte word */
|
||||
#define RELOVC4 0x06 /* VideoCore IV address in 32-bit insruction */
|
||||
#define RELPC 0x2000 /* pc relative */
|
||||
#define RELBR 0x4000 /* High order byte lowest address. */
|
||||
|
|
|
@ -18,7 +18,7 @@ static char rcsid[] = "$Id$";
|
|||
|
||||
#define UBYTE(x) ((x) & BYTEMASK)
|
||||
|
||||
static long read2(char* addr, int type)
|
||||
static uint16_t read2(char* addr, int type)
|
||||
{
|
||||
unsigned short word0, word1;
|
||||
|
||||
|
@ -28,7 +28,7 @@ static long read2(char* addr, int type)
|
|||
return (UBYTE(addr[1]) << WIDTH) + UBYTE(addr[0]);
|
||||
}
|
||||
|
||||
static long read4(char* addr, int type)
|
||||
static uint32_t read4(char* addr, int type)
|
||||
{
|
||||
unsigned short word0, word1;
|
||||
|
||||
|
@ -49,7 +49,7 @@ static long read4(char* addr, int type)
|
|||
* one of several different ways (depending on what the instruction is).
|
||||
*/
|
||||
|
||||
static long get_vc4_valu(char* addr)
|
||||
static uint32_t get_vc4_valu(char* addr)
|
||||
{
|
||||
uint16_t opcode = read2(addr, 0);
|
||||
|
||||
|
@ -104,11 +104,36 @@ static long get_vc4_valu(char* addr)
|
|||
assert(0 && "unrecognised VC4 instruction");
|
||||
}
|
||||
|
||||
/* PowerPC fixups are complex as we need to patch up to the next two
|
||||
* instructions in one of several different ways, depending on what the
|
||||
* instructions area.
|
||||
*/
|
||||
|
||||
static uint32_t get_powerpc_valu(char* addr, uint16_t type)
|
||||
{
|
||||
uint32_t opcode1 = read4(addr+0, type);
|
||||
uint32_t opcode2 = read4(addr+4, type);
|
||||
|
||||
if ((opcode1 & 0xfc000000) == 0x48000000)
|
||||
{
|
||||
/* branch instruction */
|
||||
return opcode1 & 0x03fffffd;
|
||||
}
|
||||
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) &&
|
||||
((opcode2 & 0xfc000000) == 0x60000000))
|
||||
{
|
||||
/* addis / ori instruction pair */
|
||||
return ((opcode1 & 0xffff) << 16) | (opcode2 & 0xffff);
|
||||
}
|
||||
|
||||
assert(0 && "unrecognised PowerPC instruction");
|
||||
}
|
||||
|
||||
/*
|
||||
* The bits in type indicate how many bytes the value occupies and what
|
||||
* significance should be attributed to each byte.
|
||||
*/
|
||||
static long getvalu(char* addr, uint16_t type)
|
||||
static uint32_t getvalu(char* addr, uint16_t type)
|
||||
{
|
||||
switch (type & RELSZ) {
|
||||
case RELO1:
|
||||
|
@ -118,9 +143,7 @@ static long getvalu(char* addr, uint16_t type)
|
|||
case RELO4:
|
||||
return read4(addr, type);
|
||||
case RELOPPC:
|
||||
return read4(addr, type) & 0x03FFFFFD;
|
||||
case RELOH2:
|
||||
return read2(addr, type) << 16;
|
||||
return get_powerpc_valu(addr, type);
|
||||
case RELOVC4:
|
||||
return get_vc4_valu(addr);
|
||||
default:
|
||||
|
@ -129,7 +152,7 @@ static long getvalu(char* addr, uint16_t type)
|
|||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static void write2(long valu, char* addr, int type)
|
||||
static void write2(uint16_t valu, char* addr, int type)
|
||||
{
|
||||
unsigned short word0, word1;
|
||||
|
||||
|
@ -142,7 +165,7 @@ static void write2(long valu, char* addr, int type)
|
|||
}
|
||||
}
|
||||
|
||||
static void write4(long valu, char* addr, int type)
|
||||
static void write4(uint32_t valu, char* addr, int type)
|
||||
{
|
||||
unsigned short word0, word1;
|
||||
|
||||
|
@ -170,7 +193,7 @@ static void write4(long valu, char* addr, int type)
|
|||
* one of several different ways (depending on what the instruction is).
|
||||
*/
|
||||
|
||||
static void put_vc4_valu(char* addr, long value)
|
||||
static void put_vc4_valu(char* addr, uint32_t value)
|
||||
{
|
||||
uint16_t opcode = read2(addr, 0);
|
||||
|
||||
|
@ -220,12 +243,42 @@ static void put_vc4_valu(char* addr, long value)
|
|||
assert(0 && "unrecognised VC4 instruction");
|
||||
}
|
||||
|
||||
/* PowerPC fixups are complex as we need to patch up to the next two
|
||||
* instructions in one of several different ways, depending on what the
|
||||
* instructions area.
|
||||
*/
|
||||
|
||||
static void put_powerpc_valu(char* addr, uint32_t value, uint16_t type)
|
||||
{
|
||||
uint32_t opcode1 = read4(addr+0, type);
|
||||
uint32_t opcode2 = read4(addr+4, type);
|
||||
|
||||
if ((opcode1 & 0xfc000000) == 0x48000000)
|
||||
{
|
||||
/* branch instruction */
|
||||
uint32_t i = opcode1 & ~0x03fffffd;
|
||||
i |= value & 0x03fffffd;
|
||||
write4(i, addr, type);
|
||||
}
|
||||
else if (((opcode1 & 0xfc1f0000) == 0x3c000000) &&
|
||||
((opcode2 & 0xfc000000) == 0x60000000))
|
||||
{
|
||||
uint16_t hi = value >> 16;
|
||||
uint16_t lo = value & 0xffff;
|
||||
|
||||
write4((opcode1 & 0xffff0000) | hi, addr+0, type);
|
||||
write4((opcode2 & 0xffff0000) | lo, addr+4, type);
|
||||
}
|
||||
else
|
||||
assert(0 && "unrecognised PowerPC instruction");
|
||||
}
|
||||
|
||||
/*
|
||||
* The bits in type indicate how many bytes the value occupies and what
|
||||
* significance should be attributed to each byte.
|
||||
* We do not check for overflow.
|
||||
*/
|
||||
static putvalu(long valu, char* addr, uint16_t type)
|
||||
static putvalu(uint32_t valu, char* addr, uint16_t type)
|
||||
{
|
||||
|
||||
switch (type & RELSZ) {
|
||||
|
@ -239,14 +292,7 @@ static putvalu(long valu, char* addr, uint16_t type)
|
|||
write4(valu, addr, type);
|
||||
break;
|
||||
case RELOPPC:
|
||||
{
|
||||
long i = read4(addr, type) & ~0x03FFFFFD;
|
||||
i |= valu & 0x03FFFFFD;
|
||||
write4(i, addr, type);
|
||||
break;
|
||||
}
|
||||
case RELOH2:
|
||||
write2(valu>>16, addr, type);
|
||||
put_powerpc_valu(addr, valu, type);
|
||||
break;
|
||||
case RELOVC4:
|
||||
put_vc4_valu(addr, valu);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#define BORS(x,y) y
|
||||
#endif
|
||||
|
||||
#define MAXREGS BORS(80,30)
|
||||
#define MAXREGS BORS(200,30)
|
||||
#define MAXPROPS BORS(120,20)
|
||||
#define MAXTOKENS BORS(100,60)
|
||||
#define MAXATT 6
|
||||
|
|
Loading…
Reference in a new issue