more void check
This commit is contained in:
parent
fb54211c71
commit
05f6b1906f
129
boot.c
129
boot.c
@ -524,6 +524,10 @@ void asm_addi(const char* rd, const char* rs, int imm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void load_address(int rd, int id) {
|
void load_address(int rd, int id) {
|
||||||
|
if (id == -1) {
|
||||||
|
eprintf("void cannot be arithmetically operated\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
int offset = -id * 8 - 8;
|
int offset = -id * 8 - 8;
|
||||||
if (indirection[id]) {
|
if (indirection[id]) {
|
||||||
if (check_itype_immediate(offset)) {
|
if (check_itype_immediate(offset)) {
|
||||||
@ -573,7 +577,7 @@ int materialize_t0(int type) {
|
|||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
int indirection_of(int reg) {
|
int dereference(int reg) {
|
||||||
local_type[reg] = local_type[reg] & ~TYPE_PTR_MASK;
|
local_type[reg] = local_type[reg] & ~TYPE_PTR_MASK;
|
||||||
indirection[reg] = 1;
|
indirection[reg] = 1;
|
||||||
return reg;
|
return reg;
|
||||||
@ -593,7 +597,7 @@ int lookup(int id) {
|
|||||||
printf(" la t0, %s # id: %d\n", name, id);
|
printf(" la t0, %s # id: %d\n", name, id);
|
||||||
int reg = materialize_t0(global_type[id] | TYPE_PTR_MASK);
|
int reg = materialize_t0(global_type[id] | TYPE_PTR_MASK);
|
||||||
if (global_marker[id] == MARKER_SCALAR) {
|
if (global_marker[id] == MARKER_SCALAR) {
|
||||||
reg = indirection_of(reg);
|
reg = dereference(reg);
|
||||||
}
|
}
|
||||||
if (global_marker[id] == MARKER_FUNCTION) {
|
if (global_marker[id] == MARKER_FUNCTION) {
|
||||||
indirection[reg] = 1;
|
indirection[reg] = 1;
|
||||||
@ -703,6 +707,10 @@ int asm_add(int lhs, int rhs) {
|
|||||||
idx = lhs;
|
idx = lhs;
|
||||||
}
|
}
|
||||||
int ptr_type = local_type[ptr];
|
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(0, idx);
|
||||||
load(1, ptr);
|
load(1, ptr);
|
||||||
asm_shift_t0("slli", ptr_type);
|
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 asm_sub(int lhs, int rhs) {
|
||||||
int type1 = local_type[lhs] & TYPE_PTR_MASK;
|
int lhs_type = local_type[lhs];
|
||||||
int type2 = local_type[rhs] & TYPE_PTR_MASK;
|
int rhs_type = local_type[rhs];
|
||||||
|
int type1 = lhs_type & TYPE_PTR_MASK;
|
||||||
|
int type2 = rhs_type & TYPE_PTR_MASK;
|
||||||
if (type1 && type2) {
|
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(0, lhs);
|
||||||
load(1, rhs);
|
load(1, rhs);
|
||||||
int ptr_type = local_type[lhs];
|
|
||||||
printf(" sub t0, t0, t1\n");
|
printf(" sub t0, t0, t1\n");
|
||||||
asm_shift_t0("srli", ptr_type);
|
asm_shift_t0("srli", lhs_type);
|
||||||
return materialize_t0(TYPE_INT);
|
return materialize_t0(TYPE_INT);
|
||||||
}
|
}
|
||||||
if (type1) {
|
if (type1) {
|
||||||
@ -763,31 +780,7 @@ int parse_primary_expr() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_postfix_expr() {
|
int parse_function_call(int func) {
|
||||||
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 arg = 0;
|
int arg = 0;
|
||||||
int args[8];
|
int args[8];
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -815,10 +808,42 @@ int parse_postfix_expr() {
|
|||||||
load(0, args[i]);
|
load(0, args[i]);
|
||||||
printf(" mv a%d, t0\n", i);
|
printf(" mv a%d, t0\n", i);
|
||||||
}
|
}
|
||||||
load_address(0, lhs);
|
load_address(0, func);
|
||||||
printf(" jalr t0\n");
|
printf(" jalr t0\n");
|
||||||
|
int type = local_type[func];
|
||||||
|
if (type != TYPE_VOID) {
|
||||||
printf(" mv t0, a0\n");
|
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 {
|
} else {
|
||||||
unget_token();
|
unget_token();
|
||||||
break;
|
break;
|
||||||
@ -831,12 +856,26 @@ int parse_prefix_expr() {
|
|||||||
next_token();
|
next_token();
|
||||||
if (token_type == TOKEN_AND) {
|
if (token_type == TOKEN_AND) {
|
||||||
int reg = parse_postfix_expr();
|
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);
|
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) {
|
} else if (token_type == TOKEN_STAR) {
|
||||||
int reg = parse_postfix_expr();
|
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);
|
load(0, reg);
|
||||||
return indirection_of(materialize_t0(local_type[reg]));
|
return dereference(materialize_t0(type));
|
||||||
} else if (token_type == TOKEN_MINUS) {
|
} else if (token_type == TOKEN_MINUS) {
|
||||||
int reg = parse_postfix_expr();
|
int reg = parse_postfix_expr();
|
||||||
return asm_r("neg", reg);
|
return asm_r("neg", reg);
|
||||||
@ -1314,16 +1353,16 @@ void parse_function(const char* name) {
|
|||||||
parse_stmt();
|
parse_stmt();
|
||||||
}
|
}
|
||||||
asm_j(epilog_label);
|
asm_j(epilog_label);
|
||||||
int shift = max_local_id * 8;
|
int frame_size = max_local_id * 8;
|
||||||
if (shift % 16 != 0) {
|
if (frame_size % 16 != 0) {
|
||||||
shift = shift + 8;
|
frame_size = frame_size + 8;
|
||||||
}
|
}
|
||||||
// prolog
|
// prolog
|
||||||
asm_label(prolog_label);
|
asm_label(prolog_label);
|
||||||
asm_addi("sp", "sp", -shift);
|
asm_addi("sp", "sp", -frame_size);
|
||||||
asm_sd("ra", shift - 8, "sp");
|
asm_sd("ra", frame_size - 8, "sp");
|
||||||
asm_sd("fp", shift - 16, "sp");
|
asm_sd("fp", frame_size - 16, "sp");
|
||||||
asm_addi("fp", "sp", shift);
|
asm_addi("fp", "sp", frame_size);
|
||||||
for (int i = 0; i < arg; ++i) {
|
for (int i = 0; i < arg; ++i) {
|
||||||
printf(" mv t0, a%d\n", i);
|
printf(" mv t0, a%d\n", i);
|
||||||
store_t0(args[i]);
|
store_t0(args[i]);
|
||||||
@ -1331,9 +1370,9 @@ void parse_function(const char* name) {
|
|||||||
asm_j(label);
|
asm_j(label);
|
||||||
// epilog
|
// epilog
|
||||||
asm_label(epilog_label);
|
asm_label(epilog_label);
|
||||||
asm_ld("fp", shift - 16, "sp");
|
asm_ld("fp", frame_size - 16, "sp");
|
||||||
asm_ld("ra", shift - 8, "sp");
|
asm_ld("ra", frame_size - 8, "sp");
|
||||||
asm_addi("sp", "sp", shift);
|
asm_addi("sp", "sp", frame_size);
|
||||||
printf(" ret\n");
|
printf(" ret\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user