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
58345834 if (off < std.math.minInt(i32) or off > std.math.maxInt(i32)) {
58355835 return self.fail("stack offset too large", .{});
58365836 }
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 );
58455842 },
58465843 .unreach, .none => return, // Nothing to do.
58475844 .undef => {
......@@ -5927,40 +5924,31 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
59275924 try self.loadMemPtrIntoRegister(base_reg, Type.usize, mcv);
59285925
59295926 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 }));
59495941 }
59505942
59515943 return self.fail("TODO genSetReg from memory for float with no intrinsics", .{});
59525944 },
59535945 else => {
59545946 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 );
59645952 },
59655953 }
59665954 },
......@@ -5970,40 +5958,34 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
59705958 try self.loadMemPtrIntoRegister(base_reg, Type.usize, mcv);
59715959
59725960 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 }));
59925975 }
59935976
59945977 return self.fail("TODO genSetReg from memory for float with no intrinsics", .{});
59955978 },
59965979 else => {
59975980 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 );
60075989 } else {
60085990 if (reg.to64() == .rax) {
60095991 // 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
60226004 } else {
60236005 // Rather than duplicate the logic used for the move, we just use a self-call with a new MCValue.
60246006 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 );
60366012 }
60376013 }
60386014 },
......@@ -6046,81 +6022,59 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
60466022 .Int => switch (ty.intInfo(self.target.*).signedness) {
60476023 .signed => {
60486024 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 );
60666033 }
60676034 },
60686035 .unsigned => {
60696036 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 );
60866045 }
60876046 },
60886047 },
60896048 .Float => {
60906049 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 }));
61096067 }
61106068 return self.fail("TODO genSetReg from stack offset for float with no intrinsics", .{});
61116069 },
61126070 else => {},
61136071 }
61146072
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 );
61246078 },
61256079 }
61266080}
......@@ -6184,7 +6138,16 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void {
61846138 const src_ty = self.air.typeOf(ty_op.operand);
61856139 const dst_ty = self.air.typeOfIndex(inst);
61866140 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
61896152 // move float src to ST(0)
61906153 const stack_offset = switch (operand) {
......@@ -6192,42 +6155,24 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void {
61926155 else => blk: {
61936156 const offset = @intCast(i32, try self.allocMem(
61946157 inst,
6195 @intCast(u32, src_ty.abiSize(self.target.*)),
6158 src_abi_size,
61966159 src_ty.abiAlignment(self.target.*),
61976160 ));
61986161 try self.genSetStack(src_ty, offset, operand, .{});
61996162 break :blk offset;
62006163 },
62016164 };
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 }));
62156169
62166170 // convert
62176171 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 }));
62316176
62326177 return self.finishAir(inst, stack_dst, .{ ty_op.operand, .none, .none });
62336178}
......@@ -6318,15 +6263,10 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
63186263 .linker_load, .memory => {
63196264 const reg = try self.register_manager.allocReg(null, gp);
63206265 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 }));
63306270 break :blk MCValue{ .register = reg };
63316271 },
63326272 else => break :blk src_ptr,