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