| ... | ... | @@ -5834,14 +5834,11 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5834 | 5834 | if (off < std.math.minInt(i32) or off > std.math.maxInt(i32)) { |
| 5835 | 5835 | return self.fail("stack offset too large", .{}); |
| 5836 | 5836 | } |
| 5837 | | // _ = try self.addInst(.{ |
| 5838 | | // .tag = .lea, |
| 5839 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 5840 | | // .reg1 = registerAlias(reg, abi_size), |
| 5841 | | // .reg2 = .rbp, |
| 5842 | | // }), |
| 5843 | | // .data = .{ .disp = -off }, |
| 5844 | | // }); |
| 5837 | try self.asmRegisterMemory( |
| 5838 | .lea, |
| 5839 | registerAlias(reg, abi_size), |
| 5840 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), |
| 5841 | ); |
| 5845 | 5842 | }, |
| 5846 | 5843 | .unreach, .none => return, // Nothing to do. |
| 5847 | 5844 | .undef => { |
| ... | ... | @@ -5927,40 +5924,31 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5927 | 5924 | try self.loadMemPtrIntoRegister(base_reg, Type.usize, mcv); |
| 5928 | 5925 | |
| 5929 | 5926 | if (intrinsicsAllowed(self.target.*, ty)) { |
| 5930 | | // const tag: Mir.Inst.Tag = switch (ty.tag()) { |
| 5931 | | // .f32 => Mir.Inst.Tag.mov_f32, |
| 5932 | | // .f64 => Mir.Inst.Tag.mov_f64, |
| 5933 | | // else => return self.fail("TODO genSetReg from memory for {}", .{ty.fmtDebug()}), |
| 5934 | | // }; |
| 5935 | | |
| 5936 | | // _ = try self.addInst(.{ |
| 5937 | | // .tag = tag, |
| 5938 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 5939 | | // .reg1 = reg.to128(), |
| 5940 | | // .reg2 = switch (ty.tag()) { |
| 5941 | | // .f32 => base_reg.to32(), |
| 5942 | | // .f64 => base_reg.to64(), |
| 5943 | | // else => unreachable, |
| 5944 | | // }, |
| 5945 | | // }), |
| 5946 | | // .data = .{ .disp = 0 }, |
| 5947 | | // }); |
| 5948 | | return; |
| 5927 | const tag: Mir.Inst.Tag = switch (ty.tag()) { |
| 5928 | .f32 => .movss, |
| 5929 | .f64 => .movsx, |
| 5930 | else => return self.fail("TODO genSetReg from memory for {}", .{ty.fmtDebug()}), |
| 5931 | }; |
| 5932 | const ptr_size: Memory.PtrSize = switch (ty.tag()) { |
| 5933 | .f32 => .dword, |
| 5934 | .f64 => .qword, |
| 5935 | else => unreachable, |
| 5936 | }; |
| 5937 | return self.asmRegisterMemory(tag, reg.to128(), Memory.sib(ptr_size, .{ |
| 5938 | .base = base_reg.to64(), |
| 5939 | .disp = 0, |
| 5940 | })); |
| 5949 | 5941 | } |
| 5950 | 5942 | |
| 5951 | 5943 | return self.fail("TODO genSetReg from memory for float with no intrinsics", .{}); |
| 5952 | 5944 | }, |
| 5953 | 5945 | else => { |
| 5954 | 5946 | try self.loadMemPtrIntoRegister(reg, Type.usize, mcv); |
| 5955 | | // _ = try self.addInst(.{ |
| 5956 | | // .tag = .mov, |
| 5957 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 5958 | | // .reg1 = registerAlias(reg, abi_size), |
| 5959 | | // .reg2 = reg.to64(), |
| 5960 | | // .flags = 0b01, |
| 5961 | | // }), |
| 5962 | | // .data = .{ .disp = 0 }, |
| 5963 | | // }); |
| 5947 | try self.asmRegisterMemory( |
| 5948 | .mov, |
| 5949 | registerAlias(reg, abi_size), |
| 5950 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64(), .disp = 0 }), |
| 5951 | ); |
| 5964 | 5952 | }, |
| 5965 | 5953 | } |
| 5966 | 5954 | }, |
| ... | ... | @@ -5970,40 +5958,34 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 5970 | 5958 | try self.loadMemPtrIntoRegister(base_reg, Type.usize, mcv); |
| 5971 | 5959 | |
| 5972 | 5960 | if (intrinsicsAllowed(self.target.*, ty)) { |
| 5973 | | // const tag: Mir.Inst.Tag = switch (ty.tag()) { |
| 5974 | | // .f32 => Mir.Inst.Tag.mov_f32, |
| 5975 | | // .f64 => Mir.Inst.Tag.mov_f64, |
| 5976 | | // else => return self.fail("TODO genSetReg from memory for {}", .{ty.fmtDebug()}), |
| 5977 | | // }; |
| 5978 | | |
| 5979 | | // _ = try self.addInst(.{ |
| 5980 | | // .tag = tag, |
| 5981 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 5982 | | // .reg1 = reg.to128(), |
| 5983 | | // .reg2 = switch (ty.tag()) { |
| 5984 | | // .f32 => base_reg.to32(), |
| 5985 | | // .f64 => base_reg.to64(), |
| 5986 | | // else => unreachable, |
| 5987 | | // }, |
| 5988 | | // }), |
| 5989 | | // .data = .{ .disp = 0 }, |
| 5990 | | // }); |
| 5991 | | return; |
| 5961 | const tag: Mir.Inst.Tag = switch (ty.tag()) { |
| 5962 | .f32 => .movss, |
| 5963 | .f64 => .movsd, |
| 5964 | else => return self.fail("TODO genSetReg from memory for {}", .{ty.fmtDebug()}), |
| 5965 | }; |
| 5966 | const ptr_size: Memory.PtrSize = switch (ty.tag()) { |
| 5967 | .f32 => .dword, |
| 5968 | .f64 => .qword, |
| 5969 | else => unreachable, |
| 5970 | }; |
| 5971 | return self.asmRegisterMemory(tag, reg.to128(), Memory.sib(ptr_size, .{ |
| 5972 | .base = base_reg.to64(), |
| 5973 | .disp = 0, |
| 5974 | })); |
| 5992 | 5975 | } |
| 5993 | 5976 | |
| 5994 | 5977 | return self.fail("TODO genSetReg from memory for float with no intrinsics", .{}); |
| 5995 | 5978 | }, |
| 5996 | 5979 | else => { |
| 5997 | 5980 | if (x <= math.maxInt(i32)) { |
| 5998 | | // mov reg, [ds:imm32] |
| 5999 | | // _ = try self.addInst(.{ |
| 6000 | | // .tag = .mov, |
| 6001 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 6002 | | // .reg1 = registerAlias(reg, abi_size), |
| 6003 | | // .flags = 0b01, |
| 6004 | | // }), |
| 6005 | | // .data = .{ .disp = @intCast(i32, x) }, |
| 6006 | | // }); |
| 5981 | try self.asmRegisterMemory( |
| 5982 | .mov, |
| 5983 | registerAlias(reg, abi_size), |
| 5984 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ |
| 5985 | .base = .ds, |
| 5986 | .disp = @intCast(i32, x), |
| 5987 | }), |
| 5988 | ); |
| 6007 | 5989 | } else { |
| 6008 | 5990 | if (reg.to64() == .rax) { |
| 6009 | 5991 | // If this is RAX, we can use a direct load. |
| ... | ... | @@ -6022,17 +6004,11 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 6022 | 6004 | } else { |
| 6023 | 6005 | // Rather than duplicate the logic used for the move, we just use a self-call with a new MCValue. |
| 6024 | 6006 | try self.genSetReg(ty, reg, MCValue{ .immediate = x }); |
| 6025 | | |
| 6026 | | // mov reg, [reg + 0x0] |
| 6027 | | // _ = try self.addInst(.{ |
| 6028 | | // .tag = .mov, |
| 6029 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 6030 | | // .reg1 = registerAlias(reg, abi_size), |
| 6031 | | // .reg2 = reg.to64(), |
| 6032 | | // .flags = 0b01, |
| 6033 | | // }), |
| 6034 | | // .data = .{ .disp = 0 }, |
| 6035 | | // }); |
| 6007 | try self.asmRegisterMemory( |
| 6008 | .mov, |
| 6009 | registerAlias(reg, abi_size), |
| 6010 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64(), .disp = 0 }), |
| 6011 | ); |
| 6036 | 6012 | } |
| 6037 | 6013 | } |
| 6038 | 6014 | }, |
| ... | ... | @@ -6046,81 +6022,59 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 6046 | 6022 | .Int => switch (ty.intInfo(self.target.*).signedness) { |
| 6047 | 6023 | .signed => { |
| 6048 | 6024 | if (abi_size <= 4) { |
| 6049 | | const flags: u2 = switch (abi_size) { |
| 6050 | | 1 => 0b01, |
| 6051 | | 2 => 0b10, |
| 6052 | | 4 => 0b11, |
| 6053 | | else => unreachable, |
| 6054 | | }; |
| 6055 | | _ = flags; |
| 6056 | | // _ = try self.addInst(.{ |
| 6057 | | // .tag = .mov_sign_extend, |
| 6058 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 6059 | | // .reg1 = reg.to64(), |
| 6060 | | // .reg2 = .rbp, |
| 6061 | | // .flags = flags, |
| 6062 | | // }), |
| 6063 | | // .data = .{ .disp = -off }, |
| 6064 | | // }); |
| 6065 | | return; |
| 6025 | return self.asmRegisterMemory( |
| 6026 | .movsx, |
| 6027 | reg.to64(), |
| 6028 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ |
| 6029 | .base = .rbp, |
| 6030 | .disp = -off, |
| 6031 | }), |
| 6032 | ); |
| 6066 | 6033 | } |
| 6067 | 6034 | }, |
| 6068 | 6035 | .unsigned => { |
| 6069 | 6036 | if (abi_size <= 2) { |
| 6070 | | const flags: u2 = switch (abi_size) { |
| 6071 | | 1 => 0b01, |
| 6072 | | 2 => 0b10, |
| 6073 | | else => unreachable, |
| 6074 | | }; |
| 6075 | | _ = flags; |
| 6076 | | // _ = try self.addInst(.{ |
| 6077 | | // .tag = .mov_zero_extend, |
| 6078 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 6079 | | // .reg1 = reg.to64(), |
| 6080 | | // .reg2 = .rbp, |
| 6081 | | // .flags = flags, |
| 6082 | | // }), |
| 6083 | | // .data = .{ .disp = -off }, |
| 6084 | | // }); |
| 6085 | | return; |
| 6037 | return self.asmRegisterMemory( |
| 6038 | .movzx, |
| 6039 | reg.to64(), |
| 6040 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ |
| 6041 | .base = .rbp, |
| 6042 | .disp = -off, |
| 6043 | }), |
| 6044 | ); |
| 6086 | 6045 | } |
| 6087 | 6046 | }, |
| 6088 | 6047 | }, |
| 6089 | 6048 | .Float => { |
| 6090 | 6049 | if (intrinsicsAllowed(self.target.*, ty)) { |
| 6091 | | // const tag: Mir.Inst.Tag = switch (ty.tag()) { |
| 6092 | | // .f32 => Mir.Inst.Tag.mov_f32, |
| 6093 | | // .f64 => Mir.Inst.Tag.mov_f64, |
| 6094 | | // else => return self.fail("TODO genSetReg from stack offset for {}", .{ty.fmtDebug()}), |
| 6095 | | // }; |
| 6096 | | // _ = try self.addInst(.{ |
| 6097 | | // .tag = tag, |
| 6098 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 6099 | | // .reg1 = reg.to128(), |
| 6100 | | // .reg2 = switch (ty.tag()) { |
| 6101 | | // .f32 => .ebp, |
| 6102 | | // .f64 => .rbp, |
| 6103 | | // else => unreachable, |
| 6104 | | // }, |
| 6105 | | // }), |
| 6106 | | // .data = .{ .disp = -off }, |
| 6107 | | // }); |
| 6108 | | return; |
| 6050 | const tag: Mir.Inst.Tag = switch (ty.tag()) { |
| 6051 | .f32 => .movss, |
| 6052 | .f64 => .movsd, |
| 6053 | else => return self.fail( |
| 6054 | "TODO genSetReg from stack offset for {}", |
| 6055 | .{ty.fmtDebug()}, |
| 6056 | ), |
| 6057 | }; |
| 6058 | const ptr_size: Memory.PtrSize = switch (ty.tag()) { |
| 6059 | .f32 => .dword, |
| 6060 | .f64 => .qword, |
| 6061 | else => unreachable, |
| 6062 | }; |
| 6063 | return self.asmRegisterMemory(tag, reg.to128(), Memory.sib(ptr_size, .{ |
| 6064 | .base = .rbp, |
| 6065 | .disp = -off, |
| 6066 | })); |
| 6109 | 6067 | } |
| 6110 | 6068 | return self.fail("TODO genSetReg from stack offset for float with no intrinsics", .{}); |
| 6111 | 6069 | }, |
| 6112 | 6070 | else => {}, |
| 6113 | 6071 | } |
| 6114 | 6072 | |
| 6115 | | // _ = try self.addInst(.{ |
| 6116 | | // .tag = .mov, |
| 6117 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 6118 | | // .reg1 = registerAlias(reg, abi_size), |
| 6119 | | // .reg2 = .rbp, |
| 6120 | | // .flags = 0b01, |
| 6121 | | // }), |
| 6122 | | // .data = .{ .disp = -off }, |
| 6123 | | // }); |
| 6073 | try self.asmRegisterMemory( |
| 6074 | .mov, |
| 6075 | registerAlias(reg, abi_size), |
| 6076 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), |
| 6077 | ); |
| 6124 | 6078 | }, |
| 6125 | 6079 | } |
| 6126 | 6080 | } |
| ... | ... | @@ -6184,7 +6138,16 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void { |
| 6184 | 6138 | const src_ty = self.air.typeOf(ty_op.operand); |
| 6185 | 6139 | const dst_ty = self.air.typeOfIndex(inst); |
| 6186 | 6140 | const operand = try self.resolveInst(ty_op.operand); |
| 6187 | | _ = dst_ty; |
| 6141 | const src_abi_size = @intCast(u32, src_ty.abiSize(self.target.*)); |
| 6142 | const dst_abi_size = @intCast(u32, dst_ty.abiSize(self.target.*)); |
| 6143 | |
| 6144 | switch (src_abi_size) { |
| 6145 | 4, 8 => {}, |
| 6146 | else => |size| return self.fail("TODO load ST(0) with abiSize={}", .{size}), |
| 6147 | } |
| 6148 | if (dst_abi_size > 8) { |
| 6149 | return self.fail("TODO convert float with abiSize={}", .{dst_abi_size}); |
| 6150 | } |
| 6188 | 6151 | |
| 6189 | 6152 | // move float src to ST(0) |
| 6190 | 6153 | const stack_offset = switch (operand) { |
| ... | ... | @@ -6192,42 +6155,24 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void { |
| 6192 | 6155 | else => blk: { |
| 6193 | 6156 | const offset = @intCast(i32, try self.allocMem( |
| 6194 | 6157 | inst, |
| 6195 | | @intCast(u32, src_ty.abiSize(self.target.*)), |
| 6158 | src_abi_size, |
| 6196 | 6159 | src_ty.abiAlignment(self.target.*), |
| 6197 | 6160 | )); |
| 6198 | 6161 | try self.genSetStack(src_ty, offset, operand, .{}); |
| 6199 | 6162 | break :blk offset; |
| 6200 | 6163 | }, |
| 6201 | 6164 | }; |
| 6202 | | _ = stack_offset; |
| 6203 | | // _ = try self.addInst(.{ |
| 6204 | | // .tag = .fld, |
| 6205 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 6206 | | // .reg1 = .rbp, |
| 6207 | | // .flags = switch (src_ty.abiSize(self.target.*)) { |
| 6208 | | // 4 => 0b01, |
| 6209 | | // 8 => 0b10, |
| 6210 | | // else => |size| return self.fail("TODO load ST(0) with abiSize={}", .{size}), |
| 6211 | | // }, |
| 6212 | | // }), |
| 6213 | | // .data = .{ .disp = -stack_offset }, |
| 6214 | | // }); |
| 6165 | try self.asmMemory(.fld, Memory.sib(Memory.PtrSize.fromSize(src_abi_size), .{ |
| 6166 | .base = .rbp, |
| 6167 | .disp = -stack_offset, |
| 6168 | })); |
| 6215 | 6169 | |
| 6216 | 6170 | // convert |
| 6217 | 6171 | const stack_dst = try self.allocRegOrMem(inst, false); |
| 6218 | | // _ = try self.addInst(.{ |
| 6219 | | // .tag = .fisttp, |
| 6220 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 6221 | | // .reg1 = .rbp, |
| 6222 | | // .flags = switch (dst_ty.abiSize(self.target.*)) { |
| 6223 | | // 1...2 => 0b00, |
| 6224 | | // 3...4 => 0b01, |
| 6225 | | // 5...8 => 0b10, |
| 6226 | | // else => |size| return self.fail("TODO convert float with abiSize={}", .{size}), |
| 6227 | | // }, |
| 6228 | | // }), |
| 6229 | | // .data = .{ .disp = -stack_dst.stack_offset }, |
| 6230 | | // }); |
| 6172 | try self.asmMemory(.fisttp, Memory.sib(Memory.PtrSize.fromSize(dst_abi_size), .{ |
| 6173 | .base = .rbp, |
| 6174 | .disp = -stack_dst.stack_offset, |
| 6175 | })); |
| 6231 | 6176 | |
| 6232 | 6177 | return self.finishAir(inst, stack_dst, .{ ty_op.operand, .none, .none }); |
| 6233 | 6178 | } |
| ... | ... | @@ -6318,15 +6263,10 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { |
| 6318 | 6263 | .linker_load, .memory => { |
| 6319 | 6264 | const reg = try self.register_manager.allocReg(null, gp); |
| 6320 | 6265 | try self.loadMemPtrIntoRegister(reg, src_ty, src_ptr); |
| 6321 | | // _ = try self.addInst(.{ |
| 6322 | | // .tag = .mov, |
| 6323 | | // .ops = Mir.Inst.Ops.encode(.{ |
| 6324 | | // .reg1 = reg, |
| 6325 | | // .reg2 = reg, |
| 6326 | | // .flags = 0b01, |
| 6327 | | // }), |
| 6328 | | // .data = .{ .disp = 0 }, |
| 6329 | | // }); |
| 6266 | try self.asmRegisterMemory(.mov, reg, Memory.sib(.qword, .{ |
| 6267 | .base = reg, |
| 6268 | .disp = 0, |
| 6269 | })); |
| 6330 | 6270 | break :blk MCValue{ .register = reg }; |
| 6331 | 6271 | }, |
| 6332 | 6272 | else => break :blk src_ptr, |