aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeddy <[email protected]>2014-05-05 21:01:45 +0800
committerTeddy <[email protected]>2014-05-05 21:01:45 +0800
commita144dc6641b8d0ac58c7e302e78c65810ad171dd (patch)
treed57f96f1d80ef8c4bde80b42c49ab8afe9165647
parent831c9f477cb4298fd21f8735e1789f210cd80a4d (diff)
global string opt
-rw-r--r--mips.c29
-rw-r--r--semantics.h1
2 files changed, 27 insertions, 3 deletions
diff --git a/mips.c b/mips.c
index a9c0efb..e7719f8 100644
--- a/mips.c
+++ b/mips.c
@@ -59,10 +59,28 @@ void mips_prologue(void) {
printf("\t.space %d\n", calc_size(var->type));
}
printf("\t.align 2\n");
+ prev += align_shift(prev);
for (s = cstrs; s; s = s->next)
{
+ int len = 1;
+ char *p = s->str;
printf("_str_%d:\n", s->id);
printf("\t.asciiz \"%s\"\n", s->str);
+ s->start = prev;
+ for (; *p != '\0'; p++)
+ {
+ len++;
+ if (*p == '\\')
+ {
+ switch (*(++p))
+ {
+ case '0': p += 3; break;
+ case 'x': p += 2; break;
+ default: ;
+ }
+ }
+ }
+ prev += len;
}
/* pre-calc done */
printf(".text\n");
@@ -73,7 +91,7 @@ void mips_prologue(void) {
void mips_global_addr(int reg, CVar_t var) {
int offset = var->start - 0x8000;
if (IN_IMM(offset))
- printf("\taddiu $%d, $gp, %d\n", reg, offset);
+ printf("\taddiu $%d, $gp, %d #%s\n", reg, offset, var->name);
else
printf("\tla $%d, _%s\n", reg, var->name);
}
@@ -81,7 +99,7 @@ void mips_global_addr(int reg, CVar_t var) {
void mips_global(const char *l, int reg, CVar_t var) {
int offset = var->start - 0x8000;
if (IN_IMM(offset))
- printf("\t%s $%d, %d($gp)\n", l, reg, offset);
+ printf("\t%s $%d, %d($gp) #%s\n", l, reg, offset, var->name);
else
printf("\t%s $%d, _%s\n", l, reg, var->name);
}
@@ -127,7 +145,12 @@ int mips_to_reg(COpr_t opr, int reg0) {
}
else if (opr->kind == IMMS)
{
- printf("\tla $%d, _str_%d\n", reg0, opr->info.cstr->id);
+ CSList_t cstr = opr->info.cstr;
+ int offset = cstr->start - 0x8000;
+ if (IN_IMM(offset))
+ printf("\taddiu $%d, $gp, %d # _str_%d\n", reg0, offset, cstr->id);
+ else
+ printf("\tla $%d, _str_%d\n", reg0, cstr->id);
return reg0;
}
else if (opr->kind == IMMF)
diff --git a/semantics.h b/semantics.h
index 37cffb3..b77cf2e 100644
--- a/semantics.h
+++ b/semantics.h
@@ -32,6 +32,7 @@ typedef CSList *CSList_t;
struct CSList {
char *str;
int id;
+ int start;
CSList_t next;
};