diff --git a/ps5/src/emit.h b/ps5/src/emit.h index 9a0aef6..2cda337 100644 --- a/ps5/src/emit.h +++ b/ps5/src/emit.h @@ -45,6 +45,7 @@ #define CQO EMIT("cqo"); // Sign extend RAX -> RDX:RAX #define IDIVQ(by) EMIT("idivq %s", (by)) // Divide RDX:RAX by "by", store result in RAX +#define CALL(func) EMIT("call .%s", (func)) #define RET EMIT("ret") #define CMPQ(op1, op2) EMIT("cmpq %s, %s", (op1), (op2)) // Compare the two operands diff --git a/ps5/src/generator.c b/ps5/src/generator.c index cbc06b2..f370e57 100644 --- a/ps5/src/generator.c +++ b/ps5/src/generator.c @@ -164,6 +164,18 @@ static void generate_function(symbol_t* function) static void generate_function_call(node_t* call) { // TODO (Task 4.3) + node_t *args = call->children[1]; + for (int i = args->n_children - 1; i >= 0; i--) { + node_t *expr = args->children[i]; + generate_expression(expr); + PUSHQ(RAX); + } + int spill = args->n_children > NUM_REGISTER_PARAMS + ? NUM_REGISTER_PARAMS : args->n_children; + for (int i = 0; i < spill; i++) { + POPQ(REGISTER_PARAMS[i]); + } + CALL(call->children[0]->symbol->name); } #define UNARY_OP(OP, INST) \ @@ -247,6 +259,7 @@ static void generate_expression(node_t* expression) } break; case FUNCTION_CALL: + generate_function_call(expression); break; } }