| ... | @@ -8579,56 +8579,174 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -8579,56 +8579,174 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 8579 | return self.finishAirResult(inst, result); | 8579 | return self.finishAirResult(inst, result); |
| 8580 | } | 8580 | } |
| 8581 | | 8581 | |
| 8582 | fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag { | 8582 | const MoveStrategy = union(enum) { |
| | 8583 | move: Mir.Inst.FixedTag, |
| | 8584 | insert_extract: InsertExtract, |
| | 8585 | vex_insert_extract: InsertExtract, |
| | 8586 | |
| | 8587 | const InsertExtract = struct { |
| | 8588 | insert: Mir.Inst.FixedTag, |
| | 8589 | extract: Mir.Inst.FixedTag, |
| | 8590 | imm: Immediate, |
| | 8591 | }; |
| | 8592 | }; |
| | 8593 | fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { |
| 8583 | switch (ty.zigTypeTag()) { | 8594 | switch (ty.zigTypeTag()) { |
| 8584 | else => return .{ ._, .mov }, | 8595 | else => return .{ .move = .{ ._, .mov } }, |
| 8585 | .Float => switch (ty.floatBits(self.target.*)) { | 8596 | .Float => switch (ty.floatBits(self.target.*)) { |
| 8586 | 16 => unreachable, // needs special handling | 8597 | 16 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{ |
| 8587 | 32 => return if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov }, | 8598 | .insert = .{ .vp_w, .insr }, |
| 8588 | 64 => return if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov }, | 8599 | .extract = .{ .vp_w, .extr }, |
| 8589 | 128 => return if (self.hasFeature(.avx)) | 8600 | .imm = Immediate.u(0), |
| | 8601 | } } else .{ .insert_extract = .{ |
| | 8602 | .insert = .{ .p_w, .insr }, |
| | 8603 | .extract = .{ .p_w, .extr }, |
| | 8604 | .imm = Immediate.u(0), |
| | 8605 | } }, |
| | 8606 | 32 => return .{ .move = if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov } }, |
| | 8607 | 64 => return .{ .move = if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov } }, |
| | 8608 | 128 => return .{ .move = if (self.hasFeature(.avx)) |
| 8590 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } | 8609 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } |
| 8591 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu }, | 8610 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu } }, |
| 8592 | else => {}, | 8611 | else => {}, |
| 8593 | }, | 8612 | }, |
| 8594 | .Vector => switch (ty.childType().zigTypeTag()) { | 8613 | .Vector => switch (ty.childType().zigTypeTag()) { |
| | 8614 | .Int => switch (ty.childType().intInfo(self.target.*).bits) { |
| | 8615 | 8 => switch (ty.vectorLen()) { |
| | 8616 | 1 => if (self.hasFeature(.avx)) return .{ .vex_insert_extract = .{ |
| | 8617 | .insert = .{ .vp_b, .insr }, |
| | 8618 | .extract = .{ .vp_b, .extr }, |
| | 8619 | .imm = Immediate.u(0), |
| | 8620 | } } else if (self.hasFeature(.sse4_2)) return .{ .insert_extract = .{ |
| | 8621 | .insert = .{ .p_b, .insr }, |
| | 8622 | .extract = .{ .p_b, .extr }, |
| | 8623 | .imm = Immediate.u(0), |
| | 8624 | } }, |
| | 8625 | 2 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{ |
| | 8626 | .insert = .{ .vp_w, .insr }, |
| | 8627 | .extract = .{ .vp_w, .extr }, |
| | 8628 | .imm = Immediate.u(0), |
| | 8629 | } } else .{ .insert_extract = .{ |
| | 8630 | .insert = .{ .p_w, .insr }, |
| | 8631 | .extract = .{ .p_w, .extr }, |
| | 8632 | .imm = Immediate.u(0), |
| | 8633 | } }, |
| | 8634 | 3...4 => return .{ .move = if (self.hasFeature(.avx)) |
| | 8635 | .{ .v_ss, .mov } |
| | 8636 | else |
| | 8637 | .{ ._ss, .mov } }, |
| | 8638 | 5...8 => return .{ .move = if (self.hasFeature(.avx)) |
| | 8639 | .{ .v_sd, .mov } |
| | 8640 | else |
| | 8641 | .{ ._sd, .mov } }, |
| | 8642 | else => {}, |
| | 8643 | }, |
| | 8644 | 16 => switch (ty.vectorLen()) { |
| | 8645 | 1 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{ |
| | 8646 | .insert = .{ .vp_w, .insr }, |
| | 8647 | .extract = .{ .vp_w, .extr }, |
| | 8648 | .imm = Immediate.u(0), |
| | 8649 | } } else .{ .insert_extract = .{ |
| | 8650 | .insert = .{ .p_w, .insr }, |
| | 8651 | .extract = .{ .p_w, .extr }, |
| | 8652 | .imm = Immediate.u(0), |
| | 8653 | } }, |
| | 8654 | 2 => return .{ .move = if (self.hasFeature(.avx)) |
| | 8655 | .{ .v_ss, .mov } |
| | 8656 | else |
| | 8657 | .{ ._ss, .mov } }, |
| | 8658 | 3...4 => return .{ .move = if (self.hasFeature(.avx)) |
| | 8659 | .{ .v_sd, .mov } |
| | 8660 | else |
| | 8661 | .{ ._sd, .mov } }, |
| | 8662 | 5...8 => return .{ .move = if (self.hasFeature(.avx)) |
| | 8663 | .{ .v_ps, .mov } |
| | 8664 | else |
| | 8665 | .{ ._ps, .mov } }, |
| | 8666 | else => {}, |
| | 8667 | }, |
| | 8668 | 32 => switch (ty.vectorLen()) { |
| | 8669 | 1 => return .{ .move = if (self.hasFeature(.avx)) |
| | 8670 | .{ .v_ss, .mov } |
| | 8671 | else |
| | 8672 | .{ ._ss, .mov } }, |
| | 8673 | 2 => return .{ .move = if (self.hasFeature(.avx)) |
| | 8674 | .{ .v_sd, .mov } |
| | 8675 | else |
| | 8676 | .{ ._sd, .mov } }, |
| | 8677 | 3...4 => return .{ .move = if (self.hasFeature(.avx)) |
| | 8678 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } |
| | 8679 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu } }, |
| | 8680 | 5...8 => if (self.hasFeature(.avx)) |
| | 8681 | return .{ .move = if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } }, |
| | 8682 | else => {}, |
| | 8683 | }, |
| | 8684 | 64 => switch (ty.vectorLen()) { |
| | 8685 | 1 => return .{ .move = if (self.hasFeature(.avx)) |
| | 8686 | .{ .v_sd, .mov } |
| | 8687 | else |
| | 8688 | .{ ._sd, .mov } }, |
| | 8689 | 2 => return .{ .move = if (self.hasFeature(.avx)) |
| | 8690 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } |
| | 8691 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu } }, |
| | 8692 | 3...4 => if (self.hasFeature(.avx)) |
| | 8693 | return .{ .move = if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } }, |
| | 8694 | else => {}, |
| | 8695 | }, |
| | 8696 | else => {}, |
| | 8697 | }, |
| 8595 | .Float => switch (ty.childType().floatBits(self.target.*)) { | 8698 | .Float => switch (ty.childType().floatBits(self.target.*)) { |
| 8596 | 16 => switch (ty.vectorLen()) { | 8699 | 16 => switch (ty.vectorLen()) { |
| 8597 | 1 => unreachable, // needs special handling | 8700 | 1 => {}, |
| 8598 | 2 => return if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov }, | 8701 | 2 => return .{ .move = if (self.hasFeature(.avx)) |
| 8599 | 3...4 => return if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov }, | 8702 | .{ .v_ss, .mov } |
| 8600 | 5...8 => return if (self.hasFeature(.avx)) | 8703 | else |
| | 8704 | .{ ._ss, .mov } }, |
| | 8705 | 3...4 => return .{ .move = if (self.hasFeature(.avx)) |
| | 8706 | .{ .v_sd, .mov } |
| | 8707 | else |
| | 8708 | .{ ._sd, .mov } }, |
| | 8709 | 5...8 => return .{ .move = if (self.hasFeature(.avx)) |
| 8601 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } | 8710 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } |
| 8602 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu }, | 8711 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu } }, |
| 8603 | 9...16 => if (self.hasFeature(.avx)) | 8712 | 9...16 => if (self.hasFeature(.avx)) |
| 8604 | return if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu }, | 8713 | return .{ .move = if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } }, |
| 8605 | else => {}, | 8714 | else => {}, |
| 8606 | }, | 8715 | }, |
| 8607 | 32 => switch (ty.vectorLen()) { | 8716 | 32 => switch (ty.vectorLen()) { |
| 8608 | 1 => return if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov }, | 8717 | 1 => return .{ .move = if (self.hasFeature(.avx)) |
| 8609 | 2 => return if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov }, | 8718 | .{ .v_ss, .mov } |
| 8610 | 3...4 => return if (self.hasFeature(.avx)) | 8719 | else |
| | 8720 | .{ ._ss, .mov } }, |
| | 8721 | 2 => return .{ .move = if (self.hasFeature(.avx)) |
| | 8722 | .{ .v_sd, .mov } |
| | 8723 | else |
| | 8724 | .{ ._sd, .mov } }, |
| | 8725 | 3...4 => return .{ .move = if (self.hasFeature(.avx)) |
| 8611 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } | 8726 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } |
| 8612 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu }, | 8727 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu } }, |
| 8613 | 5...8 => if (self.hasFeature(.avx)) | 8728 | 5...8 => if (self.hasFeature(.avx)) |
| 8614 | return if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu }, | 8729 | return .{ .move = if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } }, |
| 8615 | else => {}, | 8730 | else => {}, |
| 8616 | }, | 8731 | }, |
| 8617 | 64 => switch (ty.vectorLen()) { | 8732 | 64 => switch (ty.vectorLen()) { |
| 8618 | 1 => return if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov }, | 8733 | 1 => return .{ .move = if (self.hasFeature(.avx)) |
| 8619 | 2 => return if (self.hasFeature(.avx)) | 8734 | .{ .v_sd, .mov } |
| | 8735 | else |
| | 8736 | .{ ._sd, .mov } }, |
| | 8737 | 2 => return .{ .move = if (self.hasFeature(.avx)) |
| 8620 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } | 8738 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } |
| 8621 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu }, | 8739 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu } }, |
| 8622 | 3...4 => if (self.hasFeature(.avx)) | 8740 | 3...4 => if (self.hasFeature(.avx)) |
| 8623 | return if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu }, | 8741 | return .{ .move = if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } }, |
| 8624 | else => {}, | 8742 | else => {}, |
| 8625 | }, | 8743 | }, |
| 8626 | 128 => switch (ty.vectorLen()) { | 8744 | 128 => switch (ty.vectorLen()) { |
| 8627 | 1 => return if (self.hasFeature(.avx)) | 8745 | 1 => return .{ .move = if (self.hasFeature(.avx)) |
| 8628 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } | 8746 | if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } |
| 8629 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu }, | 8747 | else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu } }, |
| 8630 | 2 => if (self.hasFeature(.avx)) | 8748 | 2 => if (self.hasFeature(.avx)) |
| 8631 | return if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu }, | 8749 | return .{ .move = if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } }, |
| 8632 | else => {}, | 8750 | else => {}, |
| 8633 | }, | 8751 | }, |
| 8634 | else => {}, | 8752 | else => {}, |
| ... | @@ -8636,7 +8754,7 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag { | ... | @@ -8636,7 +8754,7 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag { |
| 8636 | else => {}, | 8754 | else => {}, |
| 8637 | }, | 8755 | }, |
| 8638 | } | 8756 | } |
| 8639 | return self.fail("TODO movMirTag for {}", .{ty.fmt(self.bin_file.options.module.?)}); | 8757 | return self.fail("TODO moveStrategy for {}", .{ty.fmt(self.bin_file.options.module.?)}); |
| 8640 | } | 8758 | } |
| 8641 | | 8759 | |
| 8642 | fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void { | 8760 | fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void { |
| ... | @@ -8764,6 +8882,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -8764,6 +8882,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 8764 | .load_frame, | 8882 | .load_frame, |
| 8765 | .lea_frame, | 8883 | .lea_frame, |
| 8766 | => { | 8884 | => { |
| | 8885 | const dst_alias = registerAlias(dst_reg, abi_size); |
| 8767 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), switch (src_mcv) { | 8886 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), switch (src_mcv) { |
| 8768 | .register_offset, .indirect => |reg_off| .{ | 8887 | .register_offset, .indirect => |reg_off| .{ |
| 8769 | .base = .{ .reg = reg_off.reg }, | 8888 | .base = .{ .reg = reg_off.reg }, |
| ... | @@ -8775,71 +8894,81 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -8775,71 +8894,81 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 8775 | }, | 8894 | }, |
| 8776 | else => unreachable, | 8895 | else => unreachable, |
| 8777 | }); | 8896 | }); |
| 8778 | if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16) | 8897 | switch (@as(MoveStrategy, switch (src_mcv) { |
| 8779 | try self.asmRegisterMemoryImmediate( | 8898 | .register_offset => |reg_off| switch (reg_off.off) { |
| 8780 | .{ .p_w, .insr }, | 8899 | 0 => return self.genSetReg(dst_reg, ty, .{ .register = reg_off.reg }), |
| 8781 | registerAlias(dst_reg, abi_size), | 8900 | else => .{ .move = .{ ._, .lea } }, |
| | 8901 | }, |
| | 8902 | .indirect => try self.moveStrategy(ty, false), |
| | 8903 | .load_frame => |frame_addr| try self.moveStrategy( |
| | 8904 | ty, |
| | 8905 | self.getFrameAddrAlignment(frame_addr) >= ty.abiAlignment(self.target.*), |
| | 8906 | ), |
| | 8907 | .lea_frame => .{ .move = .{ ._, .lea } }, |
| | 8908 | else => unreachable, |
| | 8909 | })) { |
| | 8910 | .move => |tag| try self.asmRegisterMemory(tag, dst_alias, src_mem), |
| | 8911 | .insert_extract => |ie| try self.asmRegisterMemoryImmediate( |
| | 8912 | ie.insert, |
| | 8913 | dst_alias, |
| 8782 | src_mem, | 8914 | src_mem, |
| 8783 | Immediate.u(0), | 8915 | ie.imm, |
| 8784 | ) | 8916 | ), |
| 8785 | else | 8917 | .vex_insert_extract => |ie| try self.asmRegisterRegisterMemoryImmediate( |
| 8786 | try self.asmRegisterMemory( | 8918 | ie.insert, |
| 8787 | switch (src_mcv) { | 8919 | dst_alias, |
| 8788 | .register_offset => |reg_off| switch (reg_off.off) { | 8920 | dst_alias, |
| 8789 | 0 => return self.genSetReg(dst_reg, ty, .{ .register = reg_off.reg }), | | |
| 8790 | else => .{ ._, .lea }, | | |
| 8791 | }, | | |
| 8792 | .indirect => try self.movMirTag(ty, false), | | |
| 8793 | .load_frame => |frame_addr| try self.movMirTag( | | |
| 8794 | ty, | | |
| 8795 | self.getFrameAddrAlignment(frame_addr) >= ty.abiAlignment(self.target.*), | | |
| 8796 | ), | | |
| 8797 | .lea_frame => .{ ._, .lea }, | | |
| 8798 | else => unreachable, | | |
| 8799 | }, | | |
| 8800 | registerAlias(dst_reg, abi_size), | | |
| 8801 | src_mem, | 8921 | src_mem, |
| 8802 | ); | 8922 | ie.imm, |
| | 8923 | ), |
| | 8924 | } |
| 8803 | }, | 8925 | }, |
| 8804 | .memory, .load_direct, .load_got, .load_tlv => { | 8926 | .memory, .load_direct, .load_got, .load_tlv => { |
| 8805 | switch (src_mcv) { | 8927 | switch (src_mcv) { |
| 8806 | .memory => |addr| if (math.cast(i32, @bitCast(i64, addr))) |small_addr| { | 8928 | .memory => |addr| if (math.cast(i32, @bitCast(i64, addr))) |small_addr| { |
| | 8929 | const dst_alias = registerAlias(dst_reg, abi_size); |
| 8807 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ | 8930 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ |
| 8808 | .base = .{ .reg = .ds }, | 8931 | .base = .{ .reg = .ds }, |
| 8809 | .disp = small_addr, | 8932 | .disp = small_addr, |
| 8810 | }); | 8933 | }); |
| 8811 | return if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16) | 8934 | switch (try self.moveStrategy(ty, mem.isAlignedGeneric( |
| 8812 | self.asmRegisterMemoryImmediate( | 8935 | u32, |
| 8813 | .{ .p_w, .insr }, | 8936 | @bitCast(u32, small_addr), |
| 8814 | registerAlias(dst_reg, abi_size), | 8937 | ty.abiAlignment(self.target.*), |
| | 8938 | ))) { |
| | 8939 | .move => |tag| try self.asmRegisterMemory(tag, dst_alias, src_mem), |
| | 8940 | .insert_extract => |ie| try self.asmRegisterMemoryImmediate( |
| | 8941 | ie.insert, |
| | 8942 | dst_alias, |
| 8815 | src_mem, | 8943 | src_mem, |
| 8816 | Immediate.u(0), | 8944 | ie.imm, |
| 8817 | ) | 8945 | ), |
| 8818 | else | 8946 | .vex_insert_extract => |ie| try self.asmRegisterRegisterMemoryImmediate( |
| 8819 | self.asmRegisterMemory( | 8947 | ie.insert, |
| 8820 | try self.movMirTag(ty, mem.isAlignedGeneric( | 8948 | dst_alias, |
| 8821 | u32, | 8949 | dst_alias, |
| 8822 | @bitCast(u32, small_addr), | | |
| 8823 | ty.abiAlignment(self.target.*), | | |
| 8824 | )), | | |
| 8825 | registerAlias(dst_reg, abi_size), | | |
| 8826 | src_mem, | 8950 | src_mem, |
| 8827 | ); | 8951 | ie.imm, |
| | 8952 | ), |
| | 8953 | } |
| 8828 | }, | 8954 | }, |
| 8829 | .load_direct => |sym_index| if (!ty.isRuntimeFloat()) { | 8955 | .load_direct => |sym_index| switch (ty.zigTypeTag()) { |
| 8830 | const atom_index = try self.owner.getSymbolIndex(self); | 8956 | else => { |
| 8831 | _ = try self.addInst(.{ | 8957 | const atom_index = try self.owner.getSymbolIndex(self); |
| 8832 | .tag = .mov, | 8958 | _ = try self.addInst(.{ |
| 8833 | .ops = .direct_reloc, | 8959 | .tag = .mov, |
| 8834 | .data = .{ .rx = .{ | 8960 | .ops = .direct_reloc, |
| 8835 | .r1 = dst_reg.to64(), | 8961 | .data = .{ .rx = .{ |
| 8836 | .payload = try self.addExtra(Mir.Reloc{ | 8962 | .r1 = dst_reg.to64(), |
| 8837 | .atom_index = atom_index, | 8963 | .payload = try self.addExtra(Mir.Reloc{ |
| 8838 | .sym_index = sym_index, | 8964 | .atom_index = atom_index, |
| 8839 | }), | 8965 | .sym_index = sym_index, |
| 8840 | } }, | 8966 | }), |
| 8841 | }); | 8967 | } }, |
| 8842 | return; | 8968 | }); |
| | 8969 | return; |
| | 8970 | }, |
| | 8971 | .Float, .Vector => {}, |
| 8843 | }, | 8972 | }, |
| 8844 | .load_got, .load_tlv => {}, | 8973 | .load_got, .load_tlv => {}, |
| 8845 | else => unreachable, | 8974 | else => unreachable, |
| ... | @@ -8849,22 +8978,26 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr | ... | @@ -8849,22 +8978,26 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 8849 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); | 8978 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 8850 | defer self.register_manager.unlockReg(addr_lock); | 8979 | defer self.register_manager.unlockReg(addr_lock); |
| 8851 | | 8980 | |
| | 8981 | const dst_alias = registerAlias(dst_reg, abi_size); |
| 8852 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ | 8982 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ |
| 8853 | .base = .{ .reg = addr_reg }, | 8983 | .base = .{ .reg = addr_reg }, |
| 8854 | }); | 8984 | }); |
| 8855 | if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16) | 8985 | switch (try self.moveStrategy(ty, false)) { |
| 8856 | try self.asmRegisterMemoryImmediate( | 8986 | .move => |tag| try self.asmRegisterMemory(tag, dst_alias, src_mem), |
| 8857 | .{ .p_w, .insr }, | 8987 | .insert_extract => |ie| try self.asmRegisterMemoryImmediate( |
| 8858 | registerAlias(dst_reg, abi_size), | 8988 | ie.insert, |
| | 8989 | dst_alias, |
| 8859 | src_mem, | 8990 | src_mem, |
| 8860 | Immediate.u(0), | 8991 | ie.imm, |
| 8861 | ) | 8992 | ), |
| 8862 | else | 8993 | .vex_insert_extract => |ie| try self.asmRegisterRegisterMemoryImmediate( |
| 8863 | try self.asmRegisterMemory( | 8994 | ie.insert, |
| 8864 | try self.movMirTag(ty, false), | 8995 | dst_alias, |
| 8865 | registerAlias(dst_reg, abi_size), | 8996 | dst_alias, |
| 8866 | src_mem, | 8997 | src_mem, |
| 8867 | ); | 8998 | ie.imm, |
| | 8999 | ), |
| | 9000 | } |
| 8868 | }, | 9001 | }, |
| 8869 | .lea_direct, .lea_got => |sym_index| { | 9002 | .lea_direct, .lea_got => |sym_index| { |
| 8870 | const atom_index = try self.owner.getSymbolIndex(self); | 9003 | const atom_index = try self.owner.getSymbolIndex(self); |
| ... | @@ -8966,36 +9099,33 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal | ... | @@ -8966,36 +9099,33 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal |
| 8966 | Memory.PtrSize.fromSize(abi_size), | 9099 | Memory.PtrSize.fromSize(abi_size), |
| 8967 | .{ .base = base, .disp = disp }, | 9100 | .{ .base = base, .disp = disp }, |
| 8968 | ); | 9101 | ); |
| 8969 | if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16) | 9102 | const src_alias = registerAlias(src_reg, abi_size); |
| 8970 | try self.asmMemoryRegisterImmediate( | 9103 | switch (try self.moveStrategy(ty, switch (base) { |
| 8971 | .{ .p_w, .extr }, | 9104 | .none => mem.isAlignedGeneric( |
| 8972 | dst_mem, | 9105 | u32, |
| 8973 | src_reg.to128(), | 9106 | @bitCast(u32, disp), |
| 8974 | Immediate.u(0), | 9107 | ty.abiAlignment(self.target.*), |
| 8975 | ) | 9108 | ), |
| 8976 | else | 9109 | .reg => |reg| switch (reg) { |
| 8977 | try self.asmMemoryRegister( | 9110 | .es, .cs, .ss, .ds => mem.isAlignedGeneric( |
| 8978 | try self.movMirTag(ty, switch (base) { | 9111 | u32, |
| 8979 | .none => mem.isAlignedGeneric( | 9112 | @bitCast(u32, disp), |
| 8980 | u32, | 9113 | ty.abiAlignment(self.target.*), |
| 8981 | @bitCast(u32, disp), | 9114 | ), |
| 8982 | ty.abiAlignment(self.target.*), | 9115 | else => false, |
| 8983 | ), | 9116 | }, |
| 8984 | .reg => |reg| switch (reg) { | 9117 | .frame => |frame_index| self.getFrameAddrAlignment( |
| 8985 | .es, .cs, .ss, .ds => mem.isAlignedGeneric( | 9118 | .{ .index = frame_index, .off = disp }, |
| 8986 | u32, | 9119 | ) >= ty.abiAlignment(self.target.*), |
| 8987 | @bitCast(u32, disp), | 9120 | })) { |
| 8988 | ty.abiAlignment(self.target.*), | 9121 | .move => |tag| try self.asmMemoryRegister(tag, dst_mem, src_alias), |
| 8989 | ), | 9122 | .insert_extract, .vex_insert_extract => |ie| try self.asmMemoryRegisterImmediate( |
| 8990 | else => false, | 9123 | ie.extract, |
| 8991 | }, | | |
| 8992 | .frame => |frame_index| self.getFrameAddrAlignment( | | |
| 8993 | .{ .index = frame_index, .off = disp }, | | |
| 8994 | ) >= ty.abiAlignment(self.target.*), | | |
| 8995 | }), | | |
| 8996 | dst_mem, | 9124 | dst_mem, |
| 8997 | registerAlias(src_reg, abi_size), | 9125 | src_alias, |
| 8998 | ); | 9126 | ie.imm, |
| | 9127 | ), |
| | 9128 | } |
| 8999 | }, | 9129 | }, |
| 9000 | .register_overflow => |ro| { | 9130 | .register_overflow => |ro| { |
| 9001 | try self.genSetMem( | 9131 | try self.genSetMem( |