Skip to content

Commit

Permalink
Minor fix
Browse files Browse the repository at this point in the history
  • Loading branch information
tyfkda committed Aug 24, 2023
1 parent 8dd9294 commit 635b406
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 83 deletions.
77 changes: 34 additions & 43 deletions src/cc/arch/aarch64/emit_code.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,19 +391,19 @@ static bool is_asm(Stmt *stmt) {
}

static void put_args_to_stack(Function *func) {
static const char *kReg32s[] = {W0, W1, W2, W3, W4, W5, W6, W7};
static const char *kReg64s[] = {X0, X1, X2, X3, X4, X5, X6, X7};
static const char **kRegTable[] = {kReg32s, kReg32s, kReg32s, kReg64s};
const char *kFReg32s[] = {S0, S1, S2, S3, S4, S5, S6, S7};
const char *kFReg64s[] = {D0, D1, D2, D3, D4, D5, D6, D7};
static const char *kRegParam32s[] = {W0, W1, W2, W3, W4, W5, W6, W7};
static const char *kRegParam64s[] = {X0, X1, X2, X3, X4, X5, X6, X7};
static const char **kRegParamTable[] = {kRegParam32s, kRegParam32s, kRegParam32s, kRegParam64s};
const char *kFRegParam32s[] = {S0, S1, S2, S3, S4, S5, S6, S7};
const char *kFRegParam64s[] = {D0, D1, D2, D3, D4, D5, D6, D7};
static const int kPow2Table[] = {-1, 0, 1, -1, 2, -1, -1, -1, 3};
#define kPow2TableSize ((int)(sizeof(kPow2Table) / sizeof(*kPow2Table)))

int arg_index = 0;
if (is_stack_param(func->type->func.ret)) {
// Received as a pointer at the first parameter.
const int pow = 3;
const char *src = kRegTable[pow][0];
const char *src = kRegParamTable[pow][0];
int offset = ((FuncBackend*)func->extra)->retval->frame.offset;
const char *dst = IMMEDIATE_OFFSET(FP, offset);
STR(src, dst);
Expand Down Expand Up @@ -432,54 +432,44 @@ static void put_args_to_stack(Function *func) {

if (is_flonum(type)) {
if (farg_index < MAX_FREG_ARGS) {
switch (type->flonum.kind) {
case FL_FLOAT: STR(kFReg32s[farg_index], IMMEDIATE_OFFSET(FP, offset)); break;
case FL_DOUBLE: STR(kFReg64s[farg_index], IMMEDIATE_OFFSET(FP, offset)); break;
default: assert(false); break;
}
const char *src = type->flonum.kind == FL_DOUBLE ? kFRegParam64s[farg_index] : kFRegParam32s[farg_index];
assert(offset != 0);
STR(src, IMMEDIATE_OFFSET(FP, offset));
++farg_index;
}
continue;
}

switch (type->kind) {
case TY_FIXNUM:
case TY_PTR:
break;
default: assert(false); break;
}

if (arg_index < MAX_REG_ARGS) {
int size = type_size(type);
assert(0 <= size && size < kPow2TableSize && kPow2Table[size] >= 0);
int pow = kPow2Table[size];
const char *src = kRegTable[pow][arg_index];
assert(offset < 0);
const char *dst;
if (offset >= -256) {
dst = IMMEDIATE_OFFSET(FP, offset);
} else {
mov_immediate(X9, offset, true, false); // x9 broken.
dst = REG_OFFSET(FP, X9, NULL);
}
switch (pow) {
case 0: STRB(src, dst); break;
case 1: STRH(src, dst); break;
case 2: case 3: STR(src, dst); break;
default: assert(false); break;
} else {
if (arg_index < MAX_REG_ARGS) {
int size = type_size(type);
assert(0 <= size && size < kPow2TableSize && kPow2Table[size] >= 0);
int pow = kPow2Table[size];
const char *src = kRegParamTable[pow][arg_index];
assert(offset < 0);
const char *dst;
if (offset >= -256) {
dst = IMMEDIATE_OFFSET(FP, offset);
} else {
mov_immediate(X9, offset, true, false); // x9 broken.
dst = REG_OFFSET(FP, X9, NULL);
}
switch (pow) {
case 0: STRB(src, dst); break;
case 1: STRH(src, dst); break;
case 2: case 3: STR(src, dst); break;
default: assert(false); break;
}
++arg_index;
}
++arg_index;
}
}

if (vaargs) {
for (int i = arg_index; i < MAX_REG_ARGS; ++i) {
int offset = (i - MAX_REG_ARGS - MAX_FREG_ARGS) * WORD_SIZE;
STR(kReg64s[i], IMMEDIATE_OFFSET(FP, offset));
STR(kRegParam64s[i], IMMEDIATE_OFFSET(FP, offset));
}
for (int i = farg_index; i < MAX_FREG_ARGS; ++i) {
int offset = (i - MAX_FREG_ARGS) * WORD_SIZE;
STR(kFReg64s[i], IMMEDIATE_OFFSET(FP, offset));
STR(kFRegParam64s[i], IMMEDIATE_OFFSET(FP, offset));
}
}
}
Expand Down Expand Up @@ -539,10 +529,11 @@ static void emit_defun(Function *func) {
mov_immediate(value = X9, frame_size, true, false); // x9 broken
SUB(SP, SP, value);
}
put_args_to_stack(func);

// Callee save.
callee_saved_count = push_callee_save_regs(fnbe->ra->used_reg_bits, fnbe->ra->used_freg_bits);

put_args_to_stack(func);
}

emit_bb_irs(fnbe->bbcon);
Expand Down
54 changes: 24 additions & 30 deletions src/cc/arch/x64/emit_code.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,20 +393,20 @@ static bool is_asm(Stmt *stmt) {
}

static void put_args_to_stack(Function *func) {
static const char *kReg8s[] = {DIL, SIL, DL, CL, R8B, R9B};
static const char *kReg16s[] = {DI, SI, DX, CX, R8W, R9W};
static const char *kReg32s[] = {EDI, ESI, EDX, ECX, R8D, R9D};
static const char *kReg64s[] = {RDI, RSI, RDX, RCX, R8, R9};
static const char **kRegTable[] = {kReg8s, kReg16s, kReg32s, kReg64s};
static const char *kFReg64s[] = {XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7};
static const char *kRegParam8s[] = {DIL, SIL, DL, CL, R8B, R9B};
static const char *kRegParam16s[] = {DI, SI, DX, CX, R8W, R9W};
static const char *kRegParam32s[] = {EDI, ESI, EDX, ECX, R8D, R9D};
static const char *kRegParam64s[] = {RDI, RSI, RDX, RCX, R8, R9};
static const char **kRegParamTable[] = {kRegParam8s, kRegParam16s, kRegParam32s, kRegParam64s};
static const char *kFRegParam64s[] = {XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7};
static const int kPow2Table[] = {-1, 0, 1, -1, 2, -1, -1, -1, 3};
#define kPow2TableSize ((int)(sizeof(kPow2Table) / sizeof(*kPow2Table)))

int arg_index = 0;
if (is_stack_param(func->type->func.ret)) {
// Received as a pointer at the first parameter.
const int pow = 3;
const char *src = kRegTable[pow][0];
const char *src = kRegParamTable[pow][0];
int offset = ((FuncBackend*)func->extra)->retval->frame.offset;
const char *dst = OFFSET_INDIRECT(offset, RBP, NULL, 1);
MOV(src, dst);
Expand All @@ -430,41 +430,35 @@ static void put_args_to_stack(Function *func) {

if (is_flonum(type)) {
if (farg_index < MAX_FREG_ARGS) {
const char *src = kFRegParam64s[farg_index];
assert(offset != 0);
switch (type->flonum.kind) {
case FL_FLOAT: MOVSS(kFReg64s[farg_index], OFFSET_INDIRECT(offset, RBP, NULL, 1)); break;
case FL_DOUBLE: MOVSD(kFReg64s[farg_index], OFFSET_INDIRECT(offset, RBP, NULL, 1)); break;
case FL_FLOAT: MOVSS(src, OFFSET_INDIRECT(offset, RBP, NULL, 1)); break;
case FL_DOUBLE: MOVSD(src, OFFSET_INDIRECT(offset, RBP, NULL, 1)); break;
default: assert(false); break;
}
++farg_index;
}
continue;
}

switch (type->kind) {
case TY_FIXNUM:
case TY_PTR:
break;
default: assert(false); break;
}

if (arg_index < MAX_REG_ARGS) {
int size = type_size(type);
assert(0 <= size && size < kPow2TableSize && kPow2Table[size] >= 0);
int pow = kPow2Table[size];
const char *src = kRegTable[pow][arg_index];
MOV(src, OFFSET_INDIRECT(offset, RBP, NULL, 1));
++arg_index;
} else {
if (arg_index < MAX_REG_ARGS) {
int size = type_size(type);
assert(0 <= size && size < kPow2TableSize && kPow2Table[size] >= 0);
int pow = kPow2Table[size];
const char *src = kRegParamTable[pow][arg_index];
MOV(src, OFFSET_INDIRECT(offset, RBP, NULL, 1));
++arg_index;
}
}
}

if (func->type->func.vaargs) {
for (int i = arg_index; i < MAX_REG_ARGS; ++i) {
int offset = (i - MAX_REG_ARGS - MAX_FREG_ARGS) * WORD_SIZE;
MOV(kReg64s[i], OFFSET_INDIRECT(offset, RBP, NULL, 1));
MOV(kRegParam64s[i], OFFSET_INDIRECT(offset, RBP, NULL, 1));
}
for (int i = farg_index; i < MAX_FREG_ARGS; ++i) {
int offset = (i - MAX_FREG_ARGS) * WORD_SIZE;
MOVSD(kFReg64s[i], OFFSET_INDIRECT(offset, RBP, NULL, 1));
MOVSD(kFRegParam64s[i], OFFSET_INDIRECT(offset, RBP, NULL, 1));
}
}
}
Expand Down Expand Up @@ -525,10 +519,10 @@ static void emit_defun(Function *func) {
stackpos += frame_size;
}

put_args_to_stack(func);

// Callee save.
push_callee_save_regs(fnbe->ra->used_reg_bits, fnbe->ra->used_freg_bits);

put_args_to_stack(func);
}

emit_bb_irs(fnbe->bbcon);
Expand Down
18 changes: 13 additions & 5 deletions src/cc/backend/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ static VarInfo *prepare_retvar(Function *func) {
Scope *top_scope = func->scopes->data[0];
VarInfo *varinfo = scope_add(top_scope, retval_name, retptrtype, 0);
VReg *vreg = add_new_reg(varinfo->type, VRF_PARAM);
vreg->param_index = 0;
vreg->reg_param_index = 0;
varinfo->local.vreg = vreg;
FuncBackend *fnbe = func->extra;
fnbe->retval = vreg;
Expand Down Expand Up @@ -105,20 +105,27 @@ static void alloc_variable_registers(Function *func) {
}

// Handle if return value is on the stack.
int param_index_offset = 0;
int iregindex = 0;
if (is_stack_param(func->type->func.ret)) {
prepare_retvar(func);
++param_index_offset;
++iregindex;
}

// Add flag to parameters.
int fregindex = 0;
if (func->type->func.params != NULL) {
for (int i = 0; i < func->type->func.params->len; ++i) {
VarInfo *varinfo = func->type->func.params->data[i];
VReg *vreg = varinfo->local.vreg;
if (vreg != NULL) {
vreg->flag |= VRF_PARAM;
vreg->param_index = i + param_index_offset;
if (vreg->vtype->flag & VRTF_FLONUM) {
if (fregindex < MAX_FREG_ARGS)
vreg->reg_param_index = fregindex++;
} else {
if (iregindex < MAX_REG_ARGS)
vreg->reg_param_index = iregindex++;
}
}
}
}
Expand Down Expand Up @@ -591,13 +598,14 @@ static void prepare_register_allocation(Function *func) {
int offset = DEFAULT_OFFSET;
for (int i = 0; i < func->type->func.params->len; ++i) {
VarInfo *varinfo = func->type->func.params->data[i];
if (!is_prim_type(varinfo->type)) {
if (is_stack_param(varinfo->type)) {
// stack parameters
FrameInfo *fi = varinfo->local.frameinfo;
fi->offset = offset = ALIGN(offset, align_size(varinfo->type));
offset += ALIGN(type_size(varinfo->type), WORD_SIZE);
continue;
}
assert(is_prim_type(varinfo->type));

VReg *vreg = varinfo->local.vreg;
assert(vreg != NULL);
Expand Down
2 changes: 1 addition & 1 deletion src/cc/backend/ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ typedef struct VReg {
int virt; // Virtual reg no.
int phys; // Physical reg no.
int flag;
int param_index; // Function parameter index: -1=not a param
int reg_param_index; // Index of function parameter through register: -1=not a register param.
int64_t fixnum; // Constant value.
FrameInfo frame; // FrameInfo for spilled register.
} VReg;
Expand Down
8 changes: 4 additions & 4 deletions src/cc/backend/regalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ VReg *reg_alloc_spawn(RegAlloc *ra, const VRegType *vtype, int flag) {
vreg->fixnum = 0;
vreg->vtype = vtype;
vreg->flag = flag;
vreg->param_index = -1;
vreg->reg_param_index = -1;
vreg->frame.offset = 0;

vec_push(ra->vregs, vreg);
Expand Down Expand Up @@ -256,14 +256,14 @@ static void linear_scan_register_allocation(RegAlloc *ra, LiveInterval **sorted_
} else {
int regno = -1;
for (int j = start_index; j < prsp->phys_max; ++j) {
if (!(prsp->using_bits & (1 << j))) {
if (!(prsp->using_bits & (1UL << j))) {
regno = j;
break;
}
}
assert(regno >= 0);
li->phys = regno;
prsp->using_bits |= 1 << regno;
prsp->using_bits |= 1UL << regno;

insert_active(prsp->active, prsp->active_count, li);
++prsp->active_count;
Expand Down Expand Up @@ -394,7 +394,7 @@ void alloc_physical_registers(RegAlloc *ra, BBContainer *bbcon) {
}

// Force function parameter spilled.
if (vreg->param_index >= 0) {
if (vreg->flag & VRF_PARAM) {
spill_vreg(vreg);
li->start = 0;
li->state = LI_SPILL;
Expand Down

0 comments on commit 635b406

Please sign in to comment.