mirror of
https://github.com/ziglang/zig.git
synced 2025-12-31 02:23:22 +00:00
Add move wide with zero (movz) instruction
This commit is contained in:
parent
d601b0f4eb
commit
4ef6864a15
@ -2504,7 +2504,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
else => unreachable, // unexpected register size
|
||||
}
|
||||
},
|
||||
.immediate => return self.fail(src, "TODO implement genSetReg for aarch64 {}", .{mcv}),
|
||||
.immediate => |x| {
|
||||
if (x <= math.maxInt(u16)) {
|
||||
mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movz(reg, @intCast(u16, x), 0).toU32());
|
||||
} else {
|
||||
return self.fail(src, "TODO genSetReg with 32,48,64bit immediates", .{});
|
||||
}
|
||||
},
|
||||
.register => return self.fail(src, "TODO implement genSetReg for aarch64 {}", .{mcv}),
|
||||
else => return self.fail(src, "TODO implement genSetReg for aarch64 {}", .{mcv}),
|
||||
},
|
||||
|
||||
@ -193,6 +193,15 @@ test "FloatingPointRegister.toX" {
|
||||
|
||||
/// Represents an instruction in the AArch64 instruction set
|
||||
pub const Instruction = union(enum) {
|
||||
MoveWideWithZero: packed struct {
|
||||
rd: u5,
|
||||
imm16: u16,
|
||||
hw: u2,
|
||||
fixed: u6 = 0b100101,
|
||||
opc: u2 = 0b10,
|
||||
sf: u1,
|
||||
},
|
||||
|
||||
SupervisorCall: packed struct {
|
||||
fixed_1: u5 = 0b00001,
|
||||
imm16: u16,
|
||||
@ -201,12 +210,39 @@ pub const Instruction = union(enum) {
|
||||
|
||||
pub fn toU32(self: Instruction) u32 {
|
||||
return switch (self) {
|
||||
.MoveWideWithZero => |v| @bitCast(u32, v),
|
||||
.SupervisorCall => |v| @bitCast(u32, v),
|
||||
};
|
||||
}
|
||||
|
||||
// Helper functions for assembly syntax functions
|
||||
|
||||
fn moveWideWithZero(rd: Register, imm16: u16, shift: u2) Instruction {
|
||||
switch (rd.size()) {
|
||||
32 => {
|
||||
return Instruction{
|
||||
.MoveWideWithZero = .{
|
||||
.rd = rd.id(),
|
||||
.imm16 = imm16,
|
||||
.hw = 0b01 & shift, // TODO shift should be an enum
|
||||
.sf = 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
64 => {
|
||||
return Instruction{
|
||||
.MoveWideWithZero = .{
|
||||
.rd = rd.id(),
|
||||
.imm16 = imm16,
|
||||
.hw = shift,
|
||||
.sf = 1,
|
||||
},
|
||||
};
|
||||
},
|
||||
else => unreachable, // unexpected register size
|
||||
}
|
||||
}
|
||||
|
||||
fn supervisorCall(imm16: u16) Instruction {
|
||||
return Instruction{
|
||||
.SupervisorCall = .{
|
||||
@ -215,6 +251,12 @@ pub const Instruction = union(enum) {
|
||||
};
|
||||
}
|
||||
|
||||
// movz
|
||||
|
||||
pub fn movz(rd: Register, imm16: u16, shift: u2) Instruction {
|
||||
return moveWideWithZero(rd, imm16, shift);
|
||||
}
|
||||
|
||||
// Supervisor Call
|
||||
|
||||
pub fn svc(imm16: u16) Instruction {
|
||||
@ -237,6 +279,30 @@ test "serialize instructions" {
|
||||
.inst = Instruction.svc(0x80),
|
||||
.expected = 0b1101_0100_000_0000000010000000_00001,
|
||||
},
|
||||
.{ // movz x1 #4
|
||||
.inst = Instruction.movz(.x1, 4, 0),
|
||||
.expected = 0b1_10_100101_00_0000000000000100_00001,
|
||||
},
|
||||
.{ // movz x1, #4, lsl 16
|
||||
.inst = Instruction.movz(.x1, 4, 1),
|
||||
.expected = 0b1_10_100101_01_0000000000000100_00001,
|
||||
},
|
||||
.{ // movz x1, #4, lsl 32
|
||||
.inst = Instruction.movz(.x1, 4, 2),
|
||||
.expected = 0b1_10_100101_10_0000000000000100_00001,
|
||||
},
|
||||
.{ // movz x1, #4, lsl 48
|
||||
.inst = Instruction.movz(.x1, 4, 3),
|
||||
.expected = 0b1_10_100101_11_0000000000000100_00001,
|
||||
},
|
||||
.{ // movz w1, #4
|
||||
.inst = Instruction.movz(.w1, 4, 0),
|
||||
.expected = 0b0_10_100101_00_0000000000000100_00001,
|
||||
},
|
||||
.{ // movz w1, #4, lsl 16
|
||||
.inst = Instruction.movz(.w1, 4, 1),
|
||||
.expected = 0b0_10_100101_01_0000000000000100_00001,
|
||||
},
|
||||
};
|
||||
|
||||
for (testcases) |case| {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user