authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-11-11 00:27:58+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-11-11 14:34:53+01:00
logf512676d0b4220a5f771110982657140c363a146
treef5e65489a49396f13468ce7b9b760d67b4cf5a9a
parentf1960302d115cf42554481871d22393998b87338

stage2 aarch64: add str instruction


1 files changed, 36 insertions(+), 10 deletions(-)

src/codegen/aarch64.zig+36-10
...@@ -203,11 +203,11 @@ pub const Instruction = union(enum) {...@@ -203,11 +203,11 @@ pub const Instruction = union(enum) {
203 opc: u2,203 opc: u2,
204 sf: u1,204 sf: u1,
205 },205 },
206 LoadRegister: packed struct {206 LoadStoreRegister: packed struct {
207 rt: u5,207 rt: u5,
208 rn: u5,208 rn: u5,
209 offset: u12,209 offset: u12,
210 opc: u2 = 0b01,210 opc: u2,
211 op1: u2,211 op1: u2,
212 fixed: u4 = 0b111_0,212 fixed: u4 = 0b111_0,
213 size: u2,213 size: u2,
...@@ -242,7 +242,7 @@ pub const Instruction = union(enum) {...@@ -242,7 +242,7 @@ pub const Instruction = union(enum) {
242 pub fn toU32(self: Instruction) u32 {242 pub fn toU32(self: Instruction) u32 {
243 return switch (self) {243 return switch (self) {
244 .MoveWideImmediate => |v| @bitCast(u32, v),244 .MoveWideImmediate => |v| @bitCast(u32, v),
245 .LoadRegister => |v| @bitCast(u32, v),245 .LoadStoreRegister => |v| @bitCast(u32, v),
246 .LoadLiteral => |v| @bitCast(u32, v),246 .LoadLiteral => |v| @bitCast(u32, v),
247 .ExceptionGeneration => |v| @bitCast(u32, v),247 .ExceptionGeneration => |v| @bitCast(u32, v),
248 .UnconditionalBranchRegister => |v| @bitCast(u32, v),248 .UnconditionalBranchRegister => |v| @bitCast(u32, v),
...@@ -276,8 +276,8 @@ pub const Instruction = union(enum) {...@@ -276,8 +276,8 @@ pub const Instruction = union(enum) {
276 pub fn toU12(self: Offset) u12 {276 pub fn toU12(self: Offset) u12 {
277 return switch (self) {277 return switch (self) {
278 .Immediate => |imm_type| switch (imm_type) {278 .Immediate => |imm_type| switch (imm_type) {
279 .PostIndex => |v| @intCast(u12, @bitCast(u9, v)) << 2 + 1,279 .PostIndex => |v| (@intCast(u12, @bitCast(u9, v)) << 2) + 1,
280 .PreIndex => |v| @intCast(u12, @bitCast(u9, v)) << 2 + 3,280 .PreIndex => |v| (@intCast(u12, @bitCast(u9, v)) << 2) + 3,
281 .Unsigned => |v| v,281 .Unsigned => |v| v,
282 },282 },
283 .Register => |r| switch (r.shift) {283 .Register => |r| switch (r.shift) {
...@@ -404,7 +404,7 @@ pub const Instruction = union(enum) {...@@ -404,7 +404,7 @@ pub const Instruction = union(enum) {
404 }404 }
405 }405 }
406406
407 fn loadRegister(rt: Register, rn: Register, offset: Offset) Instruction {407 fn loadStoreRegister(rt: Register, rn: Register, offset: Offset, load: bool) Instruction {
408 const off = offset.toU12();408 const off = offset.toU12();
409 const op1: u2 = blk: {409 const op1: u2 = blk: {
410 switch (offset) {410 switch (offset) {
...@@ -416,13 +416,15 @@ pub const Instruction = union(enum) {...@@ -416,13 +416,15 @@ pub const Instruction = union(enum) {
416 }416 }
417 break :blk 0b00;417 break :blk 0b00;
418 };418 };
419 const opc: u2 = if (load) 0b01 else 0b00;
419 switch (rt.size()) {420 switch (rt.size()) {
420 32 => {421 32 => {
421 return Instruction{422 return Instruction{
422 .LoadRegister = .{423 .LoadStoreRegister = .{
423 .rt = rt.id(),424 .rt = rt.id(),
424 .rn = rn.id(),425 .rn = rn.id(),
425 .offset = offset.toU12(),426 .offset = offset.toU12(),
427 .opc = opc,
426 .op1 = op1,428 .op1 = op1,
427 .size = 0b10,429 .size = 0b10,
428 },430 },
...@@ -430,10 +432,11 @@ pub const Instruction = union(enum) {...@@ -430,10 +432,11 @@ pub const Instruction = union(enum) {
430 },432 },
431 64 => {433 64 => {
432 return Instruction{434 return Instruction{
433 .LoadRegister = .{435 .LoadStoreRegister = .{
434 .rt = rt.id(),436 .rt = rt.id(),
435 .rn = rn.id(),437 .rn = rn.id(),
436 .offset = offset.toU12(),438 .offset = offset.toU12(),
439 .opc = opc,
437 .op1 = op1,440 .op1 = op1,
438 .size = 0b11,441 .size = 0b11,
439 },442 },
...@@ -529,7 +532,7 @@ pub const Instruction = union(enum) {...@@ -529,7 +532,7 @@ pub const Instruction = union(enum) {
529 return moveWideImmediate(0b11, rd, imm16, shift);532 return moveWideImmediate(0b11, rd, imm16, shift);
530 }533 }
531534
532 // Load register535 // Load or store register
533536
534 pub const LdrArgs = struct {537 pub const LdrArgs = struct {
535 rn: ?Register = null,538 rn: ?Register = null,
...@@ -538,12 +541,19 @@ pub const Instruction = union(enum) {...@@ -538,12 +541,19 @@ pub const Instruction = union(enum) {
538 };541 };
539 pub fn ldr(rt: Register, args: LdrArgs) Instruction {542 pub fn ldr(rt: Register, args: LdrArgs) Instruction {
540 if (args.rn) |rn| {543 if (args.rn) |rn| {
541 return loadRegister(rt, rn, args.offset);544 return loadStoreRegister(rt, rn, args.offset, true);
542 } else {545 } else {
543 return loadLiteral(rt, args.literal.?);546 return loadLiteral(rt, args.literal.?);
544 }547 }
545 }548 }
546549
550 pub const StrArgs = struct {
551 offset: Offset = Offset.none,
552 };
553 pub fn str(rt: Register, rn: Register, args: StrArgs) Instruction {
554 return loadStoreRegister(rt, rn, args.offset, false);
555 }
556
547 // Exception generation557 // Exception generation
548558
549 pub fn svc(imm16: u16) Instruction {559 pub fn svc(imm16: u16) Instruction {
...@@ -646,6 +656,14 @@ test "serialize instructions" {...@@ -646,6 +656,14 @@ test "serialize instructions" {
646 .inst = Instruction.ldr(.x2, .{ .rn = .x1 }),656 .inst = Instruction.ldr(.x2, .{ .rn = .x1 }),
647 .expected = 0b11_111_0_01_01_000000000000_00001_00010,657 .expected = 0b11_111_0_01_01_000000000000_00001_00010,
648 },658 },
659 .{ // ldr x2, [x1, #1]!
660 .inst = Instruction.ldr(.x2, .{ .rn = .x1, .offset = Instruction.Offset.imm_pre_index(1) }),
661 .expected = 0b11_111_0_00_01_0_000000001_11_00001_00010,
662 },
663 .{ // ldr x2, [x1], #-1
664 .inst = Instruction.ldr(.x2, .{ .rn = .x1, .offset = Instruction.Offset.imm_post_index(-1) }),
665 .expected = 0b11_111_0_00_01_0_111111111_01_00001_00010,
666 },
649 .{ // ldr x2, [x1], (x3)667 .{ // ldr x2, [x1], (x3)
650 .inst = Instruction.ldr(.x2, .{ .rn = .x1, .offset = Instruction.Offset.reg(.x3) }),668 .inst = Instruction.ldr(.x2, .{ .rn = .x1, .offset = Instruction.Offset.reg(.x3) }),
651 .expected = 0b11_111_0_00_01_1_00011_011_0_10_00001_00010,669 .expected = 0b11_111_0_00_01_1_00011_011_0_10_00001_00010,
...@@ -654,6 +672,14 @@ test "serialize instructions" {...@@ -654,6 +672,14 @@ test "serialize instructions" {
654 .inst = Instruction.ldr(.x2, .{ .literal = 0x1 }),672 .inst = Instruction.ldr(.x2, .{ .literal = 0x1 }),
655 .expected = 0b01_011_0_00_0000000000000000001_00010,673 .expected = 0b01_011_0_00_0000000000000000001_00010,
656 },674 },
675 .{ // str x2, [x1]
676 .inst = Instruction.str(.x2, .x1, .{}),
677 .expected = 0b11_111_0_01_00_000000000000_00001_00010,
678 },
679 .{ // str x2, [x1], (x3)
680 .inst = Instruction.str(.x2, .x1, .{ .offset = Instruction.Offset.reg(.x3) }),
681 .expected = 0b11_111_0_00_00_1_00011_011_0_10_00001_00010,
682 },
657 };683 };
658684
659 for (testcases) |case| {685 for (testcases) |case| {