no global and big imm
This commit is contained in:
parent
973100f180
commit
9c064f3c1c
122
boot.c
122
boot.c
@ -466,22 +466,60 @@ void declare_global(int id, int marker) {
|
||||
global_marker[id] = marker;
|
||||
}
|
||||
|
||||
int check_itype_immediate(int value) {
|
||||
return value >= -2048 && value <= 2047;
|
||||
}
|
||||
|
||||
void asm_ld(const char* rd, int imm, const char* rs) {
|
||||
if (check_itype_immediate(imm)) {
|
||||
printf(" ld %s, %d(%s)\n", rd, imm, rs);
|
||||
} else {
|
||||
printf(" li t0, %d\n", imm);
|
||||
printf(" add t0, %s, t0\n", rs);
|
||||
printf(" ld %s, 0(t0)\n", rd);
|
||||
}
|
||||
}
|
||||
|
||||
void asm_sd(const char* rs1, int imm, const char* rs2) {
|
||||
if (check_itype_immediate(imm)) {
|
||||
printf(" sd %s, %d(%s)\n", rs1, imm, rs2);
|
||||
} else {
|
||||
printf(" li t0, %d\n", imm);
|
||||
printf(" add t0, %s, t0\n", rs2);
|
||||
printf(" sd %s, 0(t0)\n", rs1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void asm_addi(const char* rd, const char* rs, int imm) {
|
||||
if (check_itype_immediate(imm)) {
|
||||
printf(" addi %s, %s, %d\n", rd, rs, imm);
|
||||
} else {
|
||||
printf(" li t0, %d\n", imm);
|
||||
printf(" add %s, %s, t0\n", rd, rs);
|
||||
}
|
||||
}
|
||||
|
||||
const int INDIRECTION = 1048576; // 2**20
|
||||
const int GLOBAL = 2097152; // 2**21
|
||||
|
||||
void load_address(int rd, int id) {
|
||||
if (id & GLOBAL) {
|
||||
id = id & ~GLOBAL;
|
||||
const char* name = CA_offset(id_table, id_lut[id]);
|
||||
printf(" la t%d, %s # id: %d\n", rd, name, id);
|
||||
} else {
|
||||
if (id & INDIRECTION) {
|
||||
id = id & ~INDIRECTION;
|
||||
int offset = -id * 8 - 8;
|
||||
if (check_itype_immediate(offset)) {
|
||||
printf(" ld t%d, %d(fp) # indirection\n", rd, offset);
|
||||
} else {
|
||||
printf(" li t%d, %d\n", rd, offset);
|
||||
printf(" add t%d, fp, t%d\n", rd, rd);
|
||||
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 {
|
||||
printf(" li t%d, %d\n", rd, offset);
|
||||
printf(" add t%d, fp, t%d\n", rd, rd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -495,27 +533,30 @@ void store(int rs1, int rs2) {
|
||||
printf(" sd t%d, 0(t%d)\n", rs1, rs2);
|
||||
}
|
||||
|
||||
int materialize_t0() {
|
||||
int reg = next_reg();
|
||||
load_address(1, reg);
|
||||
store(0, 1);
|
||||
return reg;
|
||||
}
|
||||
|
||||
int lookup(int id) {
|
||||
int local = local_table[id];
|
||||
if (local) {
|
||||
if (local_marker[local] == ARRAY) {
|
||||
int reg = next_reg();
|
||||
load_address(0, local);
|
||||
load_address(1, reg);
|
||||
store(0, 1);
|
||||
return reg;
|
||||
return materialize_t0();
|
||||
}
|
||||
return local;
|
||||
}
|
||||
if (global_marker[id]) {
|
||||
if (global_marker[id] == ARRAY) {
|
||||
int reg = next_reg();
|
||||
load_address(0, id | GLOBAL);
|
||||
load_address(1, reg);
|
||||
store(0, 1);
|
||||
return reg;
|
||||
const char* name = CA_offset(id_table, id_lut[id]);
|
||||
printf(" la t0, %s # id: %d\n", name, id);
|
||||
int reg = materialize_t0();
|
||||
if (global_marker[id] != ARRAY) {
|
||||
reg = reg | INDIRECTION;
|
||||
}
|
||||
return id | GLOBAL;
|
||||
return reg;
|
||||
}
|
||||
const char* name = CA_offset(id_table, id_lut[id]);
|
||||
eprintf("unresolved identifier: %s\n", name);
|
||||
@ -534,7 +575,7 @@ int asm_label(int label) {
|
||||
}
|
||||
|
||||
int is_not_reusable(int rs1) {
|
||||
return (rs1 & GLOBAL) || (rs1 & INDIRECTION) || local_marker[rs1];
|
||||
return (rs1 & INDIRECTION) || local_marker[rs1];
|
||||
}
|
||||
|
||||
int asm_r(const char* op, int rs1) {
|
||||
@ -559,14 +600,6 @@ int asm_rr(const char* op, int rs1, int rs2) {
|
||||
return rd;
|
||||
}
|
||||
|
||||
int asm_li(int imm) {
|
||||
printf(" li t0, %d\n", imm);
|
||||
int rd = next_reg();
|
||||
load_address(1, rd);
|
||||
store(0, 1);
|
||||
return rd;
|
||||
}
|
||||
|
||||
void asm_beqz(int rs1, int label) {
|
||||
load(0, rs1);
|
||||
printf(" beqz t0, L%d\n", label);
|
||||
@ -612,15 +645,13 @@ int parse_primary_expr() {
|
||||
if (token_type == TOKEN_EOF) {
|
||||
exit(1);
|
||||
} else if (token_type == TOKEN_NUMBER) {
|
||||
return asm_li(token_data);
|
||||
printf(" li t0, %d\n", token_data);
|
||||
return materialize_t0();
|
||||
} else if (token_type == TOKEN_ID) {
|
||||
return lookup(token_data);
|
||||
} else if (token_type == TOKEN_STRING) {
|
||||
int reg = next_reg();
|
||||
printf(" la t0, .LC%d\n", token_data);
|
||||
load_address(1, reg);
|
||||
store(0, 1);
|
||||
return reg;
|
||||
return materialize_t0();
|
||||
} else if (token_type == TOKEN_PAREN_LEFT) {
|
||||
int reg = parse_expr();
|
||||
expect_token(TOKEN_PAREN_RIGHT);
|
||||
@ -654,16 +685,13 @@ int parse_postfix_expr() {
|
||||
store(0, 1);
|
||||
return reg;
|
||||
} else if (token_type == TOKEN_BRACKET_LEFT) {
|
||||
int reg = next_reg();
|
||||
int rhs = parse_expr();
|
||||
expect_token(TOKEN_BRACKET_RIGHT);
|
||||
load(0, rhs);
|
||||
load(1, lhs);
|
||||
printf(" slli t0, t0, 3\n");
|
||||
printf(" add t0, t0, t1\n");
|
||||
load_address(1, reg);
|
||||
store(0, 1);
|
||||
return reg | INDIRECTION;
|
||||
return materialize_t0() | INDIRECTION;
|
||||
} else if (token_type == TOKEN_PAREN_LEFT) {
|
||||
int arg = 0;
|
||||
int args[8];
|
||||
@ -695,10 +723,7 @@ int parse_postfix_expr() {
|
||||
load_address(0, lhs);
|
||||
printf(" jalr t0\n");
|
||||
printf(" mv t0, a0\n");
|
||||
int reg = next_reg();
|
||||
load_address(1, reg);
|
||||
store(0, 1);
|
||||
return reg;
|
||||
return materialize_t0();
|
||||
} else {
|
||||
unget_token();
|
||||
return lhs;
|
||||
@ -710,11 +735,8 @@ int parse_prefix_expr() {
|
||||
next_token();
|
||||
if (token_type == TOKEN_AND) {
|
||||
int id = parse_postfix_expr();
|
||||
int reg = next_reg();
|
||||
load_address(0, id);
|
||||
load_address(1, reg);
|
||||
store(0, 1);
|
||||
return reg;
|
||||
return materialize_t0();
|
||||
} else if (token_type == TOKEN_STAR) {
|
||||
int reg = parse_postfix_expr();
|
||||
return reg | INDIRECTION;
|
||||
@ -1143,10 +1165,10 @@ void parse_function(const char* name) {
|
||||
}
|
||||
// prolog
|
||||
asm_label(prolog_label);
|
||||
printf(" addi sp, sp, %d\n", -shift);
|
||||
printf(" sd ra, %d(sp)\n", shift - 8);
|
||||
printf(" sd fp, %d(sp)\n", shift - 16);
|
||||
printf(" addi fp, sp, %d\n", shift);
|
||||
asm_addi("sp", "sp", -shift);
|
||||
asm_sd("ra", shift - 8, "sp");
|
||||
asm_sd("fp", shift - 16, "sp");
|
||||
asm_addi("fp", "sp", shift);
|
||||
for (int i = 0; i < arg; ++i) {
|
||||
load_address(1, args[i]);
|
||||
printf(" mv t0, a%d\n", i);
|
||||
@ -1155,9 +1177,9 @@ void parse_function(const char* name) {
|
||||
asm_j(label);
|
||||
// epilog
|
||||
asm_label(epilog_label);
|
||||
printf(" ld fp, %d(sp)\n", shift - 16);
|
||||
printf(" ld ra, %d(sp)\n", shift - 8);
|
||||
printf(" addi sp, sp, %d\n", shift);
|
||||
asm_ld("fp", shift - 16, "sp");
|
||||
asm_ld("ra", shift - 8, "sp");
|
||||
asm_addi("sp", "sp", shift);
|
||||
printf(" ret\n");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user