more void check

This commit is contained in:
Yaossg 2024-11-17 21:33:57 +08:00
parent fb54211c71
commit 05f6b1906f

129
boot.c
View File

@ -524,6 +524,10 @@ void asm_addi(const char* rd, const char* rs, int imm) {
}
void load_address(int rd, int id) {
if (id == -1) {
eprintf("void cannot be arithmetically operated\n");
exit(1);
}
int offset = -id * 8 - 8;
if (indirection[id]) {
if (check_itype_immediate(offset)) {
@ -573,7 +577,7 @@ int materialize_t0(int type) {
return reg;
}
int indirection_of(int reg) {
int dereference(int reg) {
local_type[reg] = local_type[reg] & ~TYPE_PTR_MASK;
indirection[reg] = 1;
return reg;
@ -593,7 +597,7 @@ int lookup(int id) {
printf(" la t0, %s # id: %d\n", name, id);
int reg = materialize_t0(global_type[id] | TYPE_PTR_MASK);
if (global_marker[id] == MARKER_SCALAR) {
reg = indirection_of(reg);
reg = dereference(reg);
}
if (global_marker[id] == MARKER_FUNCTION) {
indirection[reg] = 1;
@ -703,6 +707,10 @@ int asm_add(int lhs, int rhs) {
idx = lhs;
}
int ptr_type = local_type[ptr];
if (ptr_type == TYPE_VOID_PTR) {
eprintf("void pointer cannot be arithmetically operated\n");
exit(1);
}
load(0, idx);
load(1, ptr);
asm_shift_t0("slli", ptr_type);
@ -717,14 +725,23 @@ int asm_add(int lhs, int rhs) {
}
int asm_sub(int lhs, int rhs) {
int type1 = local_type[lhs] & TYPE_PTR_MASK;
int type2 = local_type[rhs] & TYPE_PTR_MASK;
int lhs_type = local_type[lhs];
int rhs_type = local_type[rhs];
int type1 = lhs_type & TYPE_PTR_MASK;
int type2 = rhs_type & TYPE_PTR_MASK;
if (type1 && type2) {
if (lhs_type != rhs_type) {
eprintf("pointer type mismatch\n");
exit(1);
}
if (lhs_type == TYPE_VOID_PTR) {
eprintf("void pointer cannot be arithmetically operated\n");
exit(1);
}
load(0, lhs);
load(1, rhs);
int ptr_type = local_type[lhs];
printf(" sub t0, t0, t1\n");
asm_shift_t0("srli", ptr_type);
asm_shift_t0("srli", lhs_type);
return materialize_t0(TYPE_INT);
}
if (type1) {
@ -763,31 +780,7 @@ int parse_primary_expr() {
}
}
int parse_postfix_expr() {
int lhs = parse_primary_expr();
while (1) {
next_token();
if (token_type == TOKEN_INC) {
int type = local_type[lhs];
int reg = next_reg(type);
load(0, lhs);
store_t0(reg);
printf(" addi t0, t0, %d\n", step_of(type));
store_t0(lhs);
lhs = reg;
} else if (token_type == TOKEN_DEC) {
int type = local_type[lhs];
int reg = next_reg(type);
load(0, lhs);
store_t0(reg);
printf(" addi t0, t0, -%d\n", step_of(type));
store_t0(lhs);
lhs = reg;
} else if (token_type == TOKEN_BRACKET_LEFT) {
int rhs = parse_expr();
expect_token(TOKEN_BRACKET_RIGHT);
lhs = indirection_of(asm_add(lhs, rhs));
} else if (token_type == TOKEN_PAREN_LEFT) {
int parse_function_call(int func) {
int arg = 0;
int args[8];
while (1) {
@ -815,10 +808,42 @@ int parse_postfix_expr() {
load(0, args[i]);
printf(" mv a%d, t0\n", i);
}
load_address(0, lhs);
load_address(0, func);
printf(" jalr t0\n");
int type = local_type[func];
if (type != TYPE_VOID) {
printf(" mv t0, a0\n");
lhs = materialize_t0(local_type[lhs]);
return materialize_t0(type);
}
return -1;
}
int parse_postfix_expr() {
int lhs = parse_primary_expr();
while (1) {
next_token();
if (token_type == TOKEN_INC) {
int type = local_type[lhs];
int reg = next_reg(type);
load(0, lhs);
store_t0(reg);
printf(" addi t0, t0, %d\n", step_of(type));
store_t0(lhs);
lhs = reg;
} else if (token_type == TOKEN_DEC) {
int type = local_type[lhs];
int reg = next_reg(type);
load(0, lhs);
store_t0(reg);
printf(" addi t0, t0, -%d\n", step_of(type));
store_t0(lhs);
lhs = reg;
} else if (token_type == TOKEN_BRACKET_LEFT) {
int rhs = parse_expr();
expect_token(TOKEN_BRACKET_RIGHT);
lhs = dereference(asm_add(lhs, rhs));
} else if (token_type == TOKEN_PAREN_LEFT) {
lhs = parse_function_call(lhs);
} else {
unget_token();
break;
@ -831,12 +856,26 @@ int parse_prefix_expr() {
next_token();
if (token_type == TOKEN_AND) {
int reg = parse_postfix_expr();
int type = local_type[reg];
if (type & TYPE_PTR_MASK) {
eprintf("cannot take address of a pointer\n");
exit(1);
}
load_address(0, reg);
return materialize_t0(local_type[reg] | TYPE_PTR_MASK);
return materialize_t0(type | TYPE_PTR_MASK);
} else if (token_type == TOKEN_STAR) {
int reg = parse_postfix_expr();
int type = local_type[reg];
if (!(type & TYPE_PTR_MASK)) {
eprintf("cannot dereference a non-pointer\n");
exit(1);
}
if (type == TYPE_VOID_PTR) {
eprintf("cannot dereference void pointer\n");
exit(1);
}
load(0, reg);
return indirection_of(materialize_t0(local_type[reg]));
return dereference(materialize_t0(type));
} else if (token_type == TOKEN_MINUS) {
int reg = parse_postfix_expr();
return asm_r("neg", reg);
@ -1314,16 +1353,16 @@ void parse_function(const char* name) {
parse_stmt();
}
asm_j(epilog_label);
int shift = max_local_id * 8;
if (shift % 16 != 0) {
shift = shift + 8;
int frame_size = max_local_id * 8;
if (frame_size % 16 != 0) {
frame_size = frame_size + 8;
}
// prolog
asm_label(prolog_label);
asm_addi("sp", "sp", -shift);
asm_sd("ra", shift - 8, "sp");
asm_sd("fp", shift - 16, "sp");
asm_addi("fp", "sp", shift);
asm_addi("sp", "sp", -frame_size);
asm_sd("ra", frame_size - 8, "sp");
asm_sd("fp", frame_size - 16, "sp");
asm_addi("fp", "sp", frame_size);
for (int i = 0; i < arg; ++i) {
printf(" mv t0, a%d\n", i);
store_t0(args[i]);
@ -1331,9 +1370,9 @@ void parse_function(const char* name) {
asm_j(label);
// epilog
asm_label(epilog_label);
asm_ld("fp", shift - 16, "sp");
asm_ld("ra", shift - 8, "sp");
asm_addi("sp", "sp", shift);
asm_ld("fp", frame_size - 16, "sp");
asm_ld("ra", frame_size - 8, "sp");
asm_addi("sp", "sp", frame_size);
printf(" ret\n");
}