mirror of
https://github.com/ziglang/zig.git
synced 2025-12-25 15:43:06 +00:00
stage2: sparcv9: Implement basic prologue/epilogue Mir emission
This commit is contained in:
parent
927706e6d0
commit
94a84e783e
@ -382,9 +382,109 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, is_caller: bool) !Ca
|
||||
|
||||
/// Caller must call `CallMCValues.deinit`.
|
||||
fn gen(self: *Self) !void {
|
||||
_ = self;
|
||||
const cc = self.fn_type.fnCallingConvention();
|
||||
if (cc != .Naked) {
|
||||
// TODO Finish function prologue and epilogue for sparcv9.
|
||||
|
||||
@panic("TODO implement gen");
|
||||
// TODO Backpatch stack offset
|
||||
// save %sp, -176, %sp
|
||||
_ = try self.addInst(.{
|
||||
.tag = .save,
|
||||
.data = .{
|
||||
.arithmetic_3op = .{
|
||||
.is_imm = true,
|
||||
.rd = .sp,
|
||||
.rs1 = .sp,
|
||||
.rs2_or_imm = .{ .imm = -176 },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
_ = try self.addInst(.{
|
||||
.tag = .dbg_prologue_end,
|
||||
.data = .{ .nop = {} },
|
||||
});
|
||||
|
||||
try self.genBody(self.air.getMainBody());
|
||||
|
||||
_ = try self.addInst(.{
|
||||
.tag = .dbg_epilogue_begin,
|
||||
.data = .{ .nop = {} },
|
||||
});
|
||||
|
||||
// exitlude jumps
|
||||
if (self.exitlude_jump_relocs.items.len > 0 and
|
||||
self.exitlude_jump_relocs.items[self.exitlude_jump_relocs.items.len - 1] == self.mir_instructions.len - 2)
|
||||
{
|
||||
// If the last Mir instruction (apart from the
|
||||
// dbg_epilogue_begin) is the last exitlude jump
|
||||
// relocation (which would just jump one instruction
|
||||
// further), it can be safely removed
|
||||
self.mir_instructions.orderedRemove(self.exitlude_jump_relocs.pop());
|
||||
}
|
||||
|
||||
for (self.exitlude_jump_relocs.items) |jmp_reloc| {
|
||||
_ = jmp_reloc;
|
||||
return self.fail("TODO add branches in sparcv9", .{});
|
||||
}
|
||||
|
||||
// return %i7 + 8
|
||||
_ = try self.addInst(.{
|
||||
.tag = .@"return",
|
||||
.data = .{
|
||||
.arithmetic_2op = .{
|
||||
.is_imm = true,
|
||||
.rs1 = .@"i7",
|
||||
.rs2_or_imm = .{ .imm = 8 },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// TODO Find a way to fill this slot
|
||||
// nop
|
||||
_ = try self.addInst(.{
|
||||
.tag = .nop,
|
||||
.data = .{ .nop = {} },
|
||||
});
|
||||
} else {
|
||||
_ = try self.addInst(.{
|
||||
.tag = .dbg_prologue_end,
|
||||
.data = .{ .nop = {} },
|
||||
});
|
||||
|
||||
try self.genBody(self.air.getMainBody());
|
||||
|
||||
_ = try self.addInst(.{
|
||||
.tag = .dbg_epilogue_begin,
|
||||
.data = .{ .nop = {} },
|
||||
});
|
||||
}
|
||||
|
||||
// Drop them off at the rbrace.
|
||||
_ = try self.addInst(.{
|
||||
.tag = .dbg_line,
|
||||
.data = .{ .dbg_line_column = .{
|
||||
.line = self.end_di_line,
|
||||
.column = self.end_di_column,
|
||||
} },
|
||||
});
|
||||
}
|
||||
|
||||
fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
_ = self;
|
||||
_ = body;
|
||||
|
||||
@panic("TODO implement genBody");
|
||||
}
|
||||
|
||||
fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
|
||||
const gpa = self.gpa;
|
||||
|
||||
try self.mir_instructions.ensureUnusedCapacity(gpa, 1);
|
||||
|
||||
const result_index = @intCast(Air.Inst.Index, self.mir_instructions.len);
|
||||
self.mir_instructions.appendAssumeCapacity(inst);
|
||||
return result_index;
|
||||
}
|
||||
|
||||
fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
//! machine code
|
||||
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const link = @import("../../link.zig");
|
||||
const Module = @import("../../Module.zig");
|
||||
const ErrorMsg = Module.ErrorMsg;
|
||||
@ -41,9 +42,15 @@ pub fn emitMir(
|
||||
const inst = @intCast(u32, index);
|
||||
switch (tag) {
|
||||
.dbg_line => try emit.mirDbgLine(inst),
|
||||
|
||||
.dbg_prologue_end => try emit.mirDebugPrologueEnd(),
|
||||
.dbg_epilogue_begin => try emit.mirDebugEpilogueBegin(),
|
||||
|
||||
.nop => @panic("TODO implement nop"),
|
||||
|
||||
.save => @panic("TODO implement save"),
|
||||
.restore => @panic("TODO implement restore"),
|
||||
|
||||
.@"return" => @panic("TODO implement return"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -91,3 +98,10 @@ fn mirDebugEpilogueBegin(self: *Emit) !void {
|
||||
.none => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
|
||||
@setCold(true);
|
||||
assert(emit.err_msg == null);
|
||||
emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args);
|
||||
return error.EmitFail;
|
||||
}
|
||||
|
||||
@ -29,6 +29,22 @@ pub const Inst = struct {
|
||||
dbg_epilogue_begin,
|
||||
/// Pseudo-instruction: Update debug line
|
||||
dbg_line,
|
||||
|
||||
// All the real instructions are ordered by their section number
|
||||
// in The SPARC Architecture Manual, Version 9.
|
||||
|
||||
/// A.40 No Operation
|
||||
/// It uses the nop field.
|
||||
nop,
|
||||
|
||||
/// A.46 SAVE and RESTORE
|
||||
/// Those uses the arithmetic_3op field.
|
||||
save,
|
||||
restore,
|
||||
|
||||
/// A.45 RETURN
|
||||
/// It uses the arithmetic_2op field.
|
||||
@"return",
|
||||
};
|
||||
|
||||
/// The position of an MIR instruction within the `Mir` instructions array.
|
||||
@ -42,6 +58,36 @@ pub const Inst = struct {
|
||||
///
|
||||
/// Used by e.g. flushw
|
||||
nop: void,
|
||||
|
||||
/// Three operand arithmetic.
|
||||
/// if is_imm true then it uses the imm field of rs2_or_imm,
|
||||
/// otherwise it uses rs2 field.
|
||||
///
|
||||
/// Used by e.g. add, sub
|
||||
arithmetic_3op: struct {
|
||||
is_imm: bool,
|
||||
rd: Register,
|
||||
rs1: Register,
|
||||
rs2_or_imm: union {
|
||||
rs2: Register,
|
||||
imm: i13,
|
||||
},
|
||||
},
|
||||
|
||||
/// Two operand arithmetic.
|
||||
/// if is_imm true then it uses the imm field of rs2_or_imm,
|
||||
/// otherwise it uses rs2 field.
|
||||
///
|
||||
/// Used by e.g. return
|
||||
arithmetic_2op: struct {
|
||||
is_imm: bool,
|
||||
rs1: Register,
|
||||
rs2_or_imm: union {
|
||||
rs2: Register,
|
||||
imm: i13,
|
||||
},
|
||||
},
|
||||
|
||||
/// Debug info: line and column
|
||||
///
|
||||
/// Used by e.g. dbg_line
|
||||
@ -77,4 +123,3 @@ pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end
|
||||
.end = i,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user