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