Merge in the unfinished PowerPC branch.
This commit is contained in:
commit
d539389e81
|
@ -8,6 +8,7 @@ vars.plats = {
|
||||||
"cpm",
|
"cpm",
|
||||||
"linux386",
|
"linux386",
|
||||||
"linux68k",
|
"linux68k",
|
||||||
|
"linuxppc",
|
||||||
"pc86",
|
"pc86",
|
||||||
"rpi",
|
"rpi",
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#define DO_TOSTACK 23
|
#define DO_TOSTACK 23
|
||||||
#define DO_KILLREG 24
|
#define DO_KILLREG 24
|
||||||
#define DO_LABDEF 25
|
#define DO_LABDEF 25
|
||||||
|
#define DO_STACKADJUST 26
|
||||||
|
|
||||||
#ifndef MAXATT
|
#ifndef MAXATT
|
||||||
#define MAXATT TOKENSIZE
|
#define MAXATT TOKENSIZE
|
||||||
|
@ -133,6 +134,7 @@ typedef struct exprnode *node_p;
|
||||||
#define EX_ISROM 44
|
#define EX_ISROM 44
|
||||||
#define EX_TOPELTSIZE 45
|
#define EX_TOPELTSIZE 45
|
||||||
#define EX_FALLTHROUGH 46
|
#define EX_FALLTHROUGH 46
|
||||||
|
#define EX_STACKOFFSET 47
|
||||||
|
|
||||||
|
|
||||||
typedef struct { /* to stack coercions */
|
typedef struct { /* to stack coercions */
|
||||||
|
|
2
h/out.h
2
h/out.h
|
@ -66,7 +66,7 @@ struct outname {
|
||||||
#define RELO2 2 /* 2 bytes */
|
#define RELO2 2 /* 2 bytes */
|
||||||
#define RELO4 3 /* 4 bytes */
|
#define RELO4 3 /* 4 bytes */
|
||||||
#define RELOPPC 4 /* PowerPC 26-bit address */
|
#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 RELOVC4 6 /* VideoCore IV address in 32-bit instruction */
|
||||||
|
|
||||||
#define RELPC 0x2000 /* pc relative */
|
#define RELPC 0x2000 /* pc relative */
|
||||||
|
|
|
@ -80,7 +80,7 @@
|
||||||
%token <y_word> OP_TO_RA_RB
|
%token <y_word> OP_TO_RA_RB
|
||||||
%token <y_word> OP_TO_RA_SI
|
%token <y_word> OP_TO_RA_SI
|
||||||
|
|
||||||
%token <y_word> OP_la
|
%token <y_word> OP_LA
|
||||||
|
|
||||||
/* Other token types */
|
/* Other token types */
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@
|
||||||
|
|
||||||
/* Special instructions */
|
/* Special instructions */
|
||||||
|
|
||||||
0, OP_la, 0, "la",
|
0, OP_LA, 0, "la",
|
||||||
|
|
||||||
/* Branch processor instructions (page 20) */
|
/* Branch processor instructions (page 20) */
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ operation
|
||||||
| OP_LEV u7 { emit4($1 | ($2<<5)); }
|
| OP_LEV u7 { emit4($1 | ($2<<5)); }
|
||||||
| OP_LIA lia { emit4($1 | $2); }
|
| OP_LIA lia { emit4($1 | $2); }
|
||||||
| OP_LIL lil { emit4($1 | $2); }
|
| OP_LIL lil { emit4($1 | $2); }
|
||||||
|
| OP_LA la /* emitted in subrule */
|
||||||
;
|
;
|
||||||
|
|
||||||
c
|
c
|
||||||
|
@ -66,26 +67,12 @@ c
|
||||||
;
|
;
|
||||||
|
|
||||||
e16
|
e16
|
||||||
: '<' expr
|
: absexp
|
||||||
{
|
{
|
||||||
DOTVAL += 2;
|
/* Allow signed or unsigned 16-bit values. */
|
||||||
newrelo($2.typ, RELOH2 | FIXUPFLAGS);
|
if (($1 < -0x8000) || ($1 > 0xffff))
|
||||||
DOTVAL -= 2;
|
serror("16-bit value out of range");
|
||||||
$$ = ($2.val >> 16) & 0xFFFF;
|
$$ = (uint16_t) $1;
|
||||||
}
|
|
||||||
| '>' 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;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -206,6 +193,15 @@ bda
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
la
|
||||||
|
: 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
|
lil
|
||||||
: expr
|
: expr
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
|
|
||||||
.define .aar4
|
.define .aar4
|
||||||
.aar4:
|
.aar4:
|
||||||
addis r0, r0, <.trap_earray
|
la r0, .trap_earray
|
||||||
ori r0, r0, >.trap_earray
|
|
||||||
mtspr ctr, r0 ! load CTR with trap address
|
mtspr ctr, r0 ! load CTR with trap address
|
||||||
|
|
||||||
lwz r0, 0(r3)
|
lwz r0, 0(r3)
|
||||||
|
|
14
mach/powerpc/libem/build.lua
Normal file
14
mach/powerpc/libem/build.lua
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
for _, plat in ipairs(vars.plats) do
|
||||||
|
acklibrary {
|
||||||
|
name = "lib_"..plat,
|
||||||
|
srcs = {
|
||||||
|
"./*.s",
|
||||||
|
"./*.c"
|
||||||
|
},
|
||||||
|
vars = { plat = plat },
|
||||||
|
deps = {
|
||||||
|
"h+emheaders"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
|
@ -13,15 +13,15 @@
|
||||||
|
|
||||||
.define .cfu8
|
.define .cfu8
|
||||||
.cfu8:
|
.cfu8:
|
||||||
la(r3, .fd_00000000)
|
la r3, .fd_00000000
|
||||||
lfd f0, 0(r3) ! f0 = 0.0
|
lfd f0, 0(r3) ! f0 = 0.0
|
||||||
|
|
||||||
lfd f1, 0(sp) ! value to be converted
|
lfd f1, 0(sp) ! value to be converted
|
||||||
|
|
||||||
la(r3, .fd_FFFFFFFF)
|
la r3, .fd_FFFFFFFF
|
||||||
lfd f3, 0(r3) ! f3 = 0xFFFFFFFF
|
lfd f3, 0(r3) ! f3 = 0xFFFFFFFF
|
||||||
|
|
||||||
la(r3, .fd_80000000)
|
la r3, .fd_80000000
|
||||||
lfd f4, 0(r3) ! f4 = 0x80000000
|
lfd f4, 0(r3) ! f4 = 0x80000000
|
||||||
|
|
||||||
fsel f2, f1, f1, f0
|
fsel f2, f1, f1, f0
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
lfd f0, 0(sp) ! load value
|
lfd f0, 0(sp) ! load value
|
||||||
|
|
||||||
la (r3, pivot)
|
la r3, pivot
|
||||||
lfd f1, 0(r3) ! load pivot value
|
lfd f1, 0(r3) ! load pivot value
|
||||||
fsub f0, f0, f1 ! adjust
|
fsub f0, f0, f1 ! adjust
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
lfd f0, 0(sp) ! load value
|
lfd f0, 0(sp) ! load value
|
||||||
|
|
||||||
la (r3, pivot)
|
la r3, pivot
|
||||||
lfd f1, 0(r3) ! load pivot value
|
lfd f1, 0(r3) ! load pivot value
|
||||||
fsub f0, f0, f1 ! adjust
|
fsub f0, f0, f1 ! adjust
|
||||||
|
|
||||||
|
|
|
@ -20,4 +20,3 @@
|
||||||
#define EQ 2
|
#define EQ 2
|
||||||
#define OV 3
|
#define OV 3
|
||||||
|
|
||||||
#define la(reg, val) addis reg, r0, <val; ori reg, reg, >val
|
|
||||||
|
|
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
|
||||||
|
|
|
@ -262,6 +262,7 @@ INSTRUCTIONS
|
||||||
fsub FD:wo, FD:ro, FD:ro.
|
fsub FD:wo, FD:ro, FD:ro.
|
||||||
fsubs FS:wo, FS:ro, FS:ro.
|
fsubs FS:wo, FS:ro, FS:ro.
|
||||||
fmr FS+FD:wo, FS+FD:ro.
|
fmr FS+FD:wo, FS+FD:ro.
|
||||||
|
la GPRI:wo, LABEL:ro.
|
||||||
lbzx GPRI:wo, GPR:ro, GPR:ro.
|
lbzx GPRI:wo, GPR:ro, GPR:ro.
|
||||||
lbz GPRI:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
|
lbz GPRI:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
|
||||||
lfd FD:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
|
lfd FD:wo, GPRINDIRECT+GPRINDIRECTLO:ro.
|
||||||
|
@ -353,8 +354,7 @@ MOVES
|
||||||
from LABEL to GPR
|
from LABEL to GPR
|
||||||
gen
|
gen
|
||||||
COMMENT("move LABEL->GPR")
|
COMMENT("move LABEL->GPR")
|
||||||
addis %2, R0, {HILABEL, %1.adr}
|
la %2, {LABEL, %1.adr}
|
||||||
ori %2, %2, {LOLABEL, %1.adr}
|
|
||||||
|
|
||||||
/* Sign extension */
|
/* Sign extension */
|
||||||
|
|
||||||
|
|
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",
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,25 +35,26 @@ var C_INCLUDES=-I{PLATFORMDIR}/include -I{EM}/share/ack/include/ansi
|
||||||
name be
|
name be
|
||||||
from .m.g
|
from .m.g
|
||||||
to .s
|
to .s
|
||||||
program {EM}/lib/ack/{ARCH}/ncg
|
program {EM}/lib/ack/{PLATFORM}/ncg
|
||||||
mapflag -gdb GF=-gdb
|
mapflag -gdb GF=-gdb
|
||||||
args {GF?} <
|
args {GF?} <
|
||||||
stdout
|
stdout
|
||||||
need .e
|
need .e
|
||||||
end
|
end
|
||||||
name asopt
|
# FIXME(dtrg): not working yet
|
||||||
from .s
|
#name asopt
|
||||||
to .so
|
# from .s
|
||||||
program {EM}/lib/ack/{ARCH}/top
|
# to .so
|
||||||
args
|
# program {EM}/lib/ack/{PLATFORM}/top
|
||||||
optimizer
|
# args
|
||||||
stdin
|
# optimizer
|
||||||
stdout
|
# stdin
|
||||||
end
|
# stdout
|
||||||
|
#end
|
||||||
name as
|
name as
|
||||||
from .s.so
|
from .s.so
|
||||||
to .o
|
to .o
|
||||||
program {EM}/lib/ack/{ARCH}/as
|
program {EM}/lib/ack/{PLATFORM}/as
|
||||||
args - -o > <
|
args - -o > <
|
||||||
prep cond
|
prep cond
|
||||||
end
|
end
|
||||||
|
@ -74,7 +75,6 @@ name led
|
||||||
(.mod:{TAIL}={PLATFORMDIR}/libmodula2.a) \
|
(.mod:{TAIL}={PLATFORMDIR}/libmodula2.a) \
|
||||||
(.ocm:{TAIL}={PLATFORMDIR}/liboccam.a) \
|
(.ocm:{TAIL}={PLATFORMDIR}/liboccam.a) \
|
||||||
(.ocm.b.mod.c.p:{TAIL}={PLATFORMDIR}/libc.a) \
|
(.ocm.b.mod.c.p:{TAIL}={PLATFORMDIR}/libc.a) \
|
||||||
{PLATFORMDIR}/liblinux.a \
|
|
||||||
{PLATFORMDIR}/libem.a \
|
{PLATFORMDIR}/libem.a \
|
||||||
{PLATFORMDIR}/libsys.a \
|
{PLATFORMDIR}/libsys.a \
|
||||||
{PLATFORMDIR}/libend.a
|
{PLATFORMDIR}/libend.a
|
||||||
|
|
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
|
bc IFTRUE, GT, 2f
|
||||||
|
|
||||||
3:
|
3:
|
||||||
addis r4, r0, <_errno
|
la r4, _errno
|
||||||
ori r4, r4, >_errno
|
|
||||||
stw r3, 0(r4)
|
stw r3, 0(r4)
|
||||||
addi r3, r0, -1
|
addi r3, r0, -1
|
||||||
bclr ALWAYS, 0, 0
|
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
|
addi r4, r0, 1
|
||||||
rlwnm r4, r4, r3, 0, 31 ! calculate trap bit
|
rlwnm r4, r4, r3, 0, 31 ! calculate trap bit
|
||||||
addis r5, r0, <.ignmask
|
la r5, .ignmask
|
||||||
ori r5, r5, >.ignmask
|
|
||||||
lwz r5, 0(r5) ! load ignore mask
|
lwz r5, 0(r5) ! load ignore mask
|
||||||
and. r4, r4, r5 ! compare
|
and. r4, r4, r5 ! compare
|
||||||
bclr IFFALSE, EQ, 0 ! return if non-zero
|
bclr IFFALSE, EQ, 0 ! return if non-zero
|
||||||
|
|
||||||
1:
|
1:
|
||||||
addis r4, r0, <.trppc
|
la r4, .trppc
|
||||||
ori r4, r4, >.trppc
|
|
||||||
lwz r5, 0(r4) ! load user trap routine
|
lwz r5, 0(r4) ! load user trap routine
|
||||||
or. r5, r5, r5 ! test
|
or. r5, r5, r5 ! test
|
||||||
bc IFTRUE, EQ, fatal ! if no user trap routine, bail out
|
bc IFTRUE, EQ, fatal ! if no user trap routine, bail out
|
||||||
|
@ -94,8 +92,7 @@ EUNIMPL = 63 ! unimplemented em-instruction called
|
||||||
|
|
||||||
fatal:
|
fatal:
|
||||||
addi r3, r0, 1
|
addi r3, r0, 1
|
||||||
addis r4, r0, <message
|
la r4, message
|
||||||
ori r4, r4, >message
|
|
||||||
addi r5, r0, 6
|
addi r5, r0, 6
|
||||||
addi r0, r0, 4 ! write()
|
addi r0, r0, 4 ! write()
|
||||||
sc 0
|
sc 0
|
||||||
|
|
|
@ -140,9 +140,6 @@ showrelo()
|
||||||
case RELOPPC:
|
case RELOPPC:
|
||||||
printf("\tPowerPC 26-bit address\n");
|
printf("\tPowerPC 26-bit address\n");
|
||||||
break;
|
break;
|
||||||
case RELOH2:
|
|
||||||
printf("\ttop 2 bytes of a 4 byte word\n");
|
|
||||||
break;
|
|
||||||
case RELOVC4:
|
case RELOVC4:
|
||||||
printf("\tVideoCore IV address in 32-bit instruction\n");
|
printf("\tVideoCore IV address in 32-bit instruction\n");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -158,12 +158,11 @@ struct outrelo {
|
||||||
/*
|
/*
|
||||||
* relocation type bits
|
* relocation type bits
|
||||||
*/
|
*/
|
||||||
#define RELSZ 0x0fffi /* relocation length */
|
#define RELSZ 0x0fff /* relocation length */
|
||||||
#define RELO1 0x01 /* 1 byte */
|
#define RELO1 0x01 /* 1 byte */
|
||||||
#define RELO2 0x02 /* 2 bytes */
|
#define RELO2 0x02 /* 2 bytes */
|
||||||
#define RELO4 0x03 /* 4 bytes */
|
#define RELO4 0x03 /* 4 bytes */
|
||||||
#define RELOPPC 0x04 /* 26-bit PowerPC address */
|
#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 RELOVC4 0x06 /* VideoCore IV address in 32-bit insruction */
|
||||||
#define RELPC 0x2000 /* pc relative */
|
#define RELPC 0x2000 /* pc relative */
|
||||||
#define RELBR 0x4000 /* High order byte lowest address. */
|
#define RELBR 0x4000 /* High order byte lowest address. */
|
||||||
|
|
|
@ -18,7 +18,7 @@ static char rcsid[] = "$Id$";
|
||||||
|
|
||||||
#define UBYTE(x) ((x) & BYTEMASK)
|
#define UBYTE(x) ((x) & BYTEMASK)
|
||||||
|
|
||||||
static long read2(char* addr, int type)
|
static uint16_t read2(char* addr, int type)
|
||||||
{
|
{
|
||||||
unsigned short word0, word1;
|
unsigned short word0, word1;
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ static long read2(char* addr, int type)
|
||||||
return (UBYTE(addr[1]) << WIDTH) + UBYTE(addr[0]);
|
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;
|
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).
|
* 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);
|
uint16_t opcode = read2(addr, 0);
|
||||||
|
|
||||||
|
@ -104,11 +104,36 @@ static long get_vc4_valu(char* addr)
|
||||||
assert(0 && "unrecognised VC4 instruction");
|
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
|
* The bits in type indicate how many bytes the value occupies and what
|
||||||
* significance should be attributed to each byte.
|
* 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) {
|
switch (type & RELSZ) {
|
||||||
case RELO1:
|
case RELO1:
|
||||||
|
@ -118,9 +143,7 @@ static long getvalu(char* addr, uint16_t type)
|
||||||
case RELO4:
|
case RELO4:
|
||||||
return read4(addr, type);
|
return read4(addr, type);
|
||||||
case RELOPPC:
|
case RELOPPC:
|
||||||
return read4(addr, type) & 0x03FFFFFD;
|
return get_powerpc_valu(addr, type);
|
||||||
case RELOH2:
|
|
||||||
return read2(addr, type) << 16;
|
|
||||||
case RELOVC4:
|
case RELOVC4:
|
||||||
return get_vc4_valu(addr);
|
return get_vc4_valu(addr);
|
||||||
default:
|
default:
|
||||||
|
@ -129,7 +152,7 @@ static long getvalu(char* addr, uint16_t type)
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write2(long valu, char* addr, int type)
|
static void write2(uint16_t valu, char* addr, int type)
|
||||||
{
|
{
|
||||||
unsigned short word0, word1;
|
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;
|
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).
|
* 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);
|
uint16_t opcode = read2(addr, 0);
|
||||||
|
|
||||||
|
@ -220,12 +243,42 @@ static void put_vc4_valu(char* addr, long value)
|
||||||
assert(0 && "unrecognised VC4 instruction");
|
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
|
* The bits in type indicate how many bytes the value occupies and what
|
||||||
* significance should be attributed to each byte.
|
* significance should be attributed to each byte.
|
||||||
* We do not check for overflow.
|
* 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) {
|
switch (type & RELSZ) {
|
||||||
|
@ -239,14 +292,7 @@ static putvalu(long valu, char* addr, uint16_t type)
|
||||||
write4(valu, addr, type);
|
write4(valu, addr, type);
|
||||||
break;
|
break;
|
||||||
case RELOPPC:
|
case RELOPPC:
|
||||||
{
|
put_powerpc_valu(addr, valu, type);
|
||||||
long i = read4(addr, type) & ~0x03FFFFFD;
|
|
||||||
i |= valu & 0x03FFFFFD;
|
|
||||||
write4(i, addr, type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case RELOH2:
|
|
||||||
write2(valu>>16, addr, type);
|
|
||||||
break;
|
break;
|
||||||
case RELOVC4:
|
case RELOVC4:
|
||||||
put_vc4_valu(addr, valu);
|
put_vc4_valu(addr, valu);
|
||||||
|
|
|
@ -38,7 +38,7 @@ int Xstackflag=0; /* set in coercions, moves, and tests. %1 means something
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct varinfo *gen_inst(),*gen_move(),*gen_test(),*gen_preturn(),*gen_tlab();
|
struct varinfo *gen_inst(),*gen_move(),*gen_test(),*gen_preturn(),*gen_tlab();
|
||||||
struct varinfo *gen_label(), *make_erase();
|
struct varinfo *gen_label(), *gen_stackadjust(), *make_erase();
|
||||||
expr_t make_expr(),ident_expr(),subreg_expr(),tokm_expr(),all_expr();
|
expr_t make_expr(),ident_expr(),subreg_expr(),tokm_expr(),all_expr();
|
||||||
expr_t perc_ident_expr(),sum_expr(),regvar_expr();
|
expr_t perc_ident_expr(),sum_expr(),regvar_expr();
|
||||||
|
|
||||||
|
@ -74,9 +74,9 @@ iocc_t iops[20];
|
||||||
%token TOPELTSIZE FALLTHROUGH LABELDEF
|
%token TOPELTSIZE FALLTHROUGH LABELDEF
|
||||||
%token PROC CALL EXAMPLE
|
%token PROC CALL EXAMPLE
|
||||||
%token FROM TO
|
%token FROM TO
|
||||||
%token TEST MOVE STACK RETURN
|
%token TEST MOVE STACK RETURN STACKADJUST
|
||||||
%token PATTERNS PAT WITH EXACT KILLS USES REUSING GEN YIELDS LEAVING
|
%token PATTERNS PAT WITH EXACT KILLS USES REUSING GEN YIELDS LEAVING
|
||||||
%token DEFINED SAMESIGN SFIT UFIT ROM LOWW HIGHW ISROM
|
%token DEFINED SAMESIGN SFIT UFIT ROM LOWW HIGHW ISROM STACKOFFSET
|
||||||
%token CMPEQ CMPNE CMPLT CMPGT CMPLE CMPGE OR2 AND2 LSHIFT RSHIFT NOT COMP
|
%token CMPEQ CMPNE CMPLT CMPGT CMPLE CMPGE OR2 AND2 LSHIFT RSHIFT NOT COMP
|
||||||
%token INREG REGVAR REG_ANY REG_FLOAT REG_LOOP REG_POINTER
|
%token INREG REGVAR REG_ANY REG_FLOAT REG_LOOP REG_POINTER
|
||||||
%token <yy_int> ADORNACCESS
|
%token <yy_int> ADORNACCESS
|
||||||
|
@ -635,8 +635,8 @@ coderule
|
||||||
maxempatlen=empatlen;
|
maxempatlen=empatlen;
|
||||||
}
|
}
|
||||||
patterns
|
patterns
|
||||||
{ if (!saferulefound)
|
{ /* if (!saferulefound)
|
||||||
error("Previous rule impossible on empty stack");
|
error("Previous rule impossible on empty stack"); */
|
||||||
outpatterns();
|
outpatterns();
|
||||||
}
|
}
|
||||||
| PROC IDENT example
|
| PROC IDENT example
|
||||||
|
@ -849,6 +849,8 @@ gen_instruction
|
||||||
{ $$ = gen_label($2-1); use_tes++; }
|
{ $$ = gen_label($2-1); use_tes++; }
|
||||||
| RETURN
|
| RETURN
|
||||||
{ $$ = gen_preturn(); }
|
{ $$ = gen_preturn(); }
|
||||||
|
| STACKADJUST expr
|
||||||
|
{ $$ = gen_stackadjust($2.ex_index); use_noframepointer++; }
|
||||||
;
|
;
|
||||||
optstar
|
optstar
|
||||||
: /* empty */
|
: /* empty */
|
||||||
|
@ -1028,6 +1030,8 @@ expr
|
||||||
{ $$ = make_expr(TYPINT,EX_LOWW,$3-1,0); }
|
{ $$ = make_expr(TYPINT,EX_LOWW,$3-1,0); }
|
||||||
| HIGHW '(' emarg ')'
|
| HIGHW '(' emarg ')'
|
||||||
{ $$ = make_expr(TYPINT,EX_HIGHW,$3-1,0); }
|
{ $$ = make_expr(TYPINT,EX_HIGHW,$3-1,0); }
|
||||||
|
| STACKOFFSET '(' ')'
|
||||||
|
{ $$ = make_expr(TYPINT,EX_STACKOFFSET, 0, 0); }
|
||||||
/* Excluded, because it causes a shift-reduce conflict
|
/* Excluded, because it causes a shift-reduce conflict
|
||||||
(problems with a tokenset_no followed by an optexpr)
|
(problems with a tokenset_no followed by an optexpr)
|
||||||
| '-' expr %prec UMINUS
|
| '-' expr %prec UMINUS
|
||||||
|
|
|
@ -127,6 +127,15 @@ struct varinfo *gen_preturn() {
|
||||||
return(vp);
|
return(vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct varinfo *gen_stackadjust(int expr) {
|
||||||
|
register struct varinfo *vp;
|
||||||
|
|
||||||
|
NEW(vp,struct varinfo);
|
||||||
|
vp->vi_int[0] = INSSTACKADJUST;
|
||||||
|
vp->vi_int[1] = expr;
|
||||||
|
return(vp);
|
||||||
|
}
|
||||||
|
|
||||||
struct varinfo *gen_tlab(n) {
|
struct varinfo *gen_tlab(n) {
|
||||||
register struct varinfo *vp;
|
register struct varinfo *vp;
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ extern int regclass;
|
||||||
extern int maxtokensize;
|
extern int maxtokensize;
|
||||||
extern int nprocargs, maxprocargs;
|
extern int nprocargs, maxprocargs;
|
||||||
extern int use_tes;
|
extern int use_tes;
|
||||||
|
extern int use_noframepointer;
|
||||||
|
|
||||||
extern char *mystrcpy();
|
extern char *mystrcpy();
|
||||||
extern char *myalloc();
|
extern char *myalloc();
|
||||||
|
|
|
@ -43,6 +43,8 @@ reusing REUSING
|
||||||
rom ROM
|
rom ROM
|
||||||
samesign SAMESIGN
|
samesign SAMESIGN
|
||||||
sfit SFIT
|
sfit SFIT
|
||||||
|
stackadjust STACKADJUST
|
||||||
|
stackoffset STACKOFFSET
|
||||||
topeltsize TOPELTSIZE
|
topeltsize TOPELTSIZE
|
||||||
test TEST
|
test TEST
|
||||||
to TO
|
to TO
|
||||||
|
|
|
@ -12,6 +12,8 @@ int tabledebug=0; /* do not generate code for table debugging */
|
||||||
#endif
|
#endif
|
||||||
int verbose=0; /* print all statistics */
|
int verbose=0; /* print all statistics */
|
||||||
int use_tes; /* use top element size information */
|
int use_tes; /* use top element size information */
|
||||||
|
int use_noframepointer; /* use stackadjust mechanism to remove requirement
|
||||||
|
for frame pointer */
|
||||||
char *c_file= "tables.c";
|
char *c_file= "tables.c";
|
||||||
char *h_file= "tables.H";
|
char *h_file= "tables.H";
|
||||||
char *cd_file= "code";
|
char *cd_file= "code";
|
||||||
|
@ -612,6 +614,8 @@ outdefs() {
|
||||||
cdef("TABLEDEBUG",1);
|
cdef("TABLEDEBUG",1);
|
||||||
if (use_tes)
|
if (use_tes)
|
||||||
cdef("USE_TES",1);
|
cdef("USE_TES",1);
|
||||||
|
if (use_noframepointer)
|
||||||
|
cdef("USE_NOFRAMEPOINTER",1);
|
||||||
}
|
}
|
||||||
|
|
||||||
outars() {
|
outars() {
|
||||||
|
@ -852,6 +856,11 @@ varinfo *kills,*allocates,*generates,*yields,*leaving;
|
||||||
codeint(vp->vi_int[1]);
|
codeint(vp->vi_int[1]);
|
||||||
codenl();
|
codenl();
|
||||||
break;
|
break;
|
||||||
|
case INSSTACKADJUST:
|
||||||
|
code8(DO_STACKADJUST);
|
||||||
|
codeint(vp->vi_int[1]);
|
||||||
|
codenl();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
codecoco(cocono);
|
codecoco(cocono);
|
||||||
|
|
|
@ -12,3 +12,4 @@
|
||||||
#define INSERASE (-6)
|
#define INSERASE (-6)
|
||||||
#define INSREMOVE (-7)
|
#define INSREMOVE (-7)
|
||||||
#define INSLABDEF (-8)
|
#define INSLABDEF (-8)
|
||||||
|
#define INSSTACKADJUST (-9)
|
||||||
|
|
Loading…
Reference in a new issue