| ... | ... | @@ -8579,56 +8579,174 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 8579 | 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 | 8594 | switch (ty.zigTypeTag()) { |
| 8584 | | else => return .{ ._, .mov }, |
| 8595 | else => return .{ .move = .{ ._, .mov } }, |
| 8585 | 8596 | .Float => switch (ty.floatBits(self.target.*)) { |
| 8586 | | 16 => unreachable, // needs special handling |
| 8587 | | 32 => return if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov }, |
| 8588 | | 64 => return if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov }, |
| 8589 | | 128 => return if (self.hasFeature(.avx)) |
| 8597 | 16 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{ |
| 8598 | .insert = .{ .vp_w, .insr }, |
| 8599 | .extract = .{ .vp_w, .extr }, |
| 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 | 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 | 8611 | else => {}, |
| 8593 | 8612 | }, |
| 8594 | 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 | 8698 | .Float => switch (ty.childType().floatBits(self.target.*)) { |
| 8596 | 8699 | 16 => switch (ty.vectorLen()) { |
| 8597 | | 1 => unreachable, // needs special handling |
| 8598 | | 2 => return if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov }, |
| 8599 | | 3...4 => return if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov }, |
| 8600 | | 5...8 => return if (self.hasFeature(.avx)) |
| 8700 | 1 => {}, |
| 8701 | 2 => return .{ .move = if (self.hasFeature(.avx)) |
| 8702 | .{ .v_ss, .mov } |
| 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 | 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 | 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 | 8714 | else => {}, |
| 8606 | 8715 | }, |
| 8607 | 8716 | 32 => switch (ty.vectorLen()) { |
| 8608 | | 1 => return if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov }, |
| 8609 | | 2 => return if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov }, |
| 8610 | | 3...4 => return if (self.hasFeature(.avx)) |
| 8717 | 1 => return .{ .move = if (self.hasFeature(.avx)) |
| 8718 | .{ .v_ss, .mov } |
| 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 | 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 | 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 | 8730 | else => {}, |
| 8616 | 8731 | }, |
| 8617 | 8732 | 64 => switch (ty.vectorLen()) { |
| 8618 | | 1 => return if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov }, |
| 8619 | | 2 => return if (self.hasFeature(.avx)) |
| 8733 | 1 => return .{ .move = if (self.hasFeature(.avx)) |
| 8734 | .{ .v_sd, .mov } |
| 8735 | else |
| 8736 | .{ ._sd, .mov } }, |
| 8737 | 2 => return .{ .move = if (self.hasFeature(.avx)) |
| 8620 | 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 | 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 | 8742 | else => {}, |
| 8625 | 8743 | }, |
| 8626 | 8744 | 128 => switch (ty.vectorLen()) { |
| 8627 | | 1 => return if (self.hasFeature(.avx)) |
| 8745 | 1 => return .{ .move = if (self.hasFeature(.avx)) |
| 8628 | 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 | 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 | 8750 | else => {}, |
| 8633 | 8751 | }, |
| 8634 | 8752 | else => {}, |
| ... | ... | @@ -8636,7 +8754,7 @@ fn movMirTag(self: *Self, ty: Type, aligned: bool) !Mir.Inst.FixedTag { |
| 8636 | 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 | 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 | 8882 | .load_frame, |
| 8765 | 8883 | .lea_frame, |
| 8766 | 8884 | => { |
| 8885 | const dst_alias = registerAlias(dst_reg, abi_size); |
| 8767 | 8886 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), switch (src_mcv) { |
| 8768 | 8887 | .register_offset, .indirect => |reg_off| .{ |
| 8769 | 8888 | .base = .{ .reg = reg_off.reg }, |
| ... | ... | @@ -8775,71 +8894,81 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 8775 | 8894 | }, |
| 8776 | 8895 | else => unreachable, |
| 8777 | 8896 | }); |
| 8778 | | if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16) |
| 8779 | | try self.asmRegisterMemoryImmediate( |
| 8780 | | .{ .p_w, .insr }, |
| 8781 | | registerAlias(dst_reg, abi_size), |
| 8897 | switch (@as(MoveStrategy, switch (src_mcv) { |
| 8898 | .register_offset => |reg_off| switch (reg_off.off) { |
| 8899 | 0 => return self.genSetReg(dst_reg, ty, .{ .register = reg_off.reg }), |
| 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 | 8914 | src_mem, |
| 8783 | | Immediate.u(0), |
| 8784 | | ) |
| 8785 | | else |
| 8786 | | try self.asmRegisterMemory( |
| 8787 | | switch (src_mcv) { |
| 8788 | | .register_offset => |reg_off| switch (reg_off.off) { |
| 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), |
| 8915 | ie.imm, |
| 8916 | ), |
| 8917 | .vex_insert_extract => |ie| try self.asmRegisterRegisterMemoryImmediate( |
| 8918 | ie.insert, |
| 8919 | dst_alias, |
| 8920 | dst_alias, |
| 8801 | 8921 | src_mem, |
| 8802 | | ); |
| 8922 | ie.imm, |
| 8923 | ), |
| 8924 | } |
| 8803 | 8925 | }, |
| 8804 | 8926 | .memory, .load_direct, .load_got, .load_tlv => { |
| 8805 | 8927 | switch (src_mcv) { |
| 8806 | 8928 | .memory => |addr| if (math.cast(i32, @bitCast(i64, addr))) |small_addr| { |
| 8929 | const dst_alias = registerAlias(dst_reg, abi_size); |
| 8807 | 8930 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ |
| 8808 | 8931 | .base = .{ .reg = .ds }, |
| 8809 | 8932 | .disp = small_addr, |
| 8810 | 8933 | }); |
| 8811 | | return if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16) |
| 8812 | | self.asmRegisterMemoryImmediate( |
| 8813 | | .{ .p_w, .insr }, |
| 8814 | | registerAlias(dst_reg, abi_size), |
| 8934 | switch (try self.moveStrategy(ty, mem.isAlignedGeneric( |
| 8935 | u32, |
| 8936 | @bitCast(u32, small_addr), |
| 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 | 8943 | src_mem, |
| 8816 | | Immediate.u(0), |
| 8817 | | ) |
| 8818 | | else |
| 8819 | | self.asmRegisterMemory( |
| 8820 | | try self.movMirTag(ty, mem.isAlignedGeneric( |
| 8821 | | u32, |
| 8822 | | @bitCast(u32, small_addr), |
| 8823 | | ty.abiAlignment(self.target.*), |
| 8824 | | )), |
| 8825 | | registerAlias(dst_reg, abi_size), |
| 8944 | ie.imm, |
| 8945 | ), |
| 8946 | .vex_insert_extract => |ie| try self.asmRegisterRegisterMemoryImmediate( |
| 8947 | ie.insert, |
| 8948 | dst_alias, |
| 8949 | dst_alias, |
| 8826 | 8950 | src_mem, |
| 8827 | | ); |
| 8951 | ie.imm, |
| 8952 | ), |
| 8953 | } |
| 8828 | 8954 | }, |
| 8829 | | .load_direct => |sym_index| if (!ty.isRuntimeFloat()) { |
| 8830 | | const atom_index = try self.owner.getSymbolIndex(self); |
| 8831 | | _ = try self.addInst(.{ |
| 8832 | | .tag = .mov, |
| 8833 | | .ops = .direct_reloc, |
| 8834 | | .data = .{ .rx = .{ |
| 8835 | | .r1 = dst_reg.to64(), |
| 8836 | | .payload = try self.addExtra(Mir.Reloc{ |
| 8837 | | .atom_index = atom_index, |
| 8838 | | .sym_index = sym_index, |
| 8839 | | }), |
| 8840 | | } }, |
| 8841 | | }); |
| 8842 | | return; |
| 8955 | .load_direct => |sym_index| switch (ty.zigTypeTag()) { |
| 8956 | else => { |
| 8957 | const atom_index = try self.owner.getSymbolIndex(self); |
| 8958 | _ = try self.addInst(.{ |
| 8959 | .tag = .mov, |
| 8960 | .ops = .direct_reloc, |
| 8961 | .data = .{ .rx = .{ |
| 8962 | .r1 = dst_reg.to64(), |
| 8963 | .payload = try self.addExtra(Mir.Reloc{ |
| 8964 | .atom_index = atom_index, |
| 8965 | .sym_index = sym_index, |
| 8966 | }), |
| 8967 | } }, |
| 8968 | }); |
| 8969 | return; |
| 8970 | }, |
| 8971 | .Float, .Vector => {}, |
| 8843 | 8972 | }, |
| 8844 | 8973 | .load_got, .load_tlv => {}, |
| 8845 | 8974 | else => unreachable, |
| ... | ... | @@ -8849,22 +8978,26 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr |
| 8849 | 8978 | const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg); |
| 8850 | 8979 | defer self.register_manager.unlockReg(addr_lock); |
| 8851 | 8980 | |
| 8981 | const dst_alias = registerAlias(dst_reg, abi_size); |
| 8852 | 8982 | const src_mem = Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ |
| 8853 | 8983 | .base = .{ .reg = addr_reg }, |
| 8854 | 8984 | }); |
| 8855 | | if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16) |
| 8856 | | try self.asmRegisterMemoryImmediate( |
| 8857 | | .{ .p_w, .insr }, |
| 8858 | | registerAlias(dst_reg, abi_size), |
| 8985 | switch (try self.moveStrategy(ty, false)) { |
| 8986 | .move => |tag| try self.asmRegisterMemory(tag, dst_alias, src_mem), |
| 8987 | .insert_extract => |ie| try self.asmRegisterMemoryImmediate( |
| 8988 | ie.insert, |
| 8989 | dst_alias, |
| 8859 | 8990 | src_mem, |
| 8860 | | Immediate.u(0), |
| 8861 | | ) |
| 8862 | | else |
| 8863 | | try self.asmRegisterMemory( |
| 8864 | | try self.movMirTag(ty, false), |
| 8865 | | registerAlias(dst_reg, abi_size), |
| 8991 | ie.imm, |
| 8992 | ), |
| 8993 | .vex_insert_extract => |ie| try self.asmRegisterRegisterMemoryImmediate( |
| 8994 | ie.insert, |
| 8995 | dst_alias, |
| 8996 | dst_alias, |
| 8866 | 8997 | src_mem, |
| 8867 | | ); |
| 8998 | ie.imm, |
| 8999 | ), |
| 9000 | } |
| 8868 | 9001 | }, |
| 8869 | 9002 | .lea_direct, .lea_got => |sym_index| { |
| 8870 | 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 | 9099 | Memory.PtrSize.fromSize(abi_size), |
| 8967 | 9100 | .{ .base = base, .disp = disp }, |
| 8968 | 9101 | ); |
| 8969 | | if (ty.isRuntimeFloat() and ty.floatBits(self.target.*) == 16) |
| 8970 | | try self.asmMemoryRegisterImmediate( |
| 8971 | | .{ .p_w, .extr }, |
| 8972 | | dst_mem, |
| 8973 | | src_reg.to128(), |
| 8974 | | Immediate.u(0), |
| 8975 | | ) |
| 8976 | | else |
| 8977 | | try self.asmMemoryRegister( |
| 8978 | | try self.movMirTag(ty, switch (base) { |
| 8979 | | .none => mem.isAlignedGeneric( |
| 8980 | | u32, |
| 8981 | | @bitCast(u32, disp), |
| 8982 | | ty.abiAlignment(self.target.*), |
| 8983 | | ), |
| 8984 | | .reg => |reg| switch (reg) { |
| 8985 | | .es, .cs, .ss, .ds => mem.isAlignedGeneric( |
| 8986 | | u32, |
| 8987 | | @bitCast(u32, disp), |
| 8988 | | ty.abiAlignment(self.target.*), |
| 8989 | | ), |
| 8990 | | else => false, |
| 8991 | | }, |
| 8992 | | .frame => |frame_index| self.getFrameAddrAlignment( |
| 8993 | | .{ .index = frame_index, .off = disp }, |
| 8994 | | ) >= ty.abiAlignment(self.target.*), |
| 8995 | | }), |
| 9102 | const src_alias = registerAlias(src_reg, abi_size); |
| 9103 | switch (try self.moveStrategy(ty, switch (base) { |
| 9104 | .none => mem.isAlignedGeneric( |
| 9105 | u32, |
| 9106 | @bitCast(u32, disp), |
| 9107 | ty.abiAlignment(self.target.*), |
| 9108 | ), |
| 9109 | .reg => |reg| switch (reg) { |
| 9110 | .es, .cs, .ss, .ds => mem.isAlignedGeneric( |
| 9111 | u32, |
| 9112 | @bitCast(u32, disp), |
| 9113 | ty.abiAlignment(self.target.*), |
| 9114 | ), |
| 9115 | else => false, |
| 9116 | }, |
| 9117 | .frame => |frame_index| self.getFrameAddrAlignment( |
| 9118 | .{ .index = frame_index, .off = disp }, |
| 9119 | ) >= ty.abiAlignment(self.target.*), |
| 9120 | })) { |
| 9121 | .move => |tag| try self.asmMemoryRegister(tag, dst_mem, src_alias), |
| 9122 | .insert_extract, .vex_insert_extract => |ie| try self.asmMemoryRegisterImmediate( |
| 9123 | ie.extract, |
| 8996 | 9124 | dst_mem, |
| 8997 | | registerAlias(src_reg, abi_size), |
| 8998 | | ); |
| 9125 | src_alias, |
| 9126 | ie.imm, |
| 9127 | ), |
| 9128 | } |
| 8999 | 9129 | }, |
| 9000 | 9130 | .register_overflow => |ro| { |
| 9001 | 9131 | try self.genSetMem( |