Compare commits

...

3 Commits

Author SHA1 Message Date
Mid
012d18cdf8 Fix stack growth and parameter passing 2025-08-04 18:06:30 +03:00
Mid
81b1010453 Basic allocators with unmanaged list (broken) 2025-07-29 17:54:13 +03:00
Mid
fb4849d382 Call pointers only 2025-07-29 17:48:31 +03:00
9 changed files with 130 additions and 32 deletions

4
examples/Alloc.nct Normal file
View File

@ -0,0 +1,4 @@
record Alloc {
u8* userdata;
u8*(u8* userdata, u8* ptr, u32 sz)* realloc;
}

View File

@ -1,5 +0,0 @@
record Allocator {
u8* userdata;
u8*(u8* userdata, u8* original, u32 size) realloc;
}

43
examples/ListDLU.nct Normal file
View File

@ -0,0 +1,43 @@
/*
* ListDLU: Dynamic, Linear growth, unmanaged
*/
use Alloc;
record ListDLU[T, S; growth] {
S capacity;
S size;
T[?]* data;
}
ListDLU_remove: [T, S; growth]u0(ListDLU[T, S; growth]* this, S index) -> {
T* data0 = &((*((*this).data))[index]);
T* data1 = data0 + @sizeof T;
S sz = (*this).size;
(*this).size = (*this).size - 1;
loop {
if(index == sz) {
break;
}
*data0 = *data1;
data0 = data0 + @sizeof T;
data1 = data1 + @sizeof T;
index = index + 1;
}
return;
};
ListDLU_add: [T, S; growth]u0(ListDLU[T, S; growth]* this, Alloc *alloc, T value) -> {
if((*this).size == (*this).capacity) {
u32 newcap = (*this).capacity + growth;
(*this).capacity = newcap;
(*this).data = ((*alloc).realloc)((*alloc).userdata, (*this).data, newcap * @sizeof T);
}
(*((*this).data))[(*this).size] = value;
(*this).size = (*this).size + 1;
return;
};

29
examples/UserListDLU.nct Normal file
View File

@ -0,0 +1,29 @@
use ListDLU;
@section(".text");
@instantiate ListDLU_remove[u32, u32; 9];
@instantiate ListDLU_add[u32, u32; 9];
extern u8*(u8* ptr, u32 sz) realloc;
libc_realloc: u8*(u8* userdata, u8* ptr, u32 sz) -> {
return realloc(ptr, sz);
};
main: u0() -> {
Alloc libc;
libc.realloc = &libc_realloc;
ListDLU[u32, u32; 9] list;
list.capacity = 0;
list.size = 0;
list.data = 0;
ListDLU_add[u32, u32; 9](&list, &libc, 1234);
ListDLU_add[u32, u32; 9](&list, &libc, 4321);
ListDLU_add[u32, u32; 9](&list, &libc, 7777);
ListDLU_add[u32, u32; 9](&list, &libc, 6969);
ListDLU_remove[u32, u32; 9](&list, 1);
return;
};
@section(".bss");

View File

@ -57,7 +57,7 @@ void generic_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST *tlc, v
} else if(n->nodeKind == AST_EXPR_CALL) { } else if(n->nodeKind == AST_EXPR_CALL) {
generic_visitor(&n->exprCall.what, stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler); generic_visitor(&n->exprCall.what, stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler);
for(size_t i = 0; i < n->exprCall.what->expression.type->function.argCount; i++) { for(size_t i = 0; i < n->exprCall.what->expression.type->pointer.of->function.argCount; i++) {
generic_visitor(&n->exprCall.args[i], stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler); generic_visitor(&n->exprCall.args[i], stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler);
} }
} else if(n->nodeKind == AST_EXPR_CAST) { } else if(n->nodeKind == AST_EXPR_CAST) {
@ -421,7 +421,7 @@ static void ast_usedef_pass(struct UsedefPassState *state, AST *tlc, AST *a, AST
} else if(a->nodeKind == AST_EXPR_CALL) { } else if(a->nodeKind == AST_EXPR_CALL) {
ast_usedef_pass(state, tlc, a->exprCall.what, wholestmt); ast_usedef_pass(state, tlc, a->exprCall.what, wholestmt);
for(size_t p = 0; p < a->exprCall.what->expression.type->function.argCount; p++) { for(size_t p = 0; p < a->exprCall.what->expression.type->pointer.of->function.argCount; p++) {
ast_usedef_pass(state, tlc, a->exprCall.args[p], wholestmt); ast_usedef_pass(state, tlc, a->exprCall.args[p], wholestmt);
} }
} else if(a->nodeKind == AST_EXPR_PRIMITIVE) { } else if(a->nodeKind == AST_EXPR_PRIMITIVE) {
@ -698,7 +698,7 @@ static char *ast_dumpe(AST *tlc, AST *e) {
char *w = ast_dumpe(tlc, e->exprCall.what); char *w = ast_dumpe(tlc, e->exprCall.what);
char *out = malp("%s(", w); char *out = malp("%s(", w);
free(w); free(w);
size_t argCount = e->exprCall.what->expression.type->function.argCount; size_t argCount = e->exprCall.what->expression.type->pointer.of->function.argCount;
for(size_t i = 0; i < argCount; i++) { for(size_t i = 0; i < argCount; i++) {
char *a = ast_dumpe(tlc, e->exprCall.args[i]); char *a = ast_dumpe(tlc, e->exprCall.args[i]);
char *out2 = malp(i == argCount - 1 ? "%s%s)" : "%s%s, ", out, a); char *out2 = malp(i == argCount - 1 ? "%s%s)" : "%s%s, ", out, a);
@ -964,6 +964,7 @@ static void spill2stack_visitor(AST **aptr, AST *stmt, AST *stmtPrev, AST *chunk
offset->nodeKind = AST_EXPR_PRIMITIVE; offset->nodeKind = AST_EXPR_PRIMITIVE;
offset->type = rsp->type; offset->type = rsp->type;
offset->val = -this->stackGrowth; // This will be affected by the other part of this pass, so we must reverse offset->val = -this->stackGrowth; // This will be affected by the other part of this pass, so we must reverse
offset->stackGrowth = true;
ASTExprBinaryOp *bop = calloc(1, sizeof(*bop)); ASTExprBinaryOp *bop = calloc(1, sizeof(*bop));
bop->nodeKind = AST_EXPR_BINARY_OP; bop->nodeKind = AST_EXPR_BINARY_OP;
@ -981,10 +982,10 @@ static void spill2stack_visitor(AST **aptr, AST *stmt, AST *stmtPrev, AST *chunk
*aptr = (AST*) deref; *aptr = (AST*) deref;
} }
} else if(a->nodeKind == AST_EXPR_BINARY_OP && a->exprBinOp.operands[0]->nodeKind == AST_EXPR_STACK_POINTER && a->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) { } else if(a->nodeKind == AST_EXPR_PRIMITIVE && a->exprPrim.stackGrowth) {
// Guaranteed to not require more dumbification // Guaranteed to not require more dumbification
a->exprBinOp.operands[1]->exprPrim.val += this->stackGrowth; a->exprPrim.val += this->stackGrowth;
} }
} }

View File

@ -123,6 +123,9 @@ typedef struct {
ASTExpr; ASTExpr;
int val; int val;
// If true, increase this literal during stack growths
bool stackGrowth;
} ASTExprPrimitive; } ASTExprPrimitive;
typedef struct { typedef struct {

View File

@ -406,13 +406,24 @@ AST *nct_parse_expression(Parser *P, int lOP) {
while(peek(P, 0).type == TOKEN_PAREN_L || peek(P, 0).type == TOKEN_SQUAREN_L) { while(peek(P, 0).type == TOKEN_PAREN_L || peek(P, 0).type == TOKEN_SQUAREN_L) {
if(maybe(P, TOKEN_PAREN_L)) { if(maybe(P, TOKEN_PAREN_L)) {
if(ret->expression.type->type != TYPE_TYPE_FUNCTION) { if(ret->expression.type->type == TYPE_TYPE_FUNCTION) {
stahp(P->tokens[P->i].row, P->tokens[P->i].column, "Only function types may be called."); ASTExprUnaryOp *ref = alloc_node(P, sizeof(*ref));
ref->nodeKind = AST_EXPR_UNARY_OP;
ref->type = type_pointer_wrap(ret->expression.type);
ref->operator = UNOP_REF;
ref->operand = ret;
ret = (AST*) ref;
} }
if(ret->expression.type->type != TYPE_TYPE_POINTER || ret->expression.type->pointer.of->type != TYPE_TYPE_FUNCTION) {
stahp(P->tokens[P->i].row, P->tokens[P->i].column, "Only function types or function pointers may be called.");
}
Type *ftype = ret->expression.type->pointer.of;
ASTExprCall *call = alloc_node(P, sizeof(*call)); ASTExprCall *call = alloc_node(P, sizeof(*call));
call->nodeKind = AST_EXPR_CALL; call->nodeKind = AST_EXPR_CALL;
call->type = ret->expression.type->function.ret; call->type = ftype->function.ret;
call->what = ret; call->what = ret;
call->args = NULL; call->args = NULL;
@ -421,7 +432,7 @@ AST *nct_parse_expression(Parser *P, int lOP) {
if(!maybe(P, TOKEN_PAREN_R)) { if(!maybe(P, TOKEN_PAREN_R)) {
while(peek(P, 0).type != TOKEN_PAREN_R && peek(P, 0).type != TOKEN_COMMA) { while(peek(P, 0).type != TOKEN_PAREN_R && peek(P, 0).type != TOKEN_COMMA) {
call->args = realloc(call->args, (argCount + 1) * sizeof(AST*)); call->args = realloc(call->args, (argCount + 1) * sizeof(AST*));
call->args[argCount] = ast_cast_expr(nct_parse_expression(P, 0), ret->expression.type->function.args[argCount]); call->args[argCount] = ast_cast_expr(nct_parse_expression(P, 0), ftype->function.args[argCount]);
argCount++; argCount++;
@ -431,7 +442,7 @@ AST *nct_parse_expression(Parser *P, int lOP) {
} }
} }
if(argCount != call->what->expression.type->function.argCount) { if(argCount != ftype->function.argCount) {
stahp(P->tokens[P->i].row, P->tokens[P->i].column, "Mismatched number of arguments"); stahp(P->tokens[P->i].row, P->tokens[P->i].column, "Mismatched number of arguments");
} }

View File

@ -131,12 +131,14 @@ static AST *is_field_access(AST *e) {
static const char *xop_sz(AST *tlc, AST *e, int sz) { static const char *xop_sz(AST *tlc, AST *e, int sz) {
#define XOPBUFS 16 #define XOPBUFS 16
#define XOPBUFSZ 24 #define XOPBUFSZ 32
static char bufs[XOPBUFS][XOPBUFSZ]; static char bufs[XOPBUFS][XOPBUFSZ];
static int bufidx = 0; static int bufidx = 0;
char *ret = bufs[bufidx]; char *ret = bufs[bufidx];
int pr = 0;
if(e->nodeKind == AST_EXPR_UNARY_OP && e->exprUnOp.operator == UNOP_DEREF) { if(e->nodeKind == AST_EXPR_UNARY_OP && e->exprUnOp.operator == UNOP_DEREF) {
AST *p = e->exprUnOp.operand; AST *p = e->exprUnOp.operand;
@ -145,12 +147,12 @@ static const char *xop_sz(AST *tlc, AST *e, int sz) {
} }
if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprVar.thing->kind == SCOPEITEM_VAR && p->exprBinOp.operands[1]->exprVar.thing->kind == SCOPEITEM_VAR) { if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprVar.thing->kind == SCOPEITEM_VAR && p->exprBinOp.operands[1]->exprVar.thing->kind == SCOPEITEM_VAR) {
snprintf(ret, XOPBUFSZ, "%s [%s + %s]", pr = snprintf(ret, XOPBUFSZ, "%s [%s + %s]",
spec(sz), spec(sz),
xv_sz(p->exprBinOp.operands[0]->exprVar.thing, 0), xv_sz(p->exprBinOp.operands[0]->exprVar.thing, 0),
xv_sz(p->exprBinOp.operands[1]->exprVar.thing, 0)); xv_sz(p->exprBinOp.operands[1]->exprVar.thing, 0));
} else if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_UNARY_OP && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprUnOp.operator == UNOP_REF && p->exprBinOp.operands[0]->exprUnOp.operand->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->kind == SCOPEITEM_SYMBOL && p->exprBinOp.operands[1]->exprVar.thing->kind == SCOPEITEM_VAR) { } else if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_UNARY_OP && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprUnOp.operator == UNOP_REF && p->exprBinOp.operands[0]->exprUnOp.operand->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->kind == SCOPEITEM_SYMBOL && p->exprBinOp.operands[1]->exprVar.thing->kind == SCOPEITEM_VAR) {
snprintf(ret, XOPBUFSZ, "%s [%s + %s]", pr = snprintf(ret, XOPBUFSZ, "%s [%s + %s]",
spec(sz), spec(sz),
p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->data.symbol.name, p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->data.symbol.name,
xv_sz(p->exprBinOp.operands[1]->exprVar.thing, 0)); xv_sz(p->exprBinOp.operands[1]->exprVar.thing, 0));
@ -160,7 +162,7 @@ static const char *xop_sz(AST *tlc, AST *e, int sz) {
if(e->exprBinOp.operands[0]->nodeKind == AST_EXPR_UNARY_OP) { if(e->exprBinOp.operands[0]->nodeKind == AST_EXPR_UNARY_OP) {
assert(e->exprBinOp.operands[0]->exprUnOp.operator == UNOP_REF); assert(e->exprBinOp.operands[0]->exprUnOp.operator == UNOP_REF);
snprintf(ret, XOPBUFSZ, "%s [%s + %i]", pr = snprintf(ret, XOPBUFSZ, "%s [%s + %i]",
spec(sz), spec(sz),
e->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->data.symbol.name, e->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->data.symbol.name,
e->exprBinOp.operands[1]->exprPrim.val); e->exprBinOp.operands[1]->exprPrim.val);
@ -169,43 +171,45 @@ static const char *xop_sz(AST *tlc, AST *e, int sz) {
ScopeItem *vte = e->exprBinOp.operands[0]->exprVar.thing; ScopeItem *vte = e->exprBinOp.operands[0]->exprVar.thing;
snprintf(ret, XOPBUFSZ, "%s [%s + %i]", pr = snprintf(ret, XOPBUFSZ, "%s [%s + %i]",
spec(sz), spec(sz),
REG_CLASSES[vte->data.var.registerClass].rsN[vte->data.var.color], REG_CLASSES[vte->data.var.registerClass].rsN[vte->data.var.color],
e->exprBinOp.operands[1]->exprPrim.val); e->exprBinOp.operands[1]->exprPrim.val);
} }
} else if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_UNARY_OP && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operands[0]->exprUnOp.operator == UNOP_REF && p->exprBinOp.operands[0]->exprUnOp.operand->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->kind == SCOPEITEM_SYMBOL && p->exprBinOp.operands[1]->exprBinOp.operator == BINOP_MUL && p->exprBinOp.operands[1]->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[1]->exprBinOp.operands[0]->nodeKind == AST_EXPR_PRIMITIVE && p->exprBinOp.operands[1]->exprBinOp.operands[1]->exprVar.thing->kind == SCOPEITEM_VAR) { } else if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_UNARY_OP && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operands[0]->exprUnOp.operator == UNOP_REF && p->exprBinOp.operands[0]->exprUnOp.operand->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->kind == SCOPEITEM_SYMBOL && p->exprBinOp.operands[1]->exprBinOp.operator == BINOP_MUL && p->exprBinOp.operands[1]->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[1]->exprBinOp.operands[0]->nodeKind == AST_EXPR_PRIMITIVE && p->exprBinOp.operands[1]->exprBinOp.operands[1]->exprVar.thing->kind == SCOPEITEM_VAR) {
snprintf(ret, XOPBUFSZ, "%s [%s + %i * %s]", pr = snprintf(ret, XOPBUFSZ, "%s [%s + %i * %s]",
spec(sz), spec(sz),
p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->data.symbol.name, p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->data.symbol.name,
p->exprBinOp.operands[1]->exprBinOp.operands[0]->exprPrim.val, p->exprBinOp.operands[1]->exprBinOp.operands[0]->exprPrim.val,
xv_sz(p->exprBinOp.operands[1]->exprBinOp.operands[1]->exprVar.thing, 0)); 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) { } else if(p->nodeKind == AST_EXPR_VAR && p->exprVar.thing->kind == SCOPEITEM_VAR) {
snprintf(ret, XOPBUFSZ, "%s [%s]", spec(sz), xv_sz(p->exprVar.thing, 0)); pr = snprintf(ret, XOPBUFSZ, "%s [%s]", spec(sz), xv_sz(p->exprVar.thing, 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) { } 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) {
snprintf(ret, XOPBUFSZ, "[esp + %i]", p->exprBinOp.operands[1]->exprPrim.val); pr = snprintf(ret, XOPBUFSZ, "[esp + %i]", p->exprBinOp.operands[1]->exprPrim.val);
} else { } else {
return NULL; return NULL;
} }
} else if(e->nodeKind == AST_EXPR_STACK_POINTER) { } else if(e->nodeKind == AST_EXPR_STACK_POINTER) {
snprintf(ret, XOPBUFSZ, "esp"); pr = snprintf(ret, XOPBUFSZ, "esp");
} else if(e->nodeKind == AST_EXPR_VAR) { } else if(e->nodeKind == AST_EXPR_VAR) {
ScopeItem *v = e->exprVar.thing; ScopeItem *v = e->exprVar.thing;
if(v->kind == SCOPEITEM_VAR) { if(v->kind == SCOPEITEM_VAR) {
return xv_sz(v, sz); return xv_sz(v, sz);
} else if(v->kind == SCOPEITEM_SYMBOL) { } else if(v->kind == SCOPEITEM_SYMBOL) {
snprintf(ret, XOPBUFSZ, "%s [%s]", spec(sz), v->data.symbol.name); pr = snprintf(ret, XOPBUFSZ, "%s [%s]", spec(sz), v->data.symbol.name);
} else abort(); } else abort();
} else if(e->nodeKind == AST_EXPR_PRIMITIVE) { } else if(e->nodeKind == AST_EXPR_PRIMITIVE) {
snprintf(ret, XOPBUFSZ, "%s %i", spec(type_size(e->exprPrim.type)), e->exprPrim.val); pr = snprintf(ret, XOPBUFSZ, "%s %i", spec(type_size(e->exprPrim.type)), e->exprPrim.val);
} else if(e->nodeKind == AST_EXPR_UNARY_OP && e->exprUnOp.operator == UNOP_REF && e->exprUnOp.operand->nodeKind == AST_EXPR_VAR && e->exprUnOp.operand->exprVar.thing->kind == SCOPEITEM_SYMBOL) { } else if(e->nodeKind == AST_EXPR_UNARY_OP && e->exprUnOp.operator == UNOP_REF && e->exprUnOp.operand->nodeKind == AST_EXPR_VAR && e->exprUnOp.operand->exprVar.thing->kind == SCOPEITEM_SYMBOL) {
snprintf(ret, XOPBUFSZ, "%s", e->exprUnOp.operand->exprVar.thing->data.symbol.name); pr = snprintf(ret, XOPBUFSZ, "%s", e->exprUnOp.operand->exprVar.thing->data.symbol.name);
} else { } else {
return NULL; return NULL;
} }
assert(pr < XOPBUFSZ && "XOPBUF OVERFLOW");
bufidx = (bufidx + 1) % XOPBUFS; bufidx = (bufidx + 1) % XOPBUFS;
return ret; return ret;
@ -322,7 +326,7 @@ void cg_chunk(CGState *cg, AST *a) {
puts("push ecx"); puts("push ecx");
puts("push edx"); puts("push edx");
int argCount = e->exprCall.what->expression.type->function.argCount; int argCount = e->exprCall.what->expression.type->pointer.of->function.argCount;
size_t argSize = 0; size_t argSize = 0;
@ -332,9 +336,11 @@ void cg_chunk(CGState *cg, AST *a) {
argSize += (type_size(e->exprCall.args[i]->expression.type) + 3) & ~3; argSize += (type_size(e->exprCall.args[i]->expression.type) + 3) & ~3;
} }
assert(e->exprCall.what->nodeKind == AST_EXPR_VAR && e->exprCall.what->exprVar.thing->kind == SCOPEITEM_SYMBOL); if(e->exprCall.what->nodeKind == AST_EXPR_VAR && e->exprCall.what->exprVar.thing->kind == SCOPEITEM_SYMBOL) {
printf("call %s\n", e->exprCall.what->exprVar.thing->data.symbol.name); printf("call %s\n", e->exprCall.what->exprVar.thing->data.symbol.name);
} else {
printf("call %s\n", xop(cg->tlc, e->exprCall.what));
}
if(argSize) printf("add esp, %lu\n", argSize); if(argSize) printf("add esp, %lu\n", argSize);
@ -562,6 +568,7 @@ static void callee_saved_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chun
offset->nodeKind = AST_EXPR_PRIMITIVE; offset->nodeKind = AST_EXPR_PRIMITIVE;
offset->type = primitive_parse("u32"); offset->type = primitive_parse("u32");
offset->val = this->calleeOffsets[i]; offset->val = this->calleeOffsets[i];
offset->stackGrowth = true;
ASTExprBinaryOp *sum = calloc(1, sizeof(*sum)); ASTExprBinaryOp *sum = calloc(1, sizeof(*sum));
sum->nodeKind = AST_EXPR_BINARY_OP; sum->nodeKind = AST_EXPR_BINARY_OP;
@ -612,6 +619,7 @@ static void callee_saved_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chun
offset->nodeKind = AST_EXPR_PRIMITIVE; offset->nodeKind = AST_EXPR_PRIMITIVE;
offset->type = primitive_parse("u32"); offset->type = primitive_parse("u32");
offset->val = this->calleeOffsets[i]; offset->val = this->calleeOffsets[i];
offset->stackGrowth = true;
ASTExprBinaryOp *sum = calloc(1, sizeof(*sum)); ASTExprBinaryOp *sum = calloc(1, sizeof(*sum));
sum->nodeKind = AST_EXPR_BINARY_OP; sum->nodeKind = AST_EXPR_BINARY_OP;

View File

@ -215,12 +215,15 @@ static void dumben_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST *
} else if(s->stmtAssign.what && s->stmtAssign.what->nodeKind == AST_EXPR_VAR && s->stmtAssign.what->exprVar.thing->kind == SCOPEITEM_VAR && s->stmtAssign.to->nodeKind == AST_EXPR_CALL) { } else if(s->stmtAssign.what && s->stmtAssign.what->nodeKind == AST_EXPR_VAR && s->stmtAssign.what->exprVar.thing->kind == SCOPEITEM_VAR && s->stmtAssign.to->nodeKind == AST_EXPR_CALL) {
ASTExprCall *call = &s->stmtAssign.to->exprCall; ASTExprCall *call = &s->stmtAssign.to->exprCall;
int argCount = call->what->expression.type->function.argCount; int argCount = call->what->expression.type->pointer.of->function.argCount;
for(int i = 0; i < argCount; i++) { for(int i = 0; i < argCount; i++) {
if(is_xop(call->args[i]) == XOP_NOT_XOP) { if(is_xop(call->args[i]) == XOP_NOT_XOP) {
call->args[i] = xopify(tlc, chu, stmtPrev, s, call->args[i]); call->args[i] = xopify(tlc, chu, stmtPrev, s, call->args[i]);
this->effective = 1; this->effective = 1;
// Xopify one argument at a time otherwise stmtPrev becomes incorrect
break;
} }
} }
} else if(s->stmtAssign.to && s->stmtAssign.to->nodeKind == AST_EXPR_UNARY_OP && s->stmtAssign.to->exprUnOp.operator == UNOP_NEGATE && !ast_expression_equal(s->stmtAssign.what, s->stmtAssign.to->exprUnOp.operand)) { } else if(s->stmtAssign.to && s->stmtAssign.to->nodeKind == AST_EXPR_UNARY_OP && s->stmtAssign.to->exprUnOp.operator == UNOP_NEGATE && !ast_expression_equal(s->stmtAssign.what, s->stmtAssign.to->exprUnOp.operand)) {
@ -373,6 +376,7 @@ static void pre_dumb_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chunk, A
offset->nodeKind = AST_EXPR_PRIMITIVE; offset->nodeKind = AST_EXPR_PRIMITIVE;
offset->type = primitive_parse("u32"); offset->type = primitive_parse("u32");
offset->val = 4 + i * 4; offset->val = 4 + i * 4;
offset->stackGrowth = true;
ASTExprBinaryOp *sum = calloc(1, sizeof(*sum)); ASTExprBinaryOp *sum = calloc(1, sizeof(*sum));
sum->nodeKind = AST_EXPR_BINARY_OP; sum->nodeKind = AST_EXPR_BINARY_OP;