Compare commits
5 Commits
692ed4d21c
...
8c4754b563
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8c4754b563 | ||
![]() |
9d975eeceb | ||
![]() |
ecab77f9e9 | ||
![]() |
132cedff09 | ||
![]() |
f978b66662 |
@ -46,8 +46,28 @@ MapDQCOaLDhS_try_add: [K, V, S]u1(MapDQCOaLDhS[K, V, S]* this, K* key, V* value)
|
||||
};
|
||||
|
||||
MapDQCOaLDhS_expand: [K, V, S]u1(MapDQCOaLDhS[K, V, S]* this) -> {
|
||||
/* Unimplemented. */
|
||||
return 0;
|
||||
S capacity = this.capacity;
|
||||
KVPair[K, V][?]* old_data = this.data;
|
||||
u8[?]* old_occupied = this.occupied;
|
||||
|
||||
S new_capacity = capacity * 2;
|
||||
this.capacity = new_capacity;
|
||||
this.data = calloc(new_capacity, @sizeof KVPair[K, V]);
|
||||
this.occupied = calloc(new_capacity, @sizeof((*this.occupied)[0]));
|
||||
|
||||
S i = 0;
|
||||
loop {
|
||||
if(i == capacity) {
|
||||
break;
|
||||
}
|
||||
if((*old_occupied)[i] != 0) {
|
||||
KVPair[K, V]* pair = &((*old_data)[i]);
|
||||
MapDQCOaLDhS_try_add[K, V, S](this, &pair.key, &pair.value);
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
MapDQCOaLDhS_add: [K, V, S]u1(MapDQCOaLDhS[K, V, S]* this, K* key, V* value) -> {
|
||||
|
@ -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;
|
||||
|
63
src/x86/cg.c
63
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) {
|
||||
@ -583,9 +608,9 @@ void cg_chunk(CGState *cg, AST *a) {
|
||||
if(a->chunk.stackReservation) {
|
||||
for(int i = 0; i < MAX_REGS_PER_CLASS && cg->calleeSaved.reg[i]; i++) {
|
||||
if(x86_ia16()) {
|
||||
printf("mov [bp + %li], %s\n", cg->calleeSaved.stackOffset[i] - a->chunk.stackReservation, cg->calleeSaved.reg[i]);
|
||||
printf("mov %s, [bp + %li]\n", cg->calleeSaved.reg[i], cg->calleeSaved.stackOffset[i] - a->chunk.stackReservation);
|
||||
} else {
|
||||
printf("mov [esp + %li], %s\n", cg->calleeSaved.stackOffset[i], cg->calleeSaved.reg[i]);
|
||||
printf("mov %s, [esp + %li]\n", cg->calleeSaved.reg[i], cg->calleeSaved.stackOffset[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -643,7 +668,7 @@ static bool var_collision(AST *tlc, ScopeItem *v1, ScopeItem *v2) {
|
||||
}
|
||||
|
||||
static void callee_saved(AST *tlc, struct CalleeSavedState *state) {
|
||||
bool ebxused = false, ediused = false, esiused = false;
|
||||
bool ebxused = false, ediused = false, esiused = false, ebpused = false;
|
||||
|
||||
for(size_t v = 0; v < tlc->chunk.varCount; v++) {
|
||||
size_t resource = REG_CLASSES[tlc->chunk.vars[v]->data.var.registerClass].rs[tlc->chunk.vars[v]->data.var.color];
|
||||
@ -657,6 +682,9 @@ static void callee_saved(AST *tlc, struct CalleeSavedState *state) {
|
||||
if(resource & HWR_ESI) {
|
||||
esiused = true;
|
||||
}
|
||||
if(resource & HWR_EBP) {
|
||||
ebpused = true;
|
||||
}
|
||||
}
|
||||
|
||||
size_t nextUser = 0;
|
||||
@ -675,6 +703,11 @@ static void callee_saved(AST *tlc, struct CalleeSavedState *state) {
|
||||
state->reg[nextUser] = x86_ia16() ? "di" : "edi";
|
||||
nextUser++;
|
||||
}
|
||||
if(ebpused) {
|
||||
state->stackOffset[nextUser] = nextUser * x86_max_gpr_size();
|
||||
state->reg[nextUser] = x86_ia16() ? "bp" : "ebp";
|
||||
nextUser++;
|
||||
}
|
||||
ast_grow_stack_frame(tlc, nextUser * x86_max_gpr_size());
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ static AST *varify(AST *tlc, AST *chunk, AST *stmtPrev, AST *stmt, AST *e) {
|
||||
assign->nodeKind = AST_STMT_ASSIGN;
|
||||
assign->what = (AST*) ev[0];
|
||||
assign->to = e;
|
||||
vte->data.var.declaration = (AST*) assign;
|
||||
|
||||
if(stmtPrev) {
|
||||
stmtPrev->statement.next = (AST*) assign;
|
||||
@ -297,6 +298,7 @@ static void normalize_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AS
|
||||
assign2->nodeKind = AST_STMT_ASSIGN;
|
||||
assign2->what = (AST*) s->stmtAssign.what;
|
||||
assign2->to = (AST*) ev[0];
|
||||
tmp->data.var.declaration = (AST*) s;
|
||||
|
||||
s->stmtAssign.what = (AST*) ev[1];
|
||||
|
||||
@ -517,6 +519,7 @@ static void pre_norm_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chunk, A
|
||||
ass->what = (AST*) evar;
|
||||
ass->to = ast_cast_expr((AST*) deref, vte->type); // Must cast because of "convention correctness"
|
||||
ass->next = n->chunk.statementFirst;
|
||||
vte->data.var.declaration = (AST*) ass;
|
||||
|
||||
if(n->chunk.statementFirst) {
|
||||
n->chunk.statementFirst = ass;
|
||||
|
Loading…
Reference in New Issue
Block a user