authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-09 21:47:11+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-11 20:05:49+01:00
log4af8313f362e393f51af1bcefd0b91c3b1ce5611
tree4055e09d64e8c9f9b6c91aad6b2d810422bec68f
parent32708dd6e2f16b4b688b2deed22253ea36233c91

x86_64: plug up all RM/MR references


1 files changed, 112 insertions(+), 172 deletions(-)

src/arch/x86_64/CodeGen.zig+112-172
...@@ -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);
59285925
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 };
59355932 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 }
59505942
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);
59715959
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 };
59785966 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 }
59935976
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 });
60256007 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 }
61146072
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 }
61886151
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 // });
62156169
6216 // convert6170 // 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 // });
62316176
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,