* Initial support for multiple arguments in rarc2 for ARM

- Some more fixes in the ARM emitter backend
  - Single quoted strings are now supported, not filtered
  - Fix math opcode names for ARM
  - Added support for /**/ and // comments
* Fix makefile for test programs in rarc2/t
  - Added simple hello world for tests in rarc2/t
This commit is contained in:
pancake 2010-09-16 20:44:22 +02:00
parent 441456767a
commit 90a2b9f84a
6 changed files with 78 additions and 44 deletions

View File

@ -1,10 +1,6 @@
RCC : Ralang/Relocatable Code Compiler
======================================
TODO:
-----
add support for /* comments */
Compiler pipeline: the picture
------------------------------

View File

@ -1,4 +1,4 @@
/* pancake // nopcode.org 2010 -- emit module for rcc */
/* pancake // nopcode.org 2010 -- arm emiter */
#include "rarc2.h"
@ -14,6 +14,8 @@
// no attsyntax for arm
static char *regs[] = R_GP;
static int lastarg = 0;
static char lastargs[16][32];
static char *emit_syscall (int num) {
return strdup (": mov "R_AX", `.arg`\n: svc 0x8000\n");
@ -64,9 +66,21 @@ static void emit_set_string(const char *dstvar, const char *str, int j) {
rcc_printf (".string \"%s\"\n", str);
if (rest) rcc_printf (".fill %d, 1, 0\n", (rest));
rcc_printf (" sub r0, pc, $%d\n", off+16);
{
char str[32], *p = mk_var (str, dstvar, 0);
//rcc_printf("DSTVAR=%s --> %s\n", dstvar, p);
rcc_printf (" str r0, [%s]\n", p);
}
}
static void emit_call(const char *str, int atr) {
int i;
//rcc_printf(" ARGS=%d CALL(%s,%d)\n", lastarg, str, atr);
for(i=0;i<lastarg;i++) {
rcc_printf (" ldr r%d, [%s]\n", lastarg-1-i, lastargs[i]);
lastargs[i][0] = 0;
}
if (atr) {
rcc_printf(" ldr r0, %s", str);
rcc_printf(" blx r0\n");
@ -77,11 +91,18 @@ static void emit_arg (int xs, int num, const char *str) {
int d = atoi (str);
if (!attsyntax && (*str=='$'))
str++;
// ARGMENTS ONLY IN R0, R1, .. ooh common!
return; // XXX
lastarg = num;
switch (xs) {
case 0:
rcc_printf (" push {%s}\n", str);
if (strchr(str, ',')) {
//rcc_printf (". str r0, [%s]\n", str);
strncpy (lastargs[num-1], str, sizeof(lastargs[0]));
} else {
if (!atoi (str)) eprintf ("WARNING: probably a bug?\n");
rcc_printf (" mov r0, $%s\n", str);
snprintf( lastargs[num-1], sizeof (lastargs[0]), "fp, $-%d", 8+(num*4));
rcc_printf (" str r0, [%s]\n", lastargs[num-1]);
}
break;
case '*':
rcc_printf (" push {%s}\n", str);
@ -99,7 +120,8 @@ static void emit_get_result(const char *ocn) {
}
static void emit_restore_stack (int size) {
//rcc_printf(" add sp, %d\n", size);
// XXX: must die.. or add emit_store_stack. not needed by ARM
// rcc_printf(" add sp, %d\n", size);
}
static void emit_get_while_end (char *str, const char *ctxpush, const char *label) {
@ -115,8 +137,8 @@ static void emit_while_end (const char *labelback) {
static void emit_get_var (int type, char *out, int idx) {
switch (type) {
case 0: sprintf (out, "fp,%c%d", idx>0?' ':'+', -idx); break; /* variable */
case 1: sprintf (out, "sp,%c%d", idx>0?'+':' ', idx); break; /* argument */
case 0: sprintf (out, "fp,$%d", -idx); break; /* variable */
case 1: sprintf (out, "sp,$%d", idx); break; /* argument */ // XXX: MUST BE r0, r1, r2, ..
}
}
@ -180,9 +202,9 @@ static void emit_load(const char *dst, int sz) {
static void emit_mathop(int ch, int vs, int type, const char *eq, const char *p) {
char *op;
switch (ch) {
case '^': op = "xor"; break;
case '^': op = "eor"; break;
case '&': op = "and"; break;
case '|': op = "or"; break;
case '|': op = "orr"; break;
case '-': op = "sub"; break;
case '+': op = "add"; break;
case '*': op = "mul"; break;

View File

@ -181,7 +181,7 @@ static void emit_trap () {
static void emit_load_ptr(const char *dst) {
int d = atoi (dst);
eprintf ("HACK HACK HACK\n");
//eprintf ("emit_load_ptr: HACK\n");
// XXX: 32/64bit care
if (attsyntax) rcc_printf (" leal %d(%%"R_BP"), %%"R_AX"\n", d);
else rcc_printf (" leal "R_AX", dword ptr ["R_BP"+%d]\n", d);

View File

@ -101,11 +101,14 @@ static char *get_frame_label(int type) {
return label;
}
static void rcc_pushstr(char *str) {
static void rcc_pushstr(char *str, int filter) {
int dotrim = 1;
int i, j, len;
emit->comment ("encode string (%s) (%s)", str, callname);
emit->comment ("encode %s string (%s) (%s)",
filter?"filtered":"unfiltered", str, callname);
if (filter)
for (i=0; str[i]; i++) {
if (str[i]=='\\') {
switch (str[i+1]) {
@ -152,7 +155,7 @@ char *mk_var(char *out, const char *_str, int delta) {
emit->get_var (0, out, idx-stackfixed);
//sprintf(out, "%d(%%"R_BP")", -(atoi(str+4)+delta+R_SZ-stackfixed));
} else
if (!memcmp(str+1, "var", 3)) {
if (!memcmp (str+1, "var", 3)) {
emit->get_var (0, out, idx);
//sprintf(out, "%d(%%"R_BP")", -(atoi(str+4)+delta+R_SZ));
} else
@ -186,7 +189,8 @@ char *mk_var(char *out, const char *_str, int delta) {
ret = str; /* TODO: show error, invalid var name? */
eprintf ("FUCKED UP\n");
}
} else if (str[0]=='"') {
} else if (*str=='"' || *str=='\'') {
int mustfilter = *str=='"';
if (!stackfixed)
eprintf ("WARNING: No room in the static stackframe!\n");
/* TODO: check for room in stackfixed area */
@ -195,7 +199,7 @@ char *mk_var(char *out, const char *_str, int delta) {
str[len]='\0';
sprintf (foo, ".fix%d", nargs*16); /* XXX FIX DELTA !!!1 */
dstvar = strdup (foo);
rcc_pushstr (str);
rcc_pushstr (str, mustfilter);
ret = mk_var (out, foo, 0);
}
//free ((void *)_str);
@ -288,7 +292,7 @@ static void rcc_element(char *str) {
if (!atoi (str)) {
if (dstvar == NULL) /* return string */
dstvar = strdup (".fix0");
rcc_pushstr (str);
rcc_pushstr (str, 1);
}
}
} else {
@ -682,6 +686,10 @@ static int parsechar(char c) {
if (oc == '\n')
skipline = 1;
break;
case '/':
if (oc == '/')
skipline = 1;
break;
default:
elem[elem_n++] = c;
}

View File

@ -1,11 +1,18 @@
LC=../rarc2
.PHONY: all clean run top
RC=../rarc2 -s
CC=tcc
CC=gcc
BIN=ptr ret hello shell loop input inline syscall data sub if dump bytedump argv room rawsys
BIN=hi ptr ret hello shell loop input inline syscall data sub if dump bytedump argv room rawsys
all: top ${BIN}
clean:
rm -f ${BIN} *.S
run:
for a in ${BIN}; do ./$$a ; done
top:
#rm -f shell
@ -13,71 +20,69 @@ top:
cd .. && ${MAKE} rarc2
syscall:
${LC} syscall.r > syscall.S
${RC} syscall.r > syscall.S
${CC} syscall.S -o syscall
hi:
${RC} hi.r > hi.S
${CC} hi.S -o hi
rawsys:
${LC} rawsys.r > rawsys.S
${RC} rawsys.r > rawsys.S
${CC} rawsys.S -o rawsys
data:
${LC} data.r > data.S
${RC} data.r > data.S
${CC} data.S -o data
ret:
${LC} ret.r > ret.S
${RC} ret.r > ret.S
${CC} ret.S -o ret
sub:
${LC} sub.r > sub.S
${RC} sub.r > sub.S
${CC} sub.S -o sub
inline:
${LC} inline.r > inline.S
${RC} inline.r > inline.S
${CC} inline.S -o inline
loop:
${LC} loop.r > loop.S
${RC} loop.r > loop.S
${CC} loop.S -o loop
shell:
${LC} shell.r > shell.S
${RC} shell.r > shell.S
${CC} shell.S -o shell
hello:
${LC} hello.r > hello.S
${RC} hello.r > hello.S
${CC} -g hello.S -o hello
ptr:
${LC} ptr.r > ptr.S
${RC} ptr.r > ptr.S
${CC} ptr.S -o ptr
input:
${LC} input.r > input.S
${RC} input.r > input.S
${CC} input.S -o input
if:
${LC} if.r > if.S
${RC} if.r > if.S
${CC} if.S -o if
dump:
${LC} dump.r > dump.S
${RC} dump.r > dump.S
${CC} dump.S -o dump
bytedump:
${LC} bytedump.r > bytedump.S
${RC} bytedump.r > bytedump.S
${CC} bytedump.S -o bytedump
argv:
${LC} argv.r > argv.S
${RC} argv.r > argv.S
${CC} argv.S -o argv
room:
${LC} room.r > room.S
${RC} room.r > room.S
${CC} room.S -o room
clean:
rm -f ${BIN} *.S
run:
for a in ${BIN}; do ./$$a ; done

3
binr/rarc2/t/hi.r Normal file
View File

@ -0,0 +1,3 @@
main@global(,32) {
printf("Hello World\n");
}