From 273e6d1058673784b86ee4ad260fa3d666da5f43 Mon Sep 17 00:00:00 2001 From: Mid <> Date: Sun, 14 Sep 2025 10:44:08 +0300 Subject: [PATCH] Add ugpr and umem types --- examples/ListDLC.nct | 4 ++-- examples/UserListDLC.nct | 16 ++++++++-------- examples/funcdefs.nct | 2 +- src/types.c | 6 ++++++ src/x86/arch.h | 34 ++++++++++++++++++++++++++++++---- src/x86/cg.c | 2 +- src/x86/dumberdowner.c | 30 +++++++++++++++++++++++++++--- 7 files changed, 75 insertions(+), 19 deletions(-) diff --git a/examples/ListDLC.nct b/examples/ListDLC.nct index 10e4e74..437d964 100644 --- a/examples/ListDLC.nct +++ b/examples/ListDLC.nct @@ -2,7 +2,7 @@ * ListDLC: Dynamic, Linear growth, C-managed */ -extern u8*(u8*, u32) realloc; +extern u8*(u8*, ugpr) realloc; record ListDLC[T, S; growth] { S capacity; @@ -31,7 +31,7 @@ ListDLC_remove: [T, S; growth]u0(ListDLC[T, S; growth]* this, S index) -> { ListDLC_add: [T, S; growth]u0(ListDLC[T, S; growth]* this, T value) -> { if((*this).size == (*this).capacity) { - u32 newcap = (*this).capacity + growth; + S newcap = (*this).capacity + growth; (*this).capacity = newcap; (*this).data = realloc((*this).data, newcap * @sizeof T); } diff --git a/examples/UserListDLC.nct b/examples/UserListDLC.nct index d8c842a..18eccda 100644 --- a/examples/UserListDLC.nct +++ b/examples/UserListDLC.nct @@ -2,16 +2,16 @@ use ListDLC; @section(".text"); -@instantiate ListDLC_remove[u32, u32; 9]; -@instantiate ListDLC_add[u32, u32; 9]; +@instantiate ListDLC_remove[u16, u16; 9]; +@instantiate ListDLC_add[u16, u16; 9]; main: u0() -> { - ListDLC[u32, u32; 9] list; - ListDLC_add[u32, u32; 9](&list, 1234); - ListDLC_add[u32, u32; 9](&list, 4321); - ListDLC_add[u32, u32; 9](&list, 7777); - ListDLC_add[u32, u32; 9](&list, 6969); - ListDLC_remove[u32, u32; 9](&list, 1); + ListDLC[u16, u16; 9] list; + ListDLC_add[u16, u16; 9](&list, 1234); + ListDLC_add[u16, u16; 9](&list, 4321); + ListDLC_add[u16, u16; 9](&list, 7777); + ListDLC_add[u16, u16; 9](&list, 6969); + ListDLC_remove[u16, u16; 9](&list, 1); return; }; diff --git a/examples/funcdefs.nct b/examples/funcdefs.nct index 46bba3f..077dc65 100644 --- a/examples/funcdefs.nct +++ b/examples/funcdefs.nct @@ -1,4 +1,4 @@ -fibonacci: u32(u32 n) -> { +fibonacci: u16(u16 n) -> { if(n <= 1) { return n; } diff --git a/src/types.c b/src/types.c index e6dd79d..759c0d2 100644 --- a/src/types.c +++ b/src/types.c @@ -24,6 +24,12 @@ Type *primitive_parse(const char *src) { } } + if(!strcmp(src, "ugpr")) { + return type_u(8 * arch_gpr_size()); + } else if(!strcmp(src, "umem")) { + return type_u(arch_memory_width()); + } + TypePrimitive *ret = calloc(1, sizeof(*ret)); ret->type = TYPE_TYPE_PRIMITIVE; ret->src = strdup(src); diff --git a/src/x86/arch.h b/src/x86/arch.h index 111038b..221ed8e 100644 --- a/src/x86/arch.h +++ b/src/x86/arch.h @@ -241,9 +241,23 @@ static inline WhysItBad_Huh x86_test_mul(AST *stmtPrev, AST *stmt) { } if(x86_imul_supported()) { - return GUCCI; - } else if(stmt->stmtAssign.to->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) { - return SRC1_IS_BAD_XOP; + if(ast_expression_equal(stmt->stmtAssign.what, stmt->stmtAssign.to->exprBinOp.operands[0])) { + if(is_xop(stmt->stmtAssign.to->exprBinOp.operands[1]) == XOP_NOT_XOP) { + return SRC1_IS_BAD_XOP; + } + return GUCCI; + } else { + if(is_xop(stmt->stmtAssign.to->exprBinOp.operands[0]) == XOP_NOT_XOP) { + return SRC0_IS_BAD_XOP; + } + if(stmt->stmtAssign.to->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) { + return GUCCI; + } + } + } else { + if(stmt->stmtAssign.to->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) { + return SRC1_IS_BAD_XOP; + } } if(is_xop(stmt->stmtAssign.to->exprBinOp.operands[1]) == XOP_NOT_XOP) { @@ -294,6 +308,18 @@ static inline int arch_gpr_size() { return x86_max_gpr_size(); } +static inline int arch_memory_width() { + switch(x86_target()) { + case I086: + case I186: + return 20; + case I286: + return 24; + default: + return 32; + } +} + // lol static inline bool is_reg_b(int cls, int res) { const char *name = REG_CLASSES[cls].rsN[res]; @@ -333,4 +359,4 @@ static inline void reg_cast_to_gpr(int *cls, int *res) { } } -void arch_init(); \ No newline at end of file +void arch_init(); diff --git a/src/x86/cg.c b/src/x86/cg.c index 298af66..78514d1 100644 --- a/src/x86/cg.c +++ b/src/x86/cg.c @@ -412,7 +412,7 @@ void cg_chunk(CGState *cg, AST *a) { assert(s->stmtAssign.what->exprVar.thing->kind == SCOPEITEM_VAR); if(!strcmp(xop(a, s->stmtAssign.what), xop(a, s->stmtAssign.to->exprBinOp.operands[0]))) { - printf("imul %s, %s, %s\n", xop(a, s->stmtAssign.what), xop(a, s->stmtAssign.what), xop(a, s->stmtAssign.to->exprBinOp.operands[1])); + printf("imul %s, %s\n", xop(a, s->stmtAssign.what), xop(a, s->stmtAssign.to->exprBinOp.operands[1])); } else { printf("imul %s, %s, %s\n", xop(a, s->stmtAssign.what), xop(a, s->stmtAssign.to->exprBinOp.operands[0]), xop(a, s->stmtAssign.to->exprBinOp.operands[1])); } diff --git a/src/x86/dumberdowner.c b/src/x86/dumberdowner.c index a0a3e0b..703daee 100644 --- a/src/x86/dumberdowner.c +++ b/src/x86/dumberdowner.c @@ -225,7 +225,7 @@ static void dumben_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST * } else if(s->nodeKind == AST_STMT_RETURN) { - // ret specifically returns in eax always, so it needs to be in a precolored var + // ret returns in eax always, so it needs to be in a precolored var AST *retval = s->stmtReturn.val; if(retval && (!is_xop(retval) || retval->nodeKind == AST_EXPR_PRIMITIVE || (retval->nodeKind == AST_EXPR_VAR && retval->exprVar.thing->kind == SCOPEITEM_VAR && (!retval->exprVar.thing->data.var.precolored || !strchr(REG_CLASSES[retval->exprVar.thing->data.var.registerClass].rsN[retval->exprVar.thing->data.var.color], 'a'))))) { @@ -392,7 +392,19 @@ static void dumben_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST * AST *hihalf = varify(tlc, chu, stmtPrev->statement.next, s, mulhi); - vte_precolor(hihalf->exprVar.thing, REG_CLASS_16_32, 7); + switch(type_size(s->stmtAssign.what->expression.type)) { + case 1: + vte_precolor(hihalf->exprVar.thing, REG_CLASS_8, 6); + break; + case 2: + vte_precolor(hihalf->exprVar.thing, REG_CLASS_16_32, 6); + break; + case 4: + vte_precolor(hihalf->exprVar.thing, REG_CLASS_16_32, 7); + break; + default: + abort(); + } } s->stmtAssign.what = ast_deep_copy(s->stmtAssign.to->exprBinOp.operands[0]); @@ -405,7 +417,19 @@ static void dumben_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST * s->stmtAssign.next = (AST*) redest; - vte_precolor(s->stmtAssign.to->exprBinOp.operands[0]->exprVar.thing, REG_CLASS_16_32, 1); + switch(type_size(s->stmtAssign.what->expression.type)) { + case 1: + vte_precolor(s->stmtAssign.to->exprBinOp.operands[0]->exprVar.thing, REG_CLASS_8, 0); + break; + case 2: + vte_precolor(s->stmtAssign.to->exprBinOp.operands[0]->exprVar.thing, REG_CLASS_16_32, 0); + break; + case 4: + vte_precolor(s->stmtAssign.to->exprBinOp.operands[0]->exprVar.thing, REG_CLASS_16_32, 1); + break; + default: + abort(); + } this->effective = 1; } else assert(because == NOT_AT_ALL_IT || because == GUCCI);