# What build flags do you want to use?
CFLAGS = -g
-LDFLAGS = -s
+LDFLAGS =
# ======================================================================= #
# END OF CONFIGURATION #
$(eval LIBCCANSIHEADERS += $o)
endef
+define ackfile-flag-impl
+ $(if $(filter n, $(libc-ansi-$(PLATFORM)-wants-$(strip $1))), \
+ , \
+ $(call ackfile, $2) \
+ )
+endef
+
+ackfile-flag = $(eval $(call ackfile-flag-impl, $1, $2))
+
define build-libcc-ansi-headers-impl
$(eval g := \
sys/time.h \
# math
-$(call ackfile, lang/cem/libcc.ansi/math/asin.c)
-$(call ackfile, lang/cem/libcc.ansi/math/atan2.c)
-$(call ackfile, lang/cem/libcc.ansi/math/atan.c)
-$(call ackfile, lang/cem/libcc.ansi/math/ceil.c)
-$(call ackfile, lang/cem/libcc.ansi/math/fabs.c)
-$(call ackfile, lang/cem/libcc.ansi/math/pow.c)
-$(call ackfile, lang/cem/libcc.ansi/math/log10.c)
-$(call ackfile, lang/cem/libcc.ansi/math/log.c)
-$(call ackfile, lang/cem/libcc.ansi/math/sin.c)
-$(call ackfile, lang/cem/libcc.ansi/math/sinh.c)
-$(call ackfile, lang/cem/libcc.ansi/math/sqrt.c)
-$(call ackfile, lang/cem/libcc.ansi/math/tan.c)
-$(call ackfile, lang/cem/libcc.ansi/math/tanh.c)
-$(call ackfile, lang/cem/libcc.ansi/math/exp.c)
-$(call ackfile, lang/cem/libcc.ansi/math/ldexp.c)
-$(call ackfile, lang/cem/libcc.ansi/math/fmod.c)
-$(call ackfile, lang/cem/libcc.ansi/math/floor.c)
-$(call ackfile, lang/cem/libcc.ansi/math/hugeval.c)
-$(call ackfile, lang/cem/libcc.ansi/math/frexp.e)
-$(call ackfile, lang/cem/libcc.ansi/math/modf.e)
-$(call ackfile, lang/cem/libcc.ansi/math/isnan.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/asin.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/atan2.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/atan.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/ceil.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/fabs.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/pow.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/log10.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/log.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/sin.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/sinh.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/sqrt.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/tan.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/tanh.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/exp.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/ldexp.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/fmod.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/floor.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/hugeval.c)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/frexp.e)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/modf.e)
+$(call ackfile-flag, math, lang/cem/libcc.ansi/math/isnan.c)
# Misc
# setjmp
-$(call ackfile, lang/cem/libcc.ansi/setjmp/setjmp.e)
+$(call ackfile-flag, em, lang/cem/libcc.ansi/setjmp/setjmp.e)
# signal
struct lconv *
localeconv(void)
{
- register struct lconv *lcp = &_lc;
+ struct lconv *lcp = &_lc;
lcp->decimal_point = ".";
lcp->thousands_sep = "";
#include "loc_incl.h"
FILE *
-tmpfile(void) {
+tmpfilez(void) {
static char name_buffer[L_tmpnam] = "/tmp/tmp." ;
static char *name = NULL;
FILE *file;
-DNATIVE_FLOATING_POINT \
-D_ISOC99_SOURCE \
-Dos_ack \
- -Dmach_$(PCCMACH) \
+ -Dmach_$(PCCARCH) \
)
$(call reset)
else if (val < 0)
fprintf(fp, "-%d", -val);
} else
- fprintf(fp, CONFMT, (CONSZ)val);
+ fprintf(fp, "#" CONFMT, (CONSZ)val);
return;
default:
typedef unsigned long long U_CONSZ;
typedef long long OFFSZ;
-#define CONFMT "#%lld" /* format for printing constants */
+#define CONFMT "%lld" /* format for printing constants */
#define LABFMT ".L%d" /* format for printing labels */
#define STABLBL "LL%d" /* format for stab (debugging) labels */
#define STAB_LINE_ABSOLUTE /* S_LINE fields use absolute addresses */
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NAREG|NASL, RESC1,
- " Os A1,AL,AR\n", },
+ " O.s A1,AL,AR\n", },
/*
/* $Header; mach1.c, v1.1 06-Mar-89 AJM */
extern word_t opcode;
extern int success; /* LDR/STR address failure flag */
+
+extern void strldr(uint32_t opc, valu_t val);
+
%token <y_word> SHIFT
%token <y_word> RRX
%token <y_word> SDT
-%token <y_word> BYTE
+%token <y_word> SDT2
%token <y_word> TRANS
%token <y_word> BDT
%token <y_word> SWI
%type <y_word> optlink optcond opts optt optp optb optexc reglist rlist
%type <y_word> optsign optpsr optshift shftcnt address offset aoptshift
+%type <y_word> splitaddress splitoffset
%type <y_expr> operand
0, RRX, 0x00000060, "rrx",
0, SDT, 0x04100000, "ldr",
+0, SDT, 0x04500000, "ldrb",
0, SDT, 0x04000000, "str",
+0, SDT, 0x04400000, "strb",
-0, BYTE, 0x00400000, ".b",
+0, SDT2, 0x001000b0, "ldrh",
+0, SDT2, 0x000000b0, "strh",
+0, SDT2, 0x001000d0, "ldrsb",
+0, SDT2, 0x000000d0, "strsb",
0, TRANS, 0x00200000, ".t",
{data($1,$2|$3|$4|$5<<12,$7.val,$7.typ);}
| DATA3 optcond opts optp REG ',' operand
{data($1,$2|$3|$4|$5<<16,$7.val,$7.typ);}
- | SDT optcond optb optt REG ',' address
- {strldr($1,$2|$3|$4|$5<<12,$7);}
+ | SDT optcond optt REG ',' address
+ {strldr($1|$2|$3|$4<<12,$6);}
+ | SDT2 optcond optt REG ',' splitaddress
+ {strldr($1|$2|$3|$4<<12,$6);}
| BDT optcond REG optexc ',' reglist optpsr
{emit4($1|$2|$3<<16|$4|$6|$7);}
| SWI optcond expr
{$$=$1;}
;
-optb : {$$=0;}
- | BYTE
- {$$=$1;}
- ;
-
optexc : {$$=0;}
| '<'
{$$=0x00200000;}
| '[' REG ']'
{success = 1; $$ = 0x01000000|$2<<16;}
| '[' REG ',' offset ']' optexc
- {success = 1; $$ = $2<<16|$4|$6|0x01000000;}
+ {success = 1; $$ = 0x01000000|$2<<16|$4|$6;}
| '[' REG ']' ',' offset
{success = 1; $$ = $2<<16|$5;}
;
{$$ = 0x02000000|$1|$2|$3;}
;
+splitaddress : expr
+ {success = 0; $$ = $1.val;}
+ | '[' REG ']'
+ {success = 1; $$ = 0x01000000|$2<<16;}
+ | '[' REG ',' splitoffset ']' optexc
+ {success = 1; $$ = 0x01000000|$2<<16|$4|$6;}
+ | '[' REG ']' ',' splitoffset
+ {success = 1; $$ = $2<<16|$5;}
+ ;
+
+splitoffset : '#' expr
+ {$$ = splitoffset($2.val);}
+ ;
+
optsign : {$$ = 0x00800000;}
| '+'
{$$ = 0x00800000;}
/* Calculate an offset in an address */
-word_t
-calcoffset(val)
-valu_t val;
+word_t calcoffset(valu_t val)
{
- if((val & 0xFFFFF000) == 0)
- return(val|0x00800000);
- val *= -1;
- if((val & 0xFFFFF000) == 0)
- return(val);
+ if (fitu(val, 12))
+ return val|0x00800000;
+ val = -val;
+ if (fitu(val, 12))
+ return val;
+
serror("offset out of range");
- return(0);
+ return 0;
}
+/* Calculate a split offset (for strh and friends). */
+
+word_t splitoffset(valu_t val)
+{
+ if (fitu(val, 8))
+ return (val&0x0f) | ((val&0xf0)<<4) | 0x00800000;
+ val = -val;
+ if (fitu(val, 8))
+ return (val&0x0f) | ((val&0xf0)<<4) | 0x00800000;
+
+ serror("offset out of range");
+ return 0;
+}
/* This routine deals with STR and LDR instructions */
-strldr(opc, ins, val)
-long opc, ins;
-valu_t val;
+void strldr(uint32_t opc, valu_t val)
{
-
- long reg, reg2; /* The registers we are using */
- long tmpval;
+ uint32_t d;
/* If the expression was a register, then just output it and save 24
bytes */
- if (success){
- emit4(opc|ins|val);
+ if (success)
+ {
+ emit4(opc|val);
return;
}
- reg = ins & 0x0000F000; /* Extract register from instruction */
-
- if (opc == LDR){
-
- tmpval = val - DOTVAL - 8;
- if (oursmall((tmpval & 0xFFFFF000) == 0, 16)){ /* If it's +ve */
- emit4(opc|ins|tmpval|0x018F0000); /* PC rel, up bit */
- return;
- }
-
- tmpval *= -1;
- if (oursmall((tmpval & 0xFFFFF000) == 0, 16)){ /* If it's -ve */
- emit4(opc|ins|tmpval|0x010F0000); /* PC rel, no up bit */
- return;
- }
-
- if (!bflag && pass == PASS_3){ /* Debugging info */
- /* warning("LDR address extension"); */
- if (dflag)
- printf("value: %lx\n", val);
- }
-
- opc = 0x03A00000; /* Set opc for putaddr */
-
- if (oursmall((val & 0xFFFF0000) == 0, 8)){
- putaddr(opc, ins & 0xFFBFFFFF, val, 2);
- emit4(0x05100000|ins|reg<<4);
- return;
- }
- if (oursmall((val & 0xFF000000) == 0, 4)){
- putaddr(opc, ins & 0xFFBFFFFF, val, 3);
- emit4(0x05100000|ins|reg<<4);
- return;
- }
- putaddr(opc, ins & 0xFFBFFFFF, val, 4);
- emit4(0x05100000|ins|reg<<4);
+ d = val - DOTVAL - 8;
+ if (fitu(d, 12))
+ { /* If it's +ve */
+ emit4(opc|d|0x018F0000); /* PC rel, up bit */
return;
}
-/* If the failure was an STR instruction, things are a bit more complicated as
- we can't overwrite the register before we store its value. We therefore
- need to use another register as well, which must be saved and restored.
- This register is saved on a stack pointed to by R12. Apart from this
- complication, the scheme is similar to the LDR above. */
-
- if (opc == STR){
- reg2 = reg >> 12; /* Use R6 as the second register, */
- reg2 = (reg2 == 6 ? 0 : 6); /* or R0 if we can't */
-
- tmpval = val - DOTVAL - 8;
- if (oursmall((tmpval & 0xFFFFF000) == 0, 24)){ /* If it's +ve */
- emit4(opc|ins|tmpval|0x018F0000); /* PC rel, up bit */
- return;
- }
-
- tmpval *= -1;
- if (oursmall((tmpval & 0xFFFFF000) == 0, 24)){ /* If it's -ve */
- emit4(opc|ins|tmpval|0x010F0000); /* PC rel, no up bit */
- return;
- }
-
- if (!bflag && pass == PASS_3){ /* Debugging info */
- /* warning("STR address extension"); */
- if (dflag)
- printf("value: %lx\n", val);
- }
-
- opc = 0x03A00000; /* Set opc for putaddr */
-
- if (oursmall((val & 0xFFFF0000) == 0, 8)){
- emit4(0xE92C0000|1<<reg2);
- putaddr(opc, (ins & 0xFFBF0FFF)|reg2<<12, val, 2);
- emit4(0x05000000|ins|reg2<<16);
- emit4(0xE8BC0000|1<<reg2);
- return;
- }
- if (oursmall((val & 0xFF000000) == 0, 4)){
- emit4(0xE92C0000|1<<reg2);
- putaddr(opc, (ins & 0xFFBF0FFF)|reg2<<12, val, 3);
- emit4(0x05000000|ins|reg2<<16);
- emit4(0xE8BC0000|1<<reg2);
- return;
- }
- emit4(0xE92C0000|1<<reg2);
- putaddr(opc, (ins & 0xFFBF0FFF)|reg2<<12, val, 4);
- emit4(0x05000000|ins|reg2<<16);
- emit4(0xE8BC0000|1<<reg2);
+ d = -d;
+ if (fitu(d, 12))
+ { /* If it's -ve */
+ emit4(opc|d|0x010F0000); /* PC rel, no up bit */
return;
}
+ serror("displacement overflow: 0x%x", d);
+ return;
}
#define lowb(z) ((int)(z) & 0xFF)
#define loww(z) ((int)(z) & 0xFFFF)
+#define fitu(x, d) (((x) & ~((int)(1<<(d))-1)) == 0)
#define fitx(x, d) ((((x) + (1<<(d-1))) & ~((int)(1<<(d))-1)) == 0)
#define fitb(x) ((((x) + 0x80) & ~((int)0xFF)) == 0)
#define fitw(x) ((((x) + 0x8000L) & ~0xFFFFL) == 0)
0, EXTERN, 0, ".define",
0, EXTERN, 0, ".extern",
0, DOT, 0, ".",
+ 0, DATA, RELO1, ".byte",
0, DATA, RELO1, ".data1",
0, DATA, RELO2, ".data2",
0, DATA, RELO4, ".data4",
$(PLATFORM_HEADERS_$(PLATFORM)) \
$(PLATDEP)/$(PLATFORM)/as \
$(if $(arch-cg-$(ARCH)), $(PLATDEP)/$(PLATFORM)/cg, $(PLATDEP)/$(PLATFORM)/ncg) \
- $(ARCHITECTURE_$(ARCH)))
+ $(ARCHITECTURE_$(ARCH)) \
+ )
# libsys
build-platform = $(eval $(call build-platform-impl, $1))
define build-pcc-platform-impl
+ $(eval libc-ansi-$(PLATFORM)-wants-em := n)
+
$(call reset)
$(call rawfile, $D/descr)
$(call installto, $(PLATIND)/descr/$(PLATFORM))
+ $(foreach f, $(platform-headers), $(call build-platform-headers, $f))
+
$(eval PLATFORM_$(PLATFORM) := \
$(PLATIND)/descr/$(PLATFORM) \
$(PLATDEP)/$(PLATFORM)/as \
$(PLATDEP)/$(PLATFORM)/pcc_ccom \
+ $(ARCHITECTURE_$(ARCH)) \
)
$(call build-as)
$(call build-pcc)
+
+ $(call build-runtime-libcc-ansi)
endef
build-pcc-platform = $(eval $(call build-pcc-platform-impl, $1))
--- /dev/null
+! Declare segments (the order is important).
+
+.sect .text
+.sect .rom
+.sect .data
+.sect .bss
+
+.sect .text
+
+begtext:
+ ! This code is placed at the beginning of the ELF executable and is the
+ ! first thing that runs.
+ !
+ ! On entry, the stack looks like this:
+ !
+ ! sp+.. NULL
+ ! sp+8+(4*argc) env (X quads)
+ ! sp+4+(4*argc) NULL
+ ! sp+4 argv (argc quads)
+ ! sp argc
+ !
+ ! On the ACK, this platform is using the pcc backend, so arguments go in
+ ! registers; we want:
+ !
+ ! r0 argc
+ ! r1 argv
+ ! r2 env
+
+ ldr r0, [sp]
+ add r1, sp, #4
+ add r2, sp, #8
+ add r2, r2, r1, lsl #2
+
+ ldr r3, __environp
+ str r2, [r3]
+
+ b __m_a_i_n
+
+__environp:
+ .data4 environ
+
+! 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:
+
D := plat/linuxarm/
+platform-headers := \
+ ack/config.h \
+ unistd.h
+
+libc-ansi-linuxarm-wants-math := n
+
$(eval $(call build-pcc-platform))
+define build-linuxarm-boot-impl
+ $(call reset)
+ $(call ackfile, $D/boot.s)
+ $(call installto, $(PLATIND)/$(PLATFORM)/boot.o)
+endef
+
+$(eval $(build-linuxarm-boot-impl))
+
program {EM}/lib/ack/{PLATFORM}/pcc_ccom
rts .c
need .c
- args
- stdin
- stdout
+ args -xtemps -xdeljumps < >
prep always
end
name as
--- /dev/null
+/* $Source: /cvsroot/tack/Ack/plat/linux386/include/ack/config.h,v $
+ * $State: Exp $
+ * $Revision: 1.1 $
+ */
+
+#ifndef _ACK_CONFIG_H
+#define _ACK_CONFIG_H
+
+/* We're providing a time() system call rather than wanting a wrapper around
+ * gettimeofday() in the libc. */
+
+/* #define ACKCONF_TIME_IS_A_SYSCALL */
+
+/* We don't support floating point right now. */
+
+#define ACKCONF_NO_STDIO_FLOAT
+
+#endif
--- /dev/null
+/*
+ * unistd.h - standard system calls
+ */
+/* $Id$ */
+
+#ifndef _UNISTD_H
+#define _UNISTD_H
+
+#include <stddef.h>
+#include <time.h>
+
+/* Types */
+
+typedef int pid_t;
+typedef int mode_t;
+
+typedef long suseconds_t;
+
+/* Time handling. */
+
+struct timeval
+{
+ time_t tv_sec;
+ suseconds_t tv_usec;
+};
+
+struct timezone
+{
+ int tz_minuteswest;
+ int tz_dsttime;
+}; /* obsolete, unused */
+
+extern int gettimeofday(struct timeval* tv, struct timezone* tz);
+extern int settimeofday(const struct timeval* tv, const struct timezone* tz);
+
+/* File access. */
+
+enum
+{
+ O_ACCMODE = 0x3,
+
+ O_RDONLY = 0,
+ O_WRONLY = 1,
+ O_RDWR = 2,
+
+ O_CREAT = 0x10,
+ O_TRUNC = 0x20,
+ O_APPEND = 0x40
+};
+
+extern int open(const char* path, int access, ...);
+extern int creat(const char* path, mode_t mode);
+extern int close(int d);
+extern int read(int fd, void* buffer, size_t count);
+extern int write(int fd, void* buffer, size_t count);
+extern off_t lseek(int fildes, off_t offset, int whence);
+extern int fcntl(int fd, int op, ...);
+
+/* Special variables */
+
+extern char** environ;
+
+/* Implemented system calls */
+
+extern void _exit(int);
+extern pid_t getpid(void);
+extern int brk(void* ptr);
+extern void* sbrk(intptr_t increment);
+extern int isatty(int d);
+
+/* Signal handling */
+
+typedef int sig_atomic_t;
+
+#define SIG_ERR ((sighandler_t) -1) /* Error return. */
+#define SIG_DFL ((sighandler_t) 0) /* Default action. */
+#define SIG_IGN ((sighandler_t) 1) /* Ignore signal. */
+
+#define SIGHUP 1 /* Hangup (POSIX). */
+#define SIGINT 2 /* Interrupt (ANSI). */
+#define SIGQUIT 3 /* Quit (POSIX). */
+#define SIGILL 4 /* Illegal instruction (ANSI). */
+#define SIGTRAP 5 /* Trace trap (POSIX). */
+#define SIGABRT 6 /* Abort (ANSI). */
+#define SIGIOT 6 /* IOT trap (4.2 BSD). */
+#define SIGBUS 7 /* BUS error (4.2 BSD). */
+#define SIGFPE 8 /* Floating-point exception (ANSI). */
+#define SIGKILL 9 /* Kill, unblockable (POSIX). */
+#define SIGUSR1 10 /* User-defined signal 1 (POSIX). */
+#define SIGSEGV 11 /* Segmentation violation (ANSI). */
+#define SIGUSR2 12 /* User-defined signal 2 (POSIX). */
+#define SIGPIPE 13 /* Broken pipe (POSIX). */
+#define SIGALRM 14 /* Alarm clock (POSIX). */
+#define SIGTERM 15 /* Termination (ANSI). */
+#define SIGSTKFLT 16 /* Stack fault. */
+#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */
+#define SIGCHLD 17 /* Child status has changed (POSIX). */
+#define SIGCONT 18 /* Continue (POSIX). */
+#define SIGSTOP 19 /* Stop, unblockable (POSIX). */
+#define SIGTSTP 20 /* Keyboard stop (POSIX). */
+#define SIGTTIN 21 /* Background read from tty (POSIX). */
+#define SIGTTOU 22 /* Background write to tty (POSIX). */
+#define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */
+#define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */
+#define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */
+#define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */
+#define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */
+#define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */
+#define SIGPOLL SIGIO /* Pollable event occurred (System V). */
+#define SIGIO 29 /* I/O now possible (4.2 BSD). */
+#define SIGPWR 30 /* Power failure restart (System V). */
+#define SIGSYS 31 /* Bad system call. */
+#define SIGUNUSED 31
+
+#define _NSIG 32 /* Biggest signal number + 1
+ (not including real-time signals). */
+typedef void (*sighandler_t)(int);
+extern sighandler_t signal(int signum, sighandler_t handler);
+extern int raise(int signum);
+
+
+
+#endif
case RELOVC4:
printf("\tVideoCore IV address in 32-bit instruction\n");
break;
+ case RELOARM:
+ printf("\tARM address in 32-bit instruction\n");
+ break;
default:
printf("\tunknown relocation type %d\n", relrec.or_type & RELSZ);
break;