refactor mv

This commit is contained in:
Yaossg 2024-11-30 00:31:33 +08:00
parent 66505c1389
commit 070b878b0c

111
boot.c
View File

@ -653,19 +653,6 @@ void asm_addi(const char* rd, const char* rs, int imm) {
// assembly helpers
// address loaders
// rd must be one of t0, t1, t2
void load_local_address(int rd, int slot_id) {
int offset = slot_id * 8 - 8;
const char* rd_name = reg_name(rd);
if (check_itype_immediate(offset)) {
printf(" addi %s, sp, %d\n", rd_name, offset);
} else {
printf(" li %s, %d\n", rd_name, offset);
printf(" add %s, sp, %s\n", rd_name, rd_name);
}
}
const char* load_op_of_type(int type) {
if (type & TYPE_PTR_MASK) {
return "ld";
@ -686,6 +673,12 @@ const char* store_op_of_type(int type) {
}
}
// address loaders
// rd must be one of t0, t1, t2
void load_local_address(int rd, int slot_id) {
asm_addi(reg_name(rd), "sp", slot_id * 8 - 8);
}
// load a non-trivial register into t0, t1 or t2
// rd must be one of t0, t1, t2
void load(int rd, int reg) {
@ -702,7 +695,7 @@ void load(int rd, int reg) {
}
// store t0 into a non-trivial register
void store_t0(int reg) {
void store(const char* rs, int reg) {
const char* op = store_op_of_type(reg_type[reg]);
if (is_overflow(reg)) {
load_local_address(REG_T2, overflow[reg]);
@ -711,67 +704,65 @@ void store_t0(int reg) {
}
reg = REG_T2;
}
printf(" %s t0, 0(%s) # store non-trivial register\n", op, reg_name(reg));
printf(" %s %s, 0(%s) # store non-trivial register\n", op, rs, reg_name(reg));
}
int is_nontrivial(int reg) {
return is_overflow(reg) || indirection[reg];
}
const char* trivialize(int rs, int t) {
if (is_nontrivial(rs)) {
load(t, rs);
return reg_name(t);
}
return reg_name(rs);
}
void _asm_r(const char* op, int rd, int rs1) {
const char* rd_name = reg_name(rd);
const char* rs1_name = reg_name(rs1);
if (is_nontrivial(rd)) rd_name = "t0";
if (is_nontrivial(rs1)) {
rs1_name = "t0";
load(REG_T0, rs1);
}
if (!(streq(op, "mv") && streq(rd_name, rs1_name)))
printf(" %s %s, %s\n", op, rd_name, rs1_name);
const char* rs1_name = trivialize(rs1, REG_T0);
printf(" %s %s, %s\n", op, rd_name, rs1_name);
if (is_nontrivial(rd)) {
store_t0(rd);
store("t0", rd);
}
}
void asm_mv(int rd, int rs1) {
const char* rs1_name = trivialize(rs1, REG_T0);
if (is_nontrivial(rd)) {
store(rs1_name, rd);
} else {
const char* rd_name = reg_name(rd);
if (!streq(rd_name, rs1_name))
printf(" mv %s, %s\n", rd_name, rs1_name);
}
}
void _asm_rr(const char* op, int rd, int rs1, int rs2) {
const char* rd_name = reg_name(rd);
const char* rs1_name = reg_name(rs1);
const char* rs2_name = reg_name(rs2);
const char* rs1_name = trivialize(rs1, REG_T0);
const char* rs2_name = trivialize(rs2, REG_T1);
if (is_nontrivial(rd)) rd_name = "t0";
if (is_nontrivial(rs1)) {
rs1_name = "t0";
load(REG_T0, rs1);
}
if (is_nontrivial(rs2)) {
rs2_name = "t1";
load(REG_T1, rs2);
}
printf(" %s %s, %s, %s\n", op, rd_name, rs1_name, rs2_name);
if (is_nontrivial(rd)) {
store_t0(rd);
store("t0", rd);
}
}
void _asm_ri(const char* op, int rd, int rs1, int imm) {
const char* rd_name = reg_name(rd);
const char* rs1_name = reg_name(rs1);
if (is_nontrivial(rd)) rd_name = "t0";
if (is_nontrivial(rs1)) {
rs1_name = "t0";
load(REG_T0, rs1);
}
const char* rs1_name = trivialize(rs1, REG_T0);
printf(" %s %s, %s, %d\n", op, rd_name, rs1_name, imm);
if (is_nontrivial(rd)) {
store_t0(rd);
store("t0", rd);
}
}
void _asm_branch(const char* op, int rs1, int label) {
const char* rs1_name = reg_name(rs1);
if (is_nontrivial(rs1)) {
rs1_name = "t0";
load(REG_T0, rs1);
}
const char* rs1_name = trivialize(rs1, REG_T0);
printf(" %s %s, L%d\n", op, rs1_name, label);
}
@ -780,7 +771,7 @@ void _asm_i(const char* op, int rd, const char* prefix1, const char* prefix2, in
if (is_nontrivial(rd)) rd_name = "t0";
printf(" %s %s, %s%s%d\n", op, rd_name, prefix1, prefix2, imm);
if (is_nontrivial(rd)) {
store_t0(rd);
store("t0", rd);
}
}
@ -803,16 +794,8 @@ int asm_rr(int type, const char* op, int rs1, int rs2) {
return rd;
}
void asm_mv(int rd, int rs1) {
_asm_r("mv", rd, rs1);
}
void store_into_local(int rs1, int slot) {
const char* rs1_name = reg_name(rs1);
if (is_nontrivial(rs1)) {
rs1_name = "t0";
load(REG_T0, rs1);
}
const char* rs1_name = trivialize(rs1, REG_T0);
load_local_address(REG_T2, slot);
printf(" %s %s, 0(t2)\n", store_op_of_type(local_type[slot]), rs1_name);
}
@ -827,14 +810,14 @@ int materialize_address(int rd, int type, int marker) {
}
int lookup_from_slot(int slot) {
int reg = next_reg(TYPE_VOID_PTR);
if (is_nontrivial(reg)) {
int rd = next_reg(TYPE_VOID_PTR);
if (is_nontrivial(rd)) {
load_local_address(REG_T0, slot);
asm_mv(reg, REG_T0);
asm_mv(rd, REG_T0);
} else {
load_local_address(reg, slot);
load_local_address(rd, slot);
}
return materialize_address(reg, local_type[slot], local_marker[slot]);
return materialize_address(rd, local_type[slot], local_marker[slot]);
}
int load_imm(int imm) {
@ -857,9 +840,9 @@ int lookup(int id) {
eprintf("function name must not appear outside function call: %s\n", name);
exit(1);
}
int reg = next_reg(TYPE_VOID_PTR);
_asm_i("la", reg, name, " # id: ", id);
return materialize_address(reg, global_type[id], global_marker[id]);
int rd = next_reg(TYPE_VOID_PTR);
_asm_i("la", rd, name, " # id: ", id);
return materialize_address(rd, global_type[id], global_marker[id]);
}
eprintf("unresolved identifier: %s\n", name);
exit(1);
@ -1582,7 +1565,7 @@ void parse_function(const char* name) {
}
int arg_type = parse_type();
if (arg_type < 0 || arg_type == TYPE_VOID) {
eprintf("unexpected a non-void argument type: %d\n", arg_type);
eprintf("expecting a non-void argument type: %d\n", arg_type);
exit(1);
}
expect_token(TOKEN_ID);