Added asm wrapper for printf

This commit is contained in:
Egor Sheremetov 2024-02-05 14:18:06 +01:00 committed by Roman Venediktov
parent f6516bae63
commit e0189d5654
3 changed files with 164 additions and 53 deletions

View file

@ -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

90
runtime/printf.s Normal file
View file

@ -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

View file

@ -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) {