| ... | @@ -1162,12 +1162,13 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO | ... | @@ -1162,12 +1162,13 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1162 | | 1162 | |
| 1163 | .slice => try airSlice(f, inst), | 1163 | .slice => try airSlice(f, inst), |
| 1164 | | 1164 | |
| 1165 | .cmp_eq => try airBinOp(f, inst, " == "), | | |
| 1166 | .cmp_gt => try airBinOp(f, inst, " > "), | 1165 | .cmp_gt => try airBinOp(f, inst, " > "), |
| 1167 | .cmp_gte => try airBinOp(f, inst, " >= "), | 1166 | .cmp_gte => try airBinOp(f, inst, " >= "), |
| 1168 | .cmp_lt => try airBinOp(f, inst, " < "), | 1167 | .cmp_lt => try airBinOp(f, inst, " < "), |
| 1169 | .cmp_lte => try airBinOp(f, inst, " <= "), | 1168 | .cmp_lte => try airBinOp(f, inst, " <= "), |
| 1170 | .cmp_neq => try airBinOp(f, inst, " != "), | 1169 | |
| | 1170 | .cmp_eq => try airEquality(f, inst, "((", "=="), |
| | 1171 | .cmp_neq => try airEquality(f, inst, "!((", "!="), |
| 1171 | | 1172 | |
| 1172 | // bool_and and bool_or are non-short-circuit operations | 1173 | // bool_and and bool_or are non-short-circuit operations |
| 1173 | .bool_and => try airBinOp(f, inst, " & "), | 1174 | .bool_and => try airBinOp(f, inst, " & "), |
| ... | @@ -1257,9 +1258,9 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO | ... | @@ -1257,9 +1258,9 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1257 | .slice_elem_ptr => try airSliceElemPtr(f, inst), | 1258 | .slice_elem_ptr => try airSliceElemPtr(f, inst), |
| 1258 | .array_elem_val => try airArrayElemVal(f, inst), | 1259 | .array_elem_val => try airArrayElemVal(f, inst), |
| 1259 | | 1260 | |
| 1260 | .unwrap_errunion_payload => try airUnwrapErrUnionPay(f, inst), | 1261 | .unwrap_errunion_payload => try airUnwrapErrUnionPay(f, inst, ""), |
| 1261 | .unwrap_errunion_err => try airUnwrapErrUnionErr(f, inst), | 1262 | .unwrap_errunion_err => try airUnwrapErrUnionErr(f, inst), |
| 1262 | .unwrap_errunion_payload_ptr => try airUnwrapErrUnionPay(f, inst), | 1263 | .unwrap_errunion_payload_ptr => try airUnwrapErrUnionPay(f, inst, "&"), |
| 1263 | .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst), | 1264 | .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst), |
| 1264 | .wrap_errunion_payload => try airWrapErrUnionPay(f, inst), | 1265 | .wrap_errunion_payload => try airWrapErrUnionPay(f, inst), |
| 1265 | .wrap_errunion_err => try airWrapErrUnionErr(f, inst), | 1266 | .wrap_errunion_err => try airWrapErrUnionErr(f, inst), |
| ... | @@ -1908,6 +1909,54 @@ fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue | ... | @@ -1908,6 +1909,54 @@ fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue |
| 1908 | return local; | 1909 | return local; |
| 1909 | } | 1910 | } |
| 1910 | | 1911 | |
| | 1912 | fn airEquality( |
| | 1913 | f: *Function, |
| | 1914 | inst: Air.Inst.Index, |
| | 1915 | negate_prefix: []const u8, |
| | 1916 | eq_op_str: []const u8, |
| | 1917 | ) !CValue { |
| | 1918 | if (f.liveness.isUnused(inst)) return CValue.none; |
| | 1919 | |
| | 1920 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| | 1921 | const lhs = try f.resolveInst(bin_op.lhs); |
| | 1922 | const rhs = try f.resolveInst(bin_op.rhs); |
| | 1923 | |
| | 1924 | const writer = f.object.writer(); |
| | 1925 | const inst_ty = f.air.typeOfIndex(inst); |
| | 1926 | const local = try f.allocLocal(inst_ty, .Const); |
| | 1927 | |
| | 1928 | try writer.writeAll(" = "); |
| | 1929 | |
| | 1930 | const lhs_ty = f.air.typeOf(bin_op.lhs); |
| | 1931 | if (lhs_ty.tag() == .optional) { |
| | 1932 | // (A && B) || (C && (A == B)) |
| | 1933 | // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload |
| | 1934 | |
| | 1935 | try writer.writeAll(negate_prefix); |
| | 1936 | try f.writeCValue(writer, lhs); |
| | 1937 | try writer.writeAll(".is_null && "); |
| | 1938 | try f.writeCValue(writer, rhs); |
| | 1939 | try writer.writeAll(".is_null) || ("); |
| | 1940 | try f.writeCValue(writer, lhs); |
| | 1941 | try writer.writeAll(".payload == "); |
| | 1942 | try f.writeCValue(writer, rhs); |
| | 1943 | try writer.writeAll(".payload && "); |
| | 1944 | try f.writeCValue(writer, lhs); |
| | 1945 | try writer.writeAll(".is_null == "); |
| | 1946 | try f.writeCValue(writer, rhs); |
| | 1947 | try writer.writeAll(".is_null));\n"); |
| | 1948 | |
| | 1949 | return local; |
| | 1950 | } |
| | 1951 | |
| | 1952 | try f.writeCValue(writer, lhs); |
| | 1953 | try writer.writeAll(eq_op_str); |
| | 1954 | try f.writeCValue(writer, rhs); |
| | 1955 | try writer.writeAll(";\n"); |
| | 1956 | |
| | 1957 | return local; |
| | 1958 | } |
| | 1959 | |
| 1911 | fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue { | 1960 | fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue { |
| 1912 | if (f.liveness.isUnused(inst)) | 1961 | if (f.liveness.isUnused(inst)) |
| 1913 | return CValue.none; | 1962 | return CValue.none; |
| ... | @@ -2104,8 +2153,8 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2104,8 +2153,8 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2104 | | 2153 | |
| 2105 | const writer = f.object.writer(); | 2154 | const writer = f.object.writer(); |
| 2106 | const inst_ty = f.air.typeOfIndex(inst); | 2155 | const inst_ty = f.air.typeOfIndex(inst); |
| 2107 | if (inst_ty.zigTypeTag() == .Pointer and | 2156 | if (inst_ty.isPtrAtRuntime() and |
| 2108 | f.air.typeOf(ty_op.operand).zigTypeTag() == .Pointer) | 2157 | f.air.typeOf(ty_op.operand).isPtrAtRuntime()) |
| 2109 | { | 2158 | { |
| 2110 | const local = try f.allocLocal(inst_ty, .Const); | 2159 | const local = try f.allocLocal(inst_ty, .Const); |
| 2111 | try writer.writeAll(" = ("); | 2160 | try writer.writeAll(" = ("); |
| ... | @@ -2503,7 +2552,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2503,7 +2552,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2503 | return local; | 2552 | return local; |
| 2504 | } | 2553 | } |
| 2505 | | 2554 | |
| 2506 | fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { | 2555 | fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, maybe_addrof: []const u8) !CValue { |
| 2507 | if (f.liveness.isUnused(inst)) | 2556 | if (f.liveness.isUnused(inst)) |
| 2508 | return CValue.none; | 2557 | return CValue.none; |
| 2509 | | 2558 | |
| ... | @@ -2519,7 +2568,6 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2519,7 +2568,6 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2519 | | 2568 | |
| 2520 | const inst_ty = f.air.typeOfIndex(inst); | 2569 | const inst_ty = f.air.typeOfIndex(inst); |
| 2521 | const maybe_deref = if (operand_ty.zigTypeTag() == .Pointer) "->" else "."; | 2570 | const maybe_deref = if (operand_ty.zigTypeTag() == .Pointer) "->" else "."; |
| 2522 | const maybe_addrof = if (inst_ty.zigTypeTag() == .Pointer) "&" else ""; | | |
| 2523 | | 2571 | |
| 2524 | const local = try f.allocLocal(inst_ty, .Const); | 2572 | const local = try f.allocLocal(inst_ty, .Const); |
| 2525 | try writer.print(" = {s}(", .{maybe_addrof}); | 2573 | try writer.print(" = {s}(", .{maybe_addrof}); |