no global and big imm

This commit is contained in:
Yaossg 2024-11-15 22:37:36 +08:00
parent 973100f180
commit 9c064f3c1c

122
boot.c
View File

@ -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");
}