Commit 1bde522c2c
Changed files (2)
src
arch
x86_64
src/arch/x86_64/CodeGen.zig
@@ -4511,35 +4511,29 @@ fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !u32 {
const abi_size = ty.abiSize(self.target.*);
switch (mcv) {
.eflags => |cc| {
- _ = cc;
- // return self.addInst(.{
- // .tag = .cond_jmp,
- // .ops = Mir.Inst.Ops.encode(.{}),
- // .data = .{
- // .inst_cc = .{
- // .inst = undefined,
- // // Here we map the opposites since the jump is to the false branch.
- // .cc = cc.negate(),
- // },
- // },
- // });
+ return self.addInst(.{
+ .tag = .jcc,
+ .ops = .inst_cc,
+ .data = .{
+ .inst_cc = .{
+ .inst = undefined,
+ // Here we map the opposites since the jump is to the false branch.
+ .cc = cc.negate(),
+ },
+ },
+ });
},
.register => |reg| {
- _ = reg;
try self.spillEflagsIfOccupied();
- // _ = try self.addInst(.{
- // .tag = .@"test",
- // .ops = Mir.Inst.Ops.encode(.{ .reg1 = reg }),
- // .data = .{ .imm = 1 },
- // });
- // return self.addInst(.{
- // .tag = .cond_jmp,
- // .ops = Mir.Inst.Ops.encode(.{}),
- // .data = .{ .inst_cc = .{
- // .inst = undefined,
- // .cc = .e,
- // } },
- // });
+ try self.asmRegisterImmediate(.@"test", reg, Immediate.u(1));
+ return self.addInst(.{
+ .tag = .jcc,
+ .ops = .inst_cc,
+ .data = .{ .inst_cc = .{
+ .inst = undefined,
+ .cc = .e,
+ } },
+ });
},
.immediate,
.stack_offset,
@@ -4961,22 +4955,17 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u
},
}
- // _ = try self.addInst(.{
- // .tag = .@"test",
- // .ops = Mir.Inst.Ops.encode(.{
- // .reg1 = registerAlias(cond_reg, abi_size),
- // .reg2 = registerAlias(cond_reg, abi_size),
- // }),
- // .data = undefined,
- // });
- // return self.addInst(.{
- // .tag = .cond_jmp,
- // .ops = Mir.Inst.Ops.encode(.{}),
- // .data = .{ .inst_cc = .{
- // .inst = undefined,
- // .cc = .ne,
- // } },
- // });
+ const aliased_reg = registerAlias(cond_reg, abi_size);
+ try self.asmRegisterRegister(.@"test", aliased_reg, aliased_reg);
+
+ return self.addInst(.{
+ .tag = .jcc,
+ .ops = .inst_cc,
+ .data = .{ .inst_cc = .{
+ .inst = undefined,
+ .cc = .ne,
+ } },
+ });
},
.stack_offset => {
try self.spillEflagsIfOccupied();
@@ -5189,9 +5178,9 @@ fn canonicaliseBranches(self: *Self, parent_branch: *Branch, canon_branch: *Bran
fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void {
const next_inst = @intCast(u32, self.mir_instructions.len);
switch (self.mir_instructions.items(.tag)[reloc]) {
- // .cond_jmp => {
- // self.mir_instructions.items(.data)[reloc].inst_cc.inst = next_inst;
- // },
+ .jcc => {
+ self.mir_instructions.items(.data)[reloc].inst_cc.inst = next_inst;
+ },
.jmp => {
self.mir_instructions.items(.data)[reloc].inst = next_inst;
},
@@ -5806,7 +5795,6 @@ fn genInlineMemcpy(
const index_reg = regs[2].to64();
const count_reg = regs[3].to64();
const tmp_reg = regs[4].to8();
- _ = index_reg;
_ = tmp_reg;
switch (dst_ptr) {
@@ -5825,15 +5813,11 @@ fn genInlineMemcpy(
// });
},
.register => |reg| {
- _ = reg;
- // _ = try self.addInst(.{
- // .tag = .mov,
- // .ops = Mir.Inst.Ops.encode(.{
- // .reg1 = registerAlias(dst_addr_reg, @intCast(u32, @divExact(reg.bitSize(), 8))),
- // .reg2 = reg,
- // }),
- // .data = undefined,
- // });
+ try self.asmRegisterRegister(
+ .mov,
+ registerAlias(dst_addr_reg, @intCast(u32, @divExact(reg.bitSize(), 8))),
+ reg,
+ );
},
else => {
return self.fail("TODO implement memcpy for setting stack when dest is {}", .{dst_ptr});
@@ -5856,15 +5840,11 @@ fn genInlineMemcpy(
// });
},
.register => |reg| {
- _ = reg;
- // _ = try self.addInst(.{
- // .tag = .mov,
- // .ops = Mir.Inst.Ops.encode(.{
- // .reg1 = registerAlias(src_addr_reg, @intCast(u32, @divExact(reg.bitSize(), 8))),
- // .reg2 = reg,
- // }),
- // .data = undefined,
- // });
+ try self.asmRegisterRegister(
+ .mov,
+ registerAlias(src_addr_reg, @intCast(u32, @divExact(reg.bitSize(), 8))),
+ reg,
+ );
},
else => {
return self.fail("TODO implement memcpy for setting stack when src is {}", .{src_ptr});
@@ -5873,30 +5853,24 @@ fn genInlineMemcpy(
try self.genSetReg(Type.usize, count_reg, len);
- // mov index_reg, 0
- // _ = try self.addInst(.{
- // .tag = .mov,
- // .ops = Mir.Inst.Ops.encode(.{ .reg1 = index_reg }),
- // .data = .{ .imm = 0 },
- // });
-
- // loop:
- // cmp count, 0
- // const loop_start = try self.addInst(.{
- // .tag = .cmp,
- // .ops = Mir.Inst.Ops.encode(.{ .reg1 = count_reg }),
- // .data = .{ .imm = 0 },
- // });
+ try self.asmRegisterImmediate(.mov, index_reg, Immediate.u(0));
- // je end
- // const loop_reloc = try self.addInst(.{
- // .tag = .cond_jmp,
- // .ops = Mir.Inst.Ops.encode(.{}),
- // .data = .{ .inst_cc = .{
- // .inst = undefined,
- // .cc = .e,
- // } },
- // });
+ const loop_start = try self.addInst(.{
+ .tag = .cmp,
+ .ops = .ri_u,
+ .data = .{ .ri_u = .{
+ .r1 = count_reg,
+ .imm = 0,
+ } },
+ });
+ const loop_reloc = try self.addInst(.{
+ .tag = .jcc,
+ .ops = .inst_cc,
+ .data = .{ .inst_cc = .{
+ .inst = undefined,
+ .cc = .e,
+ } },
+ });
// mov tmp, [addr + index_reg]
// _ = try self.addInst(.{
@@ -5918,29 +5892,16 @@ fn genInlineMemcpy(
// .data = .{ .payload = try self.addExtra(Mir.IndexRegisterDisp.encode(index_reg, 0)) },
// });
- // add index_reg, 1
- // _ = try self.addInst(.{
- // .tag = .add,
- // .ops = Mir.Inst.Ops.encode(.{ .reg1 = index_reg }),
- // .data = .{ .imm = 1 },
- // });
-
- // sub count, 1
- // _ = try self.addInst(.{
- // .tag = .sub,
- // .ops = Mir.Inst.Ops.encode(.{ .reg1 = count_reg }),
- // .data = .{ .imm = 1 },
- // });
+ try self.asmRegisterImmediate(.add, index_reg, Immediate.u(1));
+ try self.asmRegisterImmediate(.sub, count_reg, Immediate.u(1));
- // jmp loop
- // _ = try self.addInst(.{
- // .tag = .jmp,
- // .ops = Mir.Inst.Ops.encode(.{}),
- // .data = .{ .inst = loop_start },
- // });
+ _ = try self.addInst(.{
+ .tag = .jmp,
+ .ops = .inst,
+ .data = .{ .inst = loop_start },
+ });
- // end:
- // try self.performReloc(loop_reloc);
+ try self.performReloc(loop_reloc);
}
fn genInlineMemset(
@@ -5982,15 +5943,11 @@ fn genInlineMemset(
// });
},
.register => |reg| {
- _ = reg;
- // _ = try self.addInst(.{
- // .tag = .mov,
- // .ops = Mir.Inst.Ops.encode(.{
- // .reg1 = registerAlias(addr_reg, @intCast(u32, @divExact(reg.bitSize(), 8))),
- // .reg2 = reg,
- // }),
- // .data = undefined,
- // });
+ try self.asmRegisterRegister(
+ .mov,
+ registerAlias(addr_reg, @intCast(u32, @divExact(reg.bitSize(), 8))),
+ reg,
+ );
},
else => {
return self.fail("TODO implement memcpy for setting stack when dest is {}", .{dst_ptr});
@@ -6000,26 +5957,23 @@ fn genInlineMemset(
try self.genSetReg(Type.usize, index_reg, len);
try self.genBinOpMir(.sub, Type.usize, .{ .register = index_reg }, .{ .immediate = 1 });
- // loop:
- // cmp index_reg, -1
- // const loop_start = try self.addInst(.{
- // .tag = .cmp,
- // .ops = Mir.Inst.Ops.encode(.{
- // .reg1 = index_reg,
- // .flags = 0b11,
- // }),
- // .data = .{ .imm_s = -1 },
- // });
+ const loop_start = try self.addInst(.{
+ .tag = .cmp,
+ .ops = .ri_s,
+ .data = .{ .ri_s = .{
+ .r1 = index_reg,
+ .imm = -1,
+ } },
+ });
- // je end
- // const loop_reloc = try self.addInst(.{
- // .tag = .cond_jmp,
- // .ops = Mir.Inst.Ops.encode(.{}),
- // .data = .{ .inst_cc = .{
- // .inst = undefined,
- // .cc = .e,
- // } },
- // });
+ const loop_reloc = try self.addInst(.{
+ .tag = .jcc,
+ .ops = .inst_cc,
+ .data = .{ .inst_cc = .{
+ .inst = undefined,
+ .cc = .e,
+ } },
+ });
switch (value) {
.immediate => |x| {
@@ -6042,22 +5996,15 @@ fn genInlineMemset(
else => return self.fail("TODO inline memset for value of type {}", .{value}),
}
- // sub index_reg, 1
- // _ = try self.addInst(.{
- // .tag = .sub,
- // .ops = Mir.Inst.Ops.encode(.{ .reg1 = index_reg }),
- // .data = .{ .imm = 1 },
- // });
+ try self.asmRegisterImmediate(.sub, index_reg, Immediate.u(1));
- // jmp loop
- // _ = try self.addInst(.{
- // .tag = .jmp,
- // .ops = Mir.Inst.Ops.encode(.{}),
- // .data = .{ .inst = loop_start },
- // });
+ _ = try self.addInst(.{
+ .tag = .jmp,
+ .ops = .inst,
+ .data = .{ .inst = loop_start },
+ });
- // end:
- // try self.performReloc(loop_reloc);
+ try self.performReloc(loop_reloc);
}
fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
src/arch/x86_64/Emit.zig
@@ -1,4 +1,3 @@
-//!
//! This file contains the functionality for lowering x86_64 MIR into
//! machine code
@@ -118,8 +117,9 @@ pub fn lowerMir(emit: *Emit) InnerError!void {
=> try emit.mirEncodeGeneric(tag, inst),
// Pseudo-instructions
- .cmovcc => try emit.mirCmovCC(inst),
- .setcc => try emit.mirSetCC(inst),
+ .cmovcc => try emit.mirCmovcc(inst),
+ .setcc => try emit.mirSetcc(inst),
+ .jcc => try emit.mirJcc(inst),
.dbg_line => try emit.mirDbgLine(inst),
.dbg_prologue_end => try emit.mirDbgPrologueEnd(inst),
@@ -220,19 +220,19 @@ fn mirEncodeGeneric(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerE
});
}
-fn mnemonicFromCC(comptime basename: []const u8, cc: bits.Condition) Instruction.Mnemonic {
+fn mnemonicFromConditionCode(comptime basename: []const u8, cc: bits.Condition) Instruction.Mnemonic {
inline for (@typeInfo(bits.Condition).Enum.fields) |field| {
if (mem.eql(u8, field.name, @tagName(cc)))
return @field(Instruction.Mnemonic, basename ++ field.name);
} else unreachable;
}
-fn mirCmovCC(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
+fn mirCmovcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
const ops = emit.mir.instructions.items(.ops)[inst];
switch (ops) {
.rr_c => {
const data = emit.mir.instructions.items(.data)[inst].rr_c;
- const mnemonic = mnemonicFromCC("cmov", data.cc);
+ const mnemonic = mnemonicFromConditionCode("cmov", data.cc);
return emit.encode(mnemonic, .{
.op1 = .{ .reg = data.r1 },
.op2 = .{ .reg = data.r2 },
@@ -242,12 +242,12 @@ fn mirCmovCC(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
}
}
-fn mirSetCC(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
+fn mirSetcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
const ops = emit.mir.instructions.items(.ops)[inst];
switch (ops) {
.r_c => {
const data = emit.mir.instructions.items(.data)[inst].r_c;
- const mnemonic = mnemonicFromCC("set", data.cc);
+ const mnemonic = mnemonicFromConditionCode("set", data.cc);
return emit.encode(mnemonic, .{
.op1 = .{ .reg = data.r1 },
});
@@ -256,6 +256,27 @@ fn mirSetCC(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
}
}
+fn mirJcc(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
+ const ops = emit.mir.instructions.items(.ops)[inst];
+ switch (ops) {
+ .inst_cc => {
+ const data = emit.mir.instructions.items(.data)[inst].inst_cc;
+ const mnemonic = mnemonicFromConditionCode("j", data.cc);
+ const source = emit.code.items.len;
+ try emit.encode(mnemonic, .{
+ .op1 = .{ .imm = Immediate.s(0) },
+ });
+ try emit.relocs.append(emit.bin_file.allocator, .{
+ .source = source,
+ .target = data.inst,
+ .offset = emit.code.items.len - 4,
+ .length = 6,
+ });
+ },
+ else => unreachable, // TODO
+ }
+}
+
fn mirPushPopRegisterList(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) InnerError!void {
const payload = emit.mir.instructions.items(.data)[inst].payload;
const save_reg_list = emit.mir.extraData(Mir.SaveRegisterList, payload).data;
@@ -326,54 +347,6 @@ fn mirPushPopRegisterList(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index)
// }
// }
-// fn mirCondJmp(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
-// const tag = emit.mir.instructions.items(.tag)[inst];
-// assert(tag == .cond_jmp);
-// const inst_cc = emit.mir.instructions.items(.data)[inst].inst_cc;
-// const mnemonic: Instruction.Mnemonic = switch (inst_cc.cc) {
-// .a => .ja,
-// .ae => .jae,
-// .b => .jb,
-// .be => .jbe,
-// .c => .jc,
-// .e => .je,
-// .g => .jg,
-// .ge => .jge,
-// .l => .jl,
-// .le => .jle,
-// .na => .jna,
-// .nae => .jnae,
-// .nb => .jnb,
-// .nbe => .jnbe,
-// .nc => .jnc,
-// .ne => .jne,
-// .ng => .jng,
-// .nge => .jnge,
-// .nl => .jnl,
-// .nle => .jnle,
-// .no => .jno,
-// .np => .jnp,
-// .ns => .jns,
-// .nz => .jnz,
-// .o => .jo,
-// .p => .jp,
-// .pe => .jpe,
-// .po => .jpo,
-// .s => .js,
-// .z => .jz,
-// };
-// const source = emit.code.items.len;
-// try emit.encode(mnemonic, .{
-// .op1 = .{ .imm = Immediate.s(0) },
-// });
-// try emit.relocs.append(emit.bin_file.allocator, .{
-// .source = source,
-// .target = inst_cc.inst,
-// .offset = emit.code.items.len - 4,
-// .length = 6,
-// });
-// }
-
// fn mirLea(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
// const tag = emit.mir.instructions.items(.tag)[inst];
// assert(tag == .lea);