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) -> {
|
MapDQCOaLDhS_expand: [K, V, S]u1(MapDQCOaLDhS[K, V, S]* this) -> {
|
||||||
/* Unimplemented. */
|
S capacity = this.capacity;
|
||||||
return 0;
|
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) -> {
|
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++) {
|
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;
|
||||||
|
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;
|
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) {
|
||||||
@ -583,9 +608,9 @@ void cg_chunk(CGState *cg, AST *a) {
|
|||||||
if(a->chunk.stackReservation) {
|
if(a->chunk.stackReservation) {
|
||||||
for(int i = 0; i < MAX_REGS_PER_CLASS && cg->calleeSaved.reg[i]; i++) {
|
for(int i = 0; i < MAX_REGS_PER_CLASS && cg->calleeSaved.reg[i]; i++) {
|
||||||
if(x86_ia16()) {
|
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 {
|
} 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) {
|
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++) {
|
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];
|
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) {
|
if(resource & HWR_ESI) {
|
||||||
esiused = true;
|
esiused = true;
|
||||||
}
|
}
|
||||||
|
if(resource & HWR_EBP) {
|
||||||
|
ebpused = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nextUser = 0;
|
size_t nextUser = 0;
|
||||||
@ -675,6 +703,11 @@ static void callee_saved(AST *tlc, struct CalleeSavedState *state) {
|
|||||||
state->reg[nextUser] = x86_ia16() ? "di" : "edi";
|
state->reg[nextUser] = x86_ia16() ? "di" : "edi";
|
||||||
nextUser++;
|
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());
|
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->nodeKind = AST_STMT_ASSIGN;
|
||||||
assign->what = (AST*) ev[0];
|
assign->what = (AST*) ev[0];
|
||||||
assign->to = e;
|
assign->to = e;
|
||||||
|
vte->data.var.declaration = (AST*) assign;
|
||||||
|
|
||||||
if(stmtPrev) {
|
if(stmtPrev) {
|
||||||
stmtPrev->statement.next = (AST*) assign;
|
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->nodeKind = AST_STMT_ASSIGN;
|
||||||
assign2->what = (AST*) s->stmtAssign.what;
|
assign2->what = (AST*) s->stmtAssign.what;
|
||||||
assign2->to = (AST*) ev[0];
|
assign2->to = (AST*) ev[0];
|
||||||
|
tmp->data.var.declaration = (AST*) s;
|
||||||
|
|
||||||
s->stmtAssign.what = (AST*) ev[1];
|
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->what = (AST*) evar;
|
||||||
ass->to = ast_cast_expr((AST*) deref, vte->type); // Must cast because of "convention correctness"
|
ass->to = ast_cast_expr((AST*) deref, vte->type); // Must cast because of "convention correctness"
|
||||||
ass->next = n->chunk.statementFirst;
|
ass->next = n->chunk.statementFirst;
|
||||||
|
vte->data.var.declaration = (AST*) ass;
|
||||||
|
|
||||||
if(n->chunk.statementFirst) {
|
if(n->chunk.statementFirst) {
|
||||||
n->chunk.statementFirst = ass;
|
n->chunk.statementFirst = ass;
|
||||||
|
Loading…
Reference in New Issue
Block a user