diff options
| author | gingerBill <ginger.bill.22@gmail.com> | 2016-08-01 00:34:15 +0100 |
|---|---|---|
| committer | gingerBill <ginger.bill.22@gmail.com> | 2016-08-01 00:34:15 +0100 |
| commit | 88e05ad2b25b51ad3f5dd92554ffbfa3eeaa57b9 (patch) | |
| tree | f4aa339987a8aa05a86bfa410503200dfa7d72b7 /src/codegen/ssa.cpp | |
| parent | 70f6282f41cdd7f500159116c520140364f6739a (diff) | |
Basic Comparisons
Diffstat (limited to 'src/codegen/ssa.cpp')
| -rw-r--r-- | src/codegen/ssa.cpp | 67 |
1 files changed, 64 insertions, 3 deletions
diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index 070c3a1d6..b7d925d07 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -104,6 +104,7 @@ struct ssaInstruction { struct { + Type *type; Token op; ssaValue *left, *right; } binary_op; @@ -114,10 +115,10 @@ struct ssaInstruction { enum ssaValueKind { ssaValue_Invalid, + ssaValue_Constant, ssaValue_TypeName, ssaValue_Global, ssaValue_Procedure, - ssaValue_Constant, ssaValue_Block, ssaValue_Instruction, @@ -130,10 +131,10 @@ struct ssaValue { i32 id; union { + ssaConstant constant; ssaTypeName type_name; ssaGlobal global; ssaProcedure procedure; - ssaConstant constant; ssaBlock block; ssaInstruction instruction; }; @@ -157,6 +158,7 @@ struct ssaLvalue { }; }; + void ssa_module_init(ssaModule *m, Checker *c) { m->allocator = gb_heap_allocator(); m->info = &c->info; @@ -187,6 +189,8 @@ Type *ssa_instruction_type(ssaInstruction *instr) { return ssa_value_type(instr->store.address); case ssaInstruction_Load: return ssa_value_type(instr->load.address); + case ssaInstruction_BinaryOp: + return instr->binary_op.type; } return NULL; } @@ -202,6 +206,9 @@ void ssa_instruction_set_type(ssaInstruction *instr, Type *type) { case ssaInstruction_Load: // NOTE(bill): Do nothing break; + case ssaInstruction_BinaryOp: + instr->binary_op.type = type; + break; } } @@ -558,6 +565,31 @@ ssaValue *ssa_emit_arith(ssaProcedure *proc, Token op, ssaValue *left, ssaValue return ssa_emit(proc, v); } +ssaValue *ssa_emit_compare(ssaProcedure *proc, Token op, ssaValue *left, ssaValue *right) { + Type *a = get_base_type(ssa_value_type(left)); + Type *b = get_base_type(ssa_value_type(right)); + + if (op.kind == Token_CmpEq && + left->kind == ssaValue_Constant && left->constant.value.kind == ExactValue_Bool) { + if (left->constant.value.value_bool) { + if (is_type_boolean(b)) + return right; + } + } + + if (are_types_identical(a, b)) { + // NOTE(bill): No need for a conversion + } else if (left->kind == ssaValue_Constant) { + left = ssa_emit_conversion(proc, left, ssa_value_type(right)); + } else if (right->kind == ssaValue_Constant) { + right = ssa_emit_conversion(proc, right, ssa_value_type(left)); + } + + ssaValue *v = ssa_make_instruction_binary_op(proc, op, left, right); + ssa_value_set_type(v, &basic_types[Basic_bool]); + return ssa_emit(proc, v); +} + ssaValue *ssa_build_single_expression(ssaProcedure *proc, AstNode *expr, TypeAndValue *tv) { switch (expr->kind) { case AstNode_Identifier: { @@ -573,6 +605,9 @@ ssaValue *ssa_build_single_expression(ssaProcedure *proc, AstNode *expr, TypeAnd } } break; + case AstNode_ParenExpression: + return ssa_build_single_expression(proc, unparen_expression(expr), tv); + case AstNode_DereferenceExpression: { ssaLvalue addr = ssa_build_address(proc, expr->dereference_expression.operand); return ssa_lvalue_load(addr, proc); @@ -617,11 +652,37 @@ ssaValue *ssa_build_single_expression(ssaProcedure *proc, AstNode *expr, TypeAnd case Token_And: case Token_Or: case Token_Xor: - case Token_AndNot: return ssa_emit_arith(proc, be->op, ssa_build_expression(proc, be->left), ssa_build_expression(proc, be->right), tv->type); + + case Token_AndNot: { + AstNode ue = {AstNode_UnaryExpression}; + ue.unary_expression.op = be->op; + ue.unary_expression.op.kind = Token_Xor; + ue.unary_expression.operand = be->right; + ssaValue *left = ssa_build_expression(proc, be->left); + ssaValue *right = ssa_build_expression(proc, &ue); + Token op = be->op; + op.kind = Token_And; + return ssa_emit_arith(proc, op, left, right, tv->type); + } break; + + case Token_CmpEq: + case Token_NotEq: + case Token_Lt: + case Token_LtEq: + case Token_Gt: + case Token_GtEq: { + ssaValue *cmp = ssa_emit_compare(proc, be->op, + ssa_build_expression(proc, be->left), + ssa_build_expression(proc, be->right)); + return ssa_emit_conversion(proc, cmp, default_type(tv->type)); + } break; + + default: + GB_PANIC("Invalid binary expression"); } } break; case AstNode_ProcedureLiteral: |