| ... | ... | @@ -4096,9 +4096,7 @@ fn lowerTry( |
| 4096 | 4096 | const is_array = lowersToArray(payload_ty, target); |
| 4097 | 4097 | try reap(f, inst, &.{operand}); |
| 4098 | 4098 | const local = try f.allocLocal(inst, result_ty); |
| 4099 | | try f.writeCValue(writer, local, .Other); |
| 4100 | 4099 | if (is_array) { |
| 4101 | | try writer.writeAll(";\n"); |
| 4102 | 4100 | try writer.writeAll("memcpy("); |
| 4103 | 4101 | try f.writeCValue(writer, local, .FunctionArgument); |
| 4104 | 4102 | try writer.writeAll(", "); |
| ... | ... | @@ -4107,6 +4105,7 @@ fn lowerTry( |
| 4107 | 4105 | try f.renderTypecast(writer, payload_ty); |
| 4108 | 4106 | try writer.writeAll("));\n"); |
| 4109 | 4107 | } else { |
| 4108 | try f.writeCValue(writer, local, .Other); |
| 4110 | 4109 | try writer.writeAll(" = "); |
| 4111 | 4110 | if (operand_is_ptr or isByRef(payload_ty)) { |
| 4112 | 4111 | try writer.writeByte('&'); |
| ... | ... | @@ -4849,16 +4848,18 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4849 | 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 | 4854 | if (opt_ty.optionalReprIsPayload()) { |
| 4853 | 4855 | // the operand is just a regular pointer, no need to do anything special. |
| 4854 | 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 | 4863 | try writer.writeAll(";\n"); |
| 4863 | 4864 | return local; |
| 4864 | 4865 | } |
| ... | ... | @@ -4872,25 +4873,37 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4872 | 4873 | |
| 4873 | 4874 | const opt_ty = operand_ty.elemType(); |
| 4874 | 4875 | |
| 4876 | const inst_ty = f.air.typeOfIndex(inst); |
| 4877 | |
| 4875 | 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 | 4883 | // The payload and the optional are the same value. |
| 4877 | 4884 | // Setting to non-null will be done when the payload is set. |
| 4878 | | return operand; |
| 4879 | | } |
| 4880 | | |
| 4881 | | try f.writeCValueDeref(writer, operand); |
| 4882 | | try writer.writeAll(".is_null = "); |
| 4883 | | try f.object.dg.renderValue(writer, Type.bool, Value.false, .Initializer); |
| 4884 | | try writer.writeAll(";\n"); |
| 4885 | try f.writeCValue(writer, local, .Other); |
| 4886 | try writer.writeAll(" = "); |
| 4887 | try f.writeCValue(writer, operand, .Other); |
| 4888 | try writer.writeAll(";\n"); |
| 4889 | return local; |
| 4890 | } else { |
| 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); |
| 4887 | | const local = try f.allocLocal(inst, inst_ty); |
| 4888 | | try f.writeCValue(writer, local, .Other); |
| 4889 | | try writer.writeAll(" = &"); |
| 4890 | | try f.writeCValueDeref(writer, operand); |
| 4896 | if (f.liveness.isUnused(inst)) { |
| 4897 | return CValue.none; |
| 4898 | } |
| 4891 | 4899 | |
| 4892 | | try writer.writeAll(".payload;\n"); |
| 4893 | | return local; |
| 4900 | const local = try f.allocLocal(inst, inst_ty); |
| 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 | 4909 | fn airStructFieldPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| ... | ... | @@ -5164,7 +5177,6 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5164 | 5177 | } else struct_byval; |
| 5165 | 5178 | |
| 5166 | 5179 | const local = try f.allocLocal(inst, inst_ty); |
| 5167 | | try f.writeCValue(writer, local, .Other); |
| 5168 | 5180 | try writer.writeAll("memcpy(&"); |
| 5169 | 5181 | try f.writeCValue(writer, local, .FunctionArgument); |
| 5170 | 5182 | try writer.writeAll(", &"); |
| ... | ... | @@ -5230,25 +5242,28 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5230 | 5242 | const inst_ty = f.air.typeOfIndex(inst); |
| 5231 | 5243 | const operand = try f.resolveInst(ty_op.operand); |
| 5232 | 5244 | const operand_ty = f.air.typeOf(ty_op.operand); |
| 5245 | try reap(f, inst, &.{ty_op.operand}); |
| 5233 | 5246 | |
| 5234 | 5247 | const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer; |
| 5235 | 5248 | const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; |
| 5236 | 5249 | const error_ty = error_union_ty.errorUnionSet(); |
| 5237 | 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 | 5251 | const local = try f.allocLocal(inst, inst_ty); |
| 5252 | const writer = f.object.writer(); |
| 5243 | 5253 | try f.writeCValue(writer, local, .Other); |
| 5244 | 5254 | try writer.writeAll(" = "); |
| 5245 | | if (!error_ty.errorSetIsEmpty()) |
| 5246 | | if (operand_is_ptr) |
| 5247 | | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" }) |
| 5255 | |
| 5256 | if (!payload_ty.hasRuntimeBits()) { |
| 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 | 5264 | else |
| 5249 | | try f.writeCValueMember(writer, operand, .{ .identifier = "error" }) |
| 5250 | | else |
| 5251 | | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer); |
| 5265 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer); |
| 5266 | } |
| 5252 | 5267 | try writer.writeAll(";\n"); |
| 5253 | 5268 | return local; |
| 5254 | 5269 | } |
| ... | ... | @@ -5345,13 +5360,19 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5345 | 5360 | |
| 5346 | 5361 | const writer = f.object.writer(); |
| 5347 | 5362 | const operand = try f.resolveInst(ty_op.operand); |
| 5363 | try reap(f, inst, &.{ty_op.operand}); |
| 5348 | 5364 | const error_union_ty = f.air.typeOfIndex(inst); |
| 5349 | 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 | 5377 | // TODO: set the payload to undefined |
| 5357 | 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 | 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 | 5783 | return local; |
| 5758 | 5784 | } |
| 5759 | 5785 | |
| ... | ... | @@ -5790,6 +5816,11 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5790 | 5816 | try writeMemoryOrder(writer, extra.ordering()); |
| 5791 | 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 | 5824 | return local; |
| 5794 | 5825 | } |
| 5795 | 5826 | |
| ... | ... | @@ -6222,30 +6253,28 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6222 | 6253 | |
| 6223 | 6254 | const writer = f.object.writer(); |
| 6224 | 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 | 6256 | switch (inst_ty.zigTypeTag()) { |
| 6230 | 6257 | .Array, .Vector => { |
| 6231 | 6258 | const elem_ty = inst_ty.childType(); |
| 6232 | | try writer.writeByte('{'); |
| 6233 | | var empty = true; |
| 6234 | | for (resolved_elements) |element| { |
| 6235 | | if (!empty) try writer.writeAll(", "); |
| 6236 | | try f.writeCValue(writer, element, .Initializer); |
| 6237 | | empty = false; |
| 6259 | for (resolved_elements) |element, i| { |
| 6260 | try f.writeCValue(writer, local, .Other); |
| 6261 | try writer.print("[{d}] = ", .{i}); |
| 6262 | try f.writeCValue(writer, element, .Other); |
| 6263 | try writer.writeAll(";\n"); |
| 6238 | 6264 | } |
| 6239 | 6265 | if (inst_ty.sentinel()) |sentinel| { |
| 6240 | | if (!empty) try writer.writeAll(", "); |
| 6241 | | try f.object.dg.renderValue(writer, elem_ty, sentinel, .Initializer); |
| 6242 | | empty = false; |
| 6266 | try f.writeCValue(writer, local, .Other); |
| 6267 | try writer.print("[{d}] = ", .{resolved_elements.len}); |
| 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 | 6272 | .Struct => switch (inst_ty.containerLayout()) { |
| 6248 | 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 | 6278 | try writer.writeByte('{'); |
| 6250 | 6279 | var empty = true; |
| 6251 | 6280 | for (elements) |element, index| { |
| ... | ... | @@ -6291,6 +6320,10 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6291 | 6320 | } |
| 6292 | 6321 | }, |
| 6293 | 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 | 6327 | const int_info = inst_ty.intInfo(target); |
| 6295 | 6328 | |
| 6296 | 6329 | var bit_offset_ty_pl = Type.Payload.Bits{ |
| ... | ... | @@ -6468,6 +6501,7 @@ fn airFloatNeg(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6468 | 6501 | } |
| 6469 | 6502 | |
| 6470 | 6503 | const operand = try f.resolveInst(un_op); |
| 6504 | try reap(f, inst, &.{un_op}); |
| 6471 | 6505 | const operand_ty = f.air.typeOf(un_op); |
| 6472 | 6506 | |
| 6473 | 6507 | const writer = f.object.writer(); |