authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-27 12:51:46+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-27 21:38:55+01:00
log528008a981cb3c63baf1fa7ce7f888f68be725ee
tree451b3ab302ac44019fe35faa598d6835e254f01d
parent139b731d82d0b851c8fb2e6dbb48b735e63eecd1
signaturelock-open Commit is signed but in an unrecognized format.

stage2 ARM: reduce Mir.Inst.Data to 8 bytes


2 files changed, 54 insertions(+), 35 deletions(-)

src/arch/arm/Mir.zig+5-7
...@@ -118,8 +118,6 @@ pub const Inst = struct {...@@ -118,8 +118,6 @@ pub const Inst = struct {
118 /// All instructions have a 8-byte payload, which is contained within118 /// All instructions have a 8-byte payload, which is contained within
119 /// this union. `Tag` determines which union field is active, as well as119 /// this union. `Tag` determines which union field is active, as well as
120 /// how to interpret the data within.120 /// how to interpret the data within.
121 // TODO flatten down Data (remove use of tagged unions) to make it
122 // 8 bytes only
123 pub const Data = union {121 pub const Data = union {
124 /// No additional data122 /// No additional data
125 ///123 ///
...@@ -231,11 +229,11 @@ pub const Inst = struct {...@@ -231,11 +229,11 @@ pub const Inst = struct {
231229
232 // Make sure we don't accidentally make instructions bigger than expected.230 // Make sure we don't accidentally make instructions bigger than expected.
233 // Note that in Debug builds, Zig is allowed to insert a secret field for safety checks.231 // Note that in Debug builds, Zig is allowed to insert a secret field for safety checks.
234 // comptime {232 comptime {
235 // if (builtin.mode != .Debug) {233 if (builtin.mode != .Debug) {
236 // assert(@sizeOf(Data) == 8);234 assert(@sizeOf(Data) == 8);
237 // }235 }
238 // }236 }
239};237};
240238
241pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {239pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
src/arch/arm/bits.zig+49-28
...@@ -469,6 +469,23 @@ pub const Instruction = union(enum) {...@@ -469,6 +469,23 @@ pub const Instruction = union(enum) {
469 }469 }
470 };470 };
471471
472 pub const AddressingMode = enum {
473 /// [<Rn>, <offset>]
474 ///
475 /// Address = Rn + offset
476 offset,
477 /// [<Rn>, <offset>]!
478 ///
479 /// Address = Rn + offset
480 /// Rn = Rn + offset
481 pre_index,
482 /// [<Rn>], <offset>
483 ///
484 /// Address = Rn
485 /// Rn = Rn + offset
486 post_index,
487 };
488
472 /// Represents the offset operand of a load or store489 /// Represents the offset operand of a load or store
473 /// instruction. Data can be loaded from memory with either an490 /// instruction. Data can be loaded from memory with either an
474 /// immediate offset or an offset that is stored in some register.491 /// immediate offset or an offset that is stored in some register.
...@@ -730,10 +747,9 @@ pub const Instruction = union(enum) {...@@ -730,10 +747,9 @@ pub const Instruction = union(enum) {
730 rd: Register,747 rd: Register,
731 rn: Register,748 rn: Register,
732 offset: Offset,749 offset: Offset,
733 pre_index: bool,750 mode: AddressingMode,
734 positive: bool,751 positive: bool,
735 byte_word: u1,752 byte_word: u1,
736 write_back: bool,
737 load_store: u1,753 load_store: u1,
738 ) Instruction {754 ) Instruction {
739 return Instruction{755 return Instruction{
...@@ -743,10 +759,16 @@ pub const Instruction = union(enum) {...@@ -743,10 +759,16 @@ pub const Instruction = union(enum) {
743 .rd = rd.id(),759 .rd = rd.id(),
744 .offset = offset.toU12(),760 .offset = offset.toU12(),
745 .load_store = load_store,761 .load_store = load_store,
746 .write_back = @boolToInt(write_back),762 .write_back = switch (mode) {
763 .offset => 0b0,
764 .pre_index, .post_index => 0b1,
765 },
747 .byte_word = byte_word,766 .byte_word = byte_word,
748 .up_down = @boolToInt(positive),767 .up_down = @boolToInt(positive),
749 .pre_post = @boolToInt(pre_index),768 .pre_post = switch (mode) {
769 .offset, .pre_index => 0b1,
770 .post_index => 0b0,
771 },
750 .imm = @boolToInt(offset != .immediate),772 .imm = @boolToInt(offset != .immediate),
751 },773 },
752 };774 };
...@@ -754,9 +776,8 @@ pub const Instruction = union(enum) {...@@ -754,9 +776,8 @@ pub const Instruction = union(enum) {
754776
755 fn extraLoadStore(777 fn extraLoadStore(
756 cond: Condition,778 cond: Condition,
757 pre_index: bool,779 mode: AddressingMode,
758 positive: bool,780 positive: bool,
759 write_back: bool,
760 o1: u1,781 o1: u1,
761 op2: u2,782 op2: u2,
762 rn: Register,783 rn: Register,
...@@ -780,10 +801,16 @@ pub const Instruction = union(enum) {...@@ -780,10 +801,16 @@ pub const Instruction = union(enum) {
780 .rt = rt.id(),801 .rt = rt.id(),
781 .rn = rn.id(),802 .rn = rn.id(),
782 .o1 = o1,803 .o1 = o1,
783 .write_back = @boolToInt(write_back),804 .write_back = switch (mode) {
805 .offset => 0b0,
806 .pre_index, .post_index => 0b1,
807 },
784 .imm = @boolToInt(offset == .immediate),808 .imm = @boolToInt(offset == .immediate),
785 .up_down = @boolToInt(positive),809 .up_down = @boolToInt(positive),
786 .pre_index = @boolToInt(pre_index),810 .pre_index = switch (mode) {
811 .offset, .pre_index => 0b1,
812 .post_index => 0b0,
813 },
787 .cond = @enumToInt(cond),814 .cond = @enumToInt(cond),
788 },815 },
789 };816 };
...@@ -1091,51 +1118,49 @@ pub const Instruction = union(enum) {...@@ -1091,51 +1118,49 @@ pub const Instruction = union(enum) {
1091 // Single data transfer1118 // Single data transfer
10921119
1093 pub const OffsetArgs = struct {1120 pub const OffsetArgs = struct {
1094 pre_index: bool = true,1121 mode: AddressingMode = .offset,
1095 positive: bool = true,1122 positive: bool = true,
1096 offset: Offset,1123 offset: Offset,
1097 write_back: bool = false,
1098 };1124 };
10991125
1100 pub fn ldr(cond: Condition, rd: Register, rn: Register, args: OffsetArgs) Instruction {1126 pub fn ldr(cond: Condition, rd: Register, rn: Register, args: OffsetArgs) Instruction {
1101 return singleDataTransfer(cond, rd, rn, args.offset, args.pre_index, args.positive, 0, args.write_back, 1);1127 return singleDataTransfer(cond, rd, rn, args.offset, args.mode, args.positive, 0, 1);
1102 }1128 }
11031129
1104 pub fn ldrb(cond: Condition, rd: Register, rn: Register, args: OffsetArgs) Instruction {1130 pub fn ldrb(cond: Condition, rd: Register, rn: Register, args: OffsetArgs) Instruction {
1105 return singleDataTransfer(cond, rd, rn, args.offset, args.pre_index, args.positive, 1, args.write_back, 1);1131 return singleDataTransfer(cond, rd, rn, args.offset, args.mode, args.positive, 1, 1);
1106 }1132 }
11071133
1108 pub fn str(cond: Condition, rd: Register, rn: Register, args: OffsetArgs) Instruction {1134 pub fn str(cond: Condition, rd: Register, rn: Register, args: OffsetArgs) Instruction {
1109 return singleDataTransfer(cond, rd, rn, args.offset, args.pre_index, args.positive, 0, args.write_back, 0);1135 return singleDataTransfer(cond, rd, rn, args.offset, args.mode, args.positive, 0, 0);
1110 }1136 }
11111137
1112 pub fn strb(cond: Condition, rd: Register, rn: Register, args: OffsetArgs) Instruction {1138 pub fn strb(cond: Condition, rd: Register, rn: Register, args: OffsetArgs) Instruction {
1113 return singleDataTransfer(cond, rd, rn, args.offset, args.pre_index, args.positive, 1, args.write_back, 0);1139 return singleDataTransfer(cond, rd, rn, args.offset, args.mode, args.positive, 1, 0);
1114 }1140 }
11151141
1116 // Extra load/store1142 // Extra load/store
11171143
1118 pub const ExtraLoadStoreOffsetArgs = struct {1144 pub const ExtraLoadStoreOffsetArgs = struct {
1119 pre_index: bool = true,1145 mode: AddressingMode = .offset,
1120 positive: bool = true,1146 positive: bool = true,
1121 offset: ExtraLoadStoreOffset,1147 offset: ExtraLoadStoreOffset,
1122 write_back: bool = false,
1123 };1148 };
11241149
1125 pub fn strh(cond: Condition, rt: Register, rn: Register, args: ExtraLoadStoreOffsetArgs) Instruction {1150 pub fn strh(cond: Condition, rt: Register, rn: Register, args: ExtraLoadStoreOffsetArgs) Instruction {
1126 return extraLoadStore(cond, args.pre_index, args.positive, args.write_back, 0b0, 0b01, rn, rt, args.offset);1151 return extraLoadStore(cond, args.mode, args.positive, 0b0, 0b01, rn, rt, args.offset);
1127 }1152 }
11281153
1129 pub fn ldrh(cond: Condition, rt: Register, rn: Register, args: ExtraLoadStoreOffsetArgs) Instruction {1154 pub fn ldrh(cond: Condition, rt: Register, rn: Register, args: ExtraLoadStoreOffsetArgs) Instruction {
1130 return extraLoadStore(cond, args.pre_index, args.positive, args.write_back, 0b1, 0b01, rn, rt, args.offset);1155 return extraLoadStore(cond, args.mode, args.positive, 0b1, 0b01, rn, rt, args.offset);
1131 }1156 }
11321157
1133 pub fn ldrsh(cond: Condition, rt: Register, rn: Register, args: ExtraLoadStoreOffsetArgs) Instruction {1158 pub fn ldrsh(cond: Condition, rt: Register, rn: Register, args: ExtraLoadStoreOffsetArgs) Instruction {
1134 return extraLoadStore(cond, args.pre_index, args.positive, args.write_back, 0b1, 0b11, rn, rt, args.offset);1159 return extraLoadStore(cond, args.mode, args.positive, 0b1, 0b11, rn, rt, args.offset);
1135 }1160 }
11361161
1137 pub fn ldrsb(cond: Condition, rt: Register, rn: Register, args: ExtraLoadStoreOffsetArgs) Instruction {1162 pub fn ldrsb(cond: Condition, rt: Register, rn: Register, args: ExtraLoadStoreOffsetArgs) Instruction {
1138 return extraLoadStore(cond, args.pre_index, args.positive, args.write_back, 0b1, 0b10, rn, rt, args.offset);1163 return extraLoadStore(cond, args.mode, args.positive, 0b1, 0b10, rn, rt, args.offset);
1139 }1164 }
11401165
1141 // Block data transfer1166 // Block data transfer
...@@ -1234,10 +1259,9 @@ pub const Instruction = union(enum) {...@@ -1234,10 +1259,9 @@ pub const Instruction = union(enum) {
1234 } else if (args.len == 1) {1259 } else if (args.len == 1) {
1235 const reg = args[0];1260 const reg = args[0];
1236 return ldr(cond, reg, .sp, .{1261 return ldr(cond, reg, .sp, .{
1237 .pre_index = false,1262 .mode = .post_index,
1238 .positive = true,1263 .positive = true,
1239 .offset = Offset.imm(4),1264 .offset = Offset.imm(4),
1240 .write_back = false,
1241 });1265 });
1242 } else {1266 } else {
1243 var register_list: u16 = 0;1267 var register_list: u16 = 0;
...@@ -1259,10 +1283,9 @@ pub const Instruction = union(enum) {...@@ -1259,10 +1283,9 @@ pub const Instruction = union(enum) {
1259 } else if (args.len == 1) {1283 } else if (args.len == 1) {
1260 const reg = args[0];1284 const reg = args[0];
1261 return str(cond, reg, .sp, .{1285 return str(cond, reg, .sp, .{
1262 .pre_index = true,1286 .mode = .pre_index,
1263 .positive = false,1287 .positive = false,
1264 .offset = Offset.imm(4),1288 .offset = Offset.imm(4),
1265 .write_back = true,
1266 });1289 });
1267 } else {1290 } else {
1268 var register_list: u16 = 0;1291 var register_list: u16 = 0;
...@@ -1447,10 +1470,9 @@ test "aliases" {...@@ -1447,10 +1470,9 @@ test "aliases" {
1447 .{ // pop { r6 }1470 .{ // pop { r6 }
1448 .actual = Instruction.pop(.al, .{.r6}),1471 .actual = Instruction.pop(.al, .{.r6}),
1449 .expected = Instruction.ldr(.al, .r6, .sp, .{1472 .expected = Instruction.ldr(.al, .r6, .sp, .{
1450 .pre_index = false,1473 .mode = .post_index,
1451 .positive = true,1474 .positive = true,
1452 .offset = Instruction.Offset.imm(4),1475 .offset = Instruction.Offset.imm(4),
1453 .write_back = false,
1454 }),1476 }),
1455 },1477 },
1456 .{ // pop { r1, r5 }1478 .{ // pop { r1, r5 }
...@@ -1460,10 +1482,9 @@ test "aliases" {...@@ -1460,10 +1482,9 @@ test "aliases" {
1460 .{ // push { r3 }1482 .{ // push { r3 }
1461 .actual = Instruction.push(.al, .{.r3}),1483 .actual = Instruction.push(.al, .{.r3}),
1462 .expected = Instruction.str(.al, .r3, .sp, .{1484 .expected = Instruction.str(.al, .r3, .sp, .{
1463 .pre_index = true,1485 .mode = .pre_index,
1464 .positive = false,1486 .positive = false,
1465 .offset = Instruction.Offset.imm(4),1487 .offset = Instruction.Offset.imm(4),
1466 .write_back = true,
1467 }),1488 }),
1468 },1489 },
1469 .{ // push { r0, r2 }1490 .{ // push { r0, r2 }