authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-07 20:22:45+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-11 20:05:49+01:00
log219c1261a5f46636425be50fdc6e82534bb003a4
treeff067e80e5f08ab16f46d8e142ddd59f6bddfe1f
parent292f91aef2d2ed360f4dbb1f8cf6e22500a682ca

x86_64: all behavior tests passing


4 files changed, 41 insertions(+), 30 deletions(-)

src/arch/x86_64/CodeGen.zig+30-28
...@@ -2785,7 +2785,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -2785,7 +2785,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
2785 // introduce new MIR tag specifically for mov [reg + 0], imm2785 // introduce new MIR tag specifically for mov [reg + 0], imm
2786 const payload = try self.addExtra(Mir.ImmPair{2786 const payload = try self.addExtra(Mir.ImmPair{
2787 .dest_off = 0,2787 .dest_off = 0,
2788 .operand = @intCast(u32, imm),2788 .operand = @truncate(u32, imm),
2789 });2789 });
2790 _ = try self.addInst(.{2790 _ = try self.addInst(.{
2791 .tag = .mov_mem_imm,2791 .tag = .mov_mem_imm,
...@@ -5385,31 +5385,33 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE...@@ -5385,31 +5385,33 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
5385 return self.genSetStackArg(ty, stack_offset, .{ .register = reg });5385 return self.genSetStackArg(ty, stack_offset, .{ .register = reg });
5386 },5386 },
5387 .immediate => |imm| {5387 .immediate => |imm| {
5388 _ = imm;
5388 switch (abi_size) {5389 switch (abi_size) {
5389 1, 2, 4 => {5390 // TODO
5390 // We have a positive stack offset value but we want a twos complement negative5391 // 1, 2, 4 => {
5391 // offset from rbp, which is at the top of the stack frame.5392 // // We have a positive stack offset value but we want a twos complement negative
5392 // mov [rbp+offset], immediate5393 // // offset from rbp, which is at the top of the stack frame.
5393 const flags: u2 = switch (abi_size) {5394 // // mov [rbp+offset], immediate
5394 1 => 0b00,5395 // const flags: u2 = switch (abi_size) {
5395 2 => 0b01,5396 // 1 => 0b00,
5396 4 => 0b10,5397 // 2 => 0b01,
5397 else => unreachable,5398 // 4 => 0b10,
5398 };5399 // else => unreachable,
5399 const payload = try self.addExtra(Mir.ImmPair{5400 // };
5400 .dest_off = -stack_offset,5401 // const payload = try self.addExtra(Mir.ImmPair{
5401 .operand = @intCast(u32, imm),5402 // .dest_off = -stack_offset,
5402 });5403 // .operand = @intCast(u32, imm),
5403 _ = try self.addInst(.{5404 // });
5404 .tag = .mov_mem_imm,5405 // _ = try self.addInst(.{
5405 .ops = Mir.Inst.Ops.encode(.{5406 // .tag = .mov_mem_imm,
5406 .reg1 = .rsp,5407 // .ops = Mir.Inst.Ops.encode(.{
5407 .flags = flags,5408 // .reg1 = .rsp,
5408 }),5409 // .flags = flags,
5409 .data = .{ .payload = payload },5410 // }),
5410 });5411 // .data = .{ .payload = payload },
5411 },5412 // });
5412 8 => {5413 // },
5414 1, 2, 4, 8 => {
5413 const reg = try self.copyToTmpRegister(ty, mcv);5415 const reg = try self.copyToTmpRegister(ty, mcv);
5414 return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });5416 return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });
5415 },5417 },
...@@ -5543,7 +5545,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl...@@ -5543,7 +5545,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
5543 assert(ty.isError());5545 assert(ty.isError());
5544 const payload = try self.addExtra(Mir.ImmPair{5546 const payload = try self.addExtra(Mir.ImmPair{
5545 .dest_off = -stack_offset,5547 .dest_off = -stack_offset,
5546 .operand = @intCast(u32, x_big),5548 .operand = @truncate(u32, x_big),
5547 });5549 });
5548 _ = try self.addInst(.{5550 _ = try self.addInst(.{
5549 .tag = .mov_mem_imm,5551 .tag = .mov_mem_imm,
...@@ -5557,7 +5559,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl...@@ -5557,7 +5559,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
5557 1, 2, 4 => {5559 1, 2, 4 => {
5558 const payload = try self.addExtra(Mir.ImmPair{5560 const payload = try self.addExtra(Mir.ImmPair{
5559 .dest_off = -stack_offset,5561 .dest_off = -stack_offset,
5560 .operand = @intCast(u32, x_big),5562 .operand = @truncate(u32, x_big),
5561 });5563 });
5562 _ = try self.addInst(.{5564 _ = try self.addInst(.{
5563 .tag = .mov_mem_imm,5565 .tag = .mov_mem_imm,
...@@ -7020,7 +7022,7 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {...@@ -7020,7 +7022,7 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
7020 .unsigned => {7022 .unsigned => {
7021 const shift = @intCast(u6, max_reg_bit_width - int_info.bits);7023 const shift = @intCast(u6, max_reg_bit_width - int_info.bits);
7022 const mask = (~@as(u64, 0)) >> shift;7024 const mask = (~@as(u64, 0)) >> shift;
7023 if (int_info.bits <= 32) {7025 if (int_info.bits < 32) {
7024 try self.genBinOpMir(.@"and", Type.usize, .{ .register = reg }, .{ .immediate = mask });7026 try self.genBinOpMir(.@"and", Type.usize, .{ .register = reg }, .{ .immediate = mask });
7025 } else {7027 } else {
7026 const tmp_reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = mask });7028 const tmp_reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = mask });
src/arch/x86_64/Emit.zig+6-1
...@@ -612,12 +612,17 @@ fn mirArithMemImm(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.In...@@ -612,12 +612,17 @@ fn mirArithMemImm(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.In
612 0b10 => .dword,612 0b10 => .dword,
613 0b11 => .qword,613 0b11 => .qword,
614 };614 };
615 const imm = switch (ops.flags) {
616 0b00 => @truncate(u8, imm_pair.operand),
617 0b01 => @truncate(u16, imm_pair.operand),
618 0b10, 0b11 => @truncate(u32, imm_pair.operand),
619 };
615 return emit.encode(mnemonic, .{620 return emit.encode(mnemonic, .{
616 .op1 = .{ .mem = Memory.sib(ptr_size, .{621 .op1 = .{ .mem = Memory.sib(ptr_size, .{
617 .disp = imm_pair.dest_off,622 .disp = imm_pair.dest_off,
618 .base = ops.reg1,623 .base = ops.reg1,
619 }) },624 }) },
620 .op2 = .{ .imm = Immediate.u(imm_pair.operand) },625 .op2 = .{ .imm = Immediate.u(imm) },
621 });626 });
622}627}
623628
src/arch/x86_64/Encoding.zig+4
...@@ -544,6 +544,10 @@ pub const Op = enum {...@@ -544,6 +544,10 @@ pub const Op = enum {
544 }544 }
545 if (op.isImmediate() and target.isImmediate()) {545 if (op.isImmediate() and target.isImmediate()) {
546 switch (target) {546 switch (target) {
547 .imm64 => switch (op) {
548 .unity, .imm8s, .imm8, .imm16s, .imm16, .imm32s, .imm32, .imm64 => return true,
549 else => return op == target,
550 },
547 .imm32s, .rel32 => switch (op) {551 .imm32s, .rel32 => switch (op) {
548 .unity, .imm8s, .imm8, .imm16s, .imm16, .imm32s => return true,552 .unity, .imm8s, .imm8, .imm16s, .imm16, .imm32s => return true,
549 else => return op == target,553 else => return op == target,
src/arch/x86_64/encoder.zig+1-1
...@@ -108,7 +108,7 @@ pub const Instruction = struct {...@@ -108,7 +108,7 @@ pub const Instruction = struct {
108 .op3 = args.op3,108 .op3 = args.op3,
109 .op4 = args.op4,109 .op4 = args.op4,
110 })) orelse {110 })) orelse {
111 std.log.debug("{s} {s} {s} {s} {s}", .{111 std.log.warn("{s} {s} {s} {s} {s}", .{
112 @tagName(mnemonic),112 @tagName(mnemonic),
113 @tagName(Encoding.Op.fromOperand(args.op1)),113 @tagName(Encoding.Op.fromOperand(args.op1)),
114 @tagName(Encoding.Op.fromOperand(args.op2)),114 @tagName(Encoding.Op.fromOperand(args.op2)),