diff --git a/examples/UserListDLU.nct b/examples/UserListDLU.nct index e8ce170..b2277fa 100644 --- a/examples/UserListDLU.nct +++ b/examples/UserListDLU.nct @@ -18,11 +18,14 @@ main: u0() -> { 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; }; diff --git a/src/x86/arch.h b/src/x86/arch.h index ec6bc2d..134950b 100644 --- a/src/x86/arch.h +++ b/src/x86/arch.h @@ -303,3 +303,7 @@ static inline void arch_add_hidden_variables(Scope *scope) { scope_set(scope, "@seg_ds", si); }*/ } + +static inline bool x86_is_lea(AST *s) { + return !x86_ia16() && s->nodeKind == AST_STMT_ASSIGN && s->stmtAssign.to->nodeKind == AST_EXPR_BINARY_OP && s->stmtAssign.to->exprBinOp.operator == BINOP_ADD && is_xop(s->stmtAssign.what) == XOP_NOT_MEM && is_xop(s->stmtAssign.to->exprBinOp.operands[0]) == XOP_NOT_MEM && is_xop(s->stmtAssign.to->exprBinOp.operands[1]) == XOP_NOT_MEM; +} diff --git a/src/x86/cg.c b/src/x86/cg.c index 1225498..096d60f 100644 --- a/src/x86/cg.c +++ b/src/x86/cg.c @@ -203,7 +203,7 @@ static const char *xop_sz(AST *tlc, AST *e, int sz) { } else if(e->nodeKind == AST_EXPR_PRIMITIVE) { 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) { - pr = snprintf(ret, XOPBUFSZ, "%s", e->exprUnOp.operand->exprVar.thing->data.symbol.name); + pr = snprintf(ret, XOPBUFSZ, "%s %s", spec(type_size(e->exprUnOp.type)), e->exprUnOp.operand->exprVar.thing->data.symbol.name); } else { return NULL; } @@ -219,6 +219,19 @@ static const char *xop(AST *tlc, AST *e) { return xop_sz(tlc, e, type_size(e->expression.type)); } +static const char *xop_strip_size(const char *str) { + if(!strncmp(str, "byte ", 5)) { + return str + 5; + } else if(!strncmp(str, "word ", 5)) { + return str + 5; + } else if(!strncmp(str, "dword ", 6)) { + return str + 6; + } else if(!strncmp(str, "qword ", 6)) { + return str + 6; + } + return str; +} + static int lr_empty(ScopeItem *a) { assert(a->kind == SCOPEITEM_VAR); //assert(!a->data.var.liveRangeStart == !a->data.var.liveRangeEnd); @@ -393,12 +406,12 @@ void cg_chunk(CGState *cg, AST *a) { printf("%s %s, %s\n", BINOP_SIMPLE_INSTRS[s->stmtAssign.to->exprBinOp.operator], xop(cg->tlc, s->stmtAssign.what), xop(cg->tlc, s->stmtAssign.to->exprBinOp.operands[1])); - } else if(s->stmtAssign.what->nodeKind == AST_EXPR_VAR && s->stmtAssign.to->nodeKind == AST_EXPR_BINARY_OP && s->stmtAssign.to->exprBinOp.operator == BINOP_ADD && s->stmtAssign.to->exprBinOp.operands[0]->nodeKind == AST_EXPR_VAR && s->stmtAssign.to->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR && s->stmtAssign.to->exprBinOp.operands[0]->exprVar.thing->kind == SCOPEITEM_VAR && s->stmtAssign.to->exprBinOp.operands[1]->exprVar.thing->kind == SCOPEITEM_VAR) { + } else if(x86_is_lea(s)) { printf("lea %s, [%s + %s]\n", - xv(s->stmtAssign.what->exprVar.thing), - xv(s->stmtAssign.to->exprBinOp.operands[0]->exprVar.thing), - xv(s->stmtAssign.to->exprBinOp.operands[1]->exprVar.thing)); + xop(cg->tlc, s->stmtAssign.what), + xop_strip_size(xop(cg->tlc, s->stmtAssign.to->exprBinOp.operands[0])), + xop_strip_size(xop(cg->tlc, s->stmtAssign.to->exprBinOp.operands[1]))); } else if(s->stmtAssign.what->nodeKind == AST_EXPR_VAR && s->stmtAssign.to->nodeKind == AST_EXPR_BINARY_OP && s->stmtAssign.to->exprBinOp.operator == BINOP_ADD && s->stmtAssign.to->exprBinOp.operands[0]->nodeKind == AST_EXPR_UNARY_OP && s->stmtAssign.to->exprBinOp.operands[0]->exprUnOp.operator == UNOP_REF && s->stmtAssign.to->exprBinOp.operands[0]->exprUnOp.operand->nodeKind == AST_EXPR_VAR && s->stmtAssign.to->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR && s->stmtAssign.to->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->kind == SCOPEITEM_SYMBOL && s->stmtAssign.to->exprBinOp.operands[1]->exprVar.thing->kind == SCOPEITEM_VAR) { diff --git a/src/x86/dumberdowner.c b/src/x86/dumberdowner.c index 6958d39..c8e214b 100644 --- a/src/x86/dumberdowner.c +++ b/src/x86/dumberdowner.c @@ -321,21 +321,25 @@ static void dumben_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST * // a = b // a = a op c - AST *assign2 = calloc(1, sizeof(ASTStmtAssign)); - assign2->nodeKind = AST_STMT_ASSIGN; - assign2->stmtAssign.what = ast_deep_copy(s->stmtAssign.what); - assign2->stmtAssign.to = s->stmtAssign.to->exprBinOp.operands[0]; - - if(stmtPrev) { - stmtPrev->statement.next = assign2; + if(x86_is_lea(s)) { + // We do the lea trick in cg.c } else { - chu->chunk.statementFirst = assign2; + AST *assign2 = calloc(1, sizeof(ASTStmtAssign)); + assign2->nodeKind = AST_STMT_ASSIGN; + assign2->stmtAssign.what = ast_deep_copy(s->stmtAssign.what); + assign2->stmtAssign.to = s->stmtAssign.to->exprBinOp.operands[0]; + + if(stmtPrev) { + stmtPrev->statement.next = assign2; + } else { + chu->chunk.statementFirst = assign2; + } + assign2->statement.next = s; + + s->stmtAssign.to->exprBinOp.operands[0] = ast_deep_copy(s->stmtAssign.what); + + this->effective = 1; } - assign2->statement.next = s; - - s->stmtAssign.to->exprBinOp.operands[0] = ast_deep_copy(s->stmtAssign.what); - - this->effective = 1; } else if(s->stmtAssign.to->nodeKind == AST_EXPR_BINARY_OP && !is_xop(s->stmtAssign.to->exprBinOp.operands[0])) { s->stmtAssign.to->exprBinOp.operands[0] = xopify(tlc, chu, stmtPrev, s, s->stmtAssign.to->exprBinOp.operands[0]); this->effective = 1;