| ... | ... | @@ -2597,19 +2597,36 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [ |
| 2597 | 2597 | } |
| 2598 | 2598 | |
| 2599 | 2599 | fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2600 | const inst_ty = f.air.typeOfIndex(inst); |
| 2600 | 2601 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 2601 | 2602 | const ptr_ty = f.air.typeOf(bin_op.lhs); |
| 2602 | | if (!ptr_ty.isVolatilePtr() and f.liveness.isUnused(inst)) return CValue.none; |
| 2603 | if ((!ptr_ty.isVolatilePtr() and f.liveness.isUnused(inst)) or |
| 2604 | !inst_ty.hasRuntimeBitsIgnoreComptime()) return CValue.none; |
| 2603 | 2605 | |
| 2604 | 2606 | const ptr = try f.resolveInst(bin_op.lhs); |
| 2605 | 2607 | const index = try f.resolveInst(bin_op.rhs); |
| 2608 | |
| 2609 | const target = f.object.dg.module.getTarget(); |
| 2610 | const is_array = lowersToArray(inst_ty, target); |
| 2611 | |
| 2612 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); |
| 2606 | 2613 | const writer = f.object.writer(); |
| 2607 | | const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); |
| 2608 | | try writer.writeAll(" = "); |
| 2614 | if (is_array) { |
| 2615 | try writer.writeAll(";\n"); |
| 2616 | try writer.writeAll("memcpy("); |
| 2617 | try f.writeCValue(writer, local, .FunctionArgument); |
| 2618 | try writer.writeAll(", "); |
| 2619 | } else try writer.writeAll(" = "); |
| 2609 | 2620 | try f.writeCValue(writer, ptr, .Other); |
| 2610 | 2621 | try writer.writeByte('['); |
| 2611 | 2622 | try f.writeCValue(writer, index, .Other); |
| 2612 | | try writer.writeAll("];\n"); |
| 2623 | try writer.writeByte(']'); |
| 2624 | if (is_array) { |
| 2625 | try writer.writeAll(", sizeof("); |
| 2626 | try f.renderTypecast(writer, inst_ty); |
| 2627 | try writer.writeAll("))"); |
| 2628 | } |
| 2629 | try writer.writeAll(";\n"); |
| 2613 | 2630 | return local; |
| 2614 | 2631 | } |
| 2615 | 2632 | |
| ... | ... | @@ -2639,19 +2656,36 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2639 | 2656 | } |
| 2640 | 2657 | |
| 2641 | 2658 | fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2659 | const inst_ty = f.air.typeOfIndex(inst); |
| 2642 | 2660 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 2643 | 2661 | const slice_ty = f.air.typeOf(bin_op.lhs); |
| 2644 | | if (!slice_ty.isVolatilePtr() and f.liveness.isUnused(inst)) return CValue.none; |
| 2662 | if ((!slice_ty.isVolatilePtr() and f.liveness.isUnused(inst)) or |
| 2663 | !inst_ty.hasRuntimeBitsIgnoreComptime()) return CValue.none; |
| 2645 | 2664 | |
| 2646 | 2665 | const slice = try f.resolveInst(bin_op.lhs); |
| 2647 | 2666 | const index = try f.resolveInst(bin_op.rhs); |
| 2667 | |
| 2668 | const target = f.object.dg.module.getTarget(); |
| 2669 | const is_array = lowersToArray(inst_ty, target); |
| 2670 | |
| 2671 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); |
| 2648 | 2672 | const writer = f.object.writer(); |
| 2649 | | const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); |
| 2650 | | try writer.writeAll(" = "); |
| 2673 | if (is_array) { |
| 2674 | try writer.writeAll(";\n"); |
| 2675 | try writer.writeAll("memcpy("); |
| 2676 | try f.writeCValue(writer, local, .FunctionArgument); |
| 2677 | try writer.writeAll(", "); |
| 2678 | } else try writer.writeAll(" = "); |
| 2651 | 2679 | try f.writeCValue(writer, slice, .Other); |
| 2652 | 2680 | try writer.writeAll(".ptr["); |
| 2653 | 2681 | try f.writeCValue(writer, index, .Other); |
| 2654 | | try writer.writeAll("];\n"); |
| 2682 | try writer.writeByte(']'); |
| 2683 | if (is_array) { |
| 2684 | try writer.writeAll(", sizeof("); |
| 2685 | try f.renderTypecast(writer, inst_ty); |
| 2686 | try writer.writeAll("))"); |
| 2687 | } |
| 2688 | try writer.writeAll(";\n"); |
| 2655 | 2689 | return local; |
| 2656 | 2690 | } |
| 2657 | 2691 | |
| ... | ... | @@ -2674,18 +2708,34 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2674 | 2708 | } |
| 2675 | 2709 | |
| 2676 | 2710 | fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2677 | | if (f.liveness.isUnused(inst)) return CValue.none; |
| 2711 | const inst_ty = f.air.typeOfIndex(inst); |
| 2712 | if (f.liveness.isUnused(inst) or !inst_ty.hasRuntimeBitsIgnoreComptime()) return CValue.none; |
| 2678 | 2713 | |
| 2679 | 2714 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 2680 | 2715 | const array = try f.resolveInst(bin_op.lhs); |
| 2681 | 2716 | const index = try f.resolveInst(bin_op.rhs); |
| 2717 | |
| 2718 | const target = f.object.dg.module.getTarget(); |
| 2719 | const is_array = lowersToArray(inst_ty, target); |
| 2720 | |
| 2721 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); |
| 2682 | 2722 | const writer = f.object.writer(); |
| 2683 | | const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); |
| 2684 | | try writer.writeAll(" = "); |
| 2723 | if (is_array) { |
| 2724 | try writer.writeAll(";\n"); |
| 2725 | try writer.writeAll("memcpy("); |
| 2726 | try f.writeCValue(writer, local, .FunctionArgument); |
| 2727 | try writer.writeAll(", "); |
| 2728 | } else try writer.writeAll(" = "); |
| 2685 | 2729 | try f.writeCValue(writer, array, .Other); |
| 2686 | 2730 | try writer.writeByte('['); |
| 2687 | 2731 | try f.writeCValue(writer, index, .Other); |
| 2688 | | try writer.writeAll("];\n"); |
| 2732 | try writer.writeByte(']'); |
| 2733 | if (is_array) { |
| 2734 | try writer.writeAll(", sizeof("); |
| 2735 | try f.renderTypecast(writer, inst_ty); |
| 2736 | try writer.writeAll("))"); |
| 2737 | } |
| 2738 | try writer.writeAll(";\n"); |
| 2689 | 2739 | return local; |
| 2690 | 2740 | } |
| 2691 | 2741 | |
| ... | ... | @@ -3592,13 +3642,26 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3592 | 3642 | // If result is .none then the value of the block is unused. |
| 3593 | 3643 | if (result != .none) { |
| 3594 | 3644 | const operand = try f.resolveInst(branch.operand); |
| 3595 | | try f.writeCValue(writer, result, .Other); |
| 3596 | | try writer.writeAll(" = "); |
| 3597 | | try f.writeCValue(writer, operand, .Other); |
| 3645 | |
| 3646 | const operand_ty = f.air.typeOf(branch.operand); |
| 3647 | const target = f.object.dg.module.getTarget(); |
| 3648 | if (lowersToArray(operand_ty, target)) { |
| 3649 | try writer.writeAll("memcpy("); |
| 3650 | try f.writeCValue(writer, result, .FunctionArgument); |
| 3651 | try writer.writeAll(", "); |
| 3652 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 3653 | try writer.writeAll(", sizeof("); |
| 3654 | try f.renderTypecast(writer, operand_ty); |
| 3655 | try writer.writeAll("))"); |
| 3656 | } else { |
| 3657 | try f.writeCValue(writer, result, .Other); |
| 3658 | try writer.writeAll(" = "); |
| 3659 | try f.writeCValue(writer, operand, .Other); |
| 3660 | } |
| 3598 | 3661 | try writer.writeAll(";\n"); |
| 3599 | 3662 | } |
| 3600 | 3663 | |
| 3601 | | try f.object.writer().print("goto zig_block_{d};\n", .{block.block_id}); |
| 3664 | try writer.print("goto zig_block_{d};\n", .{block.block_id}); |
| 3602 | 3665 | return CValue.none; |
| 3603 | 3666 | } |
| 3604 | 3667 | |
| ... | ... | @@ -4009,26 +4072,34 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4009 | 4072 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 4010 | 4073 | |
| 4011 | 4074 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 4012 | | const writer = f.object.writer(); |
| 4013 | 4075 | const operand = try f.resolveInst(ty_op.operand); |
| 4014 | 4076 | const opt_ty = f.air.typeOf(ty_op.operand); |
| 4015 | 4077 | |
| 4016 | 4078 | var buf: Type.Payload.ElemType = undefined; |
| 4017 | 4079 | const payload_ty = opt_ty.optionalChild(&buf); |
| 4018 | 4080 | |
| 4019 | | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 4020 | | return CValue.none; |
| 4021 | | } |
| 4022 | | |
| 4023 | | if (opt_ty.optionalReprIsPayload()) { |
| 4024 | | return operand; |
| 4025 | | } |
| 4081 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return CValue.none; |
| 4082 | if (opt_ty.optionalReprIsPayload()) return operand; |
| 4026 | 4083 | |
| 4027 | 4084 | const inst_ty = f.air.typeOfIndex(inst); |
| 4028 | | const local = try f.allocLocal(inst_ty, .Const); |
| 4029 | | try writer.writeAll(" = ("); |
| 4030 | | try f.writeCValue(writer, operand, .Other); |
| 4031 | | try writer.writeAll(").payload;\n"); |
| 4085 | const target = f.object.dg.module.getTarget(); |
| 4086 | const is_array = lowersToArray(inst_ty, target); |
| 4087 | |
| 4088 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); |
| 4089 | const writer = f.object.writer(); |
| 4090 | if (is_array) { |
| 4091 | try writer.writeAll(";\n"); |
| 4092 | try writer.writeAll("memcpy("); |
| 4093 | try f.writeCValue(writer, local, .FunctionArgument); |
| 4094 | try writer.writeAll(", "); |
| 4095 | } else try writer.writeAll(" = "); |
| 4096 | try f.writeCValueMember(writer, operand, .{ .identifier = "payload" }); |
| 4097 | if (is_array) { |
| 4098 | try writer.writeAll(", sizeof("); |
| 4099 | try f.renderTypecast(writer, inst_ty); |
| 4100 | try writer.writeAll("))"); |
| 4101 | } |
| 4102 | try writer.writeAll(";\n"); |
| 4032 | 4103 | return local; |
| 4033 | 4104 | } |
| 4034 | 4105 | |
| ... | ... | @@ -4387,25 +4458,33 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu |
| 4387 | 4458 | } |
| 4388 | 4459 | |
| 4389 | 4460 | fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4390 | | if (f.liveness.isUnused(inst)) |
| 4391 | | return CValue.none; |
| 4461 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 4392 | 4462 | |
| 4463 | const inst_ty = f.air.typeOfIndex(inst); |
| 4393 | 4464 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 4394 | | const writer = f.object.writer(); |
| 4395 | | const operand = try f.resolveInst(ty_op.operand); |
| 4465 | const payload = try f.resolveInst(ty_op.operand); |
| 4466 | if (inst_ty.optionalReprIsPayload()) return payload; |
| 4396 | 4467 | |
| 4397 | | const inst_ty = f.air.typeOfIndex(inst); |
| 4398 | | if (inst_ty.optionalReprIsPayload()) { |
| 4399 | | return operand; |
| 4400 | | } |
| 4468 | const payload_ty = f.air.typeOf(ty_op.operand); |
| 4469 | const target = f.object.dg.module.getTarget(); |
| 4470 | const is_array = lowersToArray(payload_ty, target); |
| 4401 | 4471 | |
| 4402 | | // .wrap_optional is used to convert non-optionals into optionals so it can never be null. |
| 4403 | | const local = try f.allocLocal(inst_ty, .Const); |
| 4472 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); |
| 4473 | const writer = f.object.writer(); |
| 4404 | 4474 | try writer.writeAll(" = { .payload = "); |
| 4405 | | try f.writeCValue(writer, operand, .Initializer); |
| 4475 | try f.writeCValue(writer, if (is_array) CValue{ .undef = payload_ty } else payload, .Initializer); |
| 4406 | 4476 | try writer.writeAll(", .is_null = "); |
| 4407 | 4477 | try f.object.dg.renderValue(writer, Type.bool, Value.@"false", .Initializer); |
| 4408 | 4478 | try writer.writeAll(" };\n"); |
| 4479 | if (is_array) { |
| 4480 | try writer.writeAll("memcpy("); |
| 4481 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); |
| 4482 | try writer.writeAll(", "); |
| 4483 | try f.writeCValue(writer, payload, .FunctionArgument); |
| 4484 | try writer.writeAll(", sizeof("); |
| 4485 | try f.renderTypecast(writer, payload_ty); |
| 4486 | try writer.writeAll("));\n"); |
| 4487 | } |
| 4409 | 4488 | return local; |
| 4410 | 4489 | } |
| 4411 | 4490 | |
| ... | ... | @@ -4477,35 +4556,33 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4477 | 4556 | } |
| 4478 | 4557 | |
| 4479 | 4558 | fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4480 | | if (f.liveness.isUnused(inst)) |
| 4481 | | return CValue.none; |
| 4482 | | |
| 4483 | | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 4484 | | const writer = f.object.writer(); |
| 4485 | | const operand = try f.resolveInst(ty_op.operand); |
| 4559 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 4486 | 4560 | |
| 4487 | 4561 | const inst_ty = f.air.typeOfIndex(inst); |
| 4488 | | const payload_ty = inst_ty.errorUnionPayload(); |
| 4489 | 4562 | const error_ty = inst_ty.errorUnionSet(); |
| 4563 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 4564 | const payload_ty = inst_ty.errorUnionPayload(); |
| 4565 | const payload = try f.resolveInst(ty_op.operand); |
| 4566 | |
| 4490 | 4567 | const target = f.object.dg.module.getTarget(); |
| 4491 | 4568 | const is_array = lowersToArray(payload_ty, target); |
| 4569 | |
| 4492 | 4570 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); |
| 4571 | const writer = f.object.writer(); |
| 4493 | 4572 | try writer.writeAll(" = { .payload = "); |
| 4494 | | try f.writeCValue(writer, if (is_array) CValue{ .undef = payload_ty } else operand, .Initializer); |
| 4573 | try f.writeCValue(writer, if (is_array) CValue{ .undef = payload_ty } else payload, .Initializer); |
| 4495 | 4574 | try writer.writeAll(", .error = "); |
| 4496 | 4575 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer); |
| 4497 | 4576 | try writer.writeAll(" };\n"); |
| 4498 | | |
| 4499 | 4577 | if (is_array) { |
| 4500 | 4578 | try writer.writeAll("memcpy("); |
| 4501 | | try f.writeCValue(writer, local, .Other); |
| 4502 | | try writer.writeAll(".payload, "); |
| 4503 | | try f.writeCValue(writer, operand, .FunctionArgument); |
| 4579 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); |
| 4580 | try writer.writeAll(", "); |
| 4581 | try f.writeCValue(writer, payload, .FunctionArgument); |
| 4504 | 4582 | try writer.writeAll(", sizeof("); |
| 4505 | 4583 | try f.renderTypecast(writer, payload_ty); |
| 4506 | 4584 | try writer.writeAll("));\n"); |
| 4507 | 4585 | } |
| 4508 | | |
| 4509 | 4586 | return local; |
| 4510 | 4587 | } |
| 4511 | 4588 | |