From db9067b74864d46e475f976c7bd14f68879425c1 Mon Sep 17 00:00:00 2001 From: Roman Venediktov Date: Tue, 6 Feb 2024 10:27:27 +0100 Subject: [PATCH] Fix all prints --- runtime/printf.s | 115 +++++++++++++++++++++++++++++++++++++++++++++- runtime/runtime.c | 100 +++++++++++++++++++++++----------------- src/X86.ml | 3 ++ 3 files changed, 174 insertions(+), 44 deletions(-) diff --git a/runtime/printf.s b/runtime/printf.s index 6bf814ca4..7378e8c76 100644 --- a/runtime/printf.s +++ b/runtime/printf.s @@ -7,7 +7,10 @@ .extern fprintf .global Lsprintf -.extern sprintf +.extern Bsprintf + +.global Lfailure +.extern failure .extern cnt_percentage_sign @@ -21,7 +24,6 @@ Lprintf: pushq %rdx pushq %rsi movq %rsp, %rax -# pushq %rsi # rdi --- format string # r11 --- number of arguments except format string loop: @@ -49,3 +51,112 @@ continue: pushq %r14 jmp printf +Lfprintf: +# save return address + popq %r14 + + pushq %r9 + pushq %r8 + pushq %rcx + pushq %rdx + movq %rsp, %rax +# rdi --- FILE* +# rsi --- format string +# r11 --- number of arguments except format string +Lfprintf_loop: + movq $0, %r12 + cmpq %r11, %r12 + jz Lfprintf_continue + + decq %r11 + movq (%rax), %r10 + testq $1, %r10 + jz Lfprintf_loop_end +# unbox value + sarq %r10 + movq %r10, (%rax) +Lfprintf_loop_end: + addq $8, %rax + jmp Lfprintf_loop +Lfprintf_continue: + popq %rdx + popq %rcx + popq %r8 + popq %r9 +# restore return address + pushq %r14 + jmp fprintf + +Lsprintf: +# save return address + popq %r14 + + pushq %r9 + pushq %r8 + pushq %rcx + pushq %rdx + pushq %rsi + movq %rsp, %rax +# rdi --- format string +# r11 --- number of arguments except format string +Lsprintf_loop: + movq $0, %r12 + cmpq %r11, %r12 + jz Lsprintf_continue + + decq %r11 + movq (%rax), %r10 + testq $1, %r10 + jz Lsprintf_loop_end +# unbox value + sarq %r10 + movq %r10, (%rax) +Lsprintf_loop_end: + addq $8, %rax + jmp Lsprintf_loop +Lsprintf_continue: + popq %rsi + popq %rdx + popq %rcx + popq %r8 + popq %r9 +# restore return address + pushq %r14 + jmp Bsprintf + +Lfailure: +# save return address + popq %r14 + + pushq %r9 + pushq %r8 + pushq %rcx + pushq %rdx + pushq %rsi + movq %rsp, %rax +# rdi --- format string +# r11 --- number of arguments except format string +Lfailure_loop: + movq $0, %r12 + cmpq %r11, %r12 + jz Lfailure_continue + + decq %r11 + movq (%rax), %r10 + testq $1, %r10 + jz Lfailure_loop_end +# unbox value + sarq %r10 + movq %r10, (%rax) +Lfailure_loop_end: + addq $8, %rax + jmp Lfailure_loop +Lfailure_continue: + popq %rsi + popq %rdx + popq %rcx + popq %r8 + popq %r9 +# restore return address + pushq %r14 + jmp failure diff --git a/runtime/runtime.c b/runtime/runtime.c index 8a404c14a..ed7eb6bcf 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -968,28 +968,6 @@ extern void *Bsta (void *v, aint i, void *x) { return v; } -static void fix_unboxed (char *s, va_list va) { - aint *p = (aint *)va; - aint i = 0; - - while (*s) { - if (*s == '%') { - aint n = p[i]; - if (UNBOXED(n)) { p[i] = UNBOX(n); } - i++; - } - s++; - } -} - -extern void Lfailure (char *s, ...) { - va_list args; - - va_start(args, s); - fix_unboxed(s, args); - vfailure(s, args); -} - extern void Bmatch_failure (void *v, char *fname, aint line, aint col) { createStringBuf(); printValue(v); @@ -1046,24 +1024,38 @@ extern void *LgetEnv (char *var) { return s; } -#ifdef X86_64 -auint cnt_percentage_sign (char *s) { - auint cnt = 0; - while (*s) { - cnt += (*s == '%'); - ++s; - if (*s == '%') { - ++s; - --cnt; - } - } - return cnt; -} -#endif - extern aint Lsystem (char *cmd) { return BOX(system(cmd)); } +extern void Lfailure (char *s, ...); +extern void Lprintf (char *s, ...); +extern void *Lsprintf (char *fmt, ...); +extern void Lfprintf (FILE *f, char *s, ...); + #ifndef X86_64 +// In X86_64 we are not able to modify va_arg + +static void fix_unboxed (char *s, va_list va) { + aint *p = (aint *)va; + aint i = 0; + + while (*s) { + if (*s == '%') { + aint n = p[i]; + if (UNBOXED(n)) { p[i] = UNBOX(n); } + i++; + } + s++; + } +} + +extern void Lfailure (char *s, ...) { + va_list args; + + va_start(args, s); + fix_unboxed(s, args); + vfailure(s, args); +} + extern void Lprintf (char *s, ...) { va_list args; // = (va_list)BOX(NULL); @@ -1076,18 +1068,15 @@ extern void Lprintf (char *s, ...) { fflush(stdout); } -#endif -// TODO: fix extern void *Lsprintf (char *fmt, ...) { - // exit (255); va_list args; void *s; ASSERT_STRING("sprintf:1", fmt); va_start(args, fmt); - // fix_unboxed(fmt, args); + fix_unboxed(fmt, args); createStringBuf(); @@ -1107,7 +1096,6 @@ extern void *Lsprintf (char *fmt, ...) { } extern void Lfprintf (FILE *f, char *s, ...) { - exit (255); va_list args; // = (va_list)BOX(NULL); ASSERT_BOXED("fprintf:1", f); @@ -1118,6 +1106,34 @@ extern void Lfprintf (FILE *f, char *s, ...) { if (vfprintf(f, s, args) < 0) { failure("fprintf (...): %s\n", strerror(errno)); } } +#else + +extern void *Bsprintf (char *fmt, ...) { + va_list args; + void *s; + + ASSERT_STRING("sprintf:1", fmt); + + va_start(args, fmt); + + createStringBuf(); + + vprintStringBuf(fmt, args); + + PRE_GC(); + + push_extra_root((void **)&fmt); + s = Bstring(stringBuf.contents); + pop_extra_root((void **)&fmt); + + POST_GC(); + + deleteStringBuf(); + + return s; +} + +#endif extern FILE *Lfopen (char *f, char *m) { FILE *h; diff --git a/src/X86.ml b/src/X86.ml index 60887aa3d..cfa13ef6b 100644 --- a/src/X86.ml +++ b/src/X86.ml @@ -497,6 +497,9 @@ let compile_call env ?fname nargs tail = let add_printf_count = match fname with | Some "Lprintf" -> [ Mov (L (nargs - 1), r11) ] + | Some "Lsprintf" -> [ Mov (L (nargs - 1), r11) ] + | Some "Lfprintf" -> [ Mov (L (nargs - 2), r11) ] + | Some "Lfailure" -> [ Mov (L (nargs - 1), r11) ] | _ -> [] in let fname = adjust_builtin_function_name fname in