authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2021-08-19 22:43:25+02:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2021-08-20 14:25:25+02:00
log7aecf90d2eeead6796569713635f523cbe17295e
tree1259d94657f8e477da3cead3a5da05f33c130308
parent2f6dbaa0ea7307dd6806082b07266a43db5da950
signature Commit is signed but in an unrecognized format.

stage2 ARM: add lsl, lsr, asr, ror psuedo-instructions


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

src/codegen/arm.zig+87
...@@ -1142,6 +1142,79 @@ pub const Instruction = union(enum) {...@@ -1142,6 +1142,79 @@ pub const Instruction = union(enum) {
1142 return stmdb(cond, .sp, true, @bitCast(RegisterList, register_list));1142 return stmdb(cond, .sp, true, @bitCast(RegisterList, register_list));
1143 }1143 }
1144 }1144 }
1145
1146 pub const ShiftAmount = union(enum) {
1147 immediate: u5,
1148 register: Register,
1149
1150 pub fn imm(immediate: u5) ShiftAmount {
1151 return .{
1152 .immediate = immediate,
1153 };
1154 }
1155
1156 pub fn reg(register: Register) ShiftAmount {
1157 return .{
1158 .register = register,
1159 };
1160 }
1161 };
1162
1163 pub fn lsl(cond: Condition, rd: Register, rm: Register, shift: ShiftAmount) Instruction {
1164 return switch (shift) {
1165 .immediate => |imm| mov(cond, rd, Operand.reg(rm, Operand.Shift.imm(imm, .logical_left))),
1166 .register => |reg| mov(cond, rd, Operand.reg(rm, Operand.Shift.reg(reg, .logical_left))),
1167 };
1168 }
1169
1170 pub fn lsr(cond: Condition, rd: Register, rm: Register, shift: ShiftAmount) Instruction {
1171 return switch (shift) {
1172 .immediate => |imm| mov(cond, rd, Operand.reg(rm, Operand.Shift.imm(imm, .logical_right))),
1173 .register => |reg| mov(cond, rd, Operand.reg(rm, Operand.Shift.reg(reg, .logical_right))),
1174 };
1175 }
1176
1177 pub fn asr(cond: Condition, rd: Register, rm: Register, shift: ShiftAmount) Instruction {
1178 return switch (shift) {
1179 .immediate => |imm| mov(cond, rd, Operand.reg(rm, Operand.Shift.imm(imm, .arithmetic_right))),
1180 .register => |reg| mov(cond, rd, Operand.reg(rm, Operand.Shift.reg(reg, .arithmetic_right))),
1181 };
1182 }
1183
1184 pub fn ror(cond: Condition, rd: Register, rm: Register, shift: ShiftAmount) Instruction {
1185 return switch (shift) {
1186 .immediate => |imm| mov(cond, rd, Operand.reg(rm, Operand.Shift.imm(imm, .rotate_right))),
1187 .register => |reg| mov(cond, rd, Operand.reg(rm, Operand.Shift.reg(reg, .rotate_right))),
1188 };
1189 }
1190
1191 pub fn lsls(cond: Condition, rd: Register, rm: Register, shift: ShiftAmount) Instruction {
1192 return switch (shift) {
1193 .immediate => |imm| movs(cond, rd, Operand.reg(rm, Operand.Shift.imm(imm, .logical_left))),
1194 .register => |reg| movs(cond, rd, Operand.reg(rm, Operand.Shift.reg(reg, .logical_left))),
1195 };
1196 }
1197
1198 pub fn lsrs(cond: Condition, rd: Register, rm: Register, shift: ShiftAmount) Instruction {
1199 return switch (shift) {
1200 .immediate => |imm| movs(cond, rd, Operand.reg(rm, Operand.Shift.imm(imm, .logical_right))),
1201 .register => |reg| movs(cond, rd, Operand.reg(rm, Operand.Shift.reg(reg, .logical_right))),
1202 };
1203 }
1204
1205 pub fn asrs(cond: Condition, rd: Register, rm: Register, shift: ShiftAmount) Instruction {
1206 return switch (shift) {
1207 .immediate => |imm| movs(cond, rd, Operand.reg(rm, Operand.Shift.imm(imm, .arithmetic_right))),
1208 .register => |reg| movs(cond, rd, Operand.reg(rm, Operand.Shift.reg(reg, .arithmetic_right))),
1209 };
1210 }
1211
1212 pub fn rors(cond: Condition, rd: Register, rm: Register, shift: ShiftAmount) Instruction {
1213 return switch (shift) {
1214 .immediate => |imm| movs(cond, rd, Operand.reg(rm, Operand.Shift.imm(imm, .rotate_right))),
1215 .register => |reg| movs(cond, rd, Operand.reg(rm, Operand.Shift.reg(reg, .rotate_right))),
1216 };
1217 }
1145};1218};
11461219
1147test "serialize instructions" {1220test "serialize instructions" {
...@@ -1262,6 +1335,20 @@ test "aliases" {...@@ -1262,6 +1335,20 @@ test "aliases" {
1262 .actual = Instruction.push(.al, .{ .r0, .r2 }),1335 .actual = Instruction.push(.al, .{ .r0, .r2 }),
1263 .expected = Instruction.stmdb(.al, .sp, true, .{ .r0 = true, .r2 = true }),1336 .expected = Instruction.stmdb(.al, .sp, true, .{ .r0 = true, .r2 = true }),
1264 },1337 },
1338 .{ // lsl r4, r5, #5
1339 .actual = Instruction.lsl(.al, .r4, .r5, Instruction.ShiftAmount.imm(5)),
1340 .expected = Instruction.mov(.al, .r4, Instruction.Operand.reg(
1341 .r5,
1342 Instruction.Operand.Shift.imm(5, .logical_left),
1343 )),
1344 },
1345 .{ // asrs r1, r1, r3
1346 .actual = Instruction.asrs(.al, .r1, .r1, Instruction.ShiftAmount.reg(.r3)),
1347 .expected = Instruction.movs(.al, .r1, Instruction.Operand.reg(
1348 .r1,
1349 Instruction.Operand.Shift.reg(.r3, .arithmetic_right),
1350 )),
1351 },
1265 };1352 };
12661353
1267 for (testcases) |case| {1354 for (testcases) |case| {