| ... | @@ -4096,9 +4096,7 @@ fn lowerTry( | ... | @@ -4096,9 +4096,7 @@ fn lowerTry( |
| 4096 | const is_array = lowersToArray(payload_ty, target); | 4096 | const is_array = lowersToArray(payload_ty, target); |
| 4097 | try reap(f, inst, &.{operand}); | 4097 | try reap(f, inst, &.{operand}); |
| 4098 | const local = try f.allocLocal(inst, result_ty); | 4098 | const local = try f.allocLocal(inst, result_ty); |
| 4099 | try f.writeCValue(writer, local, .Other); | | |
| 4100 | if (is_array) { | 4099 | if (is_array) { |
| 4101 | try writer.writeAll(";\n"); | | |
| 4102 | try writer.writeAll("memcpy("); | 4100 | try writer.writeAll("memcpy("); |
| 4103 | try f.writeCValue(writer, local, .FunctionArgument); | 4101 | try f.writeCValue(writer, local, .FunctionArgument); |
| 4104 | try writer.writeAll(", "); | 4102 | try writer.writeAll(", "); |
| ... | @@ -4107,6 +4105,7 @@ fn lowerTry( | ... | @@ -4107,6 +4105,7 @@ fn lowerTry( |
| 4107 | try f.renderTypecast(writer, payload_ty); | 4105 | try f.renderTypecast(writer, payload_ty); |
| 4108 | try writer.writeAll("));\n"); | 4106 | try writer.writeAll("));\n"); |
| 4109 | } else { | 4107 | } else { |
| | 4108 | try f.writeCValue(writer, local, .Other); |
| 4110 | try writer.writeAll(" = "); | 4109 | try writer.writeAll(" = "); |
| 4111 | if (operand_is_ptr or isByRef(payload_ty)) { | 4110 | if (operand_is_ptr or isByRef(payload_ty)) { |
| 4112 | try writer.writeByte('&'); | 4111 | try writer.writeByte('&'); |
| ... | @@ -4849,16 +4848,18 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4849,16 +4848,18 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4849 | return CValue{ .undef = inst_ty }; | 4848 | return CValue{ .undef = inst_ty }; |
| 4850 | } | 4849 | } |
| 4851 | | 4850 | |
| | 4851 | const local = try f.allocLocal(inst, inst_ty); |
| | 4852 | try f.writeCValue(writer, local, .Other); |
| | 4853 | |
| 4852 | if (opt_ty.optionalReprIsPayload()) { | 4854 | if (opt_ty.optionalReprIsPayload()) { |
| 4853 | // the operand is just a regular pointer, no need to do anything special. | 4855 | // the operand is just a regular pointer, no need to do anything special. |
| 4854 | // *?*T -> **T and ?*T -> *T are **T -> **T and *T -> *T in C | 4856 | // *?*T -> **T and ?*T -> *T are **T -> **T and *T -> *T in C |
| 4855 | return operand; | 4857 | try writer.writeAll(" = "); |
| | 4858 | try f.writeCValue(writer, operand, .Other); |
| | 4859 | } else { |
| | 4860 | try writer.writeAll(" = &"); |
| | 4861 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" }); |
| 4856 | } | 4862 | } |
| 4857 | | | |
| 4858 | const local = try f.allocLocal(inst, inst_ty); | | |
| 4859 | try f.writeCValue(writer, local, .Other); | | |
| 4860 | try writer.writeAll(" = &"); | | |
| 4861 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" }); | | |
| 4862 | try writer.writeAll(";\n"); | 4863 | try writer.writeAll(";\n"); |
| 4863 | return local; | 4864 | return local; |
| 4864 | } | 4865 | } |
| ... | @@ -4872,25 +4873,37 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4872,25 +4873,37 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4872 | | 4873 | |
| 4873 | const opt_ty = operand_ty.elemType(); | 4874 | const opt_ty = operand_ty.elemType(); |
| 4874 | | 4875 | |
| | 4876 | const inst_ty = f.air.typeOfIndex(inst); |
| | 4877 | |
| 4875 | if (opt_ty.optionalReprIsPayload()) { | 4878 | if (opt_ty.optionalReprIsPayload()) { |
| | 4879 | if (f.liveness.isUnused(inst)) { |
| | 4880 | return CValue.none; |
| | 4881 | } |
| | 4882 | const local = try f.allocLocal(inst, inst_ty); |
| 4876 | // The payload and the optional are the same value. | 4883 | // The payload and the optional are the same value. |
| 4877 | // Setting to non-null will be done when the payload is set. | 4884 | // Setting to non-null will be done when the payload is set. |
| 4878 | return operand; | 4885 | try f.writeCValue(writer, local, .Other); |
| 4879 | } | 4886 | try writer.writeAll(" = "); |
| 4880 | | 4887 | try f.writeCValue(writer, operand, .Other); |
| 4881 | try f.writeCValueDeref(writer, operand); | 4888 | try writer.writeAll(";\n"); |
| 4882 | try writer.writeAll(".is_null = "); | 4889 | return local; |
| 4883 | try f.object.dg.renderValue(writer, Type.bool, Value.false, .Initializer); | 4890 | } else { |
| 4884 | try writer.writeAll(";\n"); | 4891 | try f.writeCValueDeref(writer, operand); |
| | 4892 | try writer.writeAll(".is_null = "); |
| | 4893 | try f.object.dg.renderValue(writer, Type.bool, Value.false, .Initializer); |
| | 4894 | try writer.writeAll(";\n"); |
| 4885 | | 4895 | |
| 4886 | const inst_ty = f.air.typeOfIndex(inst); | 4896 | if (f.liveness.isUnused(inst)) { |
| 4887 | const local = try f.allocLocal(inst, inst_ty); | 4897 | return CValue.none; |
| 4888 | try f.writeCValue(writer, local, .Other); | 4898 | } |
| 4889 | try writer.writeAll(" = &"); | | |
| 4890 | try f.writeCValueDeref(writer, operand); | | |
| 4891 | | 4899 | |
| 4892 | try writer.writeAll(".payload;\n"); | 4900 | const local = try f.allocLocal(inst, inst_ty); |
| 4893 | return local; | 4901 | try f.writeCValue(writer, local, .Other); |
| | 4902 | try writer.writeAll(" = &"); |
| | 4903 | try f.writeCValueDeref(writer, operand); |
| | 4904 | try writer.writeAll(".payload;\n"); |
| | 4905 | return local; |
| | 4906 | } |
| 4894 | } | 4907 | } |
| 4895 | | 4908 | |
| 4896 | fn airStructFieldPtr(f: *Function, inst: Air.Inst.Index) !CValue { | 4909 | fn airStructFieldPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| ... | @@ -5164,7 +5177,6 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5164,7 +5177,6 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5164 | } else struct_byval; | 5177 | } else struct_byval; |
| 5165 | | 5178 | |
| 5166 | const local = try f.allocLocal(inst, inst_ty); | 5179 | const local = try f.allocLocal(inst, inst_ty); |
| 5167 | try f.writeCValue(writer, local, .Other); | | |
| 5168 | try writer.writeAll("memcpy(&"); | 5180 | try writer.writeAll("memcpy(&"); |
| 5169 | try f.writeCValue(writer, local, .FunctionArgument); | 5181 | try f.writeCValue(writer, local, .FunctionArgument); |
| 5170 | try writer.writeAll(", &"); | 5182 | try writer.writeAll(", &"); |
| ... | @@ -5230,25 +5242,28 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5230,25 +5242,28 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5230 | const inst_ty = f.air.typeOfIndex(inst); | 5242 | const inst_ty = f.air.typeOfIndex(inst); |
| 5231 | const operand = try f.resolveInst(ty_op.operand); | 5243 | const operand = try f.resolveInst(ty_op.operand); |
| 5232 | const operand_ty = f.air.typeOf(ty_op.operand); | 5244 | const operand_ty = f.air.typeOf(ty_op.operand); |
| | 5245 | try reap(f, inst, &.{ty_op.operand}); |
| 5233 | | 5246 | |
| 5234 | const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer; | 5247 | const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer; |
| 5235 | const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; | 5248 | const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; |
| 5236 | const error_ty = error_union_ty.errorUnionSet(); | 5249 | const error_ty = error_union_ty.errorUnionSet(); |
| 5237 | const payload_ty = error_union_ty.errorUnionPayload(); | 5250 | const payload_ty = error_union_ty.errorUnionPayload(); |
| 5238 | if (!payload_ty.hasRuntimeBits()) return operand; | | |
| 5239 | try reap(f, inst, &.{ty_op.operand}); | | |
| 5240 | | | |
| 5241 | const writer = f.object.writer(); | | |
| 5242 | const local = try f.allocLocal(inst, inst_ty); | 5251 | const local = try f.allocLocal(inst, inst_ty); |
| | 5252 | const writer = f.object.writer(); |
| 5243 | try f.writeCValue(writer, local, .Other); | 5253 | try f.writeCValue(writer, local, .Other); |
| 5244 | try writer.writeAll(" = "); | 5254 | try writer.writeAll(" = "); |
| 5245 | if (!error_ty.errorSetIsEmpty()) | 5255 | |
| 5246 | if (operand_is_ptr) | 5256 | if (!payload_ty.hasRuntimeBits()) { |
| 5247 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" }) | 5257 | try f.writeCValue(writer, operand, .Other); |
| | 5258 | } else { |
| | 5259 | if (!error_ty.errorSetIsEmpty()) |
| | 5260 | if (operand_is_ptr) |
| | 5261 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" }) |
| | 5262 | else |
| | 5263 | try f.writeCValueMember(writer, operand, .{ .identifier = "error" }) |
| 5248 | else | 5264 | else |
| 5249 | try f.writeCValueMember(writer, operand, .{ .identifier = "error" }) | 5265 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer); |
| 5250 | else | 5266 | } |
| 5251 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer); | | |
| 5252 | try writer.writeAll(";\n"); | 5267 | try writer.writeAll(";\n"); |
| 5253 | return local; | 5268 | return local; |
| 5254 | } | 5269 | } |
| ... | @@ -5345,13 +5360,19 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5345,13 +5360,19 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5345 | | 5360 | |
| 5346 | const writer = f.object.writer(); | 5361 | const writer = f.object.writer(); |
| 5347 | const operand = try f.resolveInst(ty_op.operand); | 5362 | const operand = try f.resolveInst(ty_op.operand); |
| | 5363 | try reap(f, inst, &.{ty_op.operand}); |
| 5348 | const error_union_ty = f.air.typeOfIndex(inst); | 5364 | const error_union_ty = f.air.typeOfIndex(inst); |
| 5349 | const payload_ty = error_union_ty.errorUnionPayload(); | 5365 | const payload_ty = error_union_ty.errorUnionPayload(); |
| 5350 | if (!payload_ty.hasRuntimeBits()) return operand; | 5366 | const local = try f.allocLocal(inst, error_union_ty); |
| 5351 | | 5367 | |
| 5352 | try reap(f, inst, &.{ty_op.operand}); | 5368 | if (!payload_ty.hasRuntimeBits()) { |
| | 5369 | try f.writeCValue(writer, local, .Other); |
| | 5370 | try writer.writeAll(" = "); |
| | 5371 | try f.writeCValue(writer, operand, .Other); |
| | 5372 | try writer.writeAll(";\n"); |
| | 5373 | return local; |
| | 5374 | } |
| 5353 | | 5375 | |
| 5354 | const local = try f.allocLocal(inst, error_union_ty); | | |
| 5355 | { | 5376 | { |
| 5356 | // TODO: set the payload to undefined | 5377 | // TODO: set the payload to undefined |
| 5357 | //try f.writeCValue(writer, local, .Other); | 5378 | //try f.writeCValue(writer, local, .Other); |
| ... | @@ -5754,6 +5775,11 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue | ... | @@ -5754,6 +5775,11 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue |
| 5754 | try writer.writeAll(";\n"); | 5775 | try writer.writeAll(";\n"); |
| 5755 | } | 5776 | } |
| 5756 | | 5777 | |
| | 5778 | if (f.liveness.isUnused(inst)) { |
| | 5779 | try freeLocal(f, inst, local.local, 0); |
| | 5780 | return CValue.none; |
| | 5781 | } |
| | 5782 | |
| 5757 | return local; | 5783 | return local; |
| 5758 | } | 5784 | } |
| 5759 | | 5785 | |
| ... | @@ -5790,6 +5816,11 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5790,6 +5816,11 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5790 | try writeMemoryOrder(writer, extra.ordering()); | 5816 | try writeMemoryOrder(writer, extra.ordering()); |
| 5791 | try writer.writeAll(");\n"); | 5817 | try writer.writeAll(");\n"); |
| 5792 | | 5818 | |
| | 5819 | if (f.liveness.isUnused(inst)) { |
| | 5820 | try freeLocal(f, inst, local.local, 0); |
| | 5821 | return CValue.none; |
| | 5822 | } |
| | 5823 | |
| 5793 | return local; | 5824 | return local; |
| 5794 | } | 5825 | } |
| 5795 | | 5826 | |
| ... | @@ -6222,30 +6253,28 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6222,30 +6253,28 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6222 | | 6253 | |
| 6223 | const writer = f.object.writer(); | 6254 | const writer = f.object.writer(); |
| 6224 | const local = try f.allocLocal(inst, inst_ty); | 6255 | const local = try f.allocLocal(inst, inst_ty); |
| 6225 | try f.writeCValue(writer, local, .Other); | | |
| 6226 | try writer.writeAll(" = ("); | | |
| 6227 | try f.renderTypecast(writer, inst_ty); | | |
| 6228 | try writer.writeAll(")"); | | |
| 6229 | switch (inst_ty.zigTypeTag()) { | 6256 | switch (inst_ty.zigTypeTag()) { |
| 6230 | .Array, .Vector => { | 6257 | .Array, .Vector => { |
| 6231 | const elem_ty = inst_ty.childType(); | 6258 | const elem_ty = inst_ty.childType(); |
| 6232 | try writer.writeByte('{'); | 6259 | for (resolved_elements) |element, i| { |
| 6233 | var empty = true; | 6260 | try f.writeCValue(writer, local, .Other); |
| 6234 | for (resolved_elements) |element| { | 6261 | try writer.print("[{d}] = ", .{i}); |
| 6235 | if (!empty) try writer.writeAll(", "); | 6262 | try f.writeCValue(writer, element, .Other); |
| 6236 | try f.writeCValue(writer, element, .Initializer); | 6263 | try writer.writeAll(";\n"); |
| 6237 | empty = false; | | |
| 6238 | } | 6264 | } |
| 6239 | if (inst_ty.sentinel()) |sentinel| { | 6265 | if (inst_ty.sentinel()) |sentinel| { |
| 6240 | if (!empty) try writer.writeAll(", "); | 6266 | try f.writeCValue(writer, local, .Other); |
| 6241 | try f.object.dg.renderValue(writer, elem_ty, sentinel, .Initializer); | 6267 | try writer.print("[{d}] = ", .{resolved_elements.len}); |
| 6242 | empty = false; | 6268 | try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other); |
| | 6269 | try writer.writeAll(";\n"); |
| 6243 | } | 6270 | } |
| 6244 | if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)}); | | |
| 6245 | try writer.writeAll("};\n"); | | |
| 6246 | }, | 6271 | }, |
| 6247 | .Struct => switch (inst_ty.containerLayout()) { | 6272 | .Struct => switch (inst_ty.containerLayout()) { |
| 6248 | .Auto, .Extern => { | 6273 | .Auto, .Extern => { |
| | 6274 | try f.writeCValue(writer, local, .Other); |
| | 6275 | try writer.writeAll(" = ("); |
| | 6276 | try f.renderTypecast(writer, inst_ty); |
| | 6277 | try writer.writeAll(")"); |
| 6249 | try writer.writeByte('{'); | 6278 | try writer.writeByte('{'); |
| 6250 | var empty = true; | 6279 | var empty = true; |
| 6251 | for (elements) |element, index| { | 6280 | for (elements) |element, index| { |
| ... | @@ -6291,6 +6320,10 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6291,6 +6320,10 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6291 | } | 6320 | } |
| 6292 | }, | 6321 | }, |
| 6293 | .Packed => { | 6322 | .Packed => { |
| | 6323 | try f.writeCValue(writer, local, .Other); |
| | 6324 | try writer.writeAll(" = ("); |
| | 6325 | try f.renderTypecast(writer, inst_ty); |
| | 6326 | try writer.writeAll(")"); |
| 6294 | const int_info = inst_ty.intInfo(target); | 6327 | const int_info = inst_ty.intInfo(target); |
| 6295 | | 6328 | |
| 6296 | var bit_offset_ty_pl = Type.Payload.Bits{ | 6329 | var bit_offset_ty_pl = Type.Payload.Bits{ |
| ... | @@ -6468,6 +6501,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6468,6 +6501,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6468 | } | 6501 | } |
| 6469 | | 6502 | |
| 6470 | const operand = try f.resolveInst(un_op); | 6503 | const operand = try f.resolveInst(un_op); |
| | 6504 | try reap(f, inst, &.{un_op}); |
| 6471 | const operand_ty = f.air.typeOf(un_op); | 6505 | const operand_ty = f.air.typeOf(un_op); |
| 6472 | | 6506 | |
| 6473 | const writer = f.object.writer(); | 6507 | const writer = f.object.writer(); |