Conditionally save volatile regs
This commit is contained in:
parent
692ed4d21c
commit
f978b66662
@ -204,6 +204,8 @@ void ast_usedef_reset(AST *chu) {
|
|||||||
for(size_t sii = 0; sii < chu->chunk.varCount; sii++) {
|
for(size_t sii = 0; sii < chu->chunk.varCount; sii++) {
|
||||||
ScopeItem *si = chu->chunk.vars[sii];
|
ScopeItem *si = chu->chunk.vars[sii];
|
||||||
|
|
||||||
|
assert(si->data.var.declaration != NULL && "All local vars must have defined declaration location");
|
||||||
|
|
||||||
if(ast_stmt_is_after(chu, si->data.var.liveRangeEnd, s) == 0 && ast_stmt_is_after(chu, target, si->data.var.liveRangeEnd) == 0 && ast_stmt_is_after(chu, si->data.var.declaration, target) == 0) {
|
if(ast_stmt_is_after(chu, si->data.var.liveRangeEnd, s) == 0 && ast_stmt_is_after(chu, target, si->data.var.liveRangeEnd) == 0 && ast_stmt_is_after(chu, si->data.var.declaration, target) == 0) {
|
||||||
|
|
||||||
si->data.var.liveRangeEnd = s;
|
si->data.var.liveRangeEnd = s;
|
||||||
|
49
src/x86/cg.c
49
src/x86/cg.c
@ -260,6 +260,27 @@ static int lr_empty(ScopeItem *a) {
|
|||||||
return !a->data.var.liveRangeStart;
|
return !a->data.var.liveRangeStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_resource_in_use_right_now_at_this_current_point_in_time_and_also_not_created_right_now(AST *tlc, AST *statement, size_t resource) {
|
||||||
|
for(size_t vi = 0; vi < tlc->chunk.varCount; vi++) {
|
||||||
|
ScopeItem *si = tlc->chunk.vars[vi];
|
||||||
|
if((REG_CLASSES[si->data.var.registerClass].rs[si->data.var.color] & resource) == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(ast_stmt_is_after(tlc, statement, si->data.var.liveRangeEnd) == 1 || statement == si->data.var.liveRangeEnd) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(si->data.var.usedefFirst == NULL) {
|
||||||
|
// Even if the resource is in use, the variable itself isn't so we don't care
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!lr_empty(si) && (ast_stmt_is_after(tlc, statement, si->data.var.liveRangeStart) == 1
|
||||||
|
&& ast_stmt_is_after(tlc, si->data.var.liveRangeEnd, statement) == 1)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void cg_chunk(CGState *cg, AST *a) {
|
void cg_chunk(CGState *cg, AST *a) {
|
||||||
AST *s = a->chunk.statementFirst;
|
AST *s = a->chunk.statementFirst;
|
||||||
|
|
||||||
@ -390,12 +411,14 @@ void cg_chunk(CGState *cg, AST *a) {
|
|||||||
|
|
||||||
AST *e = s->stmtAssign.to;
|
AST *e = s->stmtAssign.to;
|
||||||
|
|
||||||
if(x86_ia16()) {
|
if(is_resource_in_use_right_now_at_this_current_point_in_time_and_also_not_created_right_now(a, s, HWR_ECX)) {
|
||||||
puts("push cx");
|
puts(x86_ia16() ? "push cx" : "push ecx");
|
||||||
puts("push dx");
|
}
|
||||||
} else {
|
if(is_resource_in_use_right_now_at_this_current_point_in_time_and_also_not_created_right_now(a, s, HWR_EDX)) {
|
||||||
puts("push ecx");
|
puts(x86_ia16() ? "push dx" : "push edx");
|
||||||
puts("push edx");
|
}
|
||||||
|
if(is_resource_in_use_right_now_at_this_current_point_in_time_and_also_not_created_right_now(a, s, HWR_EAX)) {
|
||||||
|
puts(x86_ia16() ? "push ax" : "push eax");
|
||||||
}
|
}
|
||||||
|
|
||||||
int argCount = e->exprCall.what->expression.type->pointer.of->function.argCount;
|
int argCount = e->exprCall.what->expression.type->pointer.of->function.argCount;
|
||||||
@ -422,12 +445,14 @@ void cg_chunk(CGState *cg, AST *a) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(x86_ia16()) {
|
if(is_resource_in_use_right_now_at_this_current_point_in_time_and_also_not_created_right_now(a, s, HWR_EAX)) {
|
||||||
puts("pop dx");
|
puts(x86_ia16() ? "pop ax" : "pop eax");
|
||||||
puts("pop cx");
|
}
|
||||||
} else {
|
if(is_resource_in_use_right_now_at_this_current_point_in_time_and_also_not_created_right_now(a, s, HWR_EDX)) {
|
||||||
puts("pop edx");
|
puts(x86_ia16() ? "pop dx" : "pop edx");
|
||||||
puts("pop ecx");
|
}
|
||||||
|
if(is_resource_in_use_right_now_at_this_current_point_in_time_and_also_not_created_right_now(a, s, HWR_ECX)) {
|
||||||
|
puts(x86_ia16() ? "pop cx" : "pop ecx");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(s->nodeKind == AST_STMT_ASSIGN) {
|
} else if(s->nodeKind == AST_STMT_ASSIGN) {
|
||||||
|
Loading…
Reference in New Issue
Block a user