ps5: implement operators in generate_expression
This commit is contained in:
@@ -166,6 +166,39 @@ static void generate_function_call(node_t* call)
|
||||
// TODO (Task 4.3)
|
||||
}
|
||||
|
||||
#define UNARY_OP(OP, INST) \
|
||||
if (strcmp(op, (OP)) == 0) { \
|
||||
generate_expression(expression->children[0]); \
|
||||
INST(RAX); \
|
||||
}
|
||||
#define BINARY_OP(OP, INST) \
|
||||
if (strcmp(op, (OP)) == 0) { \
|
||||
generate_expression(left); \
|
||||
PUSHQ(RAX); \
|
||||
generate_expression(right); \
|
||||
POPQ(RCX); \
|
||||
INST(RCX, RAX); \
|
||||
}
|
||||
#define DIVISION_OP \
|
||||
if (strcmp(op, "/") == 0) { \
|
||||
generate_expression(expression->children[1]); \
|
||||
PUSHQ(RAX); \
|
||||
generate_expression(expression->children[0]); \
|
||||
CQO; \
|
||||
POPQ(RCX); \
|
||||
IDIVQ(RCX); \
|
||||
}
|
||||
#define COMPARE_OP(OP, INST) \
|
||||
if (strcmp(op, (OP)) == 0) { \
|
||||
generate_expression(left); \
|
||||
PUSHQ(RAX); \
|
||||
generate_expression(right); \
|
||||
POPQ(RCX); \
|
||||
CMPQ(RAX, RCX); \
|
||||
INST(AL); \
|
||||
MOVZBQ(AL, RAX); \
|
||||
}
|
||||
|
||||
// Generates code to evaluate the expression, and place the result in %rax
|
||||
static void generate_expression(node_t* expression)
|
||||
{
|
||||
@@ -187,6 +220,30 @@ static void generate_expression(node_t* expression)
|
||||
EMIT("movq (%s), %s", RAX, RAX); // deref rax
|
||||
break;
|
||||
case OPERATOR:
|
||||
char *op = expression->data.operator;
|
||||
switch (expression->n_children) {
|
||||
case 1:
|
||||
UNARY_OP("-", NEGQ);
|
||||
/* logical not "!" is omitted */
|
||||
break;
|
||||
case 2:
|
||||
node_t *left = expression->children[0];
|
||||
node_t *right = expression->children[1];
|
||||
BINARY_OP("+", ADDQ);
|
||||
BINARY_OP("-", SUBQ);
|
||||
BINARY_OP("*", IMULQ);
|
||||
DIVISION_OP; // special snowflake
|
||||
COMPARE_OP("<", SETL);
|
||||
COMPARE_OP(">", SETG);
|
||||
COMPARE_OP("<=", SETLE);
|
||||
COMPARE_OP(">=", SETGE);
|
||||
COMPARE_OP("==", SETE);
|
||||
COMPARE_OP("!=", SETNE);
|
||||
break;
|
||||
case 3:
|
||||
/* ternary op "?:" is omitted */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FUNCTION_CALL:
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user