diff --git a/boot.c b/boot.c index a7b16de..1b51e0e 100644 --- a/boot.c +++ b/boot.c @@ -521,16 +521,16 @@ const char* reg_name(int reg) { if (reg == 25) return "s9"; if (reg == 26) return "s10"; if (reg == 27) return "s11"; - // overflow begin if (reg == 28) return "t3"; if (reg == 29) return "t4"; if (reg == 30) return "t5"; if (reg == 31) return "t6"; + // overflow begin return 0; } int is_overflow(int reg) { - return reg > REG_S11; + return reg > REG_T6; } void reset_local() { @@ -1017,7 +1017,17 @@ int parse_function_call(int id) { for (int i = 0; i < arg; ++i) { asm_mv(i + REG_A0, args[i]); } + for (int i = REG_T3; i <= REG_T6; ++i) { + if (i < max_reg_id) { + asm_sd(reg_name(i), (REG_S2 - i) * 8 - 24, "fp"); + } + } printf(" call %s\n", name); + for (int i = REG_T3; i <= REG_T6; ++i) { + if (i < max_reg_id) { + asm_ld(reg_name(i), (REG_S2 - i) * 8 - 24, "fp"); + } + } int type = global_type[id]; if (type != TYPE_VOID) { int rd = next_reg(type); @@ -1355,7 +1365,7 @@ int parse_expr() { void parse_local_variable(int type) { if (type == TYPE_VOID) { - eprintf("local variable of void type is not supported\n"); + eprintf("variable cannot be of void type\n"); exit(1); } expect_token(TOKEN_ID); @@ -1556,6 +1566,10 @@ void parse_function(const char* name) { } arg_type = arg_type | TYPE_PTR_MASK; } + if (arg >= 8) { + eprintf("too many arguments\n"); + exit(1); + } args[arg++] = declare_local(token_data, arg_type); if (token_type == TOKEN_COMMA) { // continue; @@ -1590,8 +1604,9 @@ void parse_function(const char* name) { } asm_j(epilog_label); int reg_used = max_reg_id - REG_S2; - if (reg_used > 10) reg_used = 10; + if (reg_used > 14) reg_used = 14; int frame_size = (max_local_id - 1 + reg_used + 2) * 8; + if (reg_used > 10) reg_used = 10; if (frame_size % 16 != 0) { frame_size = frame_size + 8; } @@ -1623,7 +1638,7 @@ void parse_function(const char* name) { void parse_global_variable(int id, const char* name, int type) { if (type == TYPE_VOID) { - eprintf("global variable of void type is not supported\n"); + eprintf("variable cannot be of void type\n"); exit(1); } printf(".data\n");