authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-11-17 22:16:26+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-11-18 08:46:52+01:00
log5ff8dd179e0ccb17f894d8d76a9079e3080653cd
treeb6b402a595bfcc5c6cfd1c263f6c0ff40abf17ee
parenta0226ab05b50341622ace8314bdad3da7cd7e35d

stage2 aarch64: add PC relative address instructions


1 files changed, 46 insertions(+), 0 deletions(-)

src/codegen/aarch64.zig+46
...@@ -203,6 +203,13 @@ pub const Instruction = union(enum) {...@@ -203,6 +203,13 @@ pub const Instruction = union(enum) {
203 opc: u2,203 opc: u2,
204 sf: u1,204 sf: u1,
205 },205 },
206 PCRelativeAddress: packed struct {
207 rd: u5,
208 immhi: u19,
209 fixed: u5 = 0b10000,
210 immlo: u2,
211 op: u1,
212 },
206 LoadStoreRegister: packed struct {213 LoadStoreRegister: packed struct {
207 rt: u5,214 rt: u5,
208 rn: u5,215 rn: u5,
...@@ -245,6 +252,7 @@ pub const Instruction = union(enum) {...@@ -245,6 +252,7 @@ pub const Instruction = union(enum) {
245 pub fn toU32(self: Instruction) u32 {252 pub fn toU32(self: Instruction) u32 {
246 return switch (self) {253 return switch (self) {
247 .MoveWideImmediate => |v| @bitCast(u32, v),254 .MoveWideImmediate => |v| @bitCast(u32, v),
255 .PCRelativeAddress => |v| @bitCast(u32, v),
248 .LoadStoreRegister => |v| @bitCast(u32, v),256 .LoadStoreRegister => |v| @bitCast(u32, v),
249 .LoadLiteral => |v| @bitCast(u32, v),257 .LoadLiteral => |v| @bitCast(u32, v),
250 .ExceptionGeneration => |v| @bitCast(u32, v),258 .ExceptionGeneration => |v| @bitCast(u32, v),
...@@ -408,6 +416,18 @@ pub const Instruction = union(enum) {...@@ -408,6 +416,18 @@ pub const Instruction = union(enum) {
408 }416 }
409 }417 }
410418
419 fn pcRelativeAddress(rd: Register, imm21: i21, op: u1) Instruction {
420 const imm21_u = @bitCast(u21, imm21);
421 return Instruction{
422 .PCRelativeAddress = .{
423 .rd = rd.id(),
424 .immlo = @truncate(u2, imm21_u),
425 .immhi = @truncate(u19, imm21_u >> 2),
426 .op = op,
427 },
428 };
429 }
430
411 fn loadStoreRegister(rt: Register, rn: Register, offset: Offset, load: bool) Instruction {431 fn loadStoreRegister(rt: Register, rn: Register, offset: Offset, load: bool) Instruction {
412 const off = offset.toU12();432 const off = offset.toU12();
413 const op1: u2 = blk: {433 const op1: u2 = blk: {
...@@ -536,6 +556,16 @@ pub const Instruction = union(enum) {...@@ -536,6 +556,16 @@ pub const Instruction = union(enum) {
536 return moveWideImmediate(0b11, rd, imm16, shift);556 return moveWideImmediate(0b11, rd, imm16, shift);
537 }557 }
538558
559 // PC relative address
560
561 pub fn adr(rd: Register, imm21: i21) Instruction {
562 return pcRelativeAddress(rd, imm21, 0b0);
563 }
564
565 pub fn adrp(rd: Register, imm21: i21) Instruction {
566 return pcRelativeAddress(rd, imm21, 0b1);
567 }
568
539 // Load or store register569 // Load or store register
540570
541 pub const LdrArgs = struct {571 pub const LdrArgs = struct {
...@@ -690,6 +720,22 @@ test "serialize instructions" {...@@ -690,6 +720,22 @@ test "serialize instructions" {
690 .inst = Instruction.str(.x2, .x1, .{ .offset = Instruction.Offset.reg(.x3) }),720 .inst = Instruction.str(.x2, .x1, .{ .offset = Instruction.Offset.reg(.x3) }),
691 .expected = 0b11_111_0_00_00_1_00011_011_0_10_00001_00010,721 .expected = 0b11_111_0_00_00_1_00011_011_0_10_00001_00010,
692 },722 },
723 .{ // adr x2, #0x8
724 .inst = Instruction.adr(.x2, 0x8),
725 .expected = 0b0_00_10000_0000000000000000010_00010,
726 },
727 .{ // adr x2, -#0x8
728 .inst = Instruction.adr(.x2, -0x8),
729 .expected = 0b0_00_10000_1111111111111111110_00010,
730 },
731 .{ // adrp x2, #0x8
732 .inst = Instruction.adrp(.x2, 0x8),
733 .expected = 0b1_00_10000_0000000000000000010_00010,
734 },
735 .{ // adrp x2, -#0x8
736 .inst = Instruction.adrp(.x2, -0x8),
737 .expected = 0b1_00_10000_1111111111111111110_00010,
738 },
693 };739 };
694740
695 for (testcases) |case| {741 for (testcases) |case| {