| ... | @@ -3339,6 +3339,9 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !void { | ... | @@ -3339,6 +3339,9 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !void { |
| 3339 | const target = f.object.dg.module.getTarget(); | 3339 | const target = f.object.dg.module.getTarget(); |
| 3340 | if (inst_ty.bitSize(target) > 64) {} | 3340 | if (inst_ty.bitSize(target) > 64) {} |
| 3341 | | 3341 | |
| | 3342 | try writer.writeByte('('); |
| | 3343 | try f.renderTypecast(writer, inst_ty); |
| | 3344 | try writer.writeByte(')'); |
| 3342 | try writer.writeByte(if (inst_ty.tag() == .bool) '!' else '~'); | 3345 | try writer.writeByte(if (inst_ty.tag() == .bool) '!' else '~'); |
| 3343 | try f.writeCValue(writer, op, .Other); | 3346 | try f.writeCValue(writer, op, .Other); |
| 3344 | } | 3347 | } |
| ... | @@ -3357,15 +3360,20 @@ fn airBinOp( | ... | @@ -3357,15 +3360,20 @@ fn airBinOp( |
| 3357 | if ((operand_ty.isInt() and operand_ty.bitSize(target) > 64) or operand_ty.isRuntimeFloat()) | 3360 | if ((operand_ty.isInt() and operand_ty.bitSize(target) > 64) or operand_ty.isRuntimeFloat()) |
| 3358 | return airBinBuiltinCall(f, inst, operation, info); | 3361 | return airBinBuiltinCall(f, inst, operation, info); |
| 3359 | | 3362 | |
| | 3363 | const inst_ty = f.air.typeOfIndex(inst); |
| 3360 | const lhs = try f.resolveInst(bin_op.lhs); | 3364 | const lhs = try f.resolveInst(bin_op.lhs); |
| 3361 | const rhs = try f.resolveInst(bin_op.rhs); | 3365 | const rhs = try f.resolveInst(bin_op.rhs); |
| 3362 | | 3366 | |
| 3363 | const writer = f.object.writer(); | 3367 | const writer = f.object.writer(); |
| | 3368 | try writer.writeByte('('); |
| | 3369 | try f.renderTypecast(writer, inst_ty); |
| | 3370 | try writer.writeAll(")("); |
| 3364 | try f.writeCValue(writer, lhs, .Other); | 3371 | try f.writeCValue(writer, lhs, .Other); |
| 3365 | try writer.writeByte(' '); | 3372 | try writer.writeByte(' '); |
| 3366 | try writer.writeAll(operator); | 3373 | try writer.writeAll(operator); |
| 3367 | try writer.writeByte(' '); | 3374 | try writer.writeByte(' '); |
| 3368 | try f.writeCValue(writer, rhs, .Other); | 3375 | try f.writeCValue(writer, rhs, .Other); |
| | 3376 | try writer.writeByte(')'); |
| 3369 | } | 3377 | } |
| 3370 | | 3378 | |
| 3371 | fn airCmpOp( | 3379 | fn airCmpOp( |
| ... | @@ -3827,32 +3835,40 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3827,32 +3835,40 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3827 | } | 3835 | } |
| 3828 | | 3836 | |
| 3829 | fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { | 3837 | fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3830 | const inst_ty = f.air.typeOfIndex(inst); | 3838 | const src_ty = f.air.typeOfIndex(inst); |
| 3831 | // No IgnoreComptime until Sema stops giving us garbage Air. | 3839 | // No IgnoreComptime until Sema stops giving us garbage Air. |
| 3832 | // https://github.com/ziglang/zig/issues/13410 | 3840 | // https://github.com/ziglang/zig/issues/13410 |
| 3833 | if (f.liveness.isUnused(inst) or !inst_ty.hasRuntimeBits()) return CValue.none; | 3841 | if (f.liveness.isUnused(inst) or !src_ty.hasRuntimeBits()) return CValue.none; |
| 3834 | | 3842 | |
| 3835 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; | 3843 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 3836 | const operand = try f.resolveInstNoInline(ty_op.operand); | 3844 | const operand = try f.resolveInstNoInline(ty_op.operand); |
| | 3845 | const dest_ty = f.air.typeOf(ty_op.operand); |
| | 3846 | const target = f.object.dg.module.getTarget(); |
| | 3847 | |
| | 3848 | if (dest_ty.isAbiInt() and src_ty.isAbiInt()) { |
| | 3849 | const src_info = src_ty.intInfo(target); |
| | 3850 | const dest_info = dest_ty.intInfo(target); |
| | 3851 | if (std.meta.eql(src_info, dest_info)) { |
| | 3852 | return operand; |
| | 3853 | } |
| | 3854 | } |
| 3837 | | 3855 | |
| 3838 | const writer = f.object.writer(); | 3856 | const writer = f.object.writer(); |
| 3839 | if (inst_ty.isPtrAtRuntime() and | 3857 | if (src_ty.isPtrAtRuntime() and dest_ty.isPtrAtRuntime()) { |
| 3840 | f.air.typeOf(ty_op.operand).isPtrAtRuntime()) | 3858 | const local = try f.allocLocal(src_ty, .Const); |
| 3841 | { | | |
| 3842 | const local = try f.allocLocal(inst_ty, .Const); | | |
| 3843 | try writer.writeAll(" = ("); | 3859 | try writer.writeAll(" = ("); |
| 3844 | try f.renderTypecast(writer, inst_ty); | 3860 | try f.renderTypecast(writer, src_ty); |
| 3845 | try writer.writeByte(')'); | 3861 | try writer.writeByte(')'); |
| 3846 | try f.writeCValue(writer, operand, .Other); | 3862 | try f.writeCValue(writer, operand, .Other); |
| 3847 | try writer.writeAll(";\n"); | 3863 | try writer.writeAll(";\n"); |
| 3848 | return local; | 3864 | return local; |
| 3849 | } | 3865 | } |
| 3850 | | 3866 | |
| 3851 | const local = try f.allocLocal(inst_ty, .Mut); | 3867 | const local = try f.allocLocal(src_ty, .Mut); |
| 3852 | try writer.writeAll(";\n"); | 3868 | try writer.writeAll(";\n"); |
| 3853 | | 3869 | |
| 3854 | const operand_lval = if (operand == .constant) blk: { | 3870 | const operand_lval = if (operand == .constant) blk: { |
| 3855 | const operand_local = try f.allocLocal(f.air.typeOf(ty_op.operand), .Const); | 3871 | const operand_local = try f.allocLocal(dest_ty, .Const); |
| 3856 | try writer.writeAll(" = "); | 3872 | try writer.writeAll(" = "); |
| 3857 | try f.writeCValue(writer, operand, .Initializer); | 3873 | try f.writeCValue(writer, operand, .Initializer); |
| 3858 | try writer.writeAll(";\n"); | 3874 | try writer.writeAll(";\n"); |
| ... | @@ -3864,17 +3880,17 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3864,17 +3880,17 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3864 | try writer.writeAll(", &"); | 3880 | try writer.writeAll(", &"); |
| 3865 | try f.writeCValue(writer, operand_lval, .Other); | 3881 | try f.writeCValue(writer, operand_lval, .Other); |
| 3866 | try writer.writeAll(", sizeof("); | 3882 | try writer.writeAll(", sizeof("); |
| 3867 | try f.renderTypecast(writer, inst_ty); | 3883 | try f.renderTypecast(writer, src_ty); |
| 3868 | try writer.writeAll("));\n"); | 3884 | try writer.writeAll("));\n"); |
| 3869 | | 3885 | |
| 3870 | // Ensure padding bits have the expected value. | 3886 | // Ensure padding bits have the expected value. |
| 3871 | if (inst_ty.isAbiInt()) { | 3887 | if (src_ty.isAbiInt()) { |
| 3872 | try f.writeCValue(writer, local, .Other); | 3888 | try f.writeCValue(writer, local, .Other); |
| 3873 | try writer.writeAll(" = zig_wrap_"); | 3889 | try writer.writeAll(" = zig_wrap_"); |
| 3874 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); | 3890 | try f.object.dg.renderTypeForBuiltinFnName(writer, src_ty); |
| 3875 | try writer.writeByte('('); | 3891 | try writer.writeByte('('); |
| 3876 | try f.writeCValue(writer, local, .Other); | 3892 | try f.writeCValue(writer, local, .Other); |
| 3877 | try f.object.dg.renderBuiltinInfo(writer, inst_ty, .Bits); | 3893 | try f.object.dg.renderBuiltinInfo(writer, src_ty, .Bits); |
| 3878 | try writer.writeAll(");\n"); | 3894 | try writer.writeAll(");\n"); |
| 3879 | } | 3895 | } |
| 3880 | | 3896 | |