new indirection
This commit is contained in:
parent
064435b316
commit
cf4c851aad
53
boot.c
53
boot.c
@ -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;
|
||||
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 {
|
||||
|
Loading…
Reference in New Issue
Block a user