x86_64: all behavior tests passing

This commit is contained in:
Jakub Konka 2023-03-07 20:22:45 +01:00
parent 292f91aef2
commit 219c1261a5
4 changed files with 41 additions and 30 deletions

View File

@ -2785,7 +2785,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
// introduce new MIR tag specifically for mov [reg + 0], imm
const payload = try self.addExtra(Mir.ImmPair{
.dest_off = 0,
.operand = @intCast(u32, imm),
.operand = @truncate(u32, imm),
});
_ = try self.addInst(.{
.tag = .mov_mem_imm,
@ -5385,31 +5385,33 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE
return self.genSetStackArg(ty, stack_offset, .{ .register = reg });
},
.immediate => |imm| {
_ = imm;
switch (abi_size) {
1, 2, 4 => {
// We have a positive stack offset value but we want a twos complement negative
// offset from rbp, which is at the top of the stack frame.
// mov [rbp+offset], immediate
const flags: u2 = switch (abi_size) {
1 => 0b00,
2 => 0b01,
4 => 0b10,
else => unreachable,
};
const payload = try self.addExtra(Mir.ImmPair{
.dest_off = -stack_offset,
.operand = @intCast(u32, imm),
});
_ = try self.addInst(.{
.tag = .mov_mem_imm,
.ops = Mir.Inst.Ops.encode(.{
.reg1 = .rsp,
.flags = flags,
}),
.data = .{ .payload = payload },
});
},
8 => {
// TODO
// 1, 2, 4 => {
// // We have a positive stack offset value but we want a twos complement negative
// // offset from rbp, which is at the top of the stack frame.
// // mov [rbp+offset], immediate
// const flags: u2 = switch (abi_size) {
// 1 => 0b00,
// 2 => 0b01,
// 4 => 0b10,
// else => unreachable,
// };
// const payload = try self.addExtra(Mir.ImmPair{
// .dest_off = -stack_offset,
// .operand = @intCast(u32, imm),
// });
// _ = try self.addInst(.{
// .tag = .mov_mem_imm,
// .ops = Mir.Inst.Ops.encode(.{
// .reg1 = .rsp,
// .flags = flags,
// }),
// .data = .{ .payload = payload },
// });
// },
1, 2, 4, 8 => {
const reg = try self.copyToTmpRegister(ty, mcv);
return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg });
},
@ -5543,7 +5545,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
assert(ty.isError());
const payload = try self.addExtra(Mir.ImmPair{
.dest_off = -stack_offset,
.operand = @intCast(u32, x_big),
.operand = @truncate(u32, x_big),
});
_ = try self.addInst(.{
.tag = .mov_mem_imm,
@ -5557,7 +5559,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
1, 2, 4 => {
const payload = try self.addExtra(Mir.ImmPair{
.dest_off = -stack_offset,
.operand = @intCast(u32, x_big),
.operand = @truncate(u32, x_big),
});
_ = try self.addInst(.{
.tag = .mov_mem_imm,
@ -7020,7 +7022,7 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
.unsigned => {
const shift = @intCast(u6, max_reg_bit_width - int_info.bits);
const mask = (~@as(u64, 0)) >> shift;
if (int_info.bits <= 32) {
if (int_info.bits < 32) {
try self.genBinOpMir(.@"and", Type.usize, .{ .register = reg }, .{ .immediate = mask });
} else {
const tmp_reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = mask });

View File

@ -612,12 +612,17 @@ fn mirArithMemImm(emit: *Emit, mnemonic: Instruction.Mnemonic, inst: Mir.Inst.In
0b10 => .dword,
0b11 => .qword,
};
const imm = switch (ops.flags) {
0b00 => @truncate(u8, imm_pair.operand),
0b01 => @truncate(u16, imm_pair.operand),
0b10, 0b11 => @truncate(u32, imm_pair.operand),
};
return emit.encode(mnemonic, .{
.op1 = .{ .mem = Memory.sib(ptr_size, .{
.disp = imm_pair.dest_off,
.base = ops.reg1,
}) },
.op2 = .{ .imm = Immediate.u(imm_pair.operand) },
.op2 = .{ .imm = Immediate.u(imm) },
});
}

View File

@ -544,6 +544,10 @@ pub const Op = enum {
}
if (op.isImmediate() and target.isImmediate()) {
switch (target) {
.imm64 => switch (op) {
.unity, .imm8s, .imm8, .imm16s, .imm16, .imm32s, .imm32, .imm64 => return true,
else => return op == target,
},
.imm32s, .rel32 => switch (op) {
.unity, .imm8s, .imm8, .imm16s, .imm16, .imm32s => return true,
else => return op == target,

View File

@ -108,7 +108,7 @@ pub const Instruction = struct {
.op3 = args.op3,
.op4 = args.op4,
})) orelse {
std.log.debug("{s} {s} {s} {s} {s}", .{
std.log.warn("{s} {s} {s} {s} {s}", .{
@tagName(mnemonic),
@tagName(Encoding.Op.fromOperand(args.op1)),
@tagName(Encoding.Op.fromOperand(args.op2)),