implement Lprintf in asm; fix int to aint in runtime

This commit is contained in:
danyaberezun 2024-02-05 16:48:27 +01:00 committed by Roman Venediktov
parent e0189d5654
commit d76d2a02ea
3 changed files with 89 additions and 125 deletions

View file

@ -51,7 +51,7 @@ runtime64.o: runtime.c runtime.h
$(CC) $(PROD_FLAGS) -c runtime.c -o runtime64.o $(CC) $(PROD_FLAGS) -c runtime.c -o runtime64.o
printf.o: printf.s printf.o: printf.s
$(CC) $(PROD_FLAGS) -c printf.s -o printf.o $(CC) $(PROD_FLAGS) -c -g printf.s -o printf.o
clean: clean:
$(RM) *.a *.o *~ negative_scenarios/*.err $(RM) *.a *.o *~ negative_scenarios/*.err

View file

@ -12,79 +12,40 @@
.extern cnt_percentage_sign .extern cnt_percentage_sign
Lprintf: Lprintf:
pushq %rbp # save return address
movq %rsp, %rbp popq %r14
movq %rdi, -40(%rbp)
movq %rsi, -48(%rbp) pushq %r9
movq -48(%rbp), %rax pushq %r8
movq %rax, -16(%rbp) pushq %rcx
movl $0, -4(%rbp) pushq %rdx
jmp .L2 pushq %rsi
.L5: movq %rsp, %rax
movq -40(%rbp), %rax # pushq %rsi
movzbl (%rax), %eax # rdi --- format string
cmpb $37, %al # r11 --- number of arguments except format string
jne .L3 loop:
movl -4(%rbp), %eax movq $0, %r12
cltq cmpq %r11, %r12
leaq 0(,%rax,8), %rdx jz continue
movq -16(%rbp), %rax
addq %rdx, %rax decq %r11
movq (%rax), %rax movq (%rax), %r10
movq %rax, -24(%rbp) testq $1, %r10
movq -24(%rbp), %rax jz jmpCont
andl $1, %eax # unbox value
testq %rax, %rax sarq %r10
je .L4 movq %r10, (%rax)
movl -4(%rbp), %eax jmpCont:
cltq addq $8, %rax
leaq 0(,%rax,8), %rdx jmp loop
movq -16(%rbp), %rax continue:
addq %rdx, %rax popq %rsi
movq -24(%rbp), %rdx popq %rdx
sarq %rdx popq %rcx
movq %rdx, (%rax) popq %r8
.L4: popq %r9
addl $1, -4(%rbp) # restore return address
.L3: pushq %r14
addq $1, -40(%rbp)
.L2:
movq -40(%rbp), %rax
movzbl (%rax), %eax
testb %al, %al
jne .L5
movq -40(%rbp), %rax
movq %rax, %rdi
cmpl $0, -4(%rbp)
jle .L6
movq -16(%rbp), %rax
movq (%rax), %rax
movq %rax, %rsi
.L6:
cmpl $1, -4(%rbp)
jle .L7
movq -16(%rbp), %rax
movq 8(%rax), %rax
movq %rax, %rdx
.L7:
cmpl $2, -4(%rbp)
jle .L8
movq -16(%rbp), %rax
movq 16(%rax), %rax
movq %rax, %rcx
.L8:
cmpl $3, -4(%rbp)
jle .L9
movq -16(%rbp), %rax
movq 24(%rax), %rax
movq %rax, %r8
.L9:
cmpl $4, -4(%rbp)
jle .L11
movq -16(%rbp), %rax
movq 32(%rax), %rax
movq %rax, %r9
.L11:
nop
popq %rbp
jmp printf jmp printf

View file

@ -63,14 +63,14 @@ extern aint LtagHash (char *);
void *global_sysargs; void *global_sysargs;
// Gets a raw data_header // Gets a raw data_header
extern int LkindOf (void *p) { extern aint LkindOf (void *p) {
if (UNBOXED(p)) return UNBOXED_TAG; if (UNBOXED(p)) return UNBOXED_TAG;
return TAG(TO_DATA(p)->data_header); return TAG(TO_DATA(p)->data_header);
} }
// Compare s-exprs tags // Compare s-exprs tags
extern int LcompareTags (void *p, void *q) { extern aint LcompareTags (void *p, void *q) {
data *pd, *qd; data *pd, *qd;
ASSERT_BOXED("compareTags, 0", p); ASSERT_BOXED("compareTags, 0", p);
@ -106,7 +106,7 @@ void *Ls__Infix_58 (void *p, void *q) {
} }
// Functional synonym for built-in operator "!!"; // Functional synonym for built-in operator "!!";
int Ls__Infix_3333 (void *p, void *q) { aint Ls__Infix_3333 (void *p, void *q) {
ASSERT_UNBOXED("captured !!:1", p); ASSERT_UNBOXED("captured !!:1", p);
ASSERT_UNBOXED("captured !!:2", q); ASSERT_UNBOXED("captured !!:2", q);
@ -114,7 +114,7 @@ int Ls__Infix_3333 (void *p, void *q) {
} }
// Functional synonym for built-in operator "&&"; // Functional synonym for built-in operator "&&";
int Ls__Infix_3838 (void *p, void *q) { aint Ls__Infix_3838 (void *p, void *q) {
ASSERT_UNBOXED("captured &&:1", p); ASSERT_UNBOXED("captured &&:1", p);
ASSERT_UNBOXED("captured &&:2", q); ASSERT_UNBOXED("captured &&:2", q);
@ -122,10 +122,10 @@ int Ls__Infix_3838 (void *p, void *q) {
} }
// Functional synonym for built-in operator "=="; // Functional synonym for built-in operator "==";
int Ls__Infix_6161 (void *p, void *q) { return BOX(p == q); } aint Ls__Infix_6161 (void *p, void *q) { return BOX(p == q); }
// Functional synonym for built-in operator "!="; // Functional synonym for built-in operator "!=";
int Ls__Infix_3361 (void *p, void *q) { aint Ls__Infix_3361 (void *p, void *q) {
ASSERT_UNBOXED("captured !=:1", p); ASSERT_UNBOXED("captured !=:1", p);
ASSERT_UNBOXED("captured !=:2", q); ASSERT_UNBOXED("captured !=:2", q);
@ -133,7 +133,7 @@ int Ls__Infix_3361 (void *p, void *q) {
} }
// Functional synonym for built-in operator "<="; // Functional synonym for built-in operator "<=";
int Ls__Infix_6061 (void *p, void *q) { aint Ls__Infix_6061 (void *p, void *q) {
ASSERT_UNBOXED("captured <=:1", p); ASSERT_UNBOXED("captured <=:1", p);
ASSERT_UNBOXED("captured <=:2", q); ASSERT_UNBOXED("captured <=:2", q);
@ -141,7 +141,7 @@ int Ls__Infix_6061 (void *p, void *q) {
} }
// Functional synonym for built-in operator "<"; // Functional synonym for built-in operator "<";
int Ls__Infix_60 (void *p, void *q) { aint Ls__Infix_60 (void *p, void *q) {
ASSERT_UNBOXED("captured <:1", p); ASSERT_UNBOXED("captured <:1", p);
ASSERT_UNBOXED("captured <:2", q); ASSERT_UNBOXED("captured <:2", q);
@ -149,7 +149,7 @@ int Ls__Infix_60 (void *p, void *q) {
} }
// Functional synonym for built-in operator ">="; // Functional synonym for built-in operator ">=";
int Ls__Infix_6261 (void *p, void *q) { aint Ls__Infix_6261 (void *p, void *q) {
ASSERT_UNBOXED("captured >=:1", p); ASSERT_UNBOXED("captured >=:1", p);
ASSERT_UNBOXED("captured >=:2", q); ASSERT_UNBOXED("captured >=:2", q);
@ -157,7 +157,7 @@ int Ls__Infix_6261 (void *p, void *q) {
} }
// Functional synonym for built-in operator ">"; // Functional synonym for built-in operator ">";
int Ls__Infix_62 (void *p, void *q) { aint Ls__Infix_62 (void *p, void *q) {
ASSERT_UNBOXED("captured >:1", p); ASSERT_UNBOXED("captured >:1", p);
ASSERT_UNBOXED("captured >:2", q); ASSERT_UNBOXED("captured >:2", q);
@ -165,7 +165,7 @@ int Ls__Infix_62 (void *p, void *q) {
} }
// Functional synonym for built-in operator "+"; // Functional synonym for built-in operator "+";
int Ls__Infix_43 (void *p, void *q) { aint Ls__Infix_43 (void *p, void *q) {
ASSERT_UNBOXED("captured +:1", p); ASSERT_UNBOXED("captured +:1", p);
ASSERT_UNBOXED("captured +:2", q); ASSERT_UNBOXED("captured +:2", q);
@ -173,7 +173,7 @@ int Ls__Infix_43 (void *p, void *q) {
} }
// Functional synonym for built-in operator "-"; // Functional synonym for built-in operator "-";
int Ls__Infix_45 (void *p, void *q) { aint Ls__Infix_45 (void *p, void *q) {
if (UNBOXED(p)) { if (UNBOXED(p)) {
ASSERT_UNBOXED("captured -:2", q); ASSERT_UNBOXED("captured -:2", q);
return BOX(UNBOX(p) - UNBOX(q)); return BOX(UNBOX(p) - UNBOX(q));
@ -184,7 +184,7 @@ int Ls__Infix_45 (void *p, void *q) {
} }
// Functional synonym for built-in operator "*"; // Functional synonym for built-in operator "*";
int Ls__Infix_42 (void *p, void *q) { aint Ls__Infix_42 (void *p, void *q) {
ASSERT_UNBOXED("captured *:1", p); ASSERT_UNBOXED("captured *:1", p);
ASSERT_UNBOXED("captured *:2", q); ASSERT_UNBOXED("captured *:2", q);
@ -192,7 +192,7 @@ int Ls__Infix_42 (void *p, void *q) {
} }
// Functional synonym for built-in operator "/"; // Functional synonym for built-in operator "/";
int Ls__Infix_47 (void *p, void *q) { aint Ls__Infix_47 (void *p, void *q) {
ASSERT_UNBOXED("captured /:1", p); ASSERT_UNBOXED("captured /:1", p);
ASSERT_UNBOXED("captured /:2", q); ASSERT_UNBOXED("captured /:2", q);
@ -200,14 +200,14 @@ int Ls__Infix_47 (void *p, void *q) {
} }
// Functional synonym for built-in operator "%"; // Functional synonym for built-in operator "%";
int Ls__Infix_37 (void *p, void *q) { aint Ls__Infix_37 (void *p, void *q) {
ASSERT_UNBOXED("captured %:1", p); ASSERT_UNBOXED("captured %:1", p);
ASSERT_UNBOXED("captured %:2", q); ASSERT_UNBOXED("captured %:2", q);
return BOX(UNBOX(p) % UNBOX(q)); return BOX(UNBOX(p) % UNBOX(q));
} }
extern int Llength (void *p) { extern aint Llength (void *p) {
ASSERT_BOXED(".length", p); ASSERT_BOXED(".length", p);
return BOX(LEN(TO_DATA(p)->data_header)); return BOX(LEN(TO_DATA(p)->data_header));
} }
@ -228,7 +228,7 @@ extern aint LtagHash (char *s) {
p = s; p = s;
while (*p && limit++ < MAX_SEXP_TAG_LEN) { while (*p && limit++ < MAX_SEXP_TAG_LEN) {
char *q = chars; char *q = chars;
int pos = 0; aint pos = 0;
for (; *q && *q != *p; q++, pos++) for (; *q && *q != *p; q++, pos++)
; ;
@ -261,8 +261,8 @@ char *de_hash (aint n) {
typedef struct { typedef struct {
char *contents; char *contents;
int ptr; aint ptr;
int len; aint len;
} StringBuf; } StringBuf;
static StringBuf stringBuf; static StringBuf stringBuf;
@ -279,14 +279,14 @@ static void createStringBuf () {
static void deleteStringBuf () { free(stringBuf.contents); } static void deleteStringBuf () { free(stringBuf.contents); }
static void extendStringBuf () { static void extendStringBuf () {
int len = stringBuf.len << 1; aint len = stringBuf.len << 1;
stringBuf.contents = (char *)realloc(stringBuf.contents, len); stringBuf.contents = (char *)realloc(stringBuf.contents, len);
stringBuf.len = len; stringBuf.len = len;
} }
static void vprintStringBuf (char *fmt, va_list args) { static void vprintStringBuf (char *fmt, va_list args) {
int written = 0, rest = 0; aint written = 0, rest = 0;
char *buf = (char *)BOX(NULL); char *buf = (char *)BOX(NULL);
va_list vsnargs; va_list vsnargs;
@ -388,7 +388,7 @@ static void printValue (void *p) {
static void stringcat (void *p) { static void stringcat (void *p) {
data *a; data *a;
int i; aint i;
if (UNBOXED(p)) if (UNBOXED(p))
; ;
@ -419,17 +419,17 @@ static void stringcat (void *p) {
} }
} }
extern int Luppercase (void *v) { extern aint Luppercase (void *v) {
ASSERT_UNBOXED("Luppercase:1", v); ASSERT_UNBOXED("Luppercase:1", v);
return BOX(toupper((int)UNBOX(v))); return BOX(toupper((int)UNBOX(v)));
} }
extern int Llowercase (void *v) { extern aint Llowercase (void *v) {
ASSERT_UNBOXED("Llowercase:1", v); ASSERT_UNBOXED("Llowercase:1", v);
return BOX(tolower((int)UNBOX(v))); return BOX(tolower((int)UNBOX(v)));
} }
extern aint LmatchSubString (char *subj, char *patt, int pos) { extern aint LmatchSubString (char *subj, char *patt, aint pos) {
data *p = TO_DATA(patt), *s = TO_DATA(subj); data *p = TO_DATA(patt), *s = TO_DATA(subj);
aint n; aint n;
@ -565,7 +565,7 @@ aint inner_hash (aint depth, auint acc, void *p) {
char *p = a->contents; char *p = a->contents;
while (*p) { while (*p) {
aint n = (int)*p++; aint n = (aint)*p++;
acc = HASH_APPEND(acc, n); acc = HASH_APPEND(acc, n);
} }
@ -580,7 +580,7 @@ aint inner_hash (aint depth, auint acc, void *p) {
case ARRAY_TAG: i = 0; break; case ARRAY_TAG: i = 0; break;
case SEXP_TAG: { case SEXP_TAG: {
int ta = TO_SEXP(p)->tag; aint ta = TO_SEXP(p)->tag;
acc = HASH_APPEND(acc, ta); acc = HASH_APPEND(acc, ta);
i = 1; i = 1;
++l; ++l;
@ -597,7 +597,7 @@ aint inner_hash (aint depth, auint acc, void *p) {
} }
extern void *LstringInt (char *b) { extern void *LstringInt (char *b) {
int n; aint n;
sscanf(b, "%d", &n); sscanf(b, "%d", &n);
return (void *)BOX(n); return (void *)BOX(n);
} }
@ -651,7 +651,7 @@ extern aint Lcompare (void *p, void *q) {
break; break;
case SEXP_TAG: { case SEXP_TAG: {
int tag_a = TO_SEXP(p)->tag, tag_b = TO_SEXP(q)->tag; aint tag_a = TO_SEXP(p)->tag, tag_b = TO_SEXP(q)->tag;
COMPARE_AND_RETURN(tag_a, tag_b); COMPARE_AND_RETURN(tag_a, tag_b);
COMPARE_AND_RETURN(la, lb); COMPARE_AND_RETURN(la, lb);
i = 0; i = 0;
@ -885,11 +885,11 @@ extern long Btag (void *d, aint t, aint n) {
} }
} }
int get_tag (data *d) { return TAG(d->data_header); } aint get_tag (data *d) { return TAG(d->data_header); }
int get_len (data *d) { return LEN(d->data_header); } aint get_len (data *d) { return LEN(d->data_header); }
extern int Barray_patt (void *d, int n) { extern aint Barray_patt (void *d, aint n) {
data *r; data *r;
if (UNBOXED(d)) return BOX(0); if (UNBOXED(d)) return BOX(0);
@ -899,7 +899,7 @@ extern int Barray_patt (void *d, int n) {
} }
} }
extern int Bstring_patt (void *x, void *y) { extern aint Bstring_patt (void *x, void *y) {
data *rx = (data *)BOX(NULL), *ry = (data *)BOX(NULL); data *rx = (data *)BOX(NULL), *ry = (data *)BOX(NULL);
ASSERT_STRING(".string_patt:2", y); ASSERT_STRING(".string_patt:2", y);
@ -915,29 +915,29 @@ extern int Bstring_patt (void *x, void *y) {
} }
} }
extern int Bclosure_tag_patt (void *x) { extern aint Bclosure_tag_patt (void *x) {
if (UNBOXED(x)) return BOX(0); if (UNBOXED(x)) return BOX(0);
return BOX(TAG(TO_DATA(x)->data_header) == CLOSURE_TAG); return BOX(TAG(TO_DATA(x)->data_header) == CLOSURE_TAG);
} }
extern int Bboxed_patt (void *x) { return BOX(UNBOXED(x) ? 0 : 1); } extern aint Bboxed_patt (void *x) { return BOX(UNBOXED(x) ? 0 : 1); }
extern int Bunboxed_patt (void *x) { return BOX(UNBOXED(x) ? 1 : 0); } extern aint Bunboxed_patt (void *x) { return BOX(UNBOXED(x) ? 1 : 0); }
extern int Barray_tag_patt (void *x) { extern aint Barray_tag_patt (void *x) {
if (UNBOXED(x)) return BOX(0); if (UNBOXED(x)) return BOX(0);
return BOX(TAG(TO_DATA(x)->data_header) == ARRAY_TAG); return BOX(TAG(TO_DATA(x)->data_header) == ARRAY_TAG);
} }
extern int Bstring_tag_patt (void *x) { extern aint Bstring_tag_patt (void *x) {
if (UNBOXED(x)) return BOX(0); if (UNBOXED(x)) return BOX(0);
return BOX(TAG(TO_DATA(x)->data_header) == STRING_TAG); return BOX(TAG(TO_DATA(x)->data_header) == STRING_TAG);
} }
extern int Bsexp_tag_patt (void *x) { extern aint Bsexp_tag_patt (void *x) {
if (UNBOXED(x)) return BOX(0); if (UNBOXED(x)) return BOX(0);
return BOX(TAG(TO_DATA(x)->data_header) == SEXP_TAG); return BOX(TAG(TO_DATA(x)->data_header) == SEXP_TAG);
@ -970,7 +970,7 @@ extern void *Bsta (void *v, aint i, void *x) {
static void fix_unboxed (char *s, va_list va) { static void fix_unboxed (char *s, va_list va) {
aint *p = (aint *)va; aint *p = (aint *)va;
int i = 0; aint i = 0;
while (*s) { while (*s) {
if (*s == '%') { if (*s == '%') {
@ -1061,7 +1061,7 @@ auint cnt_percentage_sign (char *s) {
} }
#endif #endif
extern int Lsystem (char *cmd) { return BOX(system(cmd)); } extern aint Lsystem (char *cmd) { return BOX(system(cmd)); }
#ifndef X86_64 #ifndef X86_64
extern void Lprintf (char *s, ...) { extern void Lprintf (char *s, ...) {
@ -1078,14 +1078,16 @@ extern void Lprintf (char *s, ...) {
} }
#endif #endif
// TODO: fix
extern void *Lsprintf (char *fmt, ...) { extern void *Lsprintf (char *fmt, ...) {
// exit (255);
va_list args; va_list args;
void *s; void *s;
ASSERT_STRING("sprintf:1", fmt); ASSERT_STRING("sprintf:1", fmt);
va_start(args, fmt); va_start(args, fmt);
fix_unboxed(fmt, args); // fix_unboxed(fmt, args);
createStringBuf(); createStringBuf();
@ -1105,6 +1107,7 @@ extern void *Lsprintf (char *fmt, ...) {
} }
extern void Lfprintf (FILE *f, char *s, ...) { extern void Lfprintf (FILE *f, char *s, ...) {
exit (255);
va_list args; // = (va_list)BOX(NULL); va_list args; // = (va_list)BOX(NULL);
ASSERT_BOXED("fprintf:1", f); ASSERT_BOXED("fprintf:1", f);
@ -1232,14 +1235,14 @@ extern int Lbinoperror2 (void) {
} }
/* Lwrite is an implementation of the "write" construct */ /* Lwrite is an implementation of the "write" construct */
extern long Lwrite (long n) { extern aint Lwrite (aint n) {
printf("%ld\n", UNBOX(n)); printf("%ld\n", UNBOX(n));
fflush(stdout); fflush(stdout);
return 0; return 0;
} }
extern int Lrandom (aint n) { extern aint Lrandom (aint n) {
ASSERT_UNBOXED("Lrandom, 0", n); ASSERT_UNBOXED("Lrandom, 0", n);
if (UNBOX(n) <= 0) { failure("invalid range in random: %d\n", UNBOX(n)); } if (UNBOX(n) <= 0) { failure("invalid range in random: %d\n", UNBOX(n)); }
@ -1247,7 +1250,7 @@ extern int Lrandom (aint n) {
return BOX(random() % UNBOX(n)); return BOX(random() % UNBOX(n));
} }
extern int Ltime () { extern aint Ltime () {
struct timespec t; struct timespec t;
clock_gettime(CLOCK_MONOTONIC_RAW, &t); clock_gettime(CLOCK_MONOTONIC_RAW, &t);
@ -1255,11 +1258,11 @@ extern int Ltime () {
return BOX(t.tv_sec * 1000000 + t.tv_nsec / 1000); return BOX(t.tv_sec * 1000000 + t.tv_nsec / 1000);
} }
extern void set_args (int argc, char *argv[]) { extern void set_args (aint argc, char *argv[]) {
data *a; data *a;
int n = argc; aint n = argc;
int *p = NULL; aint *p = NULL;
int i; aint i;
PRE_GC(); PRE_GC();