From 4893f0cd6865f022ad29961b198a05fa515c2747 Mon Sep 17 00:00:00 2001 From: Yaossg Date: Sat, 30 Nov 2024 00:31:33 +0800 Subject: [PATCH] refactor mv --- boot.c | 187 ++++++++++++++++++++++++++------------------------------- 1 file changed, 84 insertions(+), 103 deletions(-) diff --git a/boot.c b/boot.c index 0586617..8aa7128 100644 --- a/boot.c +++ b/boot.c @@ -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,23 +673,28 @@ const char* store_op_of_type(int type) { } } -// load a non-trivial register into t0, t1 or t2 +// address loaders // rd must be one of t0, t1, t2 -void load(int rd, int reg) { - const char* op = load_op_of_type(reg_type[reg]); - const char* rd_name = reg_name(rd); - if (is_overflow(reg)) { - load_local_address(rd, overflow[reg]); - if (indirection[reg]) { - printf(" ld %s, 0(%s)\n", rd_name, rd_name); - } - reg = rd; - } - printf(" %s %s, 0(%s) # load non-trivial register\n", op, rd_name, reg_name(reg)); +void load_local_address(int rd, int slot_id) { + asm_addi(reg_name(rd), "sp", slot_id * 8 - 8); } -// store t0 into a non-trivial register -void store_t0(int reg) { +// load a non-trivial register into trivial one +void load(int rd, int rs) { + const char* op = load_op_of_type(reg_type[rs]); + const char* rd_name = reg_name(rd); + if (is_overflow(rs)) { + load_local_address(rd, overflow[rs]); + if (indirection[rs]) { + printf(" ld %s, 0(%s)\n", rd_name, rd_name); + } + rs = rd; + } + printf(" %s %s, 0(%s) # load non-trivial register\n", op, rd_name, reg_name(rs)); +} + +// store a trivial register into a non-trivial one +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 +703,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 +770,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 +793,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 +809,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) { @@ -856,26 +838,15 @@ int lookup(int id) { if (global_marker[id] == MARKER_FUNCTION) { 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); } - -int next_label_id = 0; -int next_label() { - return next_label_id++; -} - -int asm_label(int label) { - printf("L%d:\n", label); - return label; -} - int asm_r_arith(const char* op, int rs1) { if (reg_type[rs1] & TYPE_PTR_MASK) { eprintf("pointer cannot be arithmetically operated by %s\n", op); @@ -909,6 +880,16 @@ void asm_j(int label) { printf(" j L%d\n", label); } +int next_label_id = 0; +int next_label() { + return next_label_id++; +} + +int asm_label(int label) { + printf("L%d:\n", label); + return label; +} + int break_label_stack[4096]; int cont_label_stack[4096]; int break_label_stack_size; @@ -932,11 +913,12 @@ void asm_pop_label() { --cont_label_stack_size; } +int log_step_of(int type) { + return 2 * (type == TYPE_INT_PTR); +} + int step_of(int type) { - if (type == TYPE_INT_PTR) { - return 4; - } - return 1; + return 1 << log_step_of(type); } int asm_add(int lhs, int rhs) { @@ -958,8 +940,7 @@ int asm_add(int lhs, int rhs) { exit(1); } int offset = next_reg(TYPE_INT); - int shift = 2 * (ptr_type == TYPE_INT_PTR); - _asm_ri("slli", offset, idx, shift); + _asm_ri("slli", offset, idx, log_step_of(ptr_type)); return asm_rr(ptr_type, "add", ptr, offset); } if (type1 && type2) { @@ -984,8 +965,7 @@ int asm_sub(int lhs, int rhs) { exit(1); } int difference = asm_rr(TYPE_INT, "sub", lhs, rhs); - int shift = 2 * (lhs_type == TYPE_INT_PTR); - _asm_ri("slli", difference, difference, shift); + _asm_ri("slli", difference, difference, log_step_of(lhs_type)); return difference; } if (type1) { @@ -1016,6 +996,7 @@ int addressof(int reg) { } // parser + int parse_expr(); int parse_function_call(int id) { @@ -1412,7 +1393,7 @@ void parse_local_variable(int type) { expect_token(TOKEN_BRACKET_RIGHT); declare_local_array(id, type, size); return; - } + } int slot = declare_local(id, type); if (token_type == TOKEN_SEMICOLON) { unget_token(); @@ -1582,7 +1563,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); @@ -1723,10 +1704,10 @@ void parse_global_declaration() { is_const[id] = 1; expect_token(TOKEN_SEMICOLON); } else if (token_type == TOKEN_PAREN_LEFT) { - declare_global(id, MARKER_FUNCTION, type); + declare_global(id, MARKER_FUNCTION, type); parse_function(name); } else { - declare_global(id, MARKER_SCALAR, type); + declare_global(id, MARKER_SCALAR, type); parse_global_variable(id, name, type); } } @@ -1743,9 +1724,9 @@ void dump_string_table() { printf(".data\n"); for (int i = 0; i < string_lut_size; ++i) { printf(".LC%d: .string \"", i); - int offset = string_lut[i]; - int ch; - while ((ch = string_table[offset++]) != 0) { + char* p = string_table + string_lut[i]; + int ch; + while ((ch = *p++) != 0) { if (ch == '\n') { printf("\\n"); } else if (ch == '\t') {