Skip to content

Commit 60fc2fb

Browse files
authored
Further AArch64 ISA coverage (#197)
This PR includes all instructions and syscalls added to SimEng in order to begin support for the miniFMM benchmark. Both the GNU and armclang compilers were used to compile this benchmark.
1 parent e9fc4d2 commit 60fc2fb

5 files changed

Lines changed: 350 additions & 26 deletions

File tree

src/lib/arch/aarch64/Instruction_address.cc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,14 +277,18 @@ span<const MemoryAccessTarget> Instruction::generateAddresses() {
277277
setMemoryAddresses({{operands[1].get<uint64_t>(), 4}});
278278
break;
279279
}
280-
case Opcode::AArch64_LDARB: { // ldar wt, [<xn|sp>]
280+
case Opcode::AArch64_LDARB: { // ldarb wt, [xn]
281281
setMemoryAddresses({{operands[0].get<uint64_t>(), 1}});
282282
break;
283283
}
284284
case Opcode::AArch64_LDARW: { // ldar wt, [xn]
285285
setMemoryAddresses({{operands[0].get<uint64_t>(), 4}});
286286
break;
287287
}
288+
case Opcode::AArch64_LDARX: { // ldar xt, [xn]
289+
setMemoryAddresses({{operands[0].get<uint64_t>(), 8}});
290+
break;
291+
}
288292
case Opcode::AArch64_LDAXRW: { // ldaxr wd, [xn]
289293
setMemoryAddresses({{operands[0].get<uint64_t>(), 4}});
290294
break;
@@ -1073,6 +1077,10 @@ span<const MemoryAccessTarget> Instruction::generateAddresses() {
10731077
setMemoryAddresses({{operands[1].get<uint64_t>(), 4}});
10741078
break;
10751079
}
1080+
case Opcode::AArch64_STLRX: { // stlr xt, [xn]
1081+
setMemoryAddresses({{operands[1].get<uint64_t>(), 8}});
1082+
break;
1083+
}
10761084
case Opcode::AArch64_STLXRW: { // stlxr ws, wt, [xn]
10771085
setMemoryAddresses({{operands[1].get<uint64_t>(), 4}});
10781086
break;

src/lib/arch/aarch64/Instruction_execute.cc

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,16 @@ void Instruction::execute() {
204204

205205
executed_ = true;
206206
switch (metadata.opcode) {
207+
case Opcode::AArch64_ADDv16i8: { // add vd.16b, vn.16b, vm.16b
208+
const uint8_t* n = operands[0].getAsVector<uint8_t>();
209+
const uint8_t* m = operands[1].getAsVector<uint8_t>();
210+
uint8_t out[16] = {0};
211+
for (int i = 0; i < 16; i++) {
212+
out[i] = static_cast<uint8_t>(n[i] + m[i]);
213+
}
214+
results[0] = {out, 256};
215+
break;
216+
}
207217
case Opcode::AArch64_ADDv1i64: { // add dd, dn, dm
208218
const uint64_t n = operands[0].get<uint64_t>();
209219
const uint64_t m = operands[1].get<uint64_t>();
@@ -226,6 +236,16 @@ void Instruction::execute() {
226236
results[0] = {out, 256};
227237
break;
228238
}
239+
case Opcode::AArch64_ADDv4i16: { // add vd.4h, vn.4h, vm.4h
240+
const uint16_t* n = operands[0].getAsVector<uint16_t>();
241+
const uint16_t* m = operands[1].getAsVector<uint16_t>();
242+
uint16_t out[8] = {0};
243+
for (int i = 0; i < 4; i++) {
244+
out[i] = static_cast<uint16_t>(n[i] + m[i]);
245+
}
246+
results[0] = {out, 256};
247+
break;
248+
}
229249
case Opcode::AArch64_ADDv4i32: { // add vd.4s, vn.4s, vm.4s
230250
const uint32_t* n = operands[0].getAsVector<uint32_t>();
231251
const uint32_t* m = operands[1].getAsVector<uint32_t>();
@@ -288,6 +308,26 @@ void Instruction::execute() {
288308
results[0] = out;
289309
break;
290310
}
311+
case Opcode::AArch64_ADDv8i16: { // add vd.8h, vn.8h, vm.8h
312+
const uint16_t* n = operands[0].getAsVector<uint16_t>();
313+
const uint16_t* m = operands[1].getAsVector<uint16_t>();
314+
uint16_t out[8] = {0};
315+
for (int i = 0; i < 8; i++) {
316+
out[i] = static_cast<uint16_t>(n[i] + m[i]);
317+
}
318+
results[0] = {out, 256};
319+
break;
320+
}
321+
case Opcode::AArch64_ADDv8i8: { // add vd.8b, vn.8b, vm.8b
322+
const uint8_t* n = operands[0].getAsVector<uint8_t>();
323+
const uint8_t* m = operands[1].getAsVector<uint8_t>();
324+
uint8_t out[16] = {0};
325+
for (int i = 0; i < 8; i++) {
326+
out[i] = static_cast<uint8_t>(n[i] + m[i]);
327+
}
328+
results[0] = {out, 256};
329+
break;
330+
}
291331
case Opcode::AArch64_ADCXr: { // adc xd, xn, xm
292332
const uint8_t carry = operands[0].get<uint8_t>() & 0b0010;
293333
const uint64_t n = operands[1].get<uint64_t>();
@@ -3800,14 +3840,18 @@ void Instruction::execute() {
38003840
results[2] = operands[2].get<uint64_t>() + offset;
38013841
break;
38023842
}
3803-
case Opcode::AArch64_LDARB: { // LDARB wt, [<xn|sp>]
3843+
case Opcode::AArch64_LDARB: { // ldarb wt, [xn]
38043844
results[0] = memoryData[0].zeroExtend(1, 8);
38053845
break;
38063846
}
38073847
case Opcode::AArch64_LDARW: { // ldar wt, [xn]
38083848
results[0] = memoryData[0].zeroExtend(4, 8);
38093849
break;
38103850
}
3851+
case Opcode::AArch64_LDARX: { // ldar xt, [xn]
3852+
results[0] = memoryData[0];
3853+
break;
3854+
}
38113855
case Opcode::AArch64_LDAXRW: { // ldaxr wd, [xn]
38123856
results[0] = memoryData[0].zeroExtend(4, 8);
38133857
break;
@@ -5374,6 +5418,8 @@ void Instruction::execute() {
53745418
}
53755419
case Opcode::AArch64_STLRB: // stlrb wt, [xn]
53765420
[[fallthrough]];
5421+
case Opcode::AArch64_STLRX: // stlr xt, [xn]
5422+
[[fallthrough]];
53775423
case Opcode::AArch64_STLRW: { // stlr wt, [xn]
53785424
memoryData[0] = operands[0];
53795425
break;
@@ -6159,6 +6205,16 @@ void Instruction::execute() {
61596205
results[0] = mulhi(x, y);
61606206
break;
61616207
}
6208+
case Opcode::AArch64_USHLLv16i8_shift: { // ushll2 vd.8h, vn.16b, #imm
6209+
const uint8_t* n = operands[0].getAsVector<uint8_t>();
6210+
const uint64_t shift = metadata.operands[2].imm;
6211+
uint16_t out[8] = {0};
6212+
for (int i = 0; i < 8; i++) {
6213+
out[i] = n[i + 8] << shift;
6214+
}
6215+
results[0] = {out, 256};
6216+
break;
6217+
}
61626218
case Opcode::AArch64_USHLLv4i16_shift: { // ushll vd.4s, vn.4h, #imm
61636219
const uint16_t* n = operands[0].getAsVector<uint16_t>();
61646220
const uint64_t shift = metadata.operands[2].imm;
@@ -6169,6 +6225,26 @@ void Instruction::execute() {
61696225
results[0] = {out, 256};
61706226
break;
61716227
}
6228+
case Opcode::AArch64_USHLLv8i16_shift: { // ushll2 vd.4s, vn.8h, #imm
6229+
const uint16_t* n = operands[0].getAsVector<uint16_t>();
6230+
const uint64_t shift = metadata.operands[2].imm;
6231+
uint32_t out[4] = {0};
6232+
for (int i = 0; i < 4; i++) {
6233+
out[i] = n[i + 4] << shift;
6234+
}
6235+
results[0] = {out, 256};
6236+
break;
6237+
}
6238+
case Opcode::AArch64_USHLLv8i8_shift: { // ushll vd.8h, vn.8b, #imm
6239+
const uint8_t* n = operands[0].getAsVector<uint8_t>();
6240+
const uint64_t shift = metadata.operands[2].imm;
6241+
uint16_t out[8] = {0};
6242+
for (int i = 0; i < 8; i++) {
6243+
out[i] = n[i] << shift;
6244+
}
6245+
results[0] = {out, 256};
6246+
break;
6247+
}
61726248
case Opcode::AArch64_UUNPKHI_ZZ_D: { // uunpkhi zd.d, zn.s
61736249
const uint32_t* n = operands[0].getAsVector<uint32_t>();
61746250
const uint64_t VL_bits = 512;

test/regression/aarch64/instructions/load.cc

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,24 @@ TEST_P(InstLoad, ldadd) {
265265
EXPECT_EQ(getMemoryValue<uint32_t>(process_->getStackPointer() - 928), 128);
266266
}
267267

268+
TEST_P(InstLoad, ldar) {
269+
initialHeapData_.resize(8);
270+
uint64_t* heap = reinterpret_cast<uint64_t*>(initialHeapData_.data());
271+
heap[0] = 0xDEADBEEF12345678;
272+
273+
RUN_AARCH64(R"(
274+
# Get heap address
275+
mov x0, 0
276+
mov x8, 214
277+
svc #0
278+
279+
ldar x1, [x0]
280+
ldar w2, [x0]
281+
)");
282+
EXPECT_EQ(getGeneralRegister<uint64_t>(1), 0xDEADBEEF12345678);
283+
EXPECT_EQ(getGeneralRegister<uint32_t>(2), 0x12345678);
284+
}
285+
268286
TEST_P(InstLoad, ldarb) {
269287
initialHeapData_.resize(8);
270288
uint32_t* heap = reinterpret_cast<uint32_t*>(initialHeapData_.data());
@@ -276,7 +294,6 @@ TEST_P(InstLoad, ldarb) {
276294
mov x0, 0
277295
mov x8, 214
278296
svc #0
279-
280297
ldarb w1, [x0]
281298
add x0, x0, #1
282299
ldarb w2, [x0]
@@ -308,14 +325,11 @@ TEST_P(InstLoad, ldarb) {
308325
mov w1, #32
309326
mov w2, #48
310327
mov w3, #64
311-
312328
str w0, [sp], #32
313329
str w1, [sp], #32
314330
str w2, [sp], #32
315331
str w3, [sp], #32
316-
317332
sub sp, sp, #128
318-
319333
ldarb w4, [sp]
320334
add sp, sp, #32
321335
ldarb w5, [sp]
@@ -342,12 +356,10 @@ TEST_P(InstLoad, ldrb) {
342356
mov x0, 0
343357
mov x8, 214
344358
svc #0
345-
346359
ldrb w1, [x0], 1
347360
ldrb w2, [x0]
348361
ldrb w3, [x0, 1]!
349362
ldrb w4, [x0, 2]
350-
351363
mov w5, 1
352364
ldrb w6, [x0, w5, uxtw]
353365
mov w5, 3

0 commit comments

Comments
 (0)