master
 1const std = @import("std");
 2const bits = @import("bits.zig");
 3const Register = bits.Register;
 4const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
 5
 6// SPARCv9 SysV ABI stack constants.
 7// See: Registers and the Stack Frame, page 3P-8, SCD 2.4.1.
 8
 9// The ABI specifies that %sp points to top of stack - stack bias,
10// and %fp points to top of previous frame - stack bias.
11pub const stack_bias = 2047;
12
13// The first 128 bytes of the stack is reserved for register saving purposes.
14// The ABI also requires to reserve space in the stack for the first six
15// outgoing arguments, even though they are usually passed in registers.
16// TODO Don't allocate the argument space in leaf functions
17// TODO Save an RO copy of outgoing arguments in reserved area when building in Debug
18// TODO Should we also save it in ReleaseSafe? Solaris and OpenBSD binaries seem to ship
19//      with argument copying enabled and it doesn't seem to give them big slowdowns so
20//      I guess it would be okay to do in ReleaseSafe?
21pub const stack_reserved_area = 128 + 48;
22
23// There are no callee-preserved registers since the windowing
24// mechanism already takes care of them.
25// We still need to preserve %o0-%o5, %g1, %g4, and %g5 before calling
26// something, though, as those are shared with the callee and might be
27// thrashed by it.
28pub const caller_preserved_regs = [_]Register{ .o0, .o1, .o2, .o3, .o4, .o5, .g1, .g4, .g5 };
29
30// Try to allocate i, l, o, then g sets of registers, in order of priority.
31const allocatable_regs = [_]Register{
32    // zig fmt: off
33    .@"i0", .@"i1", .@"i2", .@"i3", .@"i4", .@"i5",
34      .l0,    .l1,    .l2,    .l3,    .l4,    .l5,    .l6,    .l7,
35      .o0,    .o1,    .o2,    .o3,    .o4,    .o5,
36              .g1,                    .g4,    .g5,
37    // zig fmt: on
38};
39
40pub const c_abi_int_param_regs_caller_view = [_]Register{ .o0, .o1, .o2, .o3, .o4, .o5 };
41pub const c_abi_int_param_regs_callee_view = [_]Register{ .@"i0", .@"i1", .@"i2", .@"i3", .@"i4", .@"i5" };
42
43pub const c_abi_int_return_regs_caller_view = [_]Register{ .o0, .o1, .o2, .o3 };
44pub const c_abi_int_return_regs_callee_view = [_]Register{ .@"i0", .@"i1", .@"i2", .@"i3" };
45
46pub const RegisterManager = RegisterManagerFn(@import("CodeGen.zig"), Register, &allocatable_regs);
47
48// Register classes
49const RegisterBitSet = RegisterManager.RegisterBitSet;
50pub const RegisterClass = struct {
51    pub const gp: RegisterBitSet = blk: {
52        var set = RegisterBitSet.initEmpty();
53        set.setRangeValue(.{
54            .start = 0,
55            .end = allocatable_regs.len,
56        }, true);
57        break :blk set;
58    };
59};