diff options
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/c.zig | 64 |
1 files changed, 56 insertions, 8 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 3aef5a8f92..5695d22d45 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1162,12 +1162,13 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO .slice => try airSlice(f, inst), - .cmp_eq => try airBinOp(f, inst, " == "), .cmp_gt => try airBinOp(f, inst, " > "), .cmp_gte => try airBinOp(f, inst, " >= "), .cmp_lt => try airBinOp(f, inst, " < "), .cmp_lte => try airBinOp(f, inst, " <= "), - .cmp_neq => try airBinOp(f, inst, " != "), + + .cmp_eq => try airEquality(f, inst, "((", "=="), + .cmp_neq => try airEquality(f, inst, "!((", "!="), // bool_and and bool_or are non-short-circuit operations .bool_and => try airBinOp(f, inst, " & "), @@ -1257,9 +1258,9 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO .slice_elem_ptr => try airSliceElemPtr(f, inst), .array_elem_val => try airArrayElemVal(f, inst), - .unwrap_errunion_payload => try airUnwrapErrUnionPay(f, inst), + .unwrap_errunion_payload => try airUnwrapErrUnionPay(f, inst, ""), .unwrap_errunion_err => try airUnwrapErrUnionErr(f, inst), - .unwrap_errunion_payload_ptr => try airUnwrapErrUnionPay(f, inst), + .unwrap_errunion_payload_ptr => try airUnwrapErrUnionPay(f, inst, "&"), .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst), .wrap_errunion_payload => try airWrapErrUnionPay(f, inst), .wrap_errunion_err => try airWrapErrUnionErr(f, inst), @@ -1908,6 +1909,54 @@ fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue return local; } +fn airEquality( + f: *Function, + inst: Air.Inst.Index, + negate_prefix: []const u8, + eq_op_str: []const u8, +) !CValue { + if (f.liveness.isUnused(inst)) return CValue.none; + + const bin_op = f.air.instructions.items(.data)[inst].bin_op; + const lhs = try f.resolveInst(bin_op.lhs); + const rhs = try f.resolveInst(bin_op.rhs); + + const writer = f.object.writer(); + const inst_ty = f.air.typeOfIndex(inst); + const local = try f.allocLocal(inst_ty, .Const); + + try writer.writeAll(" = "); + + const lhs_ty = f.air.typeOf(bin_op.lhs); + if (lhs_ty.tag() == .optional) { + // (A && B) || (C && (A == B)) + // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload + + try writer.writeAll(negate_prefix); + try f.writeCValue(writer, lhs); + try writer.writeAll(".is_null && "); + try f.writeCValue(writer, rhs); + try writer.writeAll(".is_null) || ("); + try f.writeCValue(writer, lhs); + try writer.writeAll(".payload == "); + try f.writeCValue(writer, rhs); + try writer.writeAll(".payload && "); + try f.writeCValue(writer, lhs); + try writer.writeAll(".is_null == "); + try f.writeCValue(writer, rhs); + try writer.writeAll(".is_null));\n"); + + return local; + } + + try f.writeCValue(writer, lhs); + try writer.writeAll(eq_op_str); + try f.writeCValue(writer, rhs); + try writer.writeAll(";\n"); + + return local; +} + fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue { if (f.liveness.isUnused(inst)) return CValue.none; @@ -2104,8 +2153,8 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { const writer = f.object.writer(); const inst_ty = f.air.typeOfIndex(inst); - if (inst_ty.zigTypeTag() == .Pointer and - f.air.typeOf(ty_op.operand).zigTypeTag() == .Pointer) + if (inst_ty.isPtrAtRuntime() and + f.air.typeOf(ty_op.operand).isPtrAtRuntime()) { const local = try f.allocLocal(inst_ty, .Const); try writer.writeAll(" = ("); @@ -2503,7 +2552,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { return local; } -fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { +fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, maybe_addrof: []const u8) !CValue { if (f.liveness.isUnused(inst)) return CValue.none; @@ -2519,7 +2568,6 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { const inst_ty = f.air.typeOfIndex(inst); const maybe_deref = if (operand_ty.zigTypeTag() == .Pointer) "->" else "."; - const maybe_addrof = if (inst_ty.zigTypeTag() == .Pointer) "&" else ""; const local = try f.allocLocal(inst_ty, .Const); try writer.print(" = {s}(", .{maybe_addrof}); |
