diff options
Diffstat (limited to 'compiler/codegen.cup')
| -rw-r--r-- | compiler/codegen.cup | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/compiler/codegen.cup b/compiler/codegen.cup index 71ffb76..407fab5 100644 --- a/compiler/codegen.cup +++ b/compiler/codegen.cup @@ -155,6 +155,72 @@ fn generate_expr_into_rax(node: Node*) { emit_asm(" setge al\n"); emit_asm(" movzx rax, al\n"); + } else if (node.typ == AST_BWAND) { + generate_expr_into_rax(node.d.binary.rhs); + emit_asm(" push rax\n"); + generate_expr_into_rax(node.d.binary.lhs); + emit_asm(" pop rbx\n"); + emit_asm(" and rax, rbx\n"); + + } else if (node.typ == AST_BWOR) { + generate_expr_into_rax(node.d.binary.rhs); + emit_asm(" push rax\n"); + generate_expr_into_rax(node.d.binary.lhs); + emit_asm(" pop rbx\n"); + emit_asm(" or rax, rbx\n"); + + } else if (node.typ == AST_XOR) { + generate_expr_into_rax(node.d.binary.rhs); + emit_asm(" push rax\n"); + generate_expr_into_rax(node.d.binary.lhs); + emit_asm(" pop rbx\n"); + emit_asm(" xor rax, rbx\n"); + + } else if (node.typ == AST_BWINV) { + generate_expr_into_rax(node.d.unary); + emit_asm(" not rax\n"); + + } else if (node.typ == AST_NEG) { + generate_expr_into_rax(node.d.unary); + emit_asm(" neg rax\n"); + + } else if (node.typ == AST_NOT) { + generate_expr_into_rax(node.d.unary); + emit_asm(" cmp rax, 0\n"); + emit_asm(" sete al\n"); + emit_asm(" movzx rax, al\n"); + + } else if (node.typ == AST_OR) { + // With short circuiting! + let label = ++gen_label_counter; + generate_expr_into_rax(node.d.binary.lhs,); + // If left is true, we can short-circuit + emit_asm(" cmp rax, 0\n"); + emit_asm(" je .or_r"); emit_num(label); emit_asm("\n"); + emit_asm(" mov rax, 1\n"); + emit_asm(" jmp .or_e"); emit_num(label); emit_asm("\n"); + emit_asm(".or_r"); emit_num(label); emit_asm(":\n"); + generate_expr_into_rax(node.d.binary.rhs); + // Booleanize the result + emit_asm(" cmp rax, 0\n"); + emit_asm(" setne al\n"); + emit_asm(".or_e"); emit_num(label); emit_asm(":\n"); + + } else if (node.typ == AST_AND) { + let label = ++gen_label_counter; + generate_expr_into_rax(node.d.binary.lhs); + // If left is false, we can short-circuit + emit_asm(" cmp rax, 0\n"); + emit_asm(" jne .and_r"); emit_num(label); emit_asm("\n"); + emit_asm(" mov rax, 0\n"); + emit_asm(" jmp .and_e"); emit_num(label); emit_asm("\n"); + emit_asm(".and_r"); emit_num(label); emit_asm(":\n"); + generate_expr_into_rax(node.d.binary.rhs); + // Booleanize the result + emit_asm(" cmp rax, 0\n"); + emit_asm(" setne al\n"); + emit_asm(".and_e"); emit_num(label); emit_asm(":\n"); + } else if (is_lvalue(node.typ)) { generate_lvalue_into_rax(node); emit_asm(" mov rax, [rax]\n"); |