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++) {
|
||||
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) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
AST *s = a->chunk.statementFirst;
|
||||
|
||||
@ -390,12 +411,14 @@ void cg_chunk(CGState *cg, AST *a) {
|
||||
|
||||
AST *e = s->stmtAssign.to;
|
||||
|
||||
if(x86_ia16()) {
|
||||
puts("push cx");
|
||||
puts("push dx");
|
||||
} else {
|
||||
puts("push ecx");
|
||||
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_ECX)) {
|
||||
puts(x86_ia16() ? "push cx" : "push ecx");
|
||||
}
|
||||
if(is_resource_in_use_right_now_at_this_current_point_in_time_and_also_not_created_right_now(a, s, HWR_EDX)) {
|
||||
puts(x86_ia16() ? "push dx" : "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;
|
||||
@ -422,12 +445,14 @@ void cg_chunk(CGState *cg, AST *a) {
|
||||
}
|
||||
}
|
||||
|
||||
if(x86_ia16()) {
|
||||
puts("pop dx");
|
||||
puts("pop cx");
|
||||
} else {
|
||||
puts("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_EAX)) {
|
||||
puts(x86_ia16() ? "pop ax" : "pop eax");
|
||||
}
|
||||
if(is_resource_in_use_right_now_at_this_current_point_in_time_and_also_not_created_right_now(a, s, HWR_EDX)) {
|
||||
puts(x86_ia16() ? "pop dx" : "pop edx");
|
||||
}
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user