authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-11-08 14:49:31+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-11-11 14:34:53+01:00
log4ef6864a155cbb23edb5e5aaa5aa34fdd0e53b39
treef7983ff2f79c02f5f0c665ad8e6ea186e7a5a698
parentd601b0f4eb025c753ca9f139480578511122afad

Add move wide with zero (movz) instruction


2 files changed, 73 insertions(+), 1 deletions(-)

src/codegen.zig+7-1
...@@ -2504,7 +2504,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2504,7 +2504,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2504 else => unreachable, // unexpected register size2504 else => unreachable, // unexpected register size
2505 }2505 }
2506 },2506 },
2507 .immediate => return self.fail(src, "TODO implement genSetReg for aarch64 {}", .{mcv}),2507 .immediate => |x| {
2508 if (x <= math.maxInt(u16)) {
2509 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movz(reg, @intCast(u16, x), 0).toU32());
2510 } else {
2511 return self.fail(src, "TODO genSetReg with 32,48,64bit immediates", .{});
2512 }
2513 },
2508 .register => return self.fail(src, "TODO implement genSetReg for aarch64 {}", .{mcv}),2514 .register => return self.fail(src, "TODO implement genSetReg for aarch64 {}", .{mcv}),
2509 else => return self.fail(src, "TODO implement genSetReg for aarch64 {}", .{mcv}),2515 else => return self.fail(src, "TODO implement genSetReg for aarch64 {}", .{mcv}),
2510 },2516 },
src/codegen/aarch64.zig+66
...@@ -193,6 +193,15 @@ test "FloatingPointRegister.toX" {...@@ -193,6 +193,15 @@ test "FloatingPointRegister.toX" {
193193
194/// Represents an instruction in the AArch64 instruction set194/// Represents an instruction in the AArch64 instruction set
195pub const Instruction = union(enum) {195pub const Instruction = union(enum) {
196 MoveWideWithZero: packed struct {
197 rd: u5,
198 imm16: u16,
199 hw: u2,
200 fixed: u6 = 0b100101,
201 opc: u2 = 0b10,
202 sf: u1,
203 },
204
196 SupervisorCall: packed struct {205 SupervisorCall: packed struct {
197 fixed_1: u5 = 0b00001,206 fixed_1: u5 = 0b00001,
198 imm16: u16,207 imm16: u16,
...@@ -201,12 +210,39 @@ pub const Instruction = union(enum) {...@@ -201,12 +210,39 @@ pub const Instruction = union(enum) {
201210
202 pub fn toU32(self: Instruction) u32 {211 pub fn toU32(self: Instruction) u32 {
203 return switch (self) {212 return switch (self) {
213 .MoveWideWithZero => |v| @bitCast(u32, v),
204 .SupervisorCall => |v| @bitCast(u32, v),214 .SupervisorCall => |v| @bitCast(u32, v),
205 };215 };
206 }216 }
207217
208 // Helper functions for assembly syntax functions218 // Helper functions for assembly syntax functions
209219
220 fn moveWideWithZero(rd: Register, imm16: u16, shift: u2) Instruction {
221 switch (rd.size()) {
222 32 => {
223 return Instruction{
224 .MoveWideWithZero = .{
225 .rd = rd.id(),
226 .imm16 = imm16,
227 .hw = 0b01 & shift, // TODO shift should be an enum
228 .sf = 0,
229 },
230 };
231 },
232 64 => {
233 return Instruction{
234 .MoveWideWithZero = .{
235 .rd = rd.id(),
236 .imm16 = imm16,
237 .hw = shift,
238 .sf = 1,
239 },
240 };
241 },
242 else => unreachable, // unexpected register size
243 }
244 }
245
210 fn supervisorCall(imm16: u16) Instruction {246 fn supervisorCall(imm16: u16) Instruction {
211 return Instruction{247 return Instruction{
212 .SupervisorCall = .{248 .SupervisorCall = .{
...@@ -215,6 +251,12 @@ pub const Instruction = union(enum) {...@@ -215,6 +251,12 @@ pub const Instruction = union(enum) {
215 };251 };
216 }252 }
217253
254 // movz
255
256 pub fn movz(rd: Register, imm16: u16, shift: u2) Instruction {
257 return moveWideWithZero(rd, imm16, shift);
258 }
259
218 // Supervisor Call260 // Supervisor Call
219261
220 pub fn svc(imm16: u16) Instruction {262 pub fn svc(imm16: u16) Instruction {
...@@ -237,6 +279,30 @@ test "serialize instructions" {...@@ -237,6 +279,30 @@ test "serialize instructions" {
237 .inst = Instruction.svc(0x80),279 .inst = Instruction.svc(0x80),
238 .expected = 0b1101_0100_000_0000000010000000_00001,280 .expected = 0b1101_0100_000_0000000010000000_00001,
239 },281 },
282 .{ // movz x1 #4
283 .inst = Instruction.movz(.x1, 4, 0),
284 .expected = 0b1_10_100101_00_0000000000000100_00001,
285 },
286 .{ // movz x1, #4, lsl 16
287 .inst = Instruction.movz(.x1, 4, 1),
288 .expected = 0b1_10_100101_01_0000000000000100_00001,
289 },
290 .{ // movz x1, #4, lsl 32
291 .inst = Instruction.movz(.x1, 4, 2),
292 .expected = 0b1_10_100101_10_0000000000000100_00001,
293 },
294 .{ // movz x1, #4, lsl 48
295 .inst = Instruction.movz(.x1, 4, 3),
296 .expected = 0b1_10_100101_11_0000000000000100_00001,
297 },
298 .{ // movz w1, #4
299 .inst = Instruction.movz(.w1, 4, 0),
300 .expected = 0b0_10_100101_00_0000000000000100_00001,
301 },
302 .{ // movz w1, #4, lsl 16
303 .inst = Instruction.movz(.w1, 4, 1),
304 .expected = 0b0_10_100101_01_0000000000000100_00001,
305 },
240 };306 };
241307
242 for (testcases) |case| {308 for (testcases) |case| {