Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander.nutz committed Nov 19, 2024
1 parent 34b200d commit f7555f8
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 139 deletions.
87 changes: 40 additions & 47 deletions cg/x86_stupid/cg.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ static char widthToWidthWidth(char width) {
}
return 16;
}
return widthToWidthWidthLut[width];
return widthToWidthWidthLut[(int) width];
}

static char widthToWidthIdx(char width) {
Expand Down Expand Up @@ -211,7 +211,7 @@ static char widthToWidthIdx(char width) {
return 4;
}

return lut[width];
return lut[(int) width];
}

static const char * widthWidthToASM[] = {
Expand Down Expand Up @@ -262,26 +262,26 @@ static void emit(Location* loc, FILE* out) {
fprintf(out, "%zu", loc->v.imm.bits);
break;

case LOC_MEM: {
char ww = widthToWidthWidth(loc->bytesWidth);
const char * str = widthWidthToASM[ww];
fputs(str, out);
fputs(" [", out);
emit(loc->v.mem.address, out);
fputs("]", out);
} break;
case LOC_MEM: {
char ww = widthToWidthWidth(loc->bytesWidth);
const char * str = widthWidthToASM[(int) ww];
fputs(str, out);
fputs(" [", out);
emit(loc->v.mem.address, out);
fputs("]", out);
} break;

case LOC_REG:
fputs(RegLut[loc->v.reg.id]->name[widthToWidthIdx(loc->bytesWidth)], out);
break;
fputs(RegLut[loc->v.reg.id]->name[(int) widthToWidthIdx(loc->bytesWidth)], out);
break;

case LOC_LABEL:
fputs(loc->v.label.label, out);
break;
fputs(loc->v.label.label, out);
break;

case LOC_INVALID:
assert(false);
break;
assert(false);
break;
}
}

Expand Down Expand Up @@ -691,16 +691,15 @@ static Location* as_loc(size_t width, vx_IrValue val) {
}
}

static void emit_call_arg_load(vx_IrOp* callOp, FILE* file) {
static void emit_call_arg_load(vx_CU* cu, vx_IrOp* callOp, FILE* file) {
assert(callOp->args_len <= 6);

vx_IrValue fn = *vx_IrOp_param(callOp, VX_IR_NAME_ADDR);

vx_IrTypeRef type = vx_IrValue_type(callOp->parent, fn);
assert(type.ptr);
assert(type.ptr->kind == VX_IR_TYPE_FUNC);
vx_IrTypeFunc fnType = type.ptr->func;
vx_IrTypeRef_drop(type);
vx_IrType* type = vx_IrValue_type(cu, callOp->parent, fn);
assert(type);
assert(type->kind == VX_IR_TYPE_FUNC);
vx_IrTypeFunc fnType = type->func;

char regs[6] = { REG_RDI.id, REG_RSI.id, REG_RDX.id, REG_RCX.id, REG_R8.id, REG_R9.id };

Expand Down Expand Up @@ -848,7 +847,7 @@ static void emiti_ret(vx_IrBlock* block, vx_IrValue* values, FILE* out) {
fputs("ret\n", out);
}

static vx_IrOp* emiti(vx_IrBlock* block, vx_IrOp *prev, vx_IrOp* op, FILE* file) {
static vx_IrOp* emiti(vx_CU* cu, vx_IrBlock* block, vx_IrOp *prev, vx_IrOp* op, FILE* file) {
switch (op->id) {
case VX_IR_OP_RETURN:
{
Expand Down Expand Up @@ -883,9 +882,8 @@ static vx_IrOp* emiti(vx_IrBlock* block, vx_IrOp *prev, vx_IrOp* op, FILE* file)
*dest = LocReg(dest->bytesWidth, XMM_SCRATCH_REG1);
}

vx_IrTypeRef ty = vx_IrValue_type(block, val);
Location* val_loc = as_loc(vx_IrType_size(ty.ptr), val);
vx_IrTypeRef_drop(ty);
vx_IrType* ty = vx_IrValue_type(cu, block, val);
Location* val_loc = as_loc(vx_IrType_size(ty), val);

Location* src = val_loc;
if (val_loc->type != LOC_REG) {
Expand Down Expand Up @@ -960,19 +958,17 @@ static vx_IrOp* emiti(vx_IrBlock* block, vx_IrOp *prev, vx_IrOp* op, FILE* file)
{
vx_IrValue addrV = *vx_IrOp_param(op, VX_IR_NAME_ADDR);
vx_IrValue valV = *vx_IrOp_param(op, VX_IR_NAME_VALUE);
vx_IrTypeRef type = vx_IrValue_type(block, valV);
assert(type.ptr);
vx_IrType* type = vx_IrValue_type(cu, block, valV);
assert(type);

Location* addr = as_loc(PTRSIZE, addrV);
Location* addr_real = start_as_primitive(addr, file);

Location* val = as_loc(vx_IrType_size(type.ptr), valV);
Location* val = as_loc(vx_IrType_size(type), valV);
Location* mem = gen_mem_var(val->bytesWidth, addr_real);
emiti_move(val, mem, false, file);

end_as_primitive(addr_real, addr, file);

vx_IrTypeRef_drop(type);
} break;

case VX_IR_OP_PLACE: // "var"
Expand Down Expand Up @@ -1058,10 +1054,9 @@ static vx_IrOp* emiti(vx_IrBlock* block, vx_IrOp *prev, vx_IrOp* op, FILE* file)
}

case VX_IR_OP_STORE_EA: {
vx_IrTypeRef valTy = vx_IrValue_type(block, *vx_IrOp_param(op, VX_IR_NAME_VALUE));
size_t bytes = vx_IrType_size(valTy.ptr);
vx_IrType* valTy = vx_IrValue_type(cu, block, *vx_IrOp_param(op, VX_IR_NAME_VALUE));
size_t bytes = vx_IrType_size(valTy);
Location* val = as_loc(bytes, *vx_IrOp_param(op, VX_IR_NAME_VALUE));
vx_IrTypeRef_drop(valTy);
Location* mem = fastalloc(sizeof(Location));
*mem = LocMem(bytes, ea);
emiti_move(val, mem, false, file);
Expand Down Expand Up @@ -1244,7 +1239,7 @@ static vx_IrOp* emiti(vx_IrBlock* block, vx_IrOp *prev, vx_IrOp* op, FILE* file)
vx_IrValue addr = *vx_IrOp_param(op->next, VX_IR_NAME_ADDR);
vx_IrValue v = *vx_IrOp_param(op->next, VX_IR_NAME_COND);
if (v.type == VX_IR_VAL_VAR && v.var == ov) {
emit_call_arg_load(op->next, file);
emit_call_arg_load(cu, op->next, file);
emiti_jump_cond(as_loc(PTRSIZE, addr), cc, file);
emit_call_ret_store(op->next, file);
return op->next->next;
Expand Down Expand Up @@ -1272,7 +1267,7 @@ static vx_IrOp* emiti(vx_IrBlock* block, vx_IrOp *prev, vx_IrOp* op, FILE* file)
vx_IrValue cond = *vx_IrOp_param(op, VX_IR_NAME_COND);
Location* loc = as_loc(1, cond);
emiti_cmp0(loc, file);
emit_call_arg_load(op, file);
emit_call_arg_load(cu, op, file);
emiti_jump_cond(as_loc(PTRSIZE, addr), "nz", file);
} break;

Expand All @@ -1299,7 +1294,7 @@ static vx_IrOp* emiti(vx_IrBlock* block, vx_IrOp *prev, vx_IrOp* op, FILE* file)
case VX_IR_OP_CALL: // "addr": int / fnref
{
vx_IrValue addr = *vx_IrOp_param(op, VX_IR_NAME_ADDR);
emit_call_arg_load(op, file);
emit_call_arg_load(cu, op, file);
emiti_call(as_loc(PTRSIZE, addr), file);
emit_call_ret_store(op, file);
} break;
Expand All @@ -1308,7 +1303,7 @@ static vx_IrOp* emiti(vx_IrBlock* block, vx_IrOp *prev, vx_IrOp* op, FILE* file)
{
assert(!needEpilog);
vx_IrValue addr = *vx_IrOp_param(op, VX_IR_NAME_ADDR);
emit_call_arg_load(op, file);
emit_call_arg_load(cu, op, file);
emiti_jump(as_loc(PTRSIZE, addr), file);
} break;

Expand Down Expand Up @@ -1385,11 +1380,11 @@ void vx_cg_x86stupid_gen(vx_CU* cu, vx_IrBlock* block, FILE* out) {
for (vx_IrOp* op = block->first; op != NULL; op = op->next) {
if (op->id == VX_IR_OP_CALL || op->id == VX_IR_OP_TAILCALL || op->id == VX_IR_OP_CONDTAILCALL) {
vx_IrValue addr = *vx_IrOp_param(op, VX_IR_NAME_ADDR);
vx_IrTypeRef ty = vx_IrValue_type(block, addr);
assert(ty.ptr != NULL);
assert(ty.ptr->kind == VX_IR_TYPE_FUNC);
vx_IrType* ty = vx_IrValue_type(cu, block, addr);
assert(ty != NULL);
assert(ty->kind == VX_IR_TYPE_FUNC);

vx_IrTypeFunc fn = ty.ptr->func;
vx_IrTypeFunc fn = ty->func;

size_t usedInt = 0;
size_t usedXmm = 0;
Expand All @@ -1407,8 +1402,6 @@ void vx_cg_x86stupid_gen(vx_CU* cu, vx_IrBlock* block, FILE* out) {
anyCalledIntArgsCount = usedInt;
if (usedXmm > anyCalledXmmArgsCount)
anyCalledXmmArgsCount = usedXmm;

vx_IrTypeRef_drop(ty);
}
}
XMM_SCRATCH_REG1 = anyCalledXmmArgsCount;
Expand Down Expand Up @@ -1678,7 +1671,7 @@ void vx_cg_x86stupid_gen(vx_CU* cu, vx_IrBlock* block, FILE* out) {
vx_IrOp* prev = NULL;

while (op != NULL) {
vx_IrOp* new = emiti(block, prev, op, out);
vx_IrOp* new = emiti(cu, block, prev, op, out);
prev = op;
op = new;
}
Expand Down Expand Up @@ -1721,8 +1714,8 @@ static void end_scratch_reg(Location* loc, FILE* out) {
assert(loc->type == LOC_REG);

char regId = loc->v.reg.id;
assert(RegLut[regId]->stored == loc);
RegLut[regId]->stored = NULL;
assert(RegLut[(int) regId]->stored == loc);
RegLut[(int) regId]->stored = NULL;

loc->type = LOC_INVALID;
}
Expand Down
46 changes: 46 additions & 0 deletions common/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,44 @@ int vx_Target_parse(vx_Target* dest, const char * str)
return 0;
}

/** these functions are used by targets where a pointer is a integer */
#define intlikeptr(name, tgty, ptrtotypecache, ptrwbytes, ptralignbytes) \
static vx_IrType* name##_get_ptr_ty(vx_CU* cu, vx_IrBlock* root) { \
if ( ( ((tgty) cu->info.tg) ptrtotypecache) != NULL) return ( ((tgty) cu->info.tg) ptrtotypecache); \
vx_IrType* ptr = vx_IrType_heap(); \
( ((tgty) cu->info.tg) ptrtotypecache) = ptr; \
ptr->debugName = "ptr"; \
ptr->kind = VX_IR_TYPE_KIND_BASE; \
ptr->base = (vx_IrTypeBase) { \
.sizeless = false, .size = (ptrwbytes), .align = (ptralignbytes), \
.isfloat = false, \
}; \
return ptr;\
} \
static vx_IrValue name##_get_null_ptr(vx_CU* cu, vx_IrBlock* dest) { \
return VX_IR_VALUE_IMM_INT(0); \
} \
static void name##_lower_ptr_math(vx_CU* cu, vx_IrOp* op) { /* no-op */ } \
static vx_IrValue name##_cast_ptr_to_human(vx_CU* cu, vx_IrBlock* block, vx_IrVar ptr) { \
return VX_IR_VALUE_VAR(ptr); \
} \
static void name##_intlikeptr(vx_TargetInfo* dest) { \
dest->get_ptr_ty = name##_get_ptr_ty; \
dest->get_null_ptr = name##_get_null_ptr; \
dest->lower_ptr_math = name##_lower_ptr_math; \
dest->cast_ptr_to_human = name##_cast_ptr_to_human; \
}

typedef struct {
vx_IrType* ptrty_cache;
} x86;
intlikeptr(x86, x86*,->ptrty_cache, 8, 4);

typedef struct {
vx_IrType* ptrty_cache;
} etca;
intlikeptr(etca, etca*,->ptrty_cache, 4, 2);

static bool x86_need_move_ret_to_arg(vx_CU* cu, vx_IrBlock* block, size_t ret_id)
{
// TODO
Expand All @@ -54,22 +92,30 @@ static bool etca_need_move_ret_to_arg(vx_CU* cu, vx_IrBlock* block, size_t ret_i

void vx_Target_info(vx_TargetInfo* dest, vx_Target const* target)
{
#define set_tg(ty) \
dest->tg = fastalloc(sizeof(ty)); \
memset(dest->tg, 0, sizeof(ty));

memset(dest, 0, sizeof(vx_TargetInfo));
switch (target->arch)
{
case vx_TargetArch_X86_64:
{
set_tg(x86);
dest->cmov_opt = true; // TODO: target->flags.x86[vx_Target_X86_CMOV];
dest->tailcall_opt = true;
dest->ea_opt = true;
dest->need_move_ret_to_arg = x86_need_move_ret_to_arg;
x86_intlikeptr(dest);
} break;

case vx_TargetArch_ETCA:
{
set_tg(etca);
dest->cmov_opt = target->flags.etca[vx_Target_ETCA_condExec];
dest->tailcall_opt = true;
dest->need_move_ret_to_arg = etca_need_move_ret_to_arg;
etca_intlikeptr(dest);
} break;

// add target
Expand Down
49 changes: 26 additions & 23 deletions ir/ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,28 +138,30 @@ void vx_IrType_free(vx_IrType *ty) {
}
}

vx_IrTypeRef vx_IrValue_type(vx_IrBlock* root, vx_IrValue value) {
switch (value.type) {
vx_IrType* vx_IrValue_type(vx_CU* cu, vx_IrBlock* root, vx_IrValue value) {
switch (value.type)
{
case VX_IR_VAL_IMM_INT:
case VX_IR_VAL_IMM_FLT:
case VX_IR_VAL_UNINIT:
return (vx_IrTypeRef) { .ptr = value.no_read_rt_type, .shouldFree = false };
return value.no_read_rt_type;

case VX_IR_VAL_ID:
return vx_ptrType(root);
return cu->info.get_ptr_ty(cu, root);

default:
assert(false);
case VX_IR_VAL_TYPE:
case VX_IR_VAL_TYPE:
case VX_IR_VAL_BLOCK:
return (vx_IrTypeRef) { .ptr = NULL, .shouldFree = false };
return NULL;

case VX_IR_VAL_BLOCKREF:
return vx_IrBlock_type(value.block);

case VX_IR_VAL_VAR:
return (vx_IrTypeRef) { .ptr = vx_IrBlock_typeofVar(root, value.var), .shouldFree = false };
}
return vx_IrBlock_typeofVar(root, value.var);

default:
assert(false);
}
}

void vx_IrOp_warn(vx_IrOp *op, const char *optMsg0, const char *optMsg1) {
Expand Down Expand Up @@ -253,25 +255,26 @@ void vx_IrBlock_appendLabelOpPredefined(vx_IrBlock *block, size_t label_id) {
root->as_root.labels[label_id].decl = label_decl;
}

vx_IrTypeRef vx_IrBlock_type(vx_IrBlock* block) {
// TODO: multiple rets
vx_IrType *ret = block->outs_len == 1 ? vx_IrBlock_typeofVar(block, block->outs[0])
: NULL;
vx_IrType* vx_IrBlock_type(vx_IrBlock* block) {
vx_IrType *type = fastalloc(sizeof(vx_IrType));
assert(type);
type->kind = VX_IR_TYPE_FUNC;

vx_IrType **args = malloc(sizeof(vx_IrType*) * block->ins_len);
vx_IrType **args = fastalloc(sizeof(vx_IrType*) * block->ins_len);
assert(args);
for (size_t i = 0; i < block->ins_len; i ++) {
for (size_t i = 0; i < block->ins_len; i ++)
args[i] = block->ins[i].type;
}

vx_IrType *type = malloc(sizeof(vx_IrType));
assert(type);
type->kind = VX_IR_TYPE_FUNC;
type->func.nullableReturnType = ret;
type->func.args_len = block->ins_len;
type->func.args = args;

return (vx_IrTypeRef) { .ptr = type, .shouldFree = true };
vx_IrType **rets = fastalloc(sizeof(vx_IrType*) * block->outs_len);
assert(rets);
for (size_t i = 0; i < block->outs_len; i ++)
rets[i] = vx_IrBlock_typeofVar(block, block->outs[i]);
type->func.rets_len = block->outs_len;
type->func.rets = rets;

return type;
}

void vx_IrOp_updateParent(vx_IrOp* op, vx_IrBlock* to)
Expand Down
Loading

0 comments on commit f7555f8

Please sign in to comment.