ps5: various errata; it works!!
This commit is contained in:
+26
-9
@@ -135,8 +135,8 @@ static void generate_function(symbol_t* function)
|
||||
symbol_t *sym = symtable->symbols[i];
|
||||
switch (sym->type) {
|
||||
case SYMBOL_PARAMETER:
|
||||
if (i < NUM_REGISTER_PARAMS) {
|
||||
PUSHQ(REGISTER_PARAMS[i]);
|
||||
if (sym->sequence_number < NUM_REGISTER_PARAMS) {
|
||||
PUSHQ(REGISTER_PARAMS[sym->sequence_number]);
|
||||
} else {
|
||||
/* these params are already on the stack */;
|
||||
}
|
||||
@@ -177,6 +177,10 @@ static void generate_function_call(node_t* call)
|
||||
POPQ(REGISTER_PARAMS[i]);
|
||||
}
|
||||
CALL(call->children[0]->symbol->name);
|
||||
if (args->n_children > NUM_REGISTER_PARAMS) {
|
||||
int stack_args = args->n_children - NUM_REGISTER_PARAMS;
|
||||
EMIT("addq $%d, %s", stack_args * 8, RSP);
|
||||
}
|
||||
}
|
||||
|
||||
#define UNARY_OP(OP, INST) \
|
||||
@@ -189,7 +193,8 @@ static void generate_function_call(node_t* call)
|
||||
generate_expression(left); \
|
||||
PUSHQ(RAX); \
|
||||
generate_expression(right); \
|
||||
POPQ(RCX); \
|
||||
MOVQ(RAX, RCX); \
|
||||
POPQ(RAX); \
|
||||
INST(RCX, RAX); \
|
||||
}
|
||||
#define DIVISION_OP \
|
||||
@@ -238,7 +243,12 @@ static void generate_expression(node_t* expression)
|
||||
switch (expression->n_children) {
|
||||
case 1:
|
||||
UNARY_OP("-", NEGQ);
|
||||
/* logical not "!" is omitted */
|
||||
if (strcmp(op, "!") == 0) {
|
||||
generate_expression(expression->children[0]);
|
||||
CMPQ("$0", RAX);
|
||||
SETE(AL);
|
||||
MOVZBQ(AL, RAX);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
node_t *left = expression->children[0];
|
||||
@@ -269,19 +279,24 @@ static void generate_expression(node_t* expression)
|
||||
static void generate_base_address(node_t *identifier) {
|
||||
assert(identifier->type == IDENTIFIER);
|
||||
symbol_t *sym = identifier->symbol;
|
||||
int offset;
|
||||
switch (sym->type) {
|
||||
case SYMBOL_GLOBAL_VAR:
|
||||
case SYMBOL_GLOBAL_ARRAY:
|
||||
LEAQ_GLOBAL(sym->name, RAX);
|
||||
break;
|
||||
case SYMBOL_LOCAL_VAR:
|
||||
int offset = -8 * (sym->sequence_number - FUNC_PARAM_COUNT(current_function) + 6 + 1);
|
||||
int spill = FUNC_PARAM_COUNT(current_function) > NUM_REGISTER_PARAMS
|
||||
? NUM_REGISTER_PARAMS : FUNC_PARAM_COUNT(current_function);
|
||||
int local_index = sym->sequence_number - FUNC_PARAM_COUNT(current_function);
|
||||
offset = -8 * (spill + local_index + 1);
|
||||
LEAQ_OFFSET(offset, RBP, RAX);
|
||||
break;
|
||||
case SYMBOL_PARAMETER:
|
||||
if (FUNC_PARAM_COUNT(current_function) < NUM_REGISTER_PARAMS) {
|
||||
int offset = -8 * (sym->sequence_number + 1);
|
||||
if (sym->sequence_number < NUM_REGISTER_PARAMS) {
|
||||
offset = -8 * (sym->sequence_number + 1);
|
||||
} else {
|
||||
int offset = 8 * (sym->sequence_number - 6 + 2);
|
||||
offset = 8 * (sym->sequence_number - 6 + 2);
|
||||
}
|
||||
LEAQ_OFFSET(offset, RBP, RAX);
|
||||
break;
|
||||
@@ -299,7 +314,7 @@ static void generate_assignment_statement(node_t* statement)
|
||||
if (child->type == IDENTIFIER) {
|
||||
generate_expression(statement->children[1]);
|
||||
STASH();
|
||||
generate_base_address(child->children[0]);
|
||||
generate_base_address(child);
|
||||
EMIT("movq %s, (%s)", RCX, RAX);
|
||||
} else if (child->type == ARRAY_INDEXING) {
|
||||
generate_base_address(child->children[0]);
|
||||
@@ -307,7 +322,9 @@ static void generate_assignment_statement(node_t* statement)
|
||||
generate_expression(child->children[1]);
|
||||
POPQ(RCX);
|
||||
EMIT("leaq (%s, %s, 8), %s", RCX, RAX, RCX);
|
||||
PUSHQ(RCX);
|
||||
generate_expression(statement->children[1]);
|
||||
POPQ(RCX);
|
||||
EMIT("movq %s, (%s)", RAX, RCX); // save the value in rax to the address of identifier[index]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user