new indirection

This commit is contained in:
Yaossg 2024-11-16 22:28:00 +08:00
parent 064435b316
commit cf4c851aad

55
boot.c
View File

@ -28,8 +28,8 @@ const int TOKEN_REM = 6;
const int TOKEN_ASSIGN = 7;
const int TOKEN_COMMA = 8;
const int TOKEN_DOT = 9;
const int TOKEN_LSHIFT = 10; // unused
const int TOKEN_RSHIFT = 11; // unused
const int TOKEN_LSHIFT = 10;
const int TOKEN_RSHIFT = 11;
const int TOKEN_AND = 12;
const int TOKEN_OR = 13;
const int TOKEN_XOR = 14;
@ -423,7 +423,6 @@ int parse_type() {
// asm
int epilog_label;
int local_table[4096]; // id -> local id
@ -439,6 +438,7 @@ int local_marker[4096];
int global_marker[4096];
int local_type[4096];
int global_type[4096];
int indirection[4096];
void reset_local() {
next_local_id = 2;
@ -447,6 +447,7 @@ void reset_local() {
local_table[i] = 0;
local_marker[i] = MARKER_TEMP;
local_type[i] = TYPE_VOID;
indirection[i] = 0;
}
}
@ -459,6 +460,7 @@ void reset_temp() {
int next_reg(int type) {
int reg = next_local_id++;
local_type[reg] = type;
indirection[reg] = 0;
if (next_local_id > max_local_id) {
max_local_id = next_local_id;
}
@ -518,16 +520,9 @@ void asm_addi(const char* rd, const char* rs, int imm) {
}
}
const int INDIRECTION = 1048576; // 2**20
int local_type_of(int rs1) {
return local_type[rs1 & ~INDIRECTION];
}
void load_address(int rd, int id) {
if (id & INDIRECTION) {
id = id & ~INDIRECTION;
int offset = -id * 8 - 8;
int offset = -id * 8 - 8;
if (indirection[id]) {
if (check_itype_immediate(offset)) {
printf(" ld t%d, %d(fp) # indirection\n", rd, offset);
} else {
@ -536,7 +531,6 @@ void load_address(int rd, int id) {
printf(" ld t%d, 0(t%d) # indirection\n", rd, rd);
}
} else {
int offset = -id * 8 - 8;
if (check_itype_immediate(offset)) {
printf(" addi t%d, fp, %d\n", rd, offset);
} else {
@ -548,7 +542,7 @@ void load_address(int rd, int id) {
void load(int rd, int id) {
load_address(rd, id);
int type = local_type_of(id);
int type = local_type[id];
const char* op = "lw"; // int
if (type == TYPE_CHAR) {
op = "lb";
@ -561,7 +555,7 @@ void load(int rd, int id) {
void store_t0(int id) {
load_address(1, id);
int type = local_type_of(id);
int type = local_type[id];
const char* op = "sw"; // int
if (type == TYPE_CHAR) {
op = "sb";
@ -580,7 +574,8 @@ int materialize_t0(int type) {
int indirection_of(int reg) {
local_type[reg] = local_type[reg] & ~TYPE_PTR_MASK;
return reg | INDIRECTION;
indirection[reg] = 1;
return reg;
}
int lookup(int id) {
@ -600,7 +595,7 @@ int lookup(int id) {
reg = indirection_of(reg);
}
if (global_marker[id] == MARKER_FUNCTION) {
reg = reg | INDIRECTION;
indirection[reg] = 1;
}
return reg;
}
@ -620,14 +615,14 @@ int asm_label(int label) {
}
int is_not_reusable(int rs1) {
return (rs1 & INDIRECTION) || local_marker[rs1] != MARKER_TEMP;
return indirection[rs1] || local_marker[rs1] != MARKER_TEMP;
}
int asm_r(const char* op, int rs1) {
load(0, rs1);
printf(" %s t0, t0\n", op);
int rd = rs1;
if (is_not_reusable(rs1)) rd = next_reg(local_type_of(rs1));
if (is_not_reusable(rs1)) rd = next_reg(local_type[rs1]);
store_t0(rd);
return rd;
}
@ -638,7 +633,7 @@ int asm_rr(const char* op, int rs1, int rs2) {
printf(" %s t0, t0, t1\n", op);
int rd = rs1;
if (is_not_reusable(rs1)) rd = rs2;
if (is_not_reusable(rs2)) rd = next_reg(local_type_of(rs1));
if (is_not_reusable(rs2)) rd = next_reg(local_type[rs1]);
store_t0(rd);
return rd;
}
@ -694,8 +689,8 @@ void asm_slli_t0(int type) {
}
int asm_add(int lhs, int rhs) {
int type1 = local_type_of(lhs) & TYPE_PTR_MASK;
int type2 = local_type_of(rhs) & TYPE_PTR_MASK;
int type1 = local_type[lhs] & TYPE_PTR_MASK;
int type2 = local_type[rhs] & TYPE_PTR_MASK;
if (type1 != type2) {
int ptr;
int idx;
@ -706,7 +701,7 @@ int asm_add(int lhs, int rhs) {
ptr = rhs;
idx = lhs;
}
int ptr_type = local_type_of(ptr);
int ptr_type = local_type[ptr];
load(0, idx);
load(1, ptr);
asm_slli_t0(ptr_type);
@ -750,7 +745,7 @@ int parse_postfix_expr() {
while (1) {
next_token();
if (token_type == TOKEN_INC) {
int type = local_type_of(lhs);
int type = local_type[lhs];
int reg = next_reg(type);
load(0, lhs);
store_t0(reg);
@ -758,7 +753,7 @@ int parse_postfix_expr() {
store_t0(lhs);
return reg;
} else if (token_type == TOKEN_DEC) {
int type = local_type_of(lhs);
int type = local_type[lhs];
int reg = next_reg(type);
load(0, lhs);
store_t0(reg);
@ -800,7 +795,7 @@ int parse_postfix_expr() {
load_address(0, lhs);
printf(" jalr t0\n");
printf(" mv t0, a0\n");
return materialize_t0(local_type_of(lhs));
return materialize_t0(local_type[lhs]);
} else {
unget_token();
return lhs;
@ -813,11 +808,11 @@ int parse_prefix_expr() {
if (token_type == TOKEN_AND) {
int reg = parse_postfix_expr();
load_address(0, reg);
return materialize_t0(local_type_of(reg) | TYPE_PTR_MASK);
return materialize_t0(local_type[reg] | TYPE_PTR_MASK);
} else if (token_type == TOKEN_STAR) {
int reg = parse_postfix_expr();
load(0, reg);
return indirection_of(materialize_t0(local_type_of(reg)));
return indirection_of(materialize_t0(local_type[reg]));
} else if (token_type == TOKEN_MINUS) {
int reg = parse_postfix_expr();
return asm_r("neg", reg);
@ -830,13 +825,13 @@ int parse_prefix_expr() {
} else if (token_type == TOKEN_INC) {
int reg = parse_postfix_expr();
load(0, reg);
printf(" addi t0, t0, %d\n", step_of(local_type_of(reg)));
printf(" addi t0, t0, %d\n", step_of(local_type[reg]));
store_t0(reg);
return reg;
} else if (token_type == TOKEN_DEC) {
int reg = parse_postfix_expr();
load(0, reg);
printf(" addi t0, t0, -%d\n", step_of(local_type_of(reg)));
printf(" addi t0, t0, -%d\n", step_of(local_type[reg]));
store_t0(reg);
return reg;
} else {