diff --git a/runtime/Makefile b/runtime/Makefile index d70affdc9..4c5dfa612 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -5,10 +5,11 @@ TEST_FLAGS=$(COMMON_FLAGS) -DDEBUG_VERSION UNIT_TESTS_FLAGS=$(TEST_FLAGS) INVARIANTS_CHECK_FLAGS=$(TEST_FLAGS) -DFULL_INVARIANT_CHECKS -all: gc64.o runtime64.o - ar rc runtime.a runtime64.o gc64.o +# this target is the most important one, its' artefacts should be used as a runtime of x86-64 version of Lama +all: gc64.o runtime64.o printf.o + ar rc runtime.a runtime64.o gc64.o printf.o -# this target is the most important one, its' artefacts should be used as a runtime of Lama +# this target is the most important one, its' artefacts should be used as a runtime of x86 (32-bits) version Lama all32: gc.o runtime.o ar rc runtime.a runtime.o gc.o @@ -49,5 +50,8 @@ runtime.o: runtime.c runtime.h runtime64.o: runtime.c runtime.h $(CC) $(PROD_FLAGS) -c runtime.c -o runtime64.o +printf.o: printf.s + $(CC) $(PROD_FLAGS) -c printf.s -o printf.o + clean: $(RM) *.a *.o *~ negative_scenarios/*.err diff --git a/runtime/printf.s b/runtime/printf.s new file mode 100644 index 000000000..9498ac711 --- /dev/null +++ b/runtime/printf.s @@ -0,0 +1,90 @@ +.section .text + +.global Lprintf +.extern printf + +.global Lfprintf +.extern fprintf + +.global Lsprintf +.extern sprintf + +.extern cnt_percentage_sign + +Lprintf: + pushq %rbp + movq %rsp, %rbp + movq %rdi, -40(%rbp) + movq %rsi, -48(%rbp) + movq -48(%rbp), %rax + movq %rax, -16(%rbp) + movl $0, -4(%rbp) + jmp .L2 +.L5: + movq -40(%rbp), %rax + movzbl (%rax), %eax + cmpb $37, %al + jne .L3 + movl -4(%rbp), %eax + cltq + leaq 0(,%rax,8), %rdx + movq -16(%rbp), %rax + addq %rdx, %rax + movq (%rax), %rax + movq %rax, -24(%rbp) + movq -24(%rbp), %rax + andl $1, %eax + testq %rax, %rax + je .L4 + movl -4(%rbp), %eax + cltq + leaq 0(,%rax,8), %rdx + movq -16(%rbp), %rax + addq %rdx, %rax + movq -24(%rbp), %rdx + sarq %rdx + movq %rdx, (%rax) +.L4: + addl $1, -4(%rbp) +.L3: + 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 diff --git a/runtime/runtime.c b/runtime/runtime.c index a11fd1763..7cd9b2441 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -14,7 +14,7 @@ extern size_t __gc_stack_top, __gc_stack_bottom; flag = __gc_stack_top == 0; \ if (flag) { __gc_stack_top = (size_t)__builtin_frame_address(0); } \ assert(__gc_stack_top != 0); \ - assert(__gc_stack_top & 0xF == 0); \ + assert((__gc_stack_top & 0xF) == 0); \ assert(__builtin_frame_address(0) <= (void *)__gc_stack_top); #define POST_GC() \ @@ -547,15 +547,15 @@ void *Lclone (void *p) { #define HASH_DEPTH 3 #define HASH_APPEND(acc, x) \ - (((acc + (unsigned)x) << (WORD_SIZE / 2)) | ((acc + (unsigned)x) >> (WORD_SIZE / 2))) + (((acc + (auint)x) << (WORD_SIZE / 2)) | ((acc + (auint)x) >> (WORD_SIZE / 2))) -int inner_hash (int depth, unsigned acc, void *p) { +aint inner_hash (aint depth, auint acc, void *p) { if (depth > HASH_DEPTH) return acc; if (UNBOXED(p)) return HASH_APPEND(acc, UNBOX(p)); else if (is_valid_heap_pointer(p)) { data *a = TO_DATA(p); - int t = TAG(a->data_header), l = LEN(a->data_header), i; + aint t = TAG(a->data_header), l = LEN(a->data_header), i; acc = HASH_APPEND(acc, t); acc = HASH_APPEND(acc, l); @@ -565,11 +565,11 @@ int inner_hash (int depth, unsigned acc, void *p) { char *p = a->contents; while (*p) { - int n = (int)*p++; + aint n = (int)*p++; acc = HASH_APPEND(acc, n); } - return acc; + return (aint)acc; } case CLOSURE_TAG: @@ -592,7 +592,7 @@ int inner_hash (int depth, unsigned acc, void *p) { for (; i < l; i++) acc = inner_hash(depth + 1, acc, ((void **)a->contents)[i]); - return acc; + return (aint)acc; } else return HASH_APPEND(acc, p); } @@ -602,9 +602,9 @@ extern void *LstringInt (char *b) { return (void *)BOX(n); } -extern int Lhash (void *p) { return BOX(0x3fffff & inner_hash(0, 0, p)); } +extern aint Lhash (void *p) { return BOX(0x3fffff & inner_hash(0, 0, p)); } -extern int LflatCompare (void *p, void *q) { +extern aint LflatCompare (void *p, void *q) { if (UNBOXED(p)) { if (UNBOXED(q)) { return BOX(UNBOX(p) - UNBOX(q)); } return -1; @@ -1031,32 +1031,6 @@ extern void * /*Lstrcat*/ Li__Infix_4343 (void *a, void *b) { return d->contents; } -extern void *Lsprintf (char *fmt, ...) { - va_list args; - void *s; - - ASSERT_STRING("sprintf:1", fmt); - - va_start(args, fmt); - fix_unboxed(fmt, args); - - 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; -} - extern void *LgetEnv (char *var) { char *e = getenv(var); void *s; @@ -1072,31 +1046,74 @@ 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 int Lsystem (char *cmd) { return BOX(system(cmd)); } -extern void Lfprintf (FILE *f, char *s, ...) { - va_list args; // = (va_list)BOX(NULL); +#ifndef X86_64 +extern void Lprintf (char *s, ...) { + va_list args; // = (va_list)BOX(NULL); - ASSERT_BOXED("fprintf:1", f); - ASSERT_STRING("fprintf:2", s); + ASSERT_STRING("printf:1", s); - va_start(args, s); - fix_unboxed(s, args); + va_start(args, s); + fix_unboxed(s, args); - if (vfprintf(f, s, args) < 0) { failure("fprintf (...): %s\n", strerror(errno)); } + if (vprintf(s, args) < 0) { failure("fprintf (...): %s\n", strerror(errno)); } + + fflush(stdout); +} +#endif + +extern void *Lsprintf (char *fmt, ...) { + va_list args; + void *s; + + ASSERT_STRING("sprintf:1", fmt); + + va_start(args, fmt); + fix_unboxed(fmt, args); + + 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; } -extern void Lprintf (char *s, ...) { - va_list args; // = (va_list)BOX(NULL); +extern void Lfprintf (FILE *f, char *s, ...) { + va_list args; // = (va_list)BOX(NULL); - ASSERT_STRING("printf:1", s); + ASSERT_BOXED("fprintf:1", f); + ASSERT_STRING("fprintf:2", s); - va_start(args, s); - fix_unboxed(s, args); + va_start(args, s); + fix_unboxed(s, args); - if (vprintf(s, args) < 0) { failure("fprintf (...): %s\n", strerror(errno)); } - - fflush(stdout); + if (vfprintf(f, s, args) < 0) { failure("fprintf (...): %s\n", strerror(errno)); } } extern FILE *Lfopen (char *f, char *m) {