mirror of
https://github.com/ziglang/zig.git
synced 2025-12-22 06:03:16 +00:00
stage2: sparcv9: Implement basic stack load/stores
This commit is contained in:
parent
b6d7f63f34
commit
a00d69ea4a
@ -1351,7 +1351,8 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
|
||||
try self.genLoad(reg, reg, i13, 0, ty.abiSize(self.target.*));
|
||||
},
|
||||
.stack_offset => |off| {
|
||||
const simm13 = math.cast(u12, off) catch
|
||||
const biased_offset = off + abi.stack_bias;
|
||||
const simm13 = math.cast(i13, biased_offset) catch
|
||||
return self.fail("TODO larger stack offsets", .{});
|
||||
try self.genLoad(reg, .sp, i13, simm13, ty.abiSize(self.target.*));
|
||||
},
|
||||
@ -1381,11 +1382,80 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
|
||||
const reg = try self.copyToTmpRegister(ty, mcv);
|
||||
return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
|
||||
},
|
||||
.register => return self.fail("TODO implement storing types abi_size={}", .{abi_size}),
|
||||
.register => |reg| {
|
||||
const biased_offset = stack_offset + abi.stack_bias;
|
||||
const simm13 = math.cast(i13, biased_offset) catch
|
||||
return self.fail("TODO larger stack offsets", .{});
|
||||
return self.genStore(reg, .sp, i13, simm13, abi_size);
|
||||
},
|
||||
.memory, .stack_offset => return self.fail("TODO implement memcpy", .{}),
|
||||
}
|
||||
}
|
||||
|
||||
fn genStore(self: *Self, value_reg: Register, addr_reg: Register, comptime off_type: type, off: off_type, abi_size: u64) !void {
|
||||
assert(off_type == Register or off_type == i13);
|
||||
|
||||
const is_imm = (off_type == i13);
|
||||
const rs2_or_imm = if (is_imm) .{ .imm = off } else .{ .rs2 = off };
|
||||
|
||||
switch (abi_size) {
|
||||
1 => {
|
||||
_ = try self.addInst(.{
|
||||
.tag = .stb,
|
||||
.data = .{
|
||||
.arithmetic_3op = .{
|
||||
.is_imm = is_imm,
|
||||
.rd = value_reg,
|
||||
.rs1 = addr_reg,
|
||||
.rs2_or_imm = rs2_or_imm,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
2 => {
|
||||
_ = try self.addInst(.{
|
||||
.tag = .sth,
|
||||
.data = .{
|
||||
.arithmetic_3op = .{
|
||||
.is_imm = is_imm,
|
||||
.rd = value_reg,
|
||||
.rs1 = addr_reg,
|
||||
.rs2_or_imm = rs2_or_imm,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
4 => {
|
||||
_ = try self.addInst(.{
|
||||
.tag = .stw,
|
||||
.data = .{
|
||||
.arithmetic_3op = .{
|
||||
.is_imm = is_imm,
|
||||
.rd = value_reg,
|
||||
.rs1 = addr_reg,
|
||||
.rs2_or_imm = rs2_or_imm,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
8 => {
|
||||
_ = try self.addInst(.{
|
||||
.tag = .stx,
|
||||
.data = .{
|
||||
.arithmetic_3op = .{
|
||||
.is_imm = is_imm,
|
||||
.rd = value_reg,
|
||||
.rs1 = addr_reg,
|
||||
.rs2_or_imm = rs2_or_imm,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
3, 5, 6, 7 => return self.fail("TODO: genLoad for more abi_sizes", .{}),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
|
||||
if (typed_value.val.isUndef())
|
||||
return MCValue{ .undef = {} };
|
||||
|
||||
@ -76,6 +76,11 @@ pub fn emitMir(
|
||||
|
||||
.sllx => @panic("TODO implement sparcv9 sllx"),
|
||||
|
||||
.stb => try emit.mirArithmetic3Op(inst),
|
||||
.sth => try emit.mirArithmetic3Op(inst),
|
||||
.stw => try emit.mirArithmetic3Op(inst),
|
||||
.stx => try emit.mirArithmetic3Op(inst),
|
||||
|
||||
.sub => try emit.mirArithmetic3Op(inst),
|
||||
|
||||
.tcc => try emit.mirTrap(inst),
|
||||
@ -170,6 +175,10 @@ fn mirArithmetic3Op(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
.@"or" => try emit.writeInstruction(Instruction.@"or"(i13, rs1, imm, rd)),
|
||||
.save => try emit.writeInstruction(Instruction.save(i13, rs1, imm, rd)),
|
||||
.restore => try emit.writeInstruction(Instruction.restore(i13, rs1, imm, rd)),
|
||||
.stb => try emit.writeInstruction(Instruction.stb(i13, rs1, imm, rd)),
|
||||
.sth => try emit.writeInstruction(Instruction.sth(i13, rs1, imm, rd)),
|
||||
.stw => try emit.writeInstruction(Instruction.stw(i13, rs1, imm, rd)),
|
||||
.stx => try emit.writeInstruction(Instruction.stx(i13, rs1, imm, rd)),
|
||||
.sub => try emit.writeInstruction(Instruction.sub(i13, rs1, imm, rd)),
|
||||
else => unreachable,
|
||||
}
|
||||
@ -185,6 +194,10 @@ fn mirArithmetic3Op(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
.@"or" => try emit.writeInstruction(Instruction.@"or"(Register, rs1, rs2, rd)),
|
||||
.save => try emit.writeInstruction(Instruction.save(Register, rs1, rs2, rd)),
|
||||
.restore => try emit.writeInstruction(Instruction.restore(Register, rs1, rs2, rd)),
|
||||
.stb => try emit.writeInstruction(Instruction.stb(Register, rs1, rs2, rd)),
|
||||
.sth => try emit.writeInstruction(Instruction.sth(Register, rs1, rs2, rd)),
|
||||
.stw => try emit.writeInstruction(Instruction.stw(Register, rs1, rs2, rd)),
|
||||
.stx => try emit.writeInstruction(Instruction.stx(Register, rs1, rs2, rd)),
|
||||
.sub => try emit.writeInstruction(Instruction.sub(Register, rs1, rs2, rd)),
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
@ -94,6 +94,16 @@ pub const Inst = struct {
|
||||
// TODO add other operations.
|
||||
sllx,
|
||||
|
||||
/// A.54 Store Integer
|
||||
/// This uses the arithmetic_3op field.
|
||||
/// Note that the std variant of this instruction is deprecated, so do not emit
|
||||
/// it unless specifically requested (e.g. by inline assembly).
|
||||
// TODO add other operations.
|
||||
stb,
|
||||
sth,
|
||||
stw,
|
||||
stx,
|
||||
|
||||
/// A.56 Subtract
|
||||
/// Those uses the arithmetic_3op field.
|
||||
// TODO add other operations.
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
const bits = @import("bits.zig");
|
||||
const Register = bits.Register;
|
||||
|
||||
// On SPARCv9, %sp points to top of stack + stack bias,
|
||||
// and %fp points to top of previous frame + stack bias.
|
||||
// See: Registers and the Stack Frame, page 3P-8, SCD 2.4.1.
|
||||
pub const stack_bias = 2047;
|
||||
|
||||
// There are no callee-preserved registers since the windowing
|
||||
// mechanism already takes care of them.
|
||||
// We still need to preserve %o0-%o5, %g1, %g4, and %g5 before calling
|
||||
|
||||
@ -1059,6 +1059,38 @@ pub const Instruction = union(enum) {
|
||||
return format2a(0b100, imm, rd);
|
||||
}
|
||||
|
||||
pub fn stb(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3a(0b11, 0b00_0101, rs1, rs2, rd),
|
||||
i13 => format3b(0b11, 0b00_0101, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn sth(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3a(0b11, 0b00_0110, rs1, rs2, rd),
|
||||
i13 => format3b(0b11, 0b00_0110, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn stw(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3a(0b11, 0b00_0100, rs1, rs2, rd),
|
||||
i13 => format3b(0b11, 0b00_0100, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn stx(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3a(0b11, 0b00_1110, rs1, rs2, rd),
|
||||
i13 => format3b(0b11, 0b00_1110, rs1, rs2, rd),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn sub(comptime s2: type, rs1: Register, rs2: s2, rd: Register) Instruction {
|
||||
return switch (s2) {
|
||||
Register => format3a(0b10, 0b00_0100, rs1, rs2, rd),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user