From 8fc552160162a9db787f3bb9c31c77a2059a8aac Mon Sep 17 00:00:00 2001 From: Mid <> Date: Thu, 9 Oct 2025 11:36:21 +0300 Subject: [PATCH] Multiple bug fixes --- src/ast/dump.c | 13 +------------ src/ast/usedef.c | 6 ++++-- src/x86/arch.h | 4 +++- src/x86/cg.c | 6 ++++++ src/x86/dumberdowner.c | 6 +++++- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/ast/dump.c b/src/ast/dump.c index e9d7922..d07bd0c 100644 --- a/src/ast/dump.c +++ b/src/ast/dump.c @@ -213,18 +213,7 @@ static char *ast_dumpe(AST *tlc, AST *e) { } static char *ast_dumps(AST *tlc, AST *s) { - if(s->nodeKind == AST_STMT_DECL) { - ScopeItem *vte = s->stmtDecl.thing; - - if(vte->kind == SCOPEITEM_SYMBOL) { - char *t = type_to_string(vte->type); - char *e = s->stmtDecl.expression ? ast_dumpe(tlc, s->stmtDecl.expression) : strdup(""); - char *r = malp("%s%s %s: %s;", vte->data.symbol.isExternal ? "external " : "", t, vte->data.symbol.name, e); - free(t); - free(e); - return r; - } - } else if(s->nodeKind == AST_STMT_ASSIGN) { + if(s->nodeKind == AST_STMT_ASSIGN) { if(s->stmtAssign.to) { char *a = ast_dumpe(tlc, s->stmtAssign.what); char *b = ast_dumpe(tlc, s->stmtAssign.to); diff --git a/src/ast/usedef.c b/src/ast/usedef.c index 4f28dd4..76cae9b 100644 --- a/src/ast/usedef.c +++ b/src/ast/usedef.c @@ -190,8 +190,10 @@ void ast_usedef_reset(AST *chu) { assert(!!vte->data.var.usedefFirst == !!vte->data.var.usedefLast); - vte->data.var.liveRangeStart = vte->data.var.usedefFirst->stmt; - vte->data.var.liveRangeEnd = vte->data.var.usedefLast->stmt; + if(vte->data.var.usedefFirst) { + vte->data.var.liveRangeStart = vte->data.var.usedefFirst->stmt; + vte->data.var.liveRangeEnd = vte->data.var.usedefLast->stmt; + } } // fix liveRangeStart and/or liveRangeEnd depending on goto targets diff --git a/src/x86/arch.h b/src/x86/arch.h index 221ed8e..6a0bb27 100644 --- a/src/x86/arch.h +++ b/src/x86/arch.h @@ -144,7 +144,9 @@ static inline int is_xop(AST *e) { c = c->exprCast.what; } - if(c->nodeKind == AST_EXPR_VAR && c->exprVar.thing->kind == SCOPEITEM_VAR) { + if(c->nodeKind == AST_EXPR_STACK_POINTER) { + return XOP_MEM; + } else if(c->nodeKind == AST_EXPR_VAR && c->exprVar.thing->kind == SCOPEITEM_VAR) { if(x86_ia16() && !x86_is_marked_ptr(c->exprVar.thing)) { // In IA-16, pointers MUST be preclassed to REG_CLASS_IA16_PTRS return XOP_NOT_XOP; diff --git a/src/x86/cg.c b/src/x86/cg.c index 2b74453..6171629 100644 --- a/src/x86/cg.c +++ b/src/x86/cg.c @@ -195,6 +195,12 @@ static const char *xop_sz(AST *tlc, AST *e, int sz) { xv_sz(p->exprBinOp.operands[1]->exprBinOp.operands[1]->exprVar.thing, 0)); } else if(p->nodeKind == AST_EXPR_VAR && p->exprVar.thing->kind == SCOPEITEM_VAR) { pr = snprintf(ret, XOPBUFSZ, "%s [%s]", spec(sz), xv_sz(p->exprVar.thing, 0)); + } else if(p->nodeKind == AST_EXPR_STACK_POINTER) { + if(x86_ia16()) { + pr = snprintf(ret, XOPBUFSZ, "[bp + %li]", 0 - tlc->chunk.stackReservation); + } else { + pr = snprintf(ret, XOPBUFSZ, "[esp + %i]", 0); + } } else if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_STACK_POINTER && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) { if(x86_ia16()) { pr = snprintf(ret, XOPBUFSZ, "[bp + %li]", p->exprBinOp.operands[1]->exprPrim.val - tlc->chunk.stackReservation); diff --git a/src/x86/dumberdowner.c b/src/x86/dumberdowner.c index e158bba..5c5a93c 100644 --- a/src/x86/dumberdowner.c +++ b/src/x86/dumberdowner.c @@ -57,6 +57,8 @@ static AST *xopify(AST *tlc, AST *chunk, AST *stmtPrev, AST *stmt, AST *e) { return varify(tlc, chunk, stmtPrev, stmt, e); } +// This is needed for architectures where not all registers can be used +// as pointers (for example IA-16 or the 68000 series) static void mark_ptr(AST *a) { assert(a->nodeKind == AST_EXPR_VAR); assert(a->exprVar.thing->kind == SCOPEITEM_VAR); @@ -332,7 +334,9 @@ static void dumben_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST * int argCount = call->what->expression.type->pointer.of->function.argCount; for(int i = 0; i < argCount; i++) { - if(is_xop(call->args[i]) == XOP_NOT_XOP) { + // We also check for ast_references_stack because the stack gets + // shifted during a function call which screws up all of the offsets + if(is_xop(call->args[i]) == XOP_NOT_XOP || ast_references_stack(call->args[i])) { call->args[i] = xopify(tlc, chu, stmtPrev, s, call->args[i]); this->effective = 1;