From c687ed46dd33042306a68c36183f4016f210f280 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Mon, 22 Dec 2025 23:43:59 +0800 Subject: [PATCH] update Naja byte code, add some instructions to it --- docs/Naja_float.txt | 168 ++- docs/Naja_int.txt | 316 ++-- docs/Naja_sys.txt | 138 ++ docs/Naja_vector.txt | 190 +++ elf/scf_elf_naja.c | 4 +- elf/scf_elf_naja_so.c | 41 +- native/risc/scf_naja.c | 277 ++-- native/risc/scf_risc_inst.c | 3 + native/risc/scf_risc_reg.h | 1 - native/risc/scf_risc_reg_naja.c | 351 ++--- native/risc/scf_risc_util.h | 20 +- vm/scf_vm.h | 10 +- vm/scf_vm_naja.c | 2416 ++++++++++++++++++++----------- vm/scf_vm_naja_asm.c | 1317 +++++++++-------- 14 files changed, 3107 insertions(+), 2145 deletions(-) create mode 100644 docs/Naja_sys.txt create mode 100644 docs/Naja_vector.txt diff --git a/docs/Naja_float.txt b/docs/Naja_float.txt index f5e3452..cbbb452 100644 --- a/docs/Naja_float.txt +++ b/docs/Naja_float.txt @@ -1,144 +1,178 @@ - Naja float instructions + Naja instructions +------------------------------------------------------------------------------------------------ + float vector opcode format +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| type| opcode | 0|<-- rd --->| 0| size| V A |<-- rs2 -->| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| +type: 0 = integer, 1 = float, 2 = vector, 3 = system +size: 0 = 8bits, 1 = 16bits, 2 = 32bits, 3 = 64bits + V: 0 = only one, 1 = vector + A: 0 = add, 1 = sub +vlen: 0 = 64bits, 1 = 128bits, 2 = 256bits, 3 = 512bits + 0: reserved +------------------------------------------------------------------------------------------------ -16, fadd, +, +=, opcode = 16 +16, fadd, +, +=, opcode = 16 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 0 0 0 0|<--- rd ---->|0 0| 0 0 0 0 0 0 0 0 0|<--- rs1 ---->|<--- rs0 ---->| - -rd = rs0 + rs1; +| 0 1| 0 0 0 0| 0|<-- rd --->| 0| size| V 0| 0 0 0 0| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| +rd = rs0 + rs1; // V = 0, +rd[i] = rs0[i] + rs1[i]; // V = 1, N = vlen / size, i = 0 ~ N - 1 +------------------------------------------------------------------------------------------------ -17, fsub, -, -=, opcode = 17 +17, fsub, -, -=, opcode = 17 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 0 0 0 1|<--- rd ---->|0 0| 0 0 0 0 0 0 0 0 0|<--- rs1 ---->|<--- rs0 ---->| +| 0 1| 0 0 0 1| 0|<-- rd --->| 0| size| V 0| 0 0 0 0| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| -rd = rs0 - rs1; +rd = rs0 - rs1; // V = 0, +rd[i] = rs0[i] - rs1[i]; // V = 1, N = vlen / size, i = 0 ~ N - 1 ------------------------------------------------------------------------------------------------ -fcmp, >, >=, <, <=, ==, !=, opcode = 17 +fcmp, >, >=, <, <=, ==, !=, opcode = 17 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 0 0 0 1| 1 1 1 1 1|0 0| 0 0 0 0 0 0 0 0 0|<--- rs1 ---->|<--- rs0 ---->| +| 0 1| 0 0 0 1| 0|<-- rd --->| 0| size| V 1| 0 0 0 0| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| -flags = rs0 - rs1; +flags = rs0 - rs1; // V = 0, +rd[i] = rs0[i] - rs1[i]; // V = 1, N = vlen / size, i = 0 ~ N - 1 ------------------------------------------------------------------------------------------------ -18, fmul, *, *=, opcode = 18 +18, fmul, *, *=, opcode = 18 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 0 0 1 0|<--- rd ---->| opt | s| 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| +| 0 1| 0 0 1 0| 0|<-- rd --->| 0| size| V A|<-- rs2 -->| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| + +signed mul of float. -s = 1, signed mul. +rd = rs2 + rs0 * rs1; // V = 0, A = 0 +rd = rs2 - rs0 * rs1; // V = 0, A = 1 +rd[i] = rs2[i] + rs0[i] * rs1[i]; // V = 1, A = 0, N = vlen / size, i = 0 ~ N - 1 +rd[i] = rs2[i] - rs0[i] * rs1[i]; // V = 1, A = 1, N = vlen / size, i = 0 ~ N - 1 -rd = rs2 + rs0 * rs1; // opt = 0 -rd = rs2 - rs0 * rs1; // opt = 1 -rd = rs0 * rs1; // opt = 2 ------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1| 0 0 1 0| 0|<-- rd --->| 0| size| V 0| 1 1 1 1| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| +rd = rs0 * rs1; // V = 0, A = 0, rs2 = 0xf = 15 +rd[i] = rs0[i] * rs1[i]; // V = 1, A = 0, rs2 = 0xf = 15, N = vlen / size, i = 0 ~ N - 1 +------------------------------------------------------------------------------------------------ -19, fdiv, *, *=, opcode = 19 +19, fdiv, /, /=, opcode = 19 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 0 0 1 1|<--- rd ---->| opt | s| 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| +| 0 1| 0 0 1 1| 0|<-- rd --->| 0| size| V 0| 0 0 0 0| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| -s = 1, signed div. +signed div of float. -rd = rs2 + rs0 / rs1; // opt = 0 -rd = rs2 - rs0 / rs1; // opt = 1 -rd = rs0 / rs1; // opt = 2 +rd = rs0 / rs1; // V = 0, +rd[i] = rs0[i] / rs1[i]; // V = 1, N = vlen / size, i = 0 ~ N - 1 ------------------------------------------------------------------------------------------------ +20, fldr, [b + disp] opcode = 20 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1| 0 1 0 0| 0|<-- rd --->| 0| size| 0|<---------------- simm13 ------------>|<-- rb --->| + +rd = *(float *)(rb + ((int64_t)simm13 << 2)); // V = 0, size = 2, +rd = *(double*)(rb + ((int64_t)simm13 << 3)); // V = 0, size = 3, -20, fldr, b[i] opcode = 20 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 0 1 0 0|<--- rd ---->| SH | 1|<------------ simm13 ---------------->|<---- rb ---->| +| 0 1| 0 1 0 0| 0|<-- rd --->| 0| size| 1 A| 0 0 0 0| vlen| 0 0| 0 0 0 0|<-- rb --->| + +rd[i] = rb[i], // V = 1, N = vlen / size, i = 0 ~ N - 1 -rd = *(double*)(rb + ((int64_t)simm13 << 3)); // SH = 3, -rd = *(float *)(rb + ((int64_t)simm13 << 2)); // SH = 2, SS2SD +rb += vlen; // A = 1 ------------------------------------------------------------------------------------------------ -21, fpop, b[i] opcode = 21 +8, fpop = pop, b[0] opcode = 8 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 0 1 0 1|<--- rd ----->| SH | 1| 0 0 0 0 0 0 0 0 0 0 0 0 0|<---- rb ---->| +| 0 0| 1 0 0 0| 0|<-- rd --->| 0| 1 1| 1| 0 0 0 0 0 0 0 0 0 0 0 0 0|<-- rb --->| -rd = *(double*)rb; // SH = 3, -rd = *(float *)rb; // SH = 2, SS2SD +rd = *(uint64_t*)rb; // size = 3, s = 1, keep -rb += 1 << SH +rb += 1 << size ------------------------------------------------------------------------------------------------ -22, fstr, b[i] opcode = 22 +22, fstr, [b + disp] opcode = 22 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 0 1 1 0|<--- rs ----->| SH | 1|<----------- simm13 ----------------->|<---- rb ---->| +| 0 1| 0 1 1 0| 0|<-- rs --->| 0| size| 0|<---------------- simm13 ------------>|<-- rb --->| -*(double*)(rb + ((int64_t)simm13 << 3) = rs; // SH = 3, -*(float *)(rb + ((int64_t)simm13 << 2) = rs; // SH = 2, SD2SS ------------------------------------------------------------------------------------------------- +*(float *)(rb + ((int64_t)simm13 << 2)) = rs; // V = 0, size = 2, +*(double*)(rb + ((int64_t)simm13 << 3)) = rs; // V = 0, size = 3, -23, fpush, b[i] opcode = 23 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 0 1 1 1|<---- rs ---->| SH | 1| 0 0 0 0 0 0 0 0 0 0 0 0 0|<---- rb ---->| +| 0 1| 0 1 1 0| 0|<-- rd --->| 0| size| 1 A| 0 0 0 0| vlen| 0 0| 0 0 0 0|<-- rb --->| -*(double*)rb = rs; // SH = 3, -*(float *)rb = rs; // SH = 2, SD2SS +rb[i] = rd[i], // V = 1, N = vlen / size, i = 0 ~ N - 1 -rb -= 1 << SH +rb += vlen; // A = 1 ------------------------------------------------------------------------------------------------ -29, fldr, b[i << s] opcode = 29 +9, fpush = push, b[0] opcode = 9 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 1 1 0 1|<--- rd ----->| SH | 1|<-------- uimm8 ------>|<---- ri ---->|<---- rb ---->| +| 0 0| 1 0 0 1| 0|<-- rs --->| 0| 1 1| 1| 0 0 0 0 0 0 0 0 0 0 0 0 0|<-- rb --->| + +*(uint64_t*)rb = rs; // size = 3, s = 1, keep -rd = *(double*)(rb + (ri << uimm8)); // SH = 3, -rd = *(float* )(rb + (ri << uimm8)); // SH = 2, SS2SD +rb -= 1 << size ------------------------------------------------------------------------------------------------ -30, fstr, b[i << s] opcode = 30 +26, fldr, b[i << s] opcode = 26 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 1 1 1 0|<---- rs ---->| SH | 1|<-------- uimm8 ------>|<---- ri ---->|<---- rb ---->| +| 0 1| 1 0 1 0| 0|<-- rd --->| 0| size| 0| 0|<---- uimm6 ---->| 0 0|<-- ri --->|<-- rb --->| -*(double*)(rb + (ri << uimm8)) = rs; // SH = 3 -*(float *)(rb + (ri << uimm8)) = rs; // SH = 2, SD2SS +rd = *(float *)(rb + (ri << uimm6)); // size = 2, +rd = *(double*)(rb + (ri << uimm6)); // size = 3, ------------------------------------------------------------------------------------------------ -31, fmov, =, ~, -, opcode = 31 +11, fstr = str, b[i << s] opcode = 11 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 1 1 1 1|<--- rd ---->| SH | s| 0 0| 0 0 0 0 0 0 0 0 0 0 0|<---- rs ---->| +| 0 0| 1 0 1 1| 0|<-- rs --->| 0| size| 1| 0|<---- uimm6 ---->| 0 0|<-- ri --->|<-- rb --->| -rd = (double)rs; // SH = 2, s = 0, SS2SD, -rd = (float )rs; // SH = 3, s = 0, SD2SS, +*(float *)(rb + (ri << uimm8)) = rs; // size = 2, s = 1, +*(double*)(rb + (ri << uimm8)) = rs; // size = 3, s = 1, +------------------------------------------------------------------------------------------------ +28, fmov, opcode = 28 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 1 1 1 1|<--- rd ---->| SH | s| 0 1| 0 0 0 0 0 0 0 0 0 0 0|<---- rs ---->| +| 0 1| 1 1 0 0| 0|<-- rd --->| 0| size| V 0| 0 0 0 0| vlen| 0 0| 0 0 0 0|<-- rs --->| -rd = (int32_t )rs; // SH = 2, s = 1, CVTSS2SI, -rd = (int64_t )rs; // SH = 3, s = 1, CVTSD2SI, -rd = (uint32_t)rs; // SH = 2, s = 0, CVTSS2UI, -rd = (uint64_t)rs; // SH = 3, s = 0, CVTSD2UI, +rd = rs; // V = 0, +rd[i] = rs[i]; // V = 1, N = vlen / size, i = 0 ~ N - 1 +------------------------------------------------------------------------------------------------ +29, fcvt, opcode = 29 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 1 1 1 1|<--- rd ---->| SH | s| 1 0| 0 0 0 0 0 0 0 0 0 0 0|<---- rs ---->| +| 0 1| 1 1 0 1| 0|<-- rd --->| 0|dsize| V 0| 0 0 Id sd| vlen| 0 0|Is ss|ssize|<-- rs --->| -rd = (float )(int32_t )rs; // SH = 2, s = 1, CVTSI2SS, -rd = (double)(int32_t )rs; // SH = 3, s = 1, CVTSI2SD, -rd = (float )(uint32_t)rs; // SH = 2, s = 0, CVTUI2SS, -rd = (double)(uint32_t)rs; // SH = 3, s = 0, CVTUI2SD, +rd = fcvt(rs); // V = 0, +rd[i] = fcvt(rs[i]); // V = 1, N = vlen / size, i = 0 ~ N - 1 + +dsize = rd size; +ssize = rs size; +sd = rd sign; +ss = rs sign; +Id = rd int or float; +Is = rs int or float; +------------------------------------------------------------------------------------------------ +30, fneg, opcode = 30 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 1 1 1 1|<--- rd ---->| SH | s| 1 1| 0 0 0 0 0 0 0 0 0 0 0|<---- rs ---->| +| 0 1| 1 1 1 0| 0|<-- rd --->| 0| size| V 0| 0 0 0 0| vlen| 0 0| 0 0 0 0|<-- rs --->| -rd = rs; // SH = 2 or 3, s = 0, -rd = -rs; // SH = 2 or 3, s = 1, NEG, +rd = -rs; // NEG, V = 0, +rd[i] = -rs[i]; // NEG, V = 1, N = vlen / size, i = 0 ~ N - 1 ------------------------------------------------------------------------------------------------ diff --git a/docs/Naja_int.txt b/docs/Naja_int.txt index fc63fa0..1457b4d 100644 --- a/docs/Naja_int.txt +++ b/docs/Naja_int.txt @@ -1,255 +1,224 @@ - Naja interger instructions + Naja instructions +------------------------------------------------------------------------------------------------ + opcode format +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| type| opcode | 0|<-- rd --->| 0| size| SH |<---- uimm6 ---->| 0 0|<-- rs1 -->|<-- rs0 -->| +type: 0 = integer, 1 = float, 2 = vector, 3 = system +size: 0 = 8bits, 1 = 16bits, 2 = 32bits, 3 = 64bits +SH : 0 = LSL, 1 = LSR, 2 = ASR, (3 = reserved) + 0: reserved +------------------------------------------------------------------------------------------------ 0, add, +, +=, opcode = 0 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 0 0 0|<---- rd ---->| SH |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->| +| 0 0| 0 0 0 0| 0|<-- rd --->| 0| size| SH |<---- uimm6 ---->| 0 0|<-- rs1 -->|<-- rs0 -->| -rd = rs0 + (rs1 << uimm9); // SH = 0, LSL -rd = rs0 + (rs1 >> uimm9); // SH = 1, LSR -rd = rs0 + (rs1 >> uimm9); // SH = 2, ASR +rd = rs0 + (rs1 << uimm6); // SH = 0, LSL +rd = rs0 + (rs1 >> uimm6); // SH = 1, LSR +rd = rs0 + (rs1 >> uimm6); // SH = 2, ASR ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 0 0 0|<---- rd ---->| 1 1|<----------------- uimm14 -------------->|<--- rs0 ---->| +| 0 0| 0 0 0 0| 0|<-- rd --->| 0| size| 1 1|<------------- uimm12 ------------>|<-- rs0 -->| -rd = rs0 + (uint64_t)uimm14; // SH = 3, IMM +rd = rs0 + (uint64_t)uimm12; // SH = 3, IMM ------------------------------------------------------------------------------------------------ 1, sub, -, -=, opcode = 1 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 0 0 1|<---- rd ---->| SH |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->| +| 0 0| 0 0 0 1| 0|<-- rd --->| 0| size| SH |<---- uimm6 ---->| 0 0|<-- rs1 -->|<-- rs0 -->| -rd = rs0 - (rs1 << uimm9); // SH = 0, LSL -rd = rs0 - (rs1 >> uimm9); // SH = 1, LSR -rd = rs0 - (rs1 >> uimm9); // SH = 2, ASR +rd = rs0 - (rs1 << uimm6); // SH = 0, LSL +rd = rs0 - (rs1 >> uimm6); // SH = 1, LSR +rd = rs0 - (rs1 >> uimm6); // SH = 2, ASR ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 0 0 1|<---- rd ---->| 1 1|<----------------- uimm14 -------------->|<--- rs0 ---->| +| 0 0| 0 0 0 1| 0|<-- rd --->| 0| size| 1 1|<------------- uimm12 ------------>|<-- rs0 -->| -rd = rs0 - (uint64_t)uimm14; // SH = 3, IMM +rd = rs0 - (uint64_t)uimm12; // SH = 3, IMM ------------------------------------------------------------------------------------------------ cmp, >, >=, <, <=, ==, !=, opcode = 1 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 0 0 1| 1 1 1 1 1| SH |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->| +| 0 0| 0 0 0 1| 0| 1 1 1 1| 0| size| SH |<---- uimm6 ---->| 0 0|<-- rs1 -->|<-- rs0 -->| -flags = rs0 - (rs1 << uimm9); // SH = 0, LSL, rd = 31 -flags = rs0 - (rs1 >> uimm9); // SH = 1, LSR, rd = 31 -flags = rs0 - (rs1 >> uimm9); // SH = 2, ASR, rd = 31 +flags = rs0 - (rs1 << uimm6); // SH = 0, LSL, rd = 15 +flags = rs0 - (rs1 >> uimm6); // SH = 1, LSR, rd = 15 +flags = rs0 - (rs1 >> uimm6); // SH = 2, ASR, rd = 15 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 0 0 1| 1 1 1 1 1| 1 1|<----------------- uimm14 -------------->|<--- rs0 ---->| +| 0 0| 0 0 0 1| 0| 1 1 1 1| 0| size| 1 1|<------------- uimm12 ------------>|<-- rs0 -->| -flags = rs0 - (uint64_t)uimm14; // SH = 3, IMM, rd = 31 +flags = rs0 - (uint64_t)uimm12; // SH = 3, IMM, rd = 15 ------------------------------------------------------------------------------------------------ 2, mul, *, *=, opcode = 2 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 0 1 0|<---- rd ---->| opt | s| 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| +| 0 0| 0 0 1 0| 0|<-- rd --->| 0| size| s| A|<-- rs2 -->| 0 0| 0 0|<-- rs1 -->|<-- rs0 -->| s = 0, unsigned mul. s = 1, signed mul. -rd = rs2 + rs0 * rs1; // opt = 0 -rd = rs2 - rs0 * rs1; // opt = 1 -rd = rs0 * rs1; // opt = 2 ------------------------------------------------------------------------------------------------- - -3, div, *, *=, opcode = 3 ------------------------------------------------------------------------------------------------- -|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 0 1 1|<--- rd ----->| opt | s| 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| - -s = 0, unsigned div. -s = 1, signed div. - -rd = rs2 + rs0 / rs1; // opt = 0 -rd = rs2 - rs0 / rs1; // opt = 1 -rd = rs0 / rs1; // opt = 2 ------------------------------------------------------------------------------------------------- +rd = rs2 + rs0 * rs1; // A = 0 +rd = rs2 - rs0 * rs1; // A = 1 -4, ldr, b[i] opcode = 4 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 1 0 0|<--- rd ----->| SH | s|<----------- simm13 ----------------->|<---- rb ---->| +| 0 0| 0 0 1 0| 0|<-- rd --->| 0| size| s| 0| 1 1 1 1| 0 0| 0 0|<-- rs1 -->|<-- rs0 -->| -rd = *(uint8_t* )(rb + (int64_t)simm13); // SH = 0, s = 0, zbq -rd = *(uint16_t*)(rb + ((int64_t)simm13 << 1)); // SH = 1, s = 0, zwq -rd = *(uint32_t*)(rb + ((int64_t)simm13 << 2)); // SH = 2, s = 0, zlq - -rd = *(uint64_t*)(rb + ((int64_t)simm13 << 3)); // SH = 3, s = 0, keep +s = 0, unsigned mul. +s = 1, signed mul. -rd = *( int8_t* )(rb + (int64_t)simm13); // SH = 0, s = 1, sbq -rd = *( int16_t*)(rb + ((int64_t)simm13 << 1)); // SH = 1, s = 1, swq -rd = *( int32_t*)(rb + ((int64_t)simm13 << 2)); // SH = 2, s = 1, slq +rd = rs0 * rs1; // A = 0, rs2 = 0xf = 15 ------------------------------------------------------------------------------------------------ -5, pop, b[i] opcode = 5 +3, div, *, *=, opcode = 3 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 1 0 1|<--- rd ----->| SH | s| 0 0 0 0 0 0 0 0 0 0 0 0 0|<---- rb ---->| - -rd = *(uint8_t* )rb; // SH = 0, s = 0, zbq -rd = *(uint16_t*)rb; // SH = 1, s = 0, zwq -rd = *(uint32_t*)rb; // SH = 2, s = 0, zlq - -rd = *(uint64_t*)rb; // SH = 3, s = 0, keep +| 0 0| 0 0 1 1| 0|<-- rd --->| 0| size| s| 0| 0 0 0 0| 0 0| 0 0|<-- rs1 -->|<-- rs0 -->| -rd = *( int8_t* )rb; // SH = 0, s = 1, sbq -rd = *( int16_t*)rb; // SH = 1, s = 1, swq -rd = *( int32_t*)rb; // SH = 2, s = 1, slq +s = 0, unsigned div. +s = 1, signed div. -rb += 1 << SH +rd = rs0 / rs1; // A = 0, rs2 = 0xf = 15 ------------------------------------------------------------------------------------------------ -6, str, b[i] opcode = 6 +4, ldr, [b + disp] opcode = 4 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 1 1 0|<--- rs ----->| SH | 0|<----------- simm13 ----------------->|<---- rb ---->| +| 0 0| 0 1 0 0| 0|<-- rd --->| 0| size| s|<---------------- simm13 ------------>|<-- rb --->| -*(uint8_t* )(rb + (int64_t)simm13) = rs; // SH = 0, zbq -*(uint16_t*)(rb + ((int64_t)simm13 << 1)) = rs; // SH = 1, zwq -*(uint32_t*)(rb + ((int64_t)simm13 << 2)) = rs; // SH = 2, zlq -*(uint64_t*)(rb + ((int64_t)simm13 << 3)) = rs; // SH = 3, keep ------------------------------------------------------------------------------------------------- - -7, push, b[i] opcode = 7 ------------------------------------------------------------------------------------------------- -|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 1 1 1|<---- rs ---->| SH | s| 0 0 0 0 0 0 0 0 0 0 0 0 0|<---- rb ---->| +rd = *(uint8_t* )(rb + (int64_t)simm13); // size = 0, s = 0, zbq +rd = *(uint16_t*)(rb + ((int64_t)simm13 << 1)); // size = 1, s = 0, zwq +rd = *(uint32_t*)(rb + ((int64_t)simm13 << 2)); // size = 2, s = 0, zlq -*(uint8_t* )rb = rs; // SH = 0, s = 0, zbq -*(uint16_t*)rb = rs; // SH = 1, s = 0, zwq -*(uint32_t*)rb = rs; // SH = 2, s = 0, zlq -*(uint64_t*)rb = rs; // SH = 3, s = 0, keep +rd = *(uint64_t*)(rb + ((int64_t)simm13 << 3)); // size = 3, s = 0, keep -rb -= 1 << SH +rd = *( int8_t* )(rb + (int64_t)simm13); // size = 0, s = 1, sbq +rd = *( int16_t*)(rb + ((int64_t)simm13 << 1)); // size = 1, s = 1, swq +rd = *( int32_t*)(rb + ((int64_t)simm13 << 2)); // size = 2, s = 1, slq ------------------------------------------------------------------------------------------------ -8, and, &, &=, opcode = 8 +5, and, &, &=, opcode = 5 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 0 0 0|<---- rd ---->| SH |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->| +| 0 0| 0 1 0 1| 0|<-- rd --->| 0| size| SH |<---- uimm6 ---->| 0 0|<-- rs1 -->|<-- rs0 -->| -rd = rs0 & (rs1 << uimm9); // SH = 0, LSL -rd = rs0 & (rs1 >> uimm9); // SH = 1, LSR -rd = rs0 & (rs1 >> uimm9); // SH = 2, ASR +rd = rs0 & (rs1 << uimm6); // SH = 0, LSL +rd = rs0 & (rs1 >> uimm6); // SH = 1, LSR +rd = rs0 & (rs1 >> uimm6); // SH = 2, ASR ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 0 0 0|<---- rd ---->| 1 1|<---------------- uimm14 --------------->|<--- rs0 ---->| +| 0 0| 0 1 0 1| 0|<-- rd --->| 0| size| 1 1|<------------- uimm12 ------------>|<-- rs0 -->| -rd = rs0 & (uint64_t)uimm14; // SH = 3, IMM +rd = rs0 & (uint64_t)uimm12; // SH = 3, IMM ------------------------------------------------------------------------------------------------ teq, !, opcode = 8 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 0 0 0| 1 1 1 1 1| SH |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->| +| 0 0| 0 1 0 1| 0| 1 1 1 1| 0| size| SH |<---- uimm6 ---->| 0 0|<-- rs1 -->|<-- rs0 -->| -ZF = rs0 & (rs1 << uimm9); // SH = 0, LSL -ZF = rs0 & (rs1 >> uimm9); // SH = 1, LSR -ZF = rs0 & (rs1 >> uimm9); // SH = 2, ASR +ZF = rs0 & (rs1 << uimm6); // SH = 0, LSL +ZF = rs0 & (rs1 >> uimm6); // SH = 1, LSR +ZF = rs0 & (rs1 >> uimm6); // SH = 2, ASR ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 0 0 0| 1 1 1 1 1| 1 1|<---------------- uimm14 --------------->|<--- rs0 ---->| +| 0 0| 0 1 0 1| 0| 1 1 1 1| 0| size| 1 1|<------------- uimm12 ------------>|<-- rs0 -->| -ZF = rs0 & (uint64_t)uimm14; // SH = 3, IMM +ZF = rs0 & (uint64_t)uimm12; // SH = 3, IMM ------------------------------------------------------------------------------------------------ -9, or, |, |=, opcode = 9 +6, str, [b + disp] opcode = 6 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 0 0 1|<---- rd ---->| SH |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->| +| 0 0| 0 1 1 0| 0|<-- rs --->| 0| size| 0|<---------------- simm13 ------------>|<-- rb --->| -rd = rs0 | (rs1 << uimm8); // SH = 0, LSL -rd = rs0 | (rs1 >> uimm8); // SH = 1, LSR -rd = rs0 | (rs1 >> uimm8); // SH = 2, ASR +*(uint8_t* )(rb + (int64_t)simm13) = rs; // size = 0, zbq +*(uint16_t*)(rb + ((int64_t)simm13 << 1)) = rs; // size = 1, zwq +*(uint32_t*)(rb + ((int64_t)simm13 << 2)) = rs; // size = 2, zlq +*(uint64_t*)(rb + ((int64_t)simm13 << 3)) = rs; // size = 3, keep +------------------------------------------------------------------------------------------------ +7, or, |, |=, opcode = 7 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 1 1 1|<---- rd ---->| 1 1|<---------------- uimm14 --------------->|<--- rs0 ---->| +| 0 0| 0 1 1 1| 0|<-- rd --->| 0| size| SH |<---- uimm6 ---->| 0 0|<-- rs1 -->|<-- rs0 -->| -rd = rs0 | (uint64_t)uimm14; // SH = 3, IMM ------------------------------------------------------------------------------------------------- +rd = rs0 | (rs1 << uimm6); // SH = 0, LSL +rd = rs0 | (rs1 >> uimm6); // SH = 1, LSR +rd = rs0 | (rs1 >> uimm6); // SH = 2, ASR -10, jmp, disp opcode = 10 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 0 1 0|<-------------------------------- simm26:00 -------------------------------->| +| 0 0| 0 1 1 1| 0|<-- rd --->| 0| size| 1 1|<------------- uimm12 ------------>|<-- rs0 -->| -jmp disp; // -128M ~ 128M +rd = rs0 | (uint64_t)uimm12; // SH = 3, IMM ------------------------------------------------------------------------------------------------ -11, jmp, reg, opcode = 11 +8, pop, b[0] opcode = 8 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 0 1 1|<---- rd ---->| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| +| 0 0| 1 0 0 0| 0|<-- rd --->| 0| 1 1| s| 0 0 0 0 0 0 0 0 0 0 0 0 0|<-- rb --->| -jmp *rd; ------------------------------------------------------------------------------------------------- -|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 0 1 1|<----------------------------- simm21:00 -------------------->|<--- cc -->| 1| +rd = *(uint64_t*)rb; // size = 3, s = 0, +rd = *(uint64_t*)rb; // size = 3, s = 1, fpop -jcc simm21:00; // -4M ~ +4M -cc = 0, z, -cc = 1, nz, -cc = 2, ge, -cc = 3, gt, -cc = 4, le, -cc = 5, lt, +rb += 1 << size ------------------------------------------------------------------------------------------------ -12, setcc, &&,||, opcode = 12 +9, push, b[0] opcode = 9 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 0 0|<---- rd ---->| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| 0|<--- cc -->| 0| +| 0 0| 1 0 0 1| 0|<-- rs --->| 0| 1 1| s| 0 0 0 0 0 0 0 0 0 0 0 0 0|<-- rb --->| + +*(uint64_t*)rb = rs; // size = 3, s = 0, +*(uint64_t*)rb = rs; // size = 3, s = 1, fpush -cc = 0, z, -cc = 1, nz, -cc = 2, ge, -cc = 3, gt, -cc = 4, le, -cc = 5, lt, +rb -= 1 << size ------------------------------------------------------------------------------------------------ -13, ldr, b[i << s] opcode = 13 +10, ldr, b[i << s] opcode = 10 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 0 1|<--- rd ----->| SH | s|<-------- uimm8 ------>|<---- ri ---->|<---- rb ---->| +| 0 0| 1 0 1 0| 0|<-- rd --->| 0| size| s| 0|<---- uimm6 ---->| 0 0|<-- ri --->|<-- rb --->| -rd = *(uint8_t* )(rb + (ri << uimm8)); // SH = 0, s = 0, zbq -rd = *(uint16_t*)(rb + (ri << uimm8)); // SH = 1, s = 0, zwq -rd = *(uint32_t*)(rb + (ri << uimm8)); // SH = 2, s = 0, zlq +rd = *(uint8_t* )(rb + (ri << uimm6)); // size = 0, s = 0, zbq +rd = *(uint16_t*)(rb + (ri << uimm6)); // size = 1, s = 0, zwq +rd = *(uint32_t*)(rb + (ri << uimm6)); // size = 2, s = 0, zlq -rd = *(uint64_t*)(rb + (ri << uimm8)); // SH = 3, s = 0, keep +rd = *(uint64_t*)(rb + (ri << uimm6)); // size = 3, s = 0, keep -rd = *( int8_t* )(rb + (ri << uimm8)); // SH = 0, s = 1, sbq -rd = *( int16_t*)(rb + (ri << uimm8)); // SH = 1, s = 1, swq -rd = *( int32_t*)(rb + (ri << uimm8)); // SH = 2, s = 1, slq +rd = *( int8_t* )(rb + (ri << uimm6)); // size = 0, s = 1, sbq +rd = *( int16_t*)(rb + (ri << uimm6)); // size = 1, s = 1, swq +rd = *( int32_t*)(rb + (ri << uimm6)); // size = 2, s = 1, slq ------------------------------------------------------------------------------------------------ -14, str, b[i << s] opcode = 14 +11, str, b[i << s] opcode = 11 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 1 0|<---- rs ---->| SH | s|<-------- uimm8 ------>|<---- ri ---->|<---- rb ---->| +| 0 0| 1 0 1 1| 0|<-- rs --->| 0| size| s| 0|<---- uimm6 ---->| 0 0|<-- ri --->|<-- rb --->| -*(uint8_t* )(rb + (ri << uimm8)) = rs; // SH = 0, s = 0, zbq -*(uint16_t*)(rb + (ri << uimm8)) = rs; // SH = 1, s = 0, zwq -*(uint32_t*)(rb + (ri << uimm8)) = rs; // SH = 2, s = 0, zlq -*(uint64_t*)(rb + (ri << uimm8)) = rs; // SH = 3, s = 0, keep ------------------------------------------------------------------------------------------------- +*(uint8_t* )(rb + (ri << uimm8)) = rs; // size = 0, s = 0, +*(uint16_t*)(rb + (ri << uimm8)) = rs; // size = 1, s = 0, +*(uint32_t*)(rb + (ri << uimm8)) = rs; // size = 2, s = 0, +*(uint64_t*)(rb + (ri << uimm8)) = rs; // size = 3, s = 0, +*(float * )(rb + (ri << uimm8)) = rs; // size = 2, s = 1, +*(double* )(rb + (ri << uimm8)) = rs; // size = 3, s = 1, +------------------------------------------------------------------------------------------------ -15, mov, =, ~, -, opcode = 15 +12, mov, opcode = 12 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 1 1|<--- rd ---->| SH | 0| 0 0| 0 0 0 0 0 0|<--- rs1 ---->|<---- rs0---->| +| 0 0| 1 1 0 0| 0|<-- rd --->| 0| size| SH | 0 0 0 0 0 0| 0 0|<-- rs1 -->|<-- rs --->| rd = rs << rs1; // SH = 0 LSL, rd = rs >> rs1; // SH = 1 LSR, @@ -257,71 +226,52 @@ rd = rs >> rs1; // SH = 2 ASR, ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 1 1|<--- rd ---->| SH | 0| 0 1|<------------- uimm11 --------->|<---- rs ---->| - -rd = rs; // SH = 0 LSL, uimm11 = 0 -rd = rs << uimm11; // SH = 0 LSL, -rd = rs >> uimm11; // SH = 1 LSR, -rd = rs >> uimm11; // SH = 2 ASR, +| 0 0| 1 1 0 0| 0|<-- rd --->| 0| size| SH |<---- uimm6 ---->| 0 0| 1 1 1 1|<-- rs --->| +rd = rs; // SH = 0 LSL, uimm6 = 0 +rd = rs << uimm6; // SH = 0 LSL, +rd = rs >> uimm6; // SH = 1 LSR, +rd = rs >> uimm6; // SH = 2 ASR, ------------------------------------------------------------------------------------------------ -|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 1 1|<--- rd ---->| SH | s| 1 0| 0 0 0 0 0 0 0 0 0 0 0|<---- rs ---->| - -rd = uint8_t(rs); // SH = 0, s = 0, zbq, -rd = uint16_t(rs); // SH = 1, s = 0, zwq, -rd = uint32_t(rs); // SH = 2, s = 0, zlq -rd = int8_t(rs); // SH = 0, s = 1, sbq, -rd = int16_t(rs); // SH = 1, s = 1, swq -rd = int32_t(rs); // SH = 2, s = 1, slq - -rd = ~rs; // SH = 3, s = 0, NOT, -rd = -rs; // SH = 3, s = 1, NEG, +13, movx, opcode = 13 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 1 1|<--- rd ---->| SH | 0| 1 1|<------------------ uimm16 ------------------->| +| 0 0| 1 1 0 1| 0|<-- rd --->| 0| size| s| 0| 0 0 0 0 0 0| 0 0| 0 0 0 0|<-- rs --->| -rd = uint64_t(imm16); // SH = 0, IMM -rd = uint64_t(imm16) << 16; // SH = 1, IMM -rd = uint64_t(imm16) << 32; // SH = 2, IMM -rd = uint64_t(imm16) << 48; // SH = 3, IMM +rd = uint8_t(rs); // size = 0, s = 0, zbq, +rd = uint16_t(rs); // size = 1, s = 0, zwq, +rd = uint32_t(rs); // size = 2, s = 0, zlq ------------------------------------------------------------------------------------------------- -|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 1 1|<--- rd ---->| 0 0| 1| 1 1|<------------------ uimm16 ------------------->| +rd = int8_t(rs); // size = 0, s = 1, sbq, +rd = int16_t(rs); // size = 1, s = 1, swq +rd = int32_t(rs); // size = 2, s = 1, slq -rd = uint64_t(imm16); // NOT ------------------------------------------------------------------------------------------------- - -26, call, disp opcode = 26 +14, not, opcode = 14 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 1 0 1 0|<-------------------------------- simm26:00 -------------------------------->| +| 0 0| 1 1 1 0| 0|<-- rd --->| 0| size| 0 0| 0 0 0 0 0 0| 0 0| 0 0 0 0|<-- rs --->| -call disp; // -128M ~ 128M ------------------------------------------------------------------------------------------------- +rd = -rs; // NEG, -27, call, reg, opcode = 27 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 1 0 1 1|<---- rd ---->| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| +| 0 0| 1 1 1 0| 0|<-- rd --->| 0| size| 0 1| 0 0 0 0 0 0| 0 0| 0 0 0 0|<-- rs --->| -call *rd; ------------------------------------------------------------------------------------------------- +rd = ~rs; // NOT, -42, adrp, reg, opcode = 42 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 1 0 1 0 1 0|<--- rd ---->|<-------------------- simm21 ---------------------------->| +| 0 0| 1 1 1 0| 0|<-- rd --->| 0| size| 1 0|<------------------ uimm16 ------------------->| -rd = RIP + ((int64_t)simm21 << 14); // load address' high 21 bits relative to current RIP, -16G:+16G ------------------------------------------------------------------------------------------------- +rd = uimm16; // size = 0, IMM +rd = uimm16 << 16; // size = 1, IMM +rd = uimm16 << 32; // size = 2, IMM +rd = uimm16 << 48; // size = 3, IMM -56, ret, opcode = 56 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 1 1 1 0 0 0|<-------------------------------- 00 -------------------------------->| +| 0 0| 1 1 1 0| 0|<-- rd --->| 0| size| 1 1|<------------------ uimm16 ------------------->| -ret +rd = ~uimm16; // MVN ------------------------------------------------------------------------------------------------ diff --git a/docs/Naja_sys.txt b/docs/Naja_sys.txt new file mode 100644 index 0000000..fe5a334 --- /dev/null +++ b/docs/Naja_sys.txt @@ -0,0 +1,138 @@ + Naja instructions +------------------------------------------------------------------------------------------------ + opcode format +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| type| S| opcode | 0|<-- rd --->| 0| size| D 0| 0 0 0 0 0 0 0 0 0 0 0 0|<-- rs0 -->| + +type: 0 = integer, 1 = float, 2 = vector, 3 = system +SH : 0 = LSL, 1 = LSR, 2 = ASR, (3 = reserved) + D: 0 = read, 1 = write + S: 0 = user, 1 = kernel + 0: reserved +------------------------------------------------------------------------------------------------ + +48, jmp, disp opcode = 48 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 1| 0 0 0 0|<------------------------------- simm26:00 --------------------------------->| + +jmp disp; // -128M ~ 128M +------------------------------------------------------------------------------------------------ + +49, call, disp opcode = 49 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 1| 0 0 0 1|<------------------------------- simm26:00 --------------------------------->| + +call disp; // -128M ~ 128M +------------------------------------------------------------------------------------------------ + +50, jmp, reg opcode = 50 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 1| 0 0 1 0| 0|<-- rd --->| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| + +jmp *rd; +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 1| 0 0 1 0| 0|<----------------------- simm21:00 ----------------------->|<-- cc --->| 1| + +jcc simm21:00; // -4M ~ +4M +cc = 0, z, +cc = 1, nz, +cc = 2, ge, +cc = 3, gt, +cc = 4, le, +cc = 5, lt, +------------------------------------------------------------------------------------------------ + +51, call, reg opcode = 51 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 1| 0 0 1 1| 0|<-- rd --->| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| + +call *rd; +------------------------------------------------------------------------------------------------ + +52, setcc opcode = 52 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 1| 0 1 0 0| 0|<-- rd --->| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|<-- cc --->| 0| + +cc = 0, z, +cc = 1, nz, +cc = 2, ge, +cc = 3, gt, +cc = 4, le, +cc = 5, lt, +------------------------------------------------------------------------------------------------ + +53, adrp, reg opcode = 53 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 1| 0 1 0 1| 0|<-- rd --->|<-------------------------- simm21 -------------------------->| + +rd = RIP + ((int64_t)simm21 << 12); // load address' high 21 bits relative to current RIP, -4G:+4G +------------------------------------------------------------------------------------------------ + +54, ret, opcode = 54 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 1| 0 1 1 0| 0| 0 0 0 0| 0| 0 0| 0 0| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| + +ret +------------------------------------------------------------------------------------------------ + +56, spop, opcode = 56 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 1| 1 0 0 0| 0|<-- sr --->| 0| 1 1| 0| 0 0 0 0 0 0 0 0 0 0 0 0 0|<-- rb --->| + +// S = 1 +sr = *(uint64_t*)rb; // sr: system register + +rb += 8 +------------------------------------------------------------------------------------------------ + +57, spush, opcode = 57 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 1| 1 0 0 1| 0|<-- sr --->| 0| 1 1| 0| 0 0 0 0 0 0 0 0 0 0 0 0 0|<-- rb --->| + +// S = 1 +*(uint64_t*)rb = sr; // sr: system register + +rb -= 8 +------------------------------------------------------------------------------------------------ + +58, in, disp opcode = 58 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 1| 1 0 1 0| 0|<-- rd --->| 0| size| D 0|<---------------- uimm16 --------------------->| + +// S = 1 +in rd, uimm16 port; // D = 0, +out rs, uimm16 port; // D = 1, +------------------------------------------------------------------------------------------------ + +60, smov, opcode = 60 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 1| 1 1 0 0| 0|<-- rd --->| 0| 0 0| D 0| 0 0 0 0 0 0| 0 0| 0 0 0 0|<-- sr --->| + +// S = 1 +// sr: system register + +smov rd, sr // D = 0, sr --> rd +smov sr, rd // D = 1, rd --> sr +------------------------------------------------------------------------------------------------ + +62, iret, opcode = 62 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 1| 1 1 1 0| 0| 0 0 0 0| 0| 0 0| 0 0| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| + +// S = 1 +iret +------------------------------------------------------------------------------------------------ diff --git a/docs/Naja_vector.txt b/docs/Naja_vector.txt new file mode 100644 index 0000000..dac5f0c --- /dev/null +++ b/docs/Naja_vector.txt @@ -0,0 +1,190 @@ + Naja instructions +------------------------------------------------------------------------------------------------ + integer vector opcode format +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| type| opcode | 0|<-- rd --->| 0| size| s A |<-- rs2 -->| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| + +type: 0 = integer, 1 = float, 2 = vector, 3 = system +size: 0 = 8bits, 1 = 16bits, 2 = 32bits, 3 = 64bits + s: 0 = unsigned, 1 = signed + A: 0 = add, 1 = sub +vlen: 0 = 64bits, 1 = 128bits, 2 = 256bits, 3 = 512bits + 0: reserved +------------------------------------------------------------------------------------------------ + +32, vadd, +, +=, opcode = 32 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 0| 0 0 0 0| 0|<-- rd --->| 0| size| 0 0| 0 0 0 0| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| + +rd[i] = rs0[i] + rs1[i]; // N = vlen / size, i = 0 ~ N - 1 +------------------------------------------------------------------------------------------------ + +33, vsub, -, -=, opcode = 33 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 0| 0 0 0 1| 0|<-- rd --->| 0| size| 0 0| 0 0 0 0| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| + +rd[i] = rs0[i] - rs1[i]; // N = vlen / size, i = 0 ~ N - 1 +------------------------------------------------------------------------------------------------ + +vcmp, >, >=, <, <=, ==, !=, opcode = 33 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 0| 0 0 0 1| 0|<-- rd --->| 0| size| 0 1| 0 0 0 0| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| + +rd[i] = flags(rs0[i] - rs1[i]); // N = vlen / size, i = 0 ~ N - 1 + +flags = 0, z, +flags = 1, nz, +flags = 2, ge, +flags = 3, gt, +flags = 4, le, +flags = 5, lt, +------------------------------------------------------------------------------------------------ + +34, vmul, *, *=, opcode = 34 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 0| 0 0 1 0| 0|<-- rd --->| 0| size| s A|<-- rs2 -->| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| + +s = 0, unsigned mul. +s = 1, signed mul. + +rd[i] = rs2[i] + rs0[i] * rs1[i]; // A = 0, N = vlen / size, i = 0 ~ N - 1 +rd[i] = rs2[i] - rs0[i] * rs1[i]; // A = 1, N = vlen / size, i = 0 ~ N - 1 + +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 0| 0 0 1 0| 0|<-- rd --->| 0| size| s 0| 1 1 1 1| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| + +rd[i] = rs0[i] * rs1[i]; // A = 0, rs2 = 0xf = 15, N = vlen / size, i = 0 ~ N - 1 +------------------------------------------------------------------------------------------------ + +35, vdiv, /, /=, opcode = 35 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 0| 0 0 1 1| 0|<-- rd --->| 0| size| s 0| 0 0 0 0| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| + +s = 0, unsigned div. +s = 1, signed div. + +rd[i] = rs0[i] / rs1[i]; // A = 0, N = vlen / size, i = 0 ~ N - 1 +------------------------------------------------------------------------------------------------ + +20, vldr = fldr, [b + disp] opcode = 20 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1| 0 1 0 0| 0|<-- rd --->| 0| size| 1 A| 0 0 0 0| vlen| 0 0| 0 0 0 0|<-- rb --->| + +rd[i] = rb[i], // V = 1, N = vlen / size, i = 0 ~ N - 1 + +rb += vlen; // A = 1 +------------------------------------------------------------------------------------------------ + +22, vstr = fstr, [b + disp] opcode = 22 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1| 0 1 1 0| 0|<-- rd --->| 0| size| 1 A| 0 0 0 0| vlen| 0 0| 0 0 0 0|<-- rb --->| + +rb[i] = rd[i], // V = 1, N = vlen / size, i = 0 ~ N - 1 + +rb += vlen; // A = 1 +------------------------------------------------------------------------------------------------ + +37, vand, &, &=, opcode = 37 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 0| 0 1 0 1| 0|<-- rd --->| 0| size| 0 0| 0 0 0 0| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| + +rd[i] = rs0[i] & rs1[i]; // N = vlen / size, i = 0 ~ N - 1 +------------------------------------------------------------------------------------------------ + +vteq, >, >=, <, <=, ==, !=, opcode = 37 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 0| 0 1 0 1| 0|<-- rd --->| 0| size| 0 1| 0 0 0 0| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| + +rd[i] = flags(rs0[i] - rs1[i]); // N = vlen / size, i = 0 ~ N - 1 + +flags = 0, z, +flags = 1, nz, +flags = 2, ge, +flags = 3, gt, +flags = 4, le, +flags = 5, lt, +------------------------------------------------------------------------------------------------ + +39, vor, &, &=, opcode = 39 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 0| 0 1 1 1| 0|<-- rd --->| 0| size| 0 0| 0 0 0 0| vlen| 0 0|<-- rs1 -->|<-- rs0 -->| + +rd[i] = rs0[i] | rs1[i]; // N = vlen / size, i = 0 ~ N - 1 +------------------------------------------------------------------------------------------------ + +28, vmov = fmov, opcode = 28 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1| 1 1 0 0| 0|<-- rd --->| 0| size| 1 0| 0 0 0 0| vlen| 0 0| 0 0 0 0|<-- rs --->| + +rd[i] = rs[i]; // V = 1, N = vlen / size, i = 0 ~ N - 1 +------------------------------------------------------------------------------------------------ + +44, vmov, opcode = 44 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 0| 1 1 0 0| 0|<-- rd --->| 0| size| SH | 0 0 0 0| vlen| 0 0|<-- rs1 -->|<-- rs --->| + +rd[i] = rs[i] << rs1[i]; // SH = 0 LSL, +rd[i] = rs[i] >> rs1[i]; // SH = 1 LSR, +rd[i] = rs[i] >> rs1[i]; // SH = 2 ASR, + +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 0| 1 1 0 0| 0|<-- rd --->| 0| size| SH | 1 0 0 0| vlen|<---- uimm6 ---->|<-- rs --->| + +rd[i] = rs[i]; // SH = 0 LSL, uimm6 = 0 +rd[i] = rs[i] << uimm6; // SH = 0 LSL, +rd[i] = rs[i] >> uimm6; // SH = 1 LSR, +rd[i] = rs[i] >> uimm6; // SH = 2 ASR, +------------------------------------------------------------------------------------------------ + +29, vcvt = fcvt, opcode = 29 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1| 1 1 0 1| 0|<-- rd --->| 0|dsize| 1 0| 0 0 Id sd| vlen| 0 0|Is ss|ssize|<-- rs --->| + +rd[i] = fcvt(rs[i]); // V = 1, N = vlen / size, i = 0 ~ N - 1 + +dsize = rd size; +ssize = rs size; +sd = rd sign; +ss = rs sign; +Id = rd int or float; +Is = rs int or float; +------------------------------------------------------------------------------------------------ + +46, vnot, opcode = 46 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 0| 1 1 1 0| 0|<-- rd --->| 0| size| 0 A| 0 0 0 0| vlen| 0 0| 0 0 0 0|<-- rs --->| + +rd[i] = -rs[i]; // NEG, A = 0, N = vlen / size, i = 0 ~ N - 1 +rd[i] = ~rs[i]; // NOT, A = 1, N = vlen / size, i = 0 ~ N - 1 +------------------------------------------------------------------------------------------------ + +47, vmov, uimm16 opcode = 47 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 0| 1 1 1 1| 0|<-- rd --->| 0| size| vlen|<------------------ uimm16 ------------------->| + +rd[i] = uimm16; // N = vlen / size, i = 0 ~ N - 1 + +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 0| 1 1 1 1| 1|<-- rd --->| 0| size| vlen|<------------------ uimm16 ------------------->| + +rd[i] = ~uimm16; // N = vlen / size, i = 0 ~ N - 1 +------------------------------------------------------------------------------------------------ diff --git a/elf/scf_elf_naja.c b/elf/scf_elf_naja.c index a0ccf87..d399243 100644 --- a/elf/scf_elf_naja.c +++ b/elf/scf_elf_naja.c @@ -60,7 +60,7 @@ static int _naja_elf_link_cs(elf_native_t* naja, elf_section_t* s, elf_section_t case R_AARCH64_ADR_PREL_PG_HI21: - offset >>= 14; + offset >>= 12; offset &= 0x1fffff; *(uint32_t*)(s->data + rela->r_offset) |= offset; @@ -68,7 +68,7 @@ static int _naja_elf_link_cs(elf_native_t* naja, elf_section_t* s, elf_section_t case R_AARCH64_ADD_ABS_LO12_NC: - *(uint32_t*)(s->data + rela->r_offset) |= (sym->sym.st_value & 0x3fff) << 5; + *(uint32_t*)(s->data + rela->r_offset) |= (sym->sym.st_value & 0xfff) << 4; break; default: diff --git a/elf/scf_elf_naja_so.c b/elf/scf_elf_naja_so.c index 04d800c..073e962 100644 --- a/elf/scf_elf_naja_so.c +++ b/elf/scf_elf_naja_so.c @@ -1,24 +1,25 @@ #include"scf_elf_naja.h" #include"scf_elf_link.h" -static uint32_t naja_plt_lazy[8] = { - // str x16, lr, [sp, #-16]! - (7 << 26) | (16 << 21) | (3 << 19) | 0x1e, - (7 << 26) | (29 << 21) | (3 << 19) | 0x1e, - (0x2a << 26) | (16 << 21), // adrp x16, 0 - (0 << 26) | (16 << 21) | (3 << 19) | 16, // add x16, x16, #0 - - (4 << 26) | (17 << 21) | (3 << 19) | 16, // ldr x17, [x16, #0] - (0xb << 26) | (17 << 21), // jmp *x17 - (0xf << 26) | (1 << 16), // nop, mov r0, r0 - (0xf << 26) | (1 << 16), // nop, mov r0, r0 +static uint32_t naja_plt_lazy[8] = +{ + (9 << 26) | (10 << 21) | (3 << 18) | 0xe, // push r10 + (9 << 26) | (13 << 21) | (3 << 18) | 0xe, // push lr + (0x35 << 26) | (10 << 21), // adrp r10, 0 + (0 << 26) | (10 << 21) | (3 << 18) | (3 << 16) | 10, // add r10, r10, #0 + + (4 << 26) | (11 << 21) | (3 << 18) | 10, // ldr r11, [r10, #0] + (0x32 << 26) | (11 << 21), // jmp *r11 + (0xc << 26) | (3 << 18) | (0xf << 4), // nop, mov r0, r0 + (0xc << 26) | (3 << 18) | (0xf << 4), // nop, mov r0, r0 }; -static uint32_t naja_plt[4] = { - (0x2a << 26) | (16 << 21), // adrp x16, 0 - (0 << 26) | (16 << 21) | (3 << 19) | 16, // add x16, x16, #0 - (4 << 26) | (17 << 21) | (3 << 19) | 16, // ldr x17, [x16, #0] - (0xb << 26) | (17 << 21), // jmp *x17 +static uint32_t naja_plt[4] = +{ + (0x35 << 26) | (10 << 21), // adrp r10, 0 + (0 << 26) | (10 << 21) | (3 << 18) | (3 << 16) | 10, // add r10, r10, #0 + (4 << 26) | (11 << 21) | (3 << 18) | 10, // ldr r11, [r10, #0] + (0x32 << 26) | (11 << 21), // jmp *r11 }; @@ -693,8 +694,8 @@ int __naja_elf_post_dyn(elf_native_t* naja, uint64_t rx_base, uint64_t rw_base, scf_logi("got_addr: %#lx, plt_addr: %#lx, offset: %d, %#x\n", got_addr, plt_addr, offset, offset); - plt[2] |= (offset >> 14) & 0x1fffff; - plt[3] |= (got_addr & 0x3fff) << 5; + plt[2] |= (offset >> 12) & 0x1fffff; + plt[3] |= (got_addr & 0xfff) << 4; got_addr += 8; plt_addr += sizeof(naja_plt_lazy); @@ -712,8 +713,8 @@ int __naja_elf_post_dyn(elf_native_t* naja, uint64_t rx_base, uint64_t rw_base, scf_logi("i: %d, got_addr: %#lx, plt_addr: %#lx, offset: %d, %#x\n", i, got_addr, plt_addr, offset, offset); - plt[0] |= (offset >> 14) & 0x1fffff; - plt[1] |= (got_addr & 0x3fff) << 5; + plt[0] |= (offset >> 12) & 0x1fffff; + plt[1] |= (got_addr & 0xfff) << 4; plt += sizeof(naja_plt) / sizeof(naja_plt[0]); plt_addr += sizeof(naja_plt); diff --git a/native/risc/scf_naja.c b/native/risc/scf_naja.c index 791519a..ef56dff 100644 --- a/native/risc/scf_naja.c +++ b/native/risc/scf_naja.c @@ -1,5 +1,16 @@ #include"scf_risc.h" +static uint32_t naja_shift(int bytes) +{ + if (bytes <= 1) + return 0; + else if (bytes <= 2) + return 1; + else if (bytes <= 4) + return 2; + return 3; +} + int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes) { scf_instruction_t* inst; @@ -10,13 +21,13 @@ int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes if (0 == (invert >> 32)) { // mvn rd, invert[15:0] - opcode = (0xf << 26) | (rd->id << 21) | (1 << 18) | (0x3 << 16) | (invert & 0xffff); + opcode = (0xe << 26) | (rd->id << 21) | (0x3 << 18) | (0x3 << 16) | (invert & 0xffff); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); if (invert >> 16) { - // movk rd, imm[31:16] - opcode = (0xf << 26) | (rd->id << 21) | (1 << 19) | (0x3 << 16)| ((imm >> 16) & 0xffff); + // movt rd, imm[31:16] + opcode = (0xe << 26) | (rd->id << 21) | (0x1 << 18) | (0x2 << 16)| ((imm >> 16) & 0xffff); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); } @@ -25,15 +36,15 @@ int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes } // mov rd, imm[15:0] - opcode = (0xf << 26) | (rd->id << 21) | (0x3 << 16) | (imm & 0xffff); + opcode = (0xe << 26) | (rd->id << 21) | (0x2 << 16) | (imm & 0xffff); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); imm >>= 16; if (imm & 0xffff) { - // movk rd, imm[31:16] - opcode = (0xf << 26) | (rd->id << 21) | (1 << 19) | (0x3 << 16) | (imm & 0xffff); + // movt rd, imm[31:16] + opcode = (0xe << 26) | (rd->id << 21) | (1 << 18) | (0x2 << 16) | (imm & 0xffff); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); } @@ -42,7 +53,7 @@ int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes if (imm & 0xffff) { // movk rd, imm[47:32] - opcode = (0xf << 26) | (rd->id << 21) | (2 << 19) | (0x3 << 16) | (imm & 0xffff); + opcode = (0xe << 26) | (rd->id << 21) | (2 << 18) | (0x2 << 16) | (imm & 0xffff); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); } @@ -51,7 +62,7 @@ int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes if (imm & 0xffff) { // movk rd, imm[63:48] - opcode = (0xf << 26) | (rd->id << 21) | (3 << 19) | (0x3 << 16) | (imm & 0xffff); + opcode = (0xe << 26) | (rd->id << 21) | (3 << 18) | (0x2 << 16) | (imm & 0xffff); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); } @@ -76,20 +87,20 @@ int naja_inst_ADR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, sc offset = vs->bp_offset; - if (offset >= 0 && offset <= 0x3fff) + if (offset >= 0 && offset <= 0xfff) - opcode = (0 << 26) | (rd->id << 21) | (0x3 << 19) | (offset << 5) | fp->id; + opcode = (0 << 26) | (rd->id << 21) | (0x3 << 18) | (0x3 << 16) | (offset << 4) | fp->id; else if (offset < 0 && -offset <= 0x3fff) - opcode = (1 << 26) | (rd->id << 21) | (0x3 << 19) | ((-offset) << 5) | fp->id; + opcode = (1 << 26) | (rd->id << 21) | (0x3 << 18) | (0x3 << 16) | ((-offset) << 4) | fp->id; else { int ret = naja_inst_I2G(c, rd, offset, 8); if (ret < 0) return ret; - opcode = (0 << 26) | (rd->id << 21) | (rd->id << 5) | fp->id; + opcode = (0 << 26) | (rd->id << 21) | (0x3 << 18) | (rd->id << 4) | fp->id; } inst = risc_make_inst(c, opcode); @@ -98,13 +109,13 @@ int naja_inst_ADR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, sc } else if (vs->global_flag) { offset = 0; - opcode = (0x2a << 26) | (rd->id << 21); + opcode = (0x35 << 26) | (rd->id << 21); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); RISC_RELA_ADD_CHECK(f->data_relas, rela, c, vs, NULL); rela->type = R_AARCH64_ADR_PREL_PG_HI21; - opcode = (0 << 26) | (rd->id << 21) | (0x3 << 19) | rd->id; + opcode = (0 << 26) | (rd->id << 21) | (0x3 << 18) | (0x3 << 16) | rd->id; inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); RISC_RELA_ADD_CHECK(f->data_relas, rela, c, vs, NULL); @@ -194,7 +205,7 @@ int naja_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_ if (offset >= -0xfff && offset <= 0xfff) - opcode = (0x4 << 26) | ((offset & 0x1fff) << 5) | rb->id; + opcode = (0x4 << 26) | ((offset & 0x1fff) << 4) | rb->id; else { int ret = risc_select_free_reg(&ri, c, f, 0); if (ret < 0) { @@ -206,18 +217,18 @@ int naja_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_ if (ret < 0) return ret; - opcode = (0xd << 26) | (SIZE << 10) | (ri->id << 5) | rb->id; + opcode = (0xa << 26) | (SIZE << 18) | (ri->id << 4) | rb->id; } if (rd->bytes > size && scf_variable_signed(vs)) - opcode |= 0x1 << 18; + opcode |= 0x1 << 17; - else if (scf_variable_float(vs) && 4 == size) - opcode |= 0x1 << 18; +// else if (scf_variable_float(vs) && 4 == size) +// opcode |= 0x1 << 18; scf_loge("SIZE: %d, size: %d\n", SIZE, size); - opcode |= (rd->id << 21) | SIZE << 19; + opcode |= (rd->id << 21) | SIZE << 18; opcode |= RISC_COLOR_TYPE(rd->color) << 30; inst = risc_make_inst(c, opcode); @@ -308,7 +319,7 @@ int naja_inst_G2M(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_ scf_loge("offset: %ld, SIZE: %d\n", offset, SIZE); if (offset >= -0xfff && offset <= 0xfff) - opcode = (0x6 << 26) | ((offset & 0x1fff) << 5) | rb->id; + opcode = (0x6 << 26) | ((offset & 0x1fff) << 4) | rb->id; else { int ret = risc_select_free_reg(&ri, c, f, 0); if (ret < 0) { @@ -320,14 +331,14 @@ int naja_inst_G2M(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_ if (ret < 0) return ret; - opcode = (0xe << 26) | (SIZE << 10) | (ri->id << 5) | rb->id; + opcode = (0xb << 26) | (SIZE << 18) | (ri->id << 4) | rb->id; } - opcode |= (rs->id << 21) | SIZE << 19; + opcode |= (rs->id << 21) | SIZE << 18; opcode |= RISC_COLOR_TYPE(rs->color) << 30; - if (scf_variable_float(vs) && 4 == size) - opcode |= (1 << 18); +// if (scf_variable_float(vs) && 4 == size) +// opcode |= (1 << 18); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); @@ -351,13 +362,13 @@ int naja_inst_ISTR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, s uint32_t opcode; - opcode = (0x2a << 26) | (rd->id << 21); + opcode = (0x35 << 26) | (rd->id << 21); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); RISC_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL); rela->type = R_AARCH64_ADR_PREL_PG_HI21; - opcode = (0 << 26) | (rd->id << 21) | (0x3 << 19) | rd->id; + opcode = (0 << 26) | (rd->id << 21) | (0x3 << 18) | (0x3 << 16) | rd->id; inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); RISC_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL); @@ -368,8 +379,8 @@ int naja_inst_ISTR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, s int naja_inst_G2P(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_register_t* rb, int32_t offset, int size) { - scf_register_t* ri = NULL; - scf_instruction_t* inst = NULL; + scf_register_t* ri = NULL; + scf_instruction_t* inst = NULL; uint32_t opcode; uint32_t SIZE = 0; @@ -413,7 +424,7 @@ int naja_inst_G2P(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_ return -EINVAL; if (offset >= -0xfff && offset <= 0xfff) - opcode = (0x6 << 26) | ((offset & 0x1fff) << 5) | rb->id; + opcode = (0x6 << 26) | ((offset & 0x1fff) << 4) | rb->id; else { int ret = risc_select_free_reg(&ri, c, f, 0); if (ret < 0) { @@ -425,10 +436,10 @@ int naja_inst_G2P(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_ if (ret < 0) return ret; - opcode = (0xe << 26) | (SIZE << 10) | (ri->id << 5) | rb->id; + opcode = (0xb << 26) | (SIZE << 18) | (ri->id << 4) | rb->id; } - opcode |= (rs->id << 21) | SIZE << 19; + opcode |= (rs->id << 21) | SIZE << 18; opcode |= RISC_COLOR_TYPE(rs->color) << 30; inst = risc_make_inst(c, opcode); @@ -439,8 +450,8 @@ int naja_inst_G2P(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_ int naja_inst_P2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_register_t* rb, int32_t offset, int size) { - scf_register_t* ri = NULL; - scf_instruction_t* inst = NULL; + scf_register_t* ri = NULL; + scf_instruction_t* inst = NULL; uint32_t opcode; uint32_t SIZE = 0; @@ -484,7 +495,7 @@ int naja_inst_P2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_ return -EINVAL; if (offset >= -0xfff && offset <= 0xfff) - opcode = (0x4 << 26) | ((offset & 0x1fff) << 5) | rb->id; + opcode = (0x4 << 26) | ((offset & 0x1fff) << 4) | rb->id; else { int ret = risc_select_free_reg(&ri, c, f, 0); if (ret < 0) { @@ -496,10 +507,10 @@ int naja_inst_P2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_ if (ret < 0) return ret; - opcode = (0xd << 26) | (SIZE << 10) | (ri->id << 5) | rb->id; + opcode = (0xa << 26) | (SIZE << 18) | (ri->id << 4) | rb->id; } - opcode |= (rd->id << 21) | SIZE << 19; + opcode |= (rd->id << 21) | SIZE << 18; opcode |= RISC_COLOR_TYPE(rd->color) << 30; inst = risc_make_inst(c, opcode); @@ -514,11 +525,11 @@ int naja_inst_ADRP2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, s uint32_t opcode = 0; - if (offset >= 0 && offset <= 0x3fff) - opcode = (0 << 26) | (rd->id << 21) | (3 << 19) | (offset << 5) | rb->id; + if (offset >= 0 && offset <= 0xfff) + opcode = (0 << 26) | (rd->id << 21) | (3 << 18) | (3 << 16) | (offset << 4) | rb->id; - else if (offset < 0 && offset >= -0x3fff) - opcode = (1 << 26) | (rd->id << 21) | (3 << 19) | ((-offset) << 5) | rb->id; + else if (offset < 0 && offset >= -0xfff) + opcode = (1 << 26) | (rd->id << 21) | (3 << 18) | (3 << 16) | ((-offset) << 4) | rb->id; else { int ret = risc_select_free_reg(&r, c, f, 0); @@ -529,7 +540,7 @@ int naja_inst_ADRP2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, s if (ret < 0) return ret; - opcode = (0 << 26) | (rd->id << 21) | (r->id << 5) | rb->id; + opcode = (0 << 26) | (rd->id << 21) | (3 << 18) | (r->id << 4) | rb->id; } inst = risc_make_inst(c, opcode); @@ -539,9 +550,9 @@ int naja_inst_ADRP2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, s int naja_inst_ADRSIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_sib_t* sib) { - scf_register_t* rb = sib->base; - scf_register_t* ri = sib->index; - scf_instruction_t* inst = NULL; + scf_register_t* rb = sib->base; + scf_register_t* ri = sib->index; + scf_instruction_t* inst = NULL; assert(0 == sib->disp); @@ -565,7 +576,7 @@ int naja_inst_ADRSIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, else return -EINVAL; - opcode = (0 << 26) | (rd->id << 21) | (SH << 10) | (ri->id << 5) | rb->id; + opcode = (0 << 26) | (rd->id << 21) | (3 << 18) | (SH << 16) | (ri->id << 4) | rb->id; inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); return 0; @@ -573,9 +584,9 @@ int naja_inst_ADRSIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, int naja_inst_SIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_sib_t* sib) { - scf_register_t* rb = sib->base; - scf_register_t* ri = sib->index; - scf_instruction_t* inst = NULL; + scf_register_t* rb = sib->base; + scf_register_t* ri = sib->index; + scf_instruction_t* inst = NULL; assert(0 == sib->disp); @@ -602,8 +613,8 @@ int naja_inst_SIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, sc else return -EINVAL; - opcode = (0xd << 26) | (rd->id << 21) | (SIZE << 10) | (ri->id << 5) | rb->id; - opcode |= SIZE << 19; + opcode = (0xa << 26) | (rd->id << 21) | (SIZE << 10) | (ri->id << 4) | rb->id; + opcode |= SIZE << 18; opcode |= RISC_COLOR_TYPE(rd->color) << 30; inst = risc_make_inst(c, opcode); @@ -614,9 +625,9 @@ int naja_inst_SIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, sc int naja_inst_G2SIB(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_sib_t* sib) { - scf_register_t* rb = sib->base; - scf_register_t* ri = sib->index; - scf_instruction_t* inst = NULL; + scf_register_t* rb = sib->base; + scf_register_t* ri = sib->index; + scf_instruction_t* inst = NULL; assert(0 == sib->disp); @@ -643,9 +654,9 @@ int naja_inst_G2SIB(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, sc else return -EINVAL; - opcode = (0xe << 26) | (rs->id << 21) | (SIZE << 10) | (ri->id << 5) | rb->id; - opcode |= SIZE << 19; - opcode |= RISC_COLOR_TYPE(rs->color) << 26; + opcode = (0xb << 26) | (rs->id << 21) | (SIZE << 10) | (ri->id << 4) | rb->id; + opcode |= SIZE << 18; + opcode |= RISC_COLOR_TYPE(rs->color) << 16; inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); @@ -663,8 +674,9 @@ scf_instruction_t* naja_inst_PUSH(scf_3ac_code_t* c, scf_register_t* r) scf_instruction_t* inst; uint32_t opcode; - opcode = (0x7 << 26) | (r->id << 21) | (3 << 19) | 0x1e; - inst = risc_make_inst(c, opcode); + opcode = (0x9 << 26) | (r->id << 21) | (3 << 18) | 0xe; + opcode |= RISC_COLOR_TYPE(r->color) << 17; + inst = risc_make_inst(c, opcode); return inst; } @@ -674,8 +686,9 @@ scf_instruction_t* naja_inst_POP(scf_3ac_code_t* c, scf_register_t* r) scf_instruction_t* inst; uint32_t opcode; - opcode = (0x5 << 26) | (r->id << 21) | (3 << 19) | 0x1e; - inst = risc_make_inst(c, opcode); + opcode = (0x8 << 26) | (r->id << 21) | (3 << 18) | 0xe; + opcode |= RISC_COLOR_TYPE(r->color) << 17; + inst = risc_make_inst(c, opcode); return inst; } @@ -685,7 +698,7 @@ scf_instruction_t* naja_inst_RET(scf_3ac_code_t* c) scf_instruction_t* inst; uint32_t opcode; - opcode = 0x38 << 26; + opcode = 0x36 << 26; inst = risc_make_inst(c, opcode); return inst; @@ -696,7 +709,7 @@ scf_instruction_t* naja_inst_MOV_SP(scf_3ac_code_t* c, scf_register_t* rd, scf_r scf_instruction_t* inst; uint32_t opcode; - opcode = (0xf << 26) | (rd->id << 21) | (0x1 << 16) | rs->id; + opcode = (0xc << 26) | (rd->id << 21) | (3 << 18) | (0xf << 4) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -707,7 +720,7 @@ scf_instruction_t* naja_inst_MOV_G(scf_3ac_code_t* c, scf_register_t* rd, scf_re scf_instruction_t* inst; uint32_t opcode; - opcode = (0xf << 26) | (rd->id << 21) | (0x1 << 16) | rs->id; + opcode = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (0xf << 4) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -718,7 +731,7 @@ scf_instruction_t* naja_inst_MVN(scf_3ac_code_t* c, scf_register_t* rd, scf_regi scf_instruction_t* inst; uint32_t opcode; - opcode = (0xf << 26) | (rd->id << 21) | (0x3 << 19) | (0x2 << 16) | rs->id; + opcode = (0xe << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (1 << 16) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -729,7 +742,7 @@ scf_instruction_t* naja_inst_FMOV_G(scf_3ac_code_t* c, scf_register_t* rd, scf_r scf_instruction_t* inst; uint32_t opcode; - opcode = (0x1f << 26) | (rd->id << 21) | (0x3 << 19) | (0x3 << 16) | rs->id; + opcode = (0x1c << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -750,7 +763,7 @@ scf_instruction_t* naja_inst_MOVSX(scf_3ac_code_t* c, scf_register_t* rd, scf_re else return NULL; - opcode = (0xf << 26) | (rd->id << 21) | (SH << 19) | (1 << 18) | (0x2 << 16) | rs->id; + opcode = (0xd << 26) | (rd->id << 21) | (SH << 18) | (1 << 17) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -771,7 +784,7 @@ scf_instruction_t* naja_inst_MOVZX(scf_3ac_code_t* c, scf_register_t* rd, scf_re else return NULL; - opcode = (0xf << 26) | (rd->id << 21) | (SH << 19) | (0x2 << 16)| rs->id; + opcode = (0xd << 26) | (rd->id << 21) | (SH << 18) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -783,7 +796,7 @@ scf_instruction_t* naja_inst_CVTSS2SD(scf_3ac_code_t* c, scf_register_t* rd, scf uint32_t opcode; uint32_t S; - opcode = (0x1f << 26) | (rd->id << 21) | (2 << 19) | rs->id; + opcode = (0x1d << 26) | (rd->id << 21) | (3 << 18) | (1 << 12) | (1 << 6) | (2 << 4) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -794,7 +807,7 @@ scf_instruction_t* naja_inst_CVTSD2SS(scf_3ac_code_t* c, scf_register_t* rd, scf scf_instruction_t* inst; uint32_t opcode; - opcode = (0x1f << 26) | (rd->id << 21) | (3 << 19) | rs->id; + opcode = (0x1d << 26) | (rd->id << 21) | (2 << 18) | (1 << 12) | (1 << 6) | (3 << 4) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -811,7 +824,7 @@ scf_instruction_t* naja_inst_CVTF2SI(scf_3ac_code_t* c, scf_register_t* rd, scf_ else SH = 3; - opcode = (0x1f << 26) | (rd->id << 21) | (SH << 19) | (1 << 18) | (0x1 << 16) | rs->id; + opcode = (0x1d << 26) | (rd->id << 21) | (SH << 18) | (3 << 12) | (1 << 6) | (naja_shift(rs->bytes) << 4) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -828,7 +841,7 @@ scf_instruction_t* naja_inst_CVTF2UI(scf_3ac_code_t* c, scf_register_t* rd, scf_ else SH = 3; - opcode = (0x1f << 26) | (rd->id << 21) | (SH << 19) | (0x1 << 16) | rs->id; + opcode = (0x1d << 26) | (rd->id << 21) | (SH << 18) | (2 << 12) | (1 << 6) | (naja_shift(rs->bytes) << 4) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -845,7 +858,7 @@ scf_instruction_t* naja_inst_CVTSI2F(scf_3ac_code_t* c, scf_register_t* rd, scf_ else SH = 3; - opcode = (0x1f << 26) | (rd->id << 21) | (SH << 19) | (1 << 18) | (0x2 << 16) | rs->id; + opcode = (0x1d << 26) | (rd->id << 21) | (SH << 18) | (1 << 12) | (3 << 6) | (naja_shift(rs->bytes) << 4) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -862,7 +875,7 @@ scf_instruction_t* naja_inst_CVTUI2F(scf_3ac_code_t* c, scf_register_t* rd, scf_ else SH = 3; - opcode = (0x1f << 26) | (rd->id << 21) | (SH << 19) | (0x2 << 16) | rs->id; + opcode = (0x1d << 26) | (rd->id << 21) | (SH << 18) | (1 << 12) | (2 << 6) | (naja_shift(rs->bytes) << 4) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -873,12 +886,12 @@ scf_instruction_t* naja_inst_SUB_IMM(scf_3ac_code_t* c, scf_function_t* f, scf_r scf_instruction_t* inst; uint32_t opcode; - if (imm > 0x3fff) { + if (imm > 0xfff) { scf_loge("NOT support too big imm: %#lx\n", imm); return NULL; } - opcode = (1 << 26) | (rd->id << 21) | (3 << 19) | (imm << 5) | rs->id; + opcode = (1 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (3 << 16) | (imm << 4) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -889,12 +902,12 @@ scf_instruction_t* naja_inst_CMP_IMM(scf_3ac_code_t* c, scf_function_t* f, scf_r scf_instruction_t* inst; uint32_t opcode; - if (imm > 0x3fff) { + if (imm > 0xfff) { scf_loge("NOT support too big imm: %#lx\n", imm); return NULL; } - opcode = (1 << 26) | (0x1f << 21) | (3 << 19) | (imm << 5) | rs->id; + opcode = (1 << 26) | (0xf << 21) | (naja_shift(rs->bytes) << 18) | (3 << 16) | (imm << 4) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -905,12 +918,12 @@ scf_instruction_t* naja_inst_ADD_IMM(scf_3ac_code_t* c, scf_function_t* f, scf_r scf_instruction_t* inst; uint32_t opcode; - if (imm > 0x3fff) { + if (imm > 0xfff) { scf_loge("NOT support too big imm: %#lx\n", imm); return NULL; } - opcode = (0 << 26) | (rd->id << 21) | (3 << 19) | (imm << 5) | rs->id; + opcode = (0 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (3 << 16) | (imm << 4) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -921,7 +934,7 @@ scf_instruction_t* naja_inst_ADD_G(scf_3ac_code_t* c, scf_register_t* rd, scf_re scf_instruction_t* inst; uint32_t opcode; - opcode = (0 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id; + opcode = (0 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -932,7 +945,7 @@ scf_instruction_t* naja_inst_SHL(scf_3ac_code_t* c, scf_register_t* rd, scf_regi scf_instruction_t* inst; uint32_t opcode; - opcode = (0xf << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id; + opcode = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -943,7 +956,7 @@ scf_instruction_t* naja_inst_SHR(scf_3ac_code_t* c, scf_register_t* rd, scf_regi scf_instruction_t* inst; uint32_t opcode; - opcode = (0xf << 26) | (rd->id << 21) | (1 << 19) | (rs1->id << 5) | rs0->id; + opcode = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (1 << 16) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -954,7 +967,7 @@ scf_instruction_t* naja_inst_ASR(scf_3ac_code_t* c, scf_register_t* rd, scf_regi scf_instruction_t* inst; uint32_t opcode; - opcode = (0xf << 26) | (rd->id << 21) | (2 << 19) | (rs1->id << 5) | rs0->id; + opcode = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (2 << 16) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -965,7 +978,7 @@ scf_instruction_t* naja_inst_AND_G(scf_3ac_code_t* c, scf_register_t* rd, scf_re scf_instruction_t* inst; uint32_t opcode; - opcode = (0x8 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id; + opcode = (0x5 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -976,7 +989,7 @@ scf_instruction_t* naja_inst_OR_G(scf_3ac_code_t* c, scf_register_t* rd, scf_reg scf_instruction_t* inst; uint32_t opcode; - opcode = (0x9 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id; + opcode = (0x7 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -987,7 +1000,7 @@ scf_instruction_t* naja_inst_SUB_G(scf_3ac_code_t* c, scf_register_t* rd, scf_re scf_instruction_t* inst; uint32_t opcode; - opcode = (0x1 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id; + opcode = (1 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -998,7 +1011,7 @@ scf_instruction_t* naja_inst_CMP_G(scf_3ac_code_t* c, scf_register_t* rs0, scf_r scf_instruction_t* inst; uint32_t opcode; - opcode = (0x1 << 26) | (0x1f << 21) | (rs1->id << 5) | rs0->id; + opcode = (1 << 26) | (0xf << 21) | (naja_shift(rs0->bytes) << 18) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1009,7 +1022,7 @@ scf_instruction_t* naja_inst_FCMP(scf_3ac_code_t* c, scf_register_t* rs0, scf_re scf_instruction_t* inst; uint32_t opcode; - opcode = (0x11 << 26) | (0x1f << 21) | (rs1->id << 5) | rs0->id; + opcode = (0x11 << 26) | (0xf << 21) | (naja_shift(rs0->bytes) << 18) | (1 << 16) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1020,7 +1033,7 @@ scf_instruction_t* naja_inst_NEG(scf_3ac_code_t* c, scf_register_t* rd, scf_regi scf_instruction_t* inst; uint32_t opcode; - opcode = (0xf << 26) | (rd->id << 21) | (0x7 << 18) | (0x2 << 16) | rs->id; + opcode = (0xe << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -1031,7 +1044,7 @@ scf_instruction_t* naja_inst_TEQ(scf_3ac_code_t* c, scf_register_t* rs) scf_instruction_t* inst; uint32_t opcode; - opcode = (0x8 << 26) | (0x1f << 21) | (rs->id << 5) | rs->id; + opcode = (0x5 << 26) | (0xf << 21) | (naja_shift(rs->bytes) << 18) | (rs->id << 4) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -1042,7 +1055,7 @@ scf_instruction_t* naja_inst_FADD(scf_3ac_code_t* c, scf_register_t* rd, scf_reg scf_instruction_t* inst; uint32_t opcode; - opcode = (0x10 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id; + opcode = (0x10 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1053,7 +1066,7 @@ scf_instruction_t* naja_inst_FSUB(scf_3ac_code_t* c, scf_register_t* rd, scf_reg scf_instruction_t* inst; uint32_t opcode; - opcode = (0x11 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id; + opcode = (0x11 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1064,7 +1077,7 @@ scf_instruction_t* naja_inst_MUL(scf_3ac_code_t* c, scf_register_t* rd, scf_regi scf_instruction_t* inst; uint32_t opcode; - opcode = (0x2 << 26) | (rd->id << 21) | (2 << 19) | (rs1->id << 5) | rs0->id; + opcode = (2 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (0xf << 12) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1075,7 +1088,7 @@ scf_instruction_t* naja_inst_FMUL(scf_3ac_code_t* c, scf_register_t* rd, scf_reg scf_instruction_t* inst; uint32_t opcode; - opcode = (0x12 << 26) | (rd->id << 21) | (2 << 19) | (1 << 18) | (rs1->id << 5) | rs0->id; + opcode = (0x12 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (0xf << 12) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1086,7 +1099,7 @@ scf_instruction_t* naja_inst_FDIV(scf_3ac_code_t* c, scf_register_t* rd, scf_reg scf_instruction_t* inst; uint32_t opcode; - opcode = (0x13 << 26) | (rd->id << 21) | (2 << 19) | (1 << 18) | (rs1->id << 5) | rs0->id; + opcode = (0x13 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1097,7 +1110,7 @@ scf_instruction_t* naja_inst_DIV(scf_3ac_code_t* c, scf_register_t* rd, scf_regi scf_instruction_t* inst; uint32_t opcode; - opcode = (0x3 << 26) | (rd->id << 21) | (2 << 19) | (rs1->id << 5) | rs0->id; + opcode = (3 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1108,7 +1121,7 @@ scf_instruction_t* naja_inst_SDIV(scf_3ac_code_t* c, scf_register_t* rd, scf_reg scf_instruction_t* inst; uint32_t opcode; - opcode = (0x3 << 26) | (rd->id << 21) | (2 << 19) | (1 << 18) | (rs1->id << 5) | rs0->id; + opcode = (3 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (1 << 17) | (rs1->id << 4) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1119,7 +1132,7 @@ scf_instruction_t* naja_inst_MSUB(scf_3ac_code_t* c, scf_register_t* rd, scf_reg scf_instruction_t* inst; uint32_t opcode; - opcode = (0x2 << 26) | (rd->id << 21) | (1 << 19) | (1 << 18) | (ra->id << 10) | (rm->id << 5) | rn->id; + opcode = (2 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (1 << 16) | (ra->id << 12) | (rm->id << 4) | rn->id; inst = risc_make_inst(c, opcode); return inst; @@ -1131,7 +1144,7 @@ int naja_inst_BL(scf_3ac_code_t* c, scf_function_t* f, scf_function_t* pf) scf_rela_t* rela; uint32_t opcode; - opcode = (0x1a << 26); + opcode = (0x31 << 26); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); @@ -1146,7 +1159,7 @@ scf_instruction_t* naja_inst_BLR(scf_3ac_code_t* c, scf_register_t* r) scf_instruction_t* inst; uint32_t opcode; - opcode = (0x1b << 26) | (r->id << 21); + opcode = (0x33 << 26) | (r->id << 21); inst = risc_make_inst(c, opcode); return inst; @@ -1158,7 +1171,7 @@ scf_instruction_t* naja_inst_SETZ(scf_3ac_code_t* c, scf_register_t* rd) uint32_t opcode; uint32_t cc = 1; - opcode = (0xc << 26) | (rd->id << 21); + opcode = (0x34 << 26) | (rd->id << 21); inst = risc_make_inst(c, opcode); return inst; @@ -1169,7 +1182,7 @@ scf_instruction_t* naja_inst_SETNZ(scf_3ac_code_t* c, scf_register_t* rd) uint32_t opcode; uint32_t cc = 0; - opcode = (0xc << 26) | (rd->id << 21) | (1 << 1); + opcode = (0x34 << 26) | (rd->id << 21) | (1 << 1); inst = risc_make_inst(c, opcode); return inst; @@ -1179,7 +1192,7 @@ scf_instruction_t* naja_inst_SETGT(scf_3ac_code_t* c, scf_register_t* rd) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xc << 26) | (rd->id << 21) | (3 << 1); + opcode = (0x34 << 26) | (rd->id << 21) | (3 << 1); inst = risc_make_inst(c, opcode); return inst; @@ -1189,7 +1202,7 @@ scf_instruction_t* naja_inst_SETGE(scf_3ac_code_t* c, scf_register_t* rd) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xc << 26) | (rd->id << 21) | (2 << 1); + opcode = (0x34 << 26) | (rd->id << 21) | (2 << 1); inst = risc_make_inst(c, opcode); return inst; @@ -1199,7 +1212,7 @@ scf_instruction_t* naja_inst_SETLT(scf_3ac_code_t* c, scf_register_t* rd) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xb << 26) | (rd->id << 21) | (5 << 1); + opcode = (0x34 << 26) | (rd->id << 21) | (5 << 1); inst = risc_make_inst(c, opcode); return inst; @@ -1209,7 +1222,7 @@ scf_instruction_t* naja_inst_SETLE(scf_3ac_code_t* c, scf_register_t* rd) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xb << 26) | (rd->id << 21) | (4 << 1); + opcode = (0x34 << 26) | (rd->id << 21) | (4 << 1); inst = risc_make_inst(c, opcode); return inst; @@ -1220,7 +1233,7 @@ scf_instruction_t* naja_inst_JMP(scf_3ac_code_t* c) scf_instruction_t* inst; uint32_t opcode; - opcode = 0xa << 26; + opcode = 0x30 << 26; inst = risc_make_inst(c, opcode); return inst; @@ -1231,7 +1244,7 @@ scf_instruction_t* naja_inst_JZ(scf_3ac_code_t* c) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xb << 26) | 1; + opcode = (0x32 << 26) | 1; inst = risc_make_inst(c, opcode); return inst; @@ -1242,7 +1255,7 @@ scf_instruction_t* naja_inst_JNZ(scf_3ac_code_t* c) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xb << 26) | (1 << 1) | 1; + opcode = (0x32 << 26) | (1 << 1) | 1; inst = risc_make_inst(c, opcode); return inst; @@ -1253,7 +1266,7 @@ scf_instruction_t* naja_inst_JGT(scf_3ac_code_t* c) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xb << 26) | (3 << 1) | 1; + opcode = (0x32 << 26) | (3 << 1) | 1; inst = risc_make_inst(c, opcode); return inst; @@ -1264,7 +1277,7 @@ scf_instruction_t* naja_inst_JGE(scf_3ac_code_t* c) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xb << 26) | (2 << 1) | 1; + opcode = (0x32 << 26) | (2 << 1) | 1; inst = risc_make_inst(c, opcode); return inst; @@ -1275,7 +1288,7 @@ scf_instruction_t* naja_inst_JLT(scf_3ac_code_t* c) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xb << 26) | (5 << 1) | 1; + opcode = (0x32 << 26) | (5 << 1) | 1; inst = risc_make_inst(c, opcode); return inst; @@ -1286,7 +1299,7 @@ scf_instruction_t* naja_inst_JLE(scf_3ac_code_t* c) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xb << 26) | (4 << 1) | 1; + opcode = (0x32 << 26) | (4 << 1) | 1; inst = risc_make_inst(c, opcode); return inst; @@ -1318,7 +1331,7 @@ void naja_set_jmp_offset(scf_instruction_t* inst, int32_t bytes) opcode |= inst->code[2] << 16; opcode |= inst->code[3] << 24; - if (0xb == (opcode >> 26) && 1 == (opcode & 1)) { + if (0x32 == (opcode >> 26) && 1 == (opcode & 1)) { if (bytes >= 0 && bytes < (0x1 << 20)) { bytes >>= 2; @@ -1338,7 +1351,7 @@ void naja_set_jmp_offset(scf_instruction_t* inst, int32_t bytes) inst->code[3] |= 0x3 & (bytes >> 24); } else { - assert(0xa == (opcode >> 26)); + assert(0x30 == (opcode >> 26)); bytes >>= 2; @@ -1354,8 +1367,8 @@ void naja_set_jmp_offset(scf_instruction_t* inst, int32_t bytes) int naja_cmp_update(scf_3ac_code_t* c, scf_function_t* f, scf_instruction_t* cmp) { scf_instruction_t* inst; - scf_register_t* r16 = f->rops->find_register_type_id_bytes(0, 16, 8); - scf_register_t* r17 = f->rops->find_register_type_id_bytes(0, 17, 8); + scf_register_t* r10 = f->rops->find_register_type_id_bytes(0, 10, 8); + scf_register_t* r11 = f->rops->find_register_type_id_bytes(0, 11, 8); scf_register_t* r0; uint32_t opcode; @@ -1371,34 +1384,34 @@ int naja_cmp_update(scf_3ac_code_t* c, scf_function_t* f, scf_instruction_t* cmp switch (opcode >> 21) { - case 0x3f: - SH = (opcode >> 19) & 0x3; + case 0x2f: + SH = (opcode >> 16) & 0x3; if (0x3 == SH) { - i0 = opcode & 0x1f; + i0 = opcode & 0xf; r0 = f->rops->find_register_type_id_bytes(0, i0, 8); - inst = f->iops->MOV_G(c, r16, r0); // use r16 to backup r0 + inst = f->iops->MOV_G(c, r10, r0); // use r10 to backup r0 RISC_INST_ADD_CHECK(c->instructions, inst); - opcode &= ~0x1f; - opcode |= 0x10; + opcode &= ~0xf; + opcode |= 0xa; } else { - i0 = opcode & 0x1f; - i1 = (opcode >> 5) & 0x1f; + i0 = opcode & 0xf; + i1 = (opcode >> 4) & 0xf; r0 = f->rops->find_register_type_id_bytes(0, i0, 8); - inst = f->iops->MOV_G(c, r16, r0); // use r16 to backup r0 + inst = f->iops->MOV_G(c, r10, r0); // use r10 to backup r0 RISC_INST_ADD_CHECK(c->instructions, inst); r0 = f->rops->find_register_type_id_bytes(0, i1, 8); - inst = f->iops->MOV_G(c, r17, r0); // use r17 to backup r1 + inst = f->iops->MOV_G(c, r11, r0); // use r11 to backup r1 RISC_INST_ADD_CHECK(c->instructions, inst); - opcode &= ~0x1f; - opcode |= 0x10; + opcode &= ~0xf; + opcode |= 0xa; - opcode &= ~(0x1f << 5); - opcode |= (0x11 << 5); + opcode &= ~(0xf << 4); + opcode |= (0xb << 4); } break; default: diff --git a/native/risc/scf_risc_inst.c b/native/risc/scf_risc_inst.c index 221af0e..2d64b8d 100644 --- a/native/risc/scf_risc_inst.c +++ b/native/risc/scf_risc_inst.c @@ -442,6 +442,9 @@ static int _risc_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) scf_register_t* sp = f->rops->find_register("sp"); scf_register_t* x0 = f->rops->find_register("x0"); + if (!x0) + x0 = f->rops->find_register("r0"); + lr->used = 1; sp->used = 1; diff --git a/native/risc/scf_risc_reg.h b/native/risc/scf_risc_reg.h index 4a43cc7..abc0d7c 100644 --- a/native/risc/scf_risc_reg.h +++ b/native/risc/scf_risc_reg.h @@ -56,4 +56,3 @@ int risc_array_index_reg(scf_sib_t* sib, scf_dag_node_t* base, s void risc_call_rabi(int* p_nints, int* p_nfloats, scf_3ac_code_t* c, scf_function_t* f); #endif - diff --git a/native/risc/scf_risc_reg_naja.c b/native/risc/scf_risc_reg_naja.c index bd3c8ac..9b6ff13 100644 --- a/native/risc/scf_risc_reg_naja.c +++ b/native/risc/scf_risc_reg_naja.c @@ -1,237 +1,166 @@ #include"scf_risc.h" -#define SCF_RISC_REG_FP 28 -#define SCF_RISC_REG_LR 29 -#define SCF_RISC_REG_SP 30 -#define SCF_RISC_REG_NULL 31 - -scf_register_t naja_registers[] = { - - {0, 4, "w0", RISC_COLOR(0, 0, 0xf), NULL, 0, 0}, - {0, 8, "x0", RISC_COLOR(0, 0, 0xff), NULL, 0, 0}, - - {1, 4, "w1", RISC_COLOR(0, 1, 0xf), NULL, 0, 0}, - {1, 8, "x1", RISC_COLOR(0, 1, 0xff), NULL, 0, 0}, - - {2, 4, "w2", RISC_COLOR(0, 2, 0xf), NULL, 0, 0}, - {2, 8, "x2", RISC_COLOR(0, 2, 0xff), NULL, 0, 0}, - - {3, 4, "w3", RISC_COLOR(0, 3, 0xf), NULL, 0, 0}, - {3, 8, "x3", RISC_COLOR(0, 3, 0xff), NULL, 0, 0}, - - {4, 4, "w4", RISC_COLOR(0, 4, 0xf), NULL, 0, 0}, - {4, 8, "x4", RISC_COLOR(0, 4, 0xff), NULL, 0, 0}, - - {5, 4, "w5", RISC_COLOR(0, 5, 0xf), NULL, 0, 0}, - {5, 8, "x5", RISC_COLOR(0, 5, 0xff), NULL, 0, 0}, - - {6, 4, "w6", RISC_COLOR(0, 6, 0xf), NULL, 0, 0}, - {6, 8, "x6", RISC_COLOR(0, 6, 0xff), NULL, 0, 0}, - - {7, 4, "w7", RISC_COLOR(0, 7, 0xf), NULL, 0, 0}, - {7, 8, "x7", RISC_COLOR(0, 7, 0xff), NULL, 0, 0}, - -// not use x8 - -// {8, 4, "w8", RISC_COLOR(0, 8, 0xf), NULL, 0}, -// {8, 8, "x8", RISC_COLOR(0, 8, 0xff), NULL, 0}, - - {9, 4, "w9", RISC_COLOR(0, 9, 0xf), NULL, 0, 0}, - {9, 8, "x9", RISC_COLOR(0, 9, 0xff), NULL, 0, 0}, - - {10, 4, "w10", RISC_COLOR(0, 10, 0xf), NULL, 0, 0}, - {10, 8, "x10", RISC_COLOR(0, 10, 0xff), NULL, 0, 0}, - - {11, 4, "w11", RISC_COLOR(0, 11, 0xf), NULL, 0, 0}, - {11, 8, "x11", RISC_COLOR(0, 11, 0xff), NULL, 0, 0}, - - {12, 4, "w12", RISC_COLOR(0, 12, 0xf), NULL, 0, 0}, - {12, 8, "x12", RISC_COLOR(0, 12, 0xff), NULL, 0, 0}, - - {13, 4, "w13", RISC_COLOR(0, 13, 0xf), NULL, 0, 0}, - {13, 8, "x13", RISC_COLOR(0, 13, 0xff), NULL, 0, 0}, - - {14, 4, "w14", RISC_COLOR(0, 14, 0xf), NULL, 0, 0}, - {14, 8, "x14", RISC_COLOR(0, 14, 0xff), NULL, 0, 0}, - - {15, 4, "w15", RISC_COLOR(0, 15, 0xf), NULL, 0, 0}, - {15, 8, "x15", RISC_COLOR(0, 15, 0xff), NULL, 0, 0}, - -// not use x16, x17, x18 - - {16, 4, "w16", RISC_COLOR(0, 16, 0xf), NULL, 0, 0}, - {16, 8, "x16", RISC_COLOR(0, 16, 0xff), NULL, 0, 0}, - - {17, 4, "w17", RISC_COLOR(0, 17, 0xf), NULL, 0, 0}, - {17, 8, "x17", RISC_COLOR(0, 17, 0xff), NULL, 0, 0}, - -// {18, 4, "w18", RISC_COLOR(0, 18, 0xf), NULL, 0, 0}, -// {18, 8, "x18", RISC_COLOR(0, 18, 0xff), NULL, 0, 0}, - - {19, 4, "w19", RISC_COLOR(0, 19, 0xf), NULL, 0, 0}, - {19, 8, "x19", RISC_COLOR(0, 19, 0xff), NULL, 0, 0}, - - {20, 4, "w20", RISC_COLOR(0, 20, 0xf), NULL, 0, 0}, - {20, 8, "x20", RISC_COLOR(0, 20, 0xff), NULL, 0, 0}, - - {21, 4, "w21", RISC_COLOR(0, 21, 0xf), NULL, 0, 0}, - {21, 8, "x21", RISC_COLOR(0, 21, 0xff), NULL, 0, 0}, - - {22, 4, "w22", RISC_COLOR(0, 22, 0xf), NULL, 0, 0}, - {22, 8, "x22", RISC_COLOR(0, 22, 0xff), NULL, 0, 0}, - - {23, 4, "w23", RISC_COLOR(0, 23, 0xf), NULL, 0, 0}, - {23, 8, "x23", RISC_COLOR(0, 23, 0xff), NULL, 0, 0}, - - {24, 4, "w24", RISC_COLOR(0, 24, 0xf), NULL, 0, 0}, - {24, 8, "x24", RISC_COLOR(0, 24, 0xff), NULL, 0, 0}, - - {25, 4, "w25", RISC_COLOR(0, 25, 0xf), NULL, 0, 0}, - {25, 8, "x25", RISC_COLOR(0, 25, 0xff), NULL, 0, 0}, - - {26, 4, "w26", RISC_COLOR(0, 26, 0xf), NULL, 0, 0}, - {26, 8, "x26", RISC_COLOR(0, 26, 0xff), NULL, 0, 0}, - - {27, 4, "w27", RISC_COLOR(0, 27, 0xf), NULL, 0, 0}, - {27, 8, "x27", RISC_COLOR(0, 27, 0xff), NULL, 0, 0}, - -// fp = x28 = bp - {28, 4, "w28", RISC_COLOR(0, 28, 0xf), NULL, 0, 0}, - {28, 8, "fp", RISC_COLOR(0, 28, 0xff), NULL, 0, 0}, -// lr = x29 - {29, 4, "w29", RISC_COLOR(0, 29, 0xf), NULL, 0, 0}, - {29, 8, "lr", RISC_COLOR(0, 29, 0xff), NULL, 0, 0}, - {30, 8, "sp", RISC_COLOR(0, 30, 0xff), NULL, 0, 0}, -// {31, 8, "null", RISC_COLOR(0, 31, 0xff), NULL, 0, 0}, - +#define SCF_RISC_REG_FP 12 +#define SCF_RISC_REG_LR 13 +#define SCF_RISC_REG_SP 14 +#define SCF_RISC_REG_NULL 15 +scf_register_t naja_registers[] = +{ + {0, 1, "r0b", RISC_COLOR(0, 0, 0x1), NULL, 0, 0}, + {0, 2, "r0w", RISC_COLOR(0, 0, 0x3), NULL, 0, 0}, + {0, 4, "r0d", RISC_COLOR(0, 0, 0xf), NULL, 0, 0}, + {0, 8, "r0", RISC_COLOR(0, 0, 0xff), NULL, 0, 0}, + + {1, 1, "r1b", RISC_COLOR(0, 1, 0x1), NULL, 0, 0}, + {1, 2, "r1w", RISC_COLOR(0, 1, 0x3), NULL, 0, 0}, + {1, 4, "r1d", RISC_COLOR(0, 1, 0xf), NULL, 0, 0}, + {1, 8, "r1", RISC_COLOR(0, 1, 0xff), NULL, 0, 0}, + + {2, 1, "r2b", RISC_COLOR(0, 2, 0x1), NULL, 0, 0}, + {2, 2, "r2w", RISC_COLOR(0, 2, 0x3), NULL, 0, 0}, + {2, 4, "r2d", RISC_COLOR(0, 2, 0xf), NULL, 0, 0}, + {2, 8, "r2", RISC_COLOR(0, 2, 0xff), NULL, 0, 0}, + + {3, 1, "r3b", RISC_COLOR(0, 3, 0x1), NULL, 0, 0}, + {3, 2, "r3w", RISC_COLOR(0, 3, 0x3), NULL, 0, 0}, + {3, 4, "r3d", RISC_COLOR(0, 3, 0xf), NULL, 0, 0}, + {3, 8, "r3", RISC_COLOR(0, 3, 0xff), NULL, 0, 0}, + + {4, 1, "r4b", RISC_COLOR(0, 4, 0x1), NULL, 0, 0}, + {4, 2, "r4w", RISC_COLOR(0, 4, 0x3), NULL, 0, 0}, + {4, 4, "r4d", RISC_COLOR(0, 4, 0xf), NULL, 0, 0}, + {4, 8, "r4", RISC_COLOR(0, 4, 0xff), NULL, 0, 0}, + + {5, 1, "r5b", RISC_COLOR(0, 5, 0x1), NULL, 0, 0}, + {5, 2, "r5w", RISC_COLOR(0, 5, 0x3), NULL, 0, 0}, + {5, 4, "r5d", RISC_COLOR(0, 5, 0xf), NULL, 0, 0}, + {5, 8, "r5", RISC_COLOR(0, 5, 0xff), NULL, 0, 0}, + + {6, 1, "r6b", RISC_COLOR(0, 6, 0x1), NULL, 0, 0}, + {6, 2, "r6w", RISC_COLOR(0, 6, 0x3), NULL, 0, 0}, + {6, 4, "r6d", RISC_COLOR(0, 6, 0xf), NULL, 0, 0}, + {6, 8, "r6", RISC_COLOR(0, 6, 0xff), NULL, 0, 0}, + + {7, 1, "r7b", RISC_COLOR(0, 7, 0x1), NULL, 0, 0}, + {7, 2, "r7w", RISC_COLOR(0, 7, 0x3), NULL, 0, 0}, + {7, 4, "r7d", RISC_COLOR(0, 7, 0xf), NULL, 0, 0}, + {7, 8, "r7", RISC_COLOR(0, 7, 0xff), NULL, 0, 0}, + + {8, 1, "r8b", RISC_COLOR(0, 8, 0x1), NULL, 0, 0}, + {8, 2, "r8w", RISC_COLOR(0, 8, 0x3), NULL, 0, 0}, + {8, 4, "r8d", RISC_COLOR(0, 8, 0xf), NULL, 0, 0}, + {8, 8, "r8", RISC_COLOR(0, 8, 0xff), NULL, 0, 0}, + + {9, 1, "r9b", RISC_COLOR(0, 9, 0x1), NULL, 0, 0}, + {9, 2, "r9w", RISC_COLOR(0, 9, 0x3), NULL, 0, 0}, + {9, 4, "r9d", RISC_COLOR(0, 9, 0xf), NULL, 0, 0}, + {9, 8, "r9", RISC_COLOR(0, 9, 0xff), NULL, 0, 0}, + +// not use r10, r11 + {10, 1, "r10b", RISC_COLOR(0, 10, 0x1), NULL, 0, 0}, + {10, 2, "r10w", RISC_COLOR(0, 10, 0x3), NULL, 0, 0}, + {10, 4, "r10d", RISC_COLOR(0, 10, 0xf), NULL, 0, 0}, + {10, 8, "r10", RISC_COLOR(0, 10, 0xff), NULL, 0, 0}, + + {11, 1, "r11b", RISC_COLOR(0, 11, 0x1), NULL, 0, 0}, + {11, 2, "r11w", RISC_COLOR(0, 11, 0x3), NULL, 0, 0}, + {11, 4, "r11d", RISC_COLOR(0, 11, 0xf), NULL, 0, 0}, + {11, 8, "r11", RISC_COLOR(0, 11, 0xff), NULL, 0, 0}, + + {12, 1, "r12b", RISC_COLOR(0, 12, 0x1), NULL, 0, 0}, + {12, 2, "r12w", RISC_COLOR(0, 12, 0x3), NULL, 0, 0}, + {12, 4, "r12d", RISC_COLOR(0, 12, 0xf), NULL, 0, 0}, + {12, 8, "fp", RISC_COLOR(0, 12, 0xff), NULL, 0, 0}, + + {13, 1, "r13b", RISC_COLOR(0, 13, 0x1), NULL, 0, 0}, + {13, 2, "r13w", RISC_COLOR(0, 13, 0x3), NULL, 0, 0}, + {13, 4, "r13d", RISC_COLOR(0, 13, 0xf), NULL, 0, 0}, + {13, 8, "lr", RISC_COLOR(0, 13, 0xff), NULL, 0, 0}, + + {14, 8, "sp", RISC_COLOR(0, 14, 0xff), NULL, 0, 0}, +// {15, 8, "null", RISC_COLOR(0, 15, 0xff), NULL, 0, 0}, + + + {0, 1, "b0", RISC_COLOR(1, 0, 0x1), NULL, 0, 0}, {0, 2, "h0", RISC_COLOR(1, 0, 0x3), NULL, 0, 0}, {0, 4, "s0", RISC_COLOR(1, 0, 0xf), NULL, 0, 0}, {0, 8, "d0", RISC_COLOR(1, 0, 0xff), NULL, 0, 0}, + {1, 1, "b1", RISC_COLOR(1, 1, 0x1), NULL, 0, 0}, {1, 2, "h1", RISC_COLOR(1, 1, 0x3), NULL, 0, 0}, {1, 4, "s1", RISC_COLOR(1, 1, 0xf), NULL, 0, 0}, {1, 8, "d1", RISC_COLOR(1, 1, 0xff), NULL, 0, 0}, + {2, 1, "b2", RISC_COLOR(1, 2, 0x1), NULL, 0, 0}, {2, 2, "h2", RISC_COLOR(1, 2, 0x3), NULL, 0, 0}, {2, 4, "s2", RISC_COLOR(1, 2, 0xf), NULL, 0, 0}, {2, 8, "d2", RISC_COLOR(1, 2, 0xff), NULL, 0, 0}, + {3, 1, "b3", RISC_COLOR(1, 3, 0x1), NULL, 0, 0}, {3, 2, "h3", RISC_COLOR(1, 3, 0x3), NULL, 0, 0}, {3, 4, "s3", RISC_COLOR(1, 3, 0xf), NULL, 0, 0}, {3, 8, "d3", RISC_COLOR(1, 3, 0xff), NULL, 0, 0}, + {4, 1, "b4", RISC_COLOR(1, 4, 0x1), NULL, 0, 0}, {4, 2, "h4", RISC_COLOR(1, 4, 0x3), NULL, 0, 0}, {4, 4, "s4", RISC_COLOR(1, 4, 0xf), NULL, 0, 0}, {4, 8, "d4", RISC_COLOR(1, 4, 0xff), NULL, 0, 0}, + {5, 1, "b5", RISC_COLOR(1, 5, 0x1), NULL, 0, 0}, {5, 2, "h5", RISC_COLOR(1, 5, 0x3), NULL, 0, 0}, {5, 4, "s5", RISC_COLOR(1, 5, 0xf), NULL, 0, 0}, {5, 8, "d5", RISC_COLOR(1, 5, 0xff), NULL, 0, 0}, + {6, 1, "b6", RISC_COLOR(1, 6, 0x1), NULL, 0, 0}, {6, 2, "h6", RISC_COLOR(1, 6, 0x3), NULL, 0, 0}, {6, 4, "s6", RISC_COLOR(1, 6, 0xf), NULL, 0, 0}, {6, 8, "d6", RISC_COLOR(1, 6, 0xff), NULL, 0, 0}, + {7, 1, "b7", RISC_COLOR(1, 7, 0x1), NULL, 0, 0}, {7, 2, "h7", RISC_COLOR(1, 7, 0x3), NULL, 0, 0}, {7, 4, "s7", RISC_COLOR(1, 7, 0xf), NULL, 0, 0}, {7, 8, "d7", RISC_COLOR(1, 7, 0xff), NULL, 0, 0}, + {8, 1, "b8", RISC_COLOR(1, 8, 0x1), NULL, 0, 0}, {8, 2, "h8", RISC_COLOR(1, 8, 0x3), NULL, 0, 0}, {8, 4, "s8", RISC_COLOR(1, 8, 0xf), NULL, 0, 0}, {8, 8, "d8", RISC_COLOR(1, 8, 0xff), NULL, 0, 0}, + {9, 1, "b9", RISC_COLOR(1, 9, 0x1), NULL, 0, 0}, {9, 2, "h9", RISC_COLOR(1, 9, 0x3), NULL, 0, 0}, {9, 4, "s9", RISC_COLOR(1, 9, 0xf), NULL, 0, 0}, {9, 8, "d9", RISC_COLOR(1, 9, 0xff), NULL, 0, 0}, + {10, 1, "b10", RISC_COLOR(1, 10, 0x1), NULL, 0, 0}, {10, 2, "h10", RISC_COLOR(1, 10, 0x3), NULL, 0, 0}, {10, 4, "s10", RISC_COLOR(1, 10, 0xf), NULL, 0, 0}, {10, 8, "d10", RISC_COLOR(1, 10, 0xff), NULL, 0, 0}, + {11, 1, "b11", RISC_COLOR(1, 11, 0x1), NULL, 0, 0}, {11, 2, "h11", RISC_COLOR(1, 11, 0x3), NULL, 0, 0}, {11, 4, "s11", RISC_COLOR(1, 11, 0xf), NULL, 0, 0}, {11, 8, "d11", RISC_COLOR(1, 11, 0xff), NULL, 0, 0}, + {12, 1, "b12", RISC_COLOR(1, 12, 0x1), NULL, 0, 0}, {12, 2, "h12", RISC_COLOR(1, 12, 0x3), NULL, 0, 0}, {12, 4, "s12", RISC_COLOR(1, 12, 0xf), NULL, 0, 0}, {12, 8, "d12", RISC_COLOR(1, 12, 0xff), NULL, 0, 0}, + {13, 1, "b13", RISC_COLOR(1, 13, 0x1), NULL, 0, 0}, {13, 2, "h13", RISC_COLOR(1, 13, 0x3), NULL, 0, 0}, {13, 4, "s13", RISC_COLOR(1, 13, 0xf), NULL, 0, 0}, {13, 8, "d13", RISC_COLOR(1, 13, 0xff), NULL, 0, 0}, + {14, 1, "b14", RISC_COLOR(1, 14, 0x1), NULL, 0, 0}, {14, 2, "h14", RISC_COLOR(1, 14, 0x3), NULL, 0, 0}, {14, 4, "s14", RISC_COLOR(1, 14, 0xf), NULL, 0, 0}, {14, 8, "d14", RISC_COLOR(1, 14, 0xff), NULL, 0, 0}, + {15, 1, "b15", RISC_COLOR(1, 15, 0x1), NULL, 0, 0}, {15, 2, "h15", RISC_COLOR(1, 15, 0x3), NULL, 0, 0}, {15, 4, "s15", RISC_COLOR(1, 15, 0xf), NULL, 0, 0}, {15, 8, "d15", RISC_COLOR(1, 15, 0xff), NULL, 0, 0}, - - {16, 2, "h16", RISC_COLOR(1, 16, 0x3), NULL, 0, 0}, - {16, 4, "s16", RISC_COLOR(1, 16, 0xf), NULL, 0, 0}, - {16, 8, "d16", RISC_COLOR(1, 16, 0xff), NULL, 0, 0}, - - {17, 2, "h17", RISC_COLOR(1, 17, 0x3), NULL, 0, 0}, - {17, 4, "s17", RISC_COLOR(1, 17, 0xf), NULL, 0, 0}, - {17, 8, "d17", RISC_COLOR(1, 17, 0xff), NULL, 0, 0}, - - {18, 2, "h18", RISC_COLOR(1, 18, 0x3), NULL, 0, 0}, - {18, 4, "s18", RISC_COLOR(1, 18, 0xf), NULL, 0, 0}, - {18, 8, "d18", RISC_COLOR(1, 18, 0xff), NULL, 0, 0}, - - {19, 2, "h19", RISC_COLOR(1, 19, 0x3), NULL, 0, 0}, - {19, 4, "s19", RISC_COLOR(1, 19, 0xf), NULL, 0, 0}, - {19, 8, "d19", RISC_COLOR(1, 19, 0xff), NULL, 0, 0}, - - {20, 2, "h20", RISC_COLOR(1, 20, 0x3), NULL, 0, 0}, - {20, 4, "s20", RISC_COLOR(1, 20, 0xf), NULL, 0, 0}, - {20, 8, "d20", RISC_COLOR(1, 20, 0xff), NULL, 0, 0}, - - {21, 2, "h21", RISC_COLOR(1, 21, 0x3), NULL, 0, 0}, - {21, 4, "s21", RISC_COLOR(1, 21, 0xf), NULL, 0, 0}, - {21, 8, "d21", RISC_COLOR(1, 21, 0xff), NULL, 0, 0}, - - {22, 2, "h22", RISC_COLOR(1, 22, 0x3), NULL, 0, 0}, - {22, 4, "s22", RISC_COLOR(1, 22, 0xf), NULL, 0, 0}, - {22, 8, "d22", RISC_COLOR(1, 22, 0xff), NULL, 0, 0}, - - {23, 2, "h23", RISC_COLOR(1, 23, 0x3), NULL, 0, 0}, - {23, 4, "s23", RISC_COLOR(1, 23, 0xf), NULL, 0, 0}, - {23, 8, "d23", RISC_COLOR(1, 23, 0xff), NULL, 0, 0}, - - {24, 2, "h24", RISC_COLOR(1, 24, 0x3), NULL, 0, 0}, - {24, 4, "s24", RISC_COLOR(1, 24, 0xf), NULL, 0, 0}, - {24, 8, "d24", RISC_COLOR(1, 24, 0xff), NULL, 0, 0}, - - {25, 2, "h25", RISC_COLOR(1, 25, 0x3), NULL, 0, 0}, - {25, 4, "s25", RISC_COLOR(1, 25, 0xf), NULL, 0, 0}, - {25, 8, "d25", RISC_COLOR(1, 25, 0xff), NULL, 0, 0}, - - {26, 2, "h26", RISC_COLOR(1, 26, 0x3), NULL, 0, 0}, - {26, 4, "s26", RISC_COLOR(1, 26, 0xf), NULL, 0, 0}, - {26, 8, "d26", RISC_COLOR(1, 26, 0xff), NULL, 0, 0}, - - {27, 2, "h27", RISC_COLOR(1, 27, 0x3), NULL, 0, 0}, - {27, 4, "s27", RISC_COLOR(1, 27, 0xf), NULL, 0, 0}, - {27, 8, "d27", RISC_COLOR(1, 27, 0xff), NULL, 0, 0}, - - {28, 2, "h28", RISC_COLOR(1, 28, 0x3), NULL, 0, 0}, - {28, 4, "s28", RISC_COLOR(1, 28, 0xf), NULL, 0, 0}, - {28, 8, "d28", RISC_COLOR(1, 28, 0xff), NULL, 0, 0}, - - {29, 2, "h29", RISC_COLOR(1, 29, 0x3), NULL, 0, 0}, - {29, 4, "s29", RISC_COLOR(1, 29, 0xf), NULL, 0, 0}, - {29, 8, "d29", RISC_COLOR(1, 29, 0xff), NULL, 0, 0}, - - {30, 2, "h30", RISC_COLOR(1, 30, 0x3), NULL, 0, 0}, - {30, 4, "s30", RISC_COLOR(1, 30, 0xf), NULL, 0, 0}, - {30, 8, "d30", RISC_COLOR(1, 30, 0xff), NULL, 0, 0}, - - {31, 2, "h31", RISC_COLOR(1, 31, 0x3), NULL, 0, 0}, - {31, 4, "s31", RISC_COLOR(1, 31, 0xf), NULL, 0, 0}, - {31, 8, "d31", RISC_COLOR(1, 31, 0xff), NULL, 0, 0}, }; static uint32_t naja_abi_regs[] = @@ -242,8 +171,6 @@ static uint32_t naja_abi_regs[] = SCF_RISC_REG_X3, SCF_RISC_REG_X4, SCF_RISC_REG_X5, - SCF_RISC_REG_X6, - SCF_RISC_REG_X7, }; static uint32_t naja_abi_float_regs[] = @@ -274,31 +201,16 @@ static uint32_t naja_abi_caller_saves[] = SCF_RISC_REG_X3, SCF_RISC_REG_X4, SCF_RISC_REG_X5, - SCF_RISC_REG_X6, - SCF_RISC_REG_X7, - - SCF_RISC_REG_X9, - SCF_RISC_REG_X10, - SCF_RISC_REG_X11, - SCF_RISC_REG_X12, - SCF_RISC_REG_X13, - SCF_RISC_REG_X14, - SCF_RISC_REG_X15, }; static uint32_t naja_abi_callee_saves[] = { - SCF_RISC_REG_X19, - SCF_RISC_REG_X20, - SCF_RISC_REG_X21, - SCF_RISC_REG_X22, - SCF_RISC_REG_X23, - SCF_RISC_REG_X24, - SCF_RISC_REG_X25, - SCF_RISC_REG_X26, - SCF_RISC_REG_X27, - SCF_RISC_REG_X28, - SCF_RISC_REG_X29, + SCF_RISC_REG_X6, + SCF_RISC_REG_X7, + SCF_RISC_REG_X8, + SCF_RISC_REG_X9, + SCF_RISC_REG_FP, + SCF_RISC_REG_LR, }; static int naja_color_conflict(intptr_t c0, intptr_t c1) @@ -317,7 +229,7 @@ static int naja_variable_size(scf_variable_t* v) if (v->type >= SCF_STRUCT && 0 == v->nb_pointers) return 8; - return v->size < 4 ? 4 : v->size; + return v->size; } scf_register_t* naja_find_register(const char* name) @@ -386,8 +298,8 @@ scf_vector_t* naja_register_colors() if (SCF_RISC_REG_SP == r->id || SCF_RISC_REG_FP == r->id || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) + || SCF_RISC_REG_X10 == r->id + || SCF_RISC_REG_X11 == r->id) continue; int ret = scf_vector_add(colors, (void*)r->color); @@ -421,8 +333,8 @@ int naja_reg_cached_vars(scf_register_t* r) if (SCF_RISC_REG_SP == r2->id || SCF_RISC_REG_FP == r2->id || SCF_RISC_REG_LR == r2->id - || SCF_RISC_REG_X16 == r2->id - || SCF_RISC_REG_X17 == r2->id) + || SCF_RISC_REG_X10 == r2->id + || SCF_RISC_REG_X11 == r2->id) continue; if (!naja_color_conflict(r->color, r2->color)) @@ -444,8 +356,8 @@ int naja_registers_init() if (SCF_RISC_REG_SP == r->id || SCF_RISC_REG_FP == r->id || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) + || SCF_RISC_REG_X10 == r->id + || SCF_RISC_REG_X11 == r->id) continue; assert(!r->dag_nodes); @@ -470,8 +382,8 @@ void naja_registers_clear() if (SCF_RISC_REG_SP == r->id || SCF_RISC_REG_FP == r->id || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) + || SCF_RISC_REG_X10 == r->id + || SCF_RISC_REG_X11 == r->id) continue; if (r->dag_nodes) { @@ -534,8 +446,8 @@ int naja_caller_save_regs(scf_3ac_code_t* c, scf_function_t* f, uint32_t* regs, if (SCF_RISC_REG_SP == r->id || SCF_RISC_REG_FP == r->id || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) + || SCF_RISC_REG_X10 == r->id + || SCF_RISC_REG_X11 == r->id) continue; if (0 == r->dag_nodes->size) @@ -607,8 +519,8 @@ int naja_pop_regs(scf_3ac_code_t* c, scf_function_t* f, scf_register_t** regs, i if (SCF_RISC_REG_SP == r->id || SCF_RISC_REG_FP == r->id || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) + || SCF_RISC_REG_X10 == r->id + || SCF_RISC_REG_X11 == r->id) continue; if (0 == r->dag_nodes->size) @@ -650,8 +562,8 @@ int naja_registers_reset() if (SCF_RISC_REG_SP == r->id || SCF_RISC_REG_FP == r->id || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) + || SCF_RISC_REG_X10 == r->id + || SCF_RISC_REG_X11 == r->id) continue; if (!r->dag_nodes) @@ -692,8 +604,8 @@ int naja_overflow_reg(scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f) if (SCF_RISC_REG_SP == r2->id || SCF_RISC_REG_FP == r2->id || SCF_RISC_REG_LR == r2->id - || SCF_RISC_REG_X16 == r2->id - || SCF_RISC_REG_X17 == r2->id) + || SCF_RISC_REG_X10 == r2->id + || SCF_RISC_REG_X11 == r2->id) continue; if (!naja_color_conflict(r->color, r2->color)) @@ -725,8 +637,8 @@ int naja_overflow_reg2(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, if (SCF_RISC_REG_SP == r2->id || SCF_RISC_REG_FP == r2->id || SCF_RISC_REG_LR == r2->id - || SCF_RISC_REG_X16 == r2->id - || SCF_RISC_REG_X17 == r2->id) + || SCF_RISC_REG_X10 == r2->id + || SCF_RISC_REG_X11 == r2->id) continue; if (!naja_color_conflict(r->color, r2->color)) @@ -767,8 +679,8 @@ int naja_overflow_reg3(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, if (SCF_RISC_REG_SP == r2->id || SCF_RISC_REG_FP == r2->id || SCF_RISC_REG_LR == r2->id - || SCF_RISC_REG_X16 == r2->id - || SCF_RISC_REG_X17 == r2->id) + || SCF_RISC_REG_X10 == r2->id + || SCF_RISC_REG_X11 == r2->id) continue; if (!naja_color_conflict(r->color, r2->color)) @@ -830,8 +742,8 @@ int naja_reg_used(scf_register_t* r, scf_dag_node_t* dn) if (SCF_RISC_REG_SP == r2->id || SCF_RISC_REG_FP == r2->id || SCF_RISC_REG_LR == r2->id - || SCF_RISC_REG_X16 == r2->id - || SCF_RISC_REG_X17 == r2->id) + || SCF_RISC_REG_X10 == r2->id + || SCF_RISC_REG_X11 == r2->id) continue; if (!naja_color_conflict(r->color, r2->color)) @@ -880,8 +792,8 @@ scf_register_t* naja_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c if (SCF_RISC_REG_SP == r->id || SCF_RISC_REG_FP == r->id || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) + || SCF_RISC_REG_X10 == r->id + || SCF_RISC_REG_X11 == r->id) continue; if (r->bytes < bytes || RISC_COLOR_TYPE(r->color) != is_float) @@ -920,8 +832,8 @@ scf_register_t* naja_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c if (SCF_RISC_REG_SP == r->id || SCF_RISC_REG_FP == r->id || SCF_RISC_REG_LR == r->id - || SCF_RISC_REG_X16 == r->id - || SCF_RISC_REG_X17 == r->id) + || SCF_RISC_REG_X10 == r->id + || SCF_RISC_REG_X11 == r->id) continue; if (r->bytes < bytes || RISC_COLOR_TYPE(r->color) != is_float) @@ -1057,6 +969,7 @@ int naja_push_callee_regs(scf_3ac_code_t* c, scf_function_t* f) int i; for (i = 0; i < f->rops->ABI_CALLEE_SAVES_NB; i++) { + scf_logi("f->rops->abi_callee_saves[%d]: %d\n", i, f->rops->abi_callee_saves[i]); r = f->rops->find_register_type_id_bytes(0, f->rops->abi_callee_saves[i], 8); if (!r->used) { @@ -1085,6 +998,8 @@ int naja_pop_callee_regs(scf_3ac_code_t* c, scf_function_t* f) r = f->rops->find_register_type_id_bytes(0, f->rops->abi_callee_saves[i], 8); + scf_logi("r: %p, f->rops->abi_callee_saves[%d]: %d\n", r, i, f->rops->abi_callee_saves[i]); + if (!r->used) { r = f->rops->find_register_type_id_bytes(0, f->rops->abi_callee_saves[i], 4); diff --git a/native/risc/scf_risc_util.h b/native/risc/scf_risc_util.h index c64aa7a..d8209eb 100644 --- a/native/risc/scf_risc_util.h +++ b/native/risc/scf_risc_util.h @@ -3,8 +3,9 @@ #include"scf_def.h" -enum scf_risc_OpCode_types { - SCF_RISC_MOV = 0, +enum scf_risc_OpCode_types +{ + SCF_RISC_MOV = 0, SCF_RISC_MOVSX, SCF_RISC_MOVZX, @@ -117,7 +118,8 @@ enum scf_risc_OpCode_types { SCF_RISC_NB }; -enum scf_risc_REGs { +enum scf_risc_REGs +{ SCF_RISC_REG_W0 = 0, SCF_RISC_REG_X0 = 0, SCF_RISC_REG_S0 = 0, @@ -238,15 +240,15 @@ enum scf_risc_REGs { SCF_RISC_REG_X31 = 31, }; -enum scf_risc_EG_types { - SCF_RISC_G = 0, - SCF_RISC_I = 1, - SCF_RISC_G2E = 2, +enum scf_risc_EG_types +{ + SCF_RISC_G = 0, + SCF_RISC_I = 1, + SCF_RISC_G2E = 2, SCF_RISC_E2G = 3, SCF_RISC_I2E = 4, SCF_RISC_I2G = 5, - SCF_RISC_E = 6, + SCF_RISC_E = 6, }; #endif - diff --git a/vm/scf_vm.h b/vm/scf_vm.h index 98d32ed..9a6dd35 100644 --- a/vm/scf_vm.h +++ b/vm/scf_vm.h @@ -10,9 +10,9 @@ #define NAJA_PRINTF #endif -#define NAJA_REG_FP 28 -#define NAJA_REG_LR 29 -#define NAJA_REG_SP 30 +#define NAJA_REG_FP 12 +#define NAJA_REG_LR 13 +#define NAJA_REG_SP 14 typedef struct scf_vm_s scf_vm_t; typedef struct scf_vm_ops_s scf_vm_ops_t; @@ -67,8 +67,8 @@ typedef union { } fv256_t; typedef struct { - uint64_t regs[32]; - fv256_t fvec[32]; + uint64_t regs[16]; + fv256_t fvec[16]; uint64_t ip; uint64_t flags; diff --git a/vm/scf_vm_naja.c b/vm/scf_vm_naja.c index bf1f0df..a840da0 100644 --- a/vm/scf_vm_naja.c +++ b/vm/scf_vm_naja.c @@ -6,14 +6,31 @@ static const char* somaps[][3] = {"x64", "libc.so.6", "/lib/x86_64-linux-gnu/libc.so.6"}, }; +static char* __naja_sign[] = {"", "s"}; +static char __naja_size[] = {'b', 'w', 'l', 'q'}; +static char __naja_float[] = {'B', 'H', 'S', 'D'}; + +static char* __naja_SH[] = { + "LSL", + "LSR", + "ASR", + "IMM" +}; + +static char* __naja_reg[] = +{ + "r0", "r1", "r2", "r3", "r4", + "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "fp", "lr", "sp", + "null" +}; + typedef int (*dyn_func_pt)(uint64_t r0, uint64_t r1, uint64_t r2, uint64_t r3, uint64_t r4, uint64_t r5, - uint64_t r6, - uint64_t r7, double d0, double d1, double d2, @@ -56,21 +73,21 @@ static int naja_vm_dynamic_link(scf_vm_t* vm) int64_t sp = naja->regs[NAJA_REG_SP]; uint64_t lr = *(uint64_t*)(naja->stack - (sp + 8)); - uint64_t r16 = *(uint64_t*)(naja->stack - (sp + 16)); + uint64_t r10 = *(uint64_t*)(naja->stack - (sp + 16)); - scf_logw("sp: %ld, r16: %#lx, lr: %#lx, vm->jmprel_size: %ld\n", sp, r16, lr, vm->jmprel_size); + scf_logw("sp: %ld, r10: %#lx, lr: %#lx, vm->jmprel_size: %ld\n", sp, r10, lr, vm->jmprel_size); - if (r16 > (uint64_t)vm->data->data) { - r16 -= (uint64_t)vm->data->data; - r16 += vm->data->addr; + if (r10 > (uint64_t)vm->data->data) { + r10 -= (uint64_t)vm->data->data; + r10 += vm->data->addr; } - scf_logw("r16: %#lx, text: %p, rodata: %p, data: %p\n", r16, vm->text->data, vm->rodata->data, vm->data->data); + scf_logw("r10: %#lx, text: %p, rodata: %p, data: %p\n", r10, vm->text->data, vm->rodata->data, vm->data->data); int i; for (i = 0; i < vm->jmprel_size / sizeof(Elf64_Rela); i++) { - if (r16 == vm->jmprel[i].r_offset) { + if (r10 == vm->jmprel[i].r_offset) { int j = ELF64_R_SYM(vm->jmprel[i].r_info); char* fname = vm->dynstr + vm->dynsym[j].st_name; @@ -103,8 +120,6 @@ static int naja_vm_dynamic_link(scf_vm_t* vm) naja->regs[3], naja->regs[4], naja->regs[5], - naja->regs[6], - naja->regs[7], naja->fvec[0].d[0], naja->fvec[1].d[0], naja->fvec[2].d[0], @@ -294,36 +309,33 @@ static int __naja_add(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; + int rs0 = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int SH = (inst >> 16) & 0x3; if (0x3 == SH) { - uint64_t uimm14 = (inst >> 5) & 0x3fff; + uint64_t uimm12 = (inst >> 4) & 0xfff; - naja->regs[rd] = naja->regs[rs0] + uimm14; + naja->regs[rd] = naja->regs[rs0] + uimm12; - NAJA_PRINTF("add r%d, r%d, %lu\n", rd, rs0, uimm14); + NAJA_PRINTF("add%c %s, %s, %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12); } else { - uint64_t uimm9 = (inst >> 10) & 0x1ff; - int rs1 = (inst >> 5) & 0x1f; + uint64_t uimm6 = (inst >> 10) & 0x3f; + int rs1 = (inst >> 4) & 0xf; + uint64_t v1 = naja->regs[rs1]; + + NAJA_PRINTF("add%c %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6); switch (SH) { case 0: - naja->regs[rd] = naja->regs[rs0] + (naja->regs[rs1] << uimm9); - - NAJA_PRINTF("add r%d, r%d, r%d << %lu\n", rd, rs0, rs1, uimm9); + naja->regs[rd] = naja->regs[rs0] + (scf_zero_extend(v1, 8 << size) << uimm6); break; - case 1: - naja->regs[rd] = naja->regs[rs0] + (naja->regs[rs1] >> uimm9); - - NAJA_PRINTF("add r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm9); + naja->regs[rd] = naja->regs[rs0] + (scf_zero_extend(v1, 8 << size) >> uimm6); break; default: - naja->regs[rd] = naja->regs[rs0] + (((int64_t)naja->regs[rs1]) >> uimm9); - - NAJA_PRINTF("add r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm9); + naja->regs[rd] = naja->regs[rs0] + (((int64_t)scf_sign_extend(v1, 8 << size)) >> uimm6); break; }; } @@ -332,90 +344,49 @@ static int __naja_add(scf_vm_t* vm, uint32_t inst) return 0; } -static int __naja_fadd(scf_vm_t* vm, uint32_t inst) -{ - scf_vm_naja_t* naja = vm->priv; - - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; - int rd = (inst >> 21) & 0x1f; - - naja->fvec[rd].d[0] = naja->fvec[rs0].d[0] + naja->fvec[rs1].d[0]; - - NAJA_PRINTF("fadd d%d, d%d, d%d\n", rd, rs0, rs1); - - naja->ip += 4; - return 0; -} - -static int __naja_fsub(scf_vm_t* vm, uint32_t inst) -{ - scf_vm_naja_t* naja = vm->priv; - - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; - int rd = (inst >> 21) & 0x1f; - - naja->fvec[rd].d[0] = naja->fvec[rs0].d[0] - naja->fvec[rs1].d[0]; - - if (31 == rd) { - double d = naja->fvec[rd].d[0]; - - if (d > 0.0) - naja->flags = 0x4; - else if (d < 0.0) - naja->flags = 0x2; - else - naja->flags = 0x1; - - NAJA_PRINTF("fcmp d%d, d%d\n", rs0, rs1); - } else - NAJA_PRINTF("fsub r%d, r%d, r%d\n", rd, rs0, rs1); - - naja->ip += 4; - return 0; -} - static int __naja_sub(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; + int rs0 = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int SH = (inst >> 16) & 0x3; if (0x3 == SH) { - uint64_t uimm14 = (inst >> 5) & 0x3fff; + uint64_t uimm12 = (inst >> 4) & 0xfff; - naja->regs[rd] = naja->regs[rs0] - uimm14; + naja->regs[rd] = naja->regs[rs0] - uimm12; - NAJA_PRINTF("sub r%d, r%d, %lu\n", rd, rs0, uimm14); + if (0xf == rd) + NAJA_PRINTF("cmp%c %s, %lu\n", __naja_size[size], __naja_reg[rs0], uimm12); + else + NAJA_PRINTF("sub%c %s, %s, %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12); } else { - uint64_t uimm9 = (inst >> 10) & 0x1ff; - int rs1 = (inst >> 5) & 0x1f; + uint64_t uimm6 = (inst >> 10) & 0x3f; + int rs1 = (inst >> 4) & 0xf; + uint64_t v1 = naja->regs[rs1]; + + if (0xf == rd) + NAJA_PRINTF("cmp%c %s, %s %s %lu\n", __naja_size[size], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6); + else + NAJA_PRINTF("sub%c %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6); switch (SH) { case 0: - naja->regs[rd] = naja->regs[rs0] - (naja->regs[rs1] << uimm9); - - NAJA_PRINTF("sub r%d, r%d, r%d << %lu\n", rd, rs0, rs1, uimm9); + naja->regs[rd] = naja->regs[rs0] - (scf_zero_extend(v1, 8 << size) << uimm6); break; - case 1: - naja->regs[rd] = naja->regs[rs0] - (naja->regs[rs1] >> uimm9); - - NAJA_PRINTF("sub r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm9); + naja->regs[rd] = naja->regs[rs0] - (scf_zero_extend(v1, 8 << size) >> uimm6); break; default: - naja->regs[rd] = naja->regs[rs0] - (((int64_t)naja->regs[rs1]) >> uimm9); - - NAJA_PRINTF("sub r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm9); + naja->regs[rd] = naja->regs[rs0] - (((int64_t)scf_sign_extend(v1, 8 << size)) >> uimm6); break; } } - if (31 == rd) { // cmp - int ret = naja->regs[rd]; + if (0xf == rd) { // cmp + int ret = scf_sign_extend(naja->regs[rd], 8 << size); if (0 == ret) naja->flags = 0x1; @@ -433,88 +404,37 @@ static int __naja_mul(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; - int rs2 = (inst >> 10) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int S = (inst >> 18) & 0x1; - int opt = (inst >> 19) & 0x3; - - if (S) - naja->regs[rd] = (int64_t)naja->regs[rs0] * (int64_t)naja->regs[rs1]; - else - naja->regs[rd] = naja->regs[rs0] * naja->regs[rs1]; - - if (0 == opt) { - naja->regs[rd] += naja->regs[rs2]; - - NAJA_PRINTF("madd r%d, r%d, r%d, r%d", rd, rs2, rs0, rs1); - } else if (1 == opt) { - naja->regs[rd] = naja->regs[rs2] - naja->regs[rd]; + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rs2 = (inst >> 12) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + int A = (inst >> 16) & 0x1; - NAJA_PRINTF("msub r%d, r%d, r%d, r%d", rd, rs2, rs0, rs1); - } else { - if (S) - NAJA_PRINTF("smul r%d, r%d, r%d", rd, rs0, rs1); + if (0xf == rs2) + NAJA_PRINTF("%smul%c %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1]); + else { + if (0 == A) + NAJA_PRINTF("%smadd%c %s, %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs2], __naja_reg[rs0], __naja_reg[rs1]); else - NAJA_PRINTF("mul r%d, r%d, r%d", rd, rs0, rs1); + NAJA_PRINTF("%smsub%c %s, %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs2], __naja_reg[rs0], __naja_reg[rs1]); } - naja->ip += 4; - return 0; -} - -static int __naja_fmul(scf_vm_t* vm, uint32_t inst) -{ - scf_vm_naja_t* naja = vm->priv; - - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; - int rs2 = (inst >> 10) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int opt = (inst >> 18) & 0x3; - - naja->fvec[rd].d[0] = naja->fvec[rs0].d[0] * naja->fvec[rs1].d[0]; - - if (0 == opt) { - naja->fvec[rd].d[0] += naja->fvec[rs2].d[0]; - - NAJA_PRINTF("fmadd d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1); - - } else if (1 == opt) { - naja->fvec[rd].d[0] = naja->fvec[rs2].d[0] - naja->fvec[rd].d[0]; + uint64_t v0 = naja->regs[rs0]; + uint64_t v1 = naja->regs[rs1]; - NAJA_PRINTF("fmsub d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1); - } else - NAJA_PRINTF("fmul d%d, d%d, d%d", rd, rs0, rs1); - - naja->ip += 4; - return 0; -} - -static int __naja_fdiv(scf_vm_t* vm, uint32_t inst) -{ - scf_vm_naja_t* naja = vm->priv; - - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; - int rs2 = (inst >> 10) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int opt = (inst >> 18) & 0x3; - - naja->fvec[rd].d[0] = naja->fvec[rs0].d[0] / naja->fvec[rs1].d[0]; - - if (0 == opt) { - naja->fvec[rd].d[0] += naja->fvec[rs2].d[0]; - - NAJA_PRINTF("fdadd d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1); - - } else if (1 == opt) { - naja->fvec[rd].d[0] = naja->fvec[rs2].d[0] - naja->fvec[rd].d[0]; + if (s) + naja->regs[rd] = (int64_t)scf_sign_extend(v0, 8 << size) * (int64_t)scf_sign_extend(v1, 8 << size); + else + naja->regs[rd] = v0 * v1; - NAJA_PRINTF("fdsub d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1); - } else - NAJA_PRINTF("fdiv d%d, d%d, d%d", rd, rs0, rs1); + if (0xf != rs2) { + if (0 == A) + naja->regs[rd] += naja->regs[rs2]; + else + naja->regs[rd] = naja->regs[rs2] - naja->regs[rd]; + } naja->ip += 4; return 0; @@ -524,33 +444,23 @@ static int __naja_div(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; - int rs2 = (inst >> 10) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int S = (inst >> 18) & 0x1; - int opt = (inst >> 19) & 0x3; - - if (S) - naja->regs[rd] = (int64_t)naja->regs[rs0] / (int64_t)naja->regs[rs1]; - else - naja->regs[rd] = naja->regs[rs0] / naja->regs[rs1]; - - if (0 == opt) { - naja->regs[rd] += naja->regs[rs2]; + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rs2 = (inst >> 12) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + int A = (inst >> 16) & 0x1; - NAJA_PRINTF("fdadd d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1); + NAJA_PRINTF("%sdiv%c %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1]); - } else if (1 == opt) { - naja->regs[rd] = naja->regs[rs2] - naja->regs[rd]; + uint64_t v0 = naja->regs[rs0]; + uint64_t v1 = naja->regs[rs1]; - NAJA_PRINTF("dsub r%d, r%d, r%d, r%d", rd, rs2, rs0, rs1); - } else { - if (S) - NAJA_PRINTF("sdiv r%d, r%d, r%d", rd, rs0, rs1); - else - NAJA_PRINTF("div r%d, r%d, r%d", rd, rs0, rs1); - } + if (s) + naja->regs[rd] = (int64_t)scf_sign_extend(v0, 8 << size) / (int64_t)scf_sign_extend(v1, 8 << size); + else + naja->regs[rd] = scf_zero_extend(v0, 8 << size) / scf_zero_extend(v1, 8 << size); naja->ip += 4; return 0; @@ -612,7 +522,6 @@ static int __naja_mem(scf_vm_t* vm, int64_t addr, uint8_t** pdata, int64_t* poff scf_loge("\n"); return -1; } - } else { data = naja->stack; offset = addr; @@ -623,19 +532,20 @@ static int __naja_mem(scf_vm_t* vm, int64_t addr, uint8_t** pdata, int64_t* poff return 0; } -static int __naja_fstr_disp(scf_vm_t* vm, uint32_t inst) +static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s13 = (inst >> 5) & 0x1fff; + int rb = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + int s13 = (inst >> 4) & 0x1fff; if (s13 & 0x1000) s13 |= 0xffffe000; - scf_logd("rd: %d, rb: %d, s13: %d, SH: %d\n", rd, rb, s13, SH); + NAJA_PRINTF("ldr%s%c %s, [%s, %d]\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rb], s13 << size); int64_t addr = naja->regs[rb]; int64_t offset = 0; @@ -645,36 +555,46 @@ static int __naja_fstr_disp(scf_vm_t* vm, uint32_t inst) if (ret < 0) return ret; - offset += s13 << SH; + offset += s13 << size; if (data == naja->stack) { offset = -offset; - assert(offset > 0); + scf_logd("offset0: %ld, size: %ld\n", offset, naja->size); + assert(offset >= 0); if (naja->size < offset) { - scf_loge("offset0: %ld, size: %ld\n", offset, naja->size); + scf_loge("offset: %ld, size: %ld\n", offset, naja->size); return -EINVAL; } - offset -= 1 << SH; + offset -= 1 << size; } - switch (SH) { - case 2: - *(float*)(data + offset) = naja->fvec[rd].d[0]; - - NAJA_PRINTF("fstr f%d, [r%d, %d]\n", rd, rb, s13 << 2); + switch (size) { + case 0: + if (s) + naja->regs[rd] = *(int8_t*)(data + offset); + else + naja->regs[rd] = *(uint8_t*)(data + offset); break; - case 3: - *(double*)(data + offset) = naja->fvec[rd].d[0]; + case 1: + if (s) + naja->regs[rd] = *(int16_t*)(data + offset); + else + naja->regs[rd] = *(uint16_t*)(data + offset); + break; - NAJA_PRINTF("fstr d%d, [r%d, %d]\n", rd, rb, s13 << 3); + case 2: + if (s) + naja->regs[rd] = *(int32_t*)(data + offset); + else + naja->regs[rd] = *(uint32_t*)(data + offset); break; + default: - scf_loge("SH: %d\n", SH); - return -1; + naja->regs[rd] = *(uint64_t*)(data + offset); break; }; @@ -682,13 +602,62 @@ static int __naja_fstr_disp(scf_vm_t* vm, uint32_t inst) return 0; } -static int __naja_fpush(scf_vm_t* vm, uint32_t inst) +static int __naja_and(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rs0 = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int SH = (inst >> 16) & 0x3; + + if (0x3 == SH) { + uint64_t uimm12 = (inst >> 4) & 0xfff; + + if (0xf == rd) + NAJA_PRINTF("teq%c %s, %#lx\n", __naja_size[size], __naja_reg[rs0], uimm12); + else + NAJA_PRINTF("and%c %s, %s, %#lx\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12); + + naja->regs[rd] = naja->regs[rs0] & uimm12; + } else { + uint64_t uimm6 = (inst >> 10) & 0x3f; + int rs1 = (inst >> 4) & 0xf; + uint64_t v1 = naja->regs[rs1]; + + if (0xf == rd) + NAJA_PRINTF("teq%c %s, %s %s %lu\n", __naja_size[size], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6); + else + NAJA_PRINTF("and%c %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6); + + if (0 == SH) + naja->regs[rd] = naja->regs[rs0] & (v1 << uimm6); + else if (1 == SH) + naja->regs[rd] = naja->regs[rs0] & (v1 >> uimm6); + else + naja->regs[rd] = naja->regs[rs0] & (((int64_t)scf_sign_extend(v1, 8 << size)) >> uimm6); + } + + if (0xf == rd) + naja->flags = !!scf_zero_extend(naja->regs[rd], 8 << size); + + naja->ip += 4; + return 0; +} + +static int __naja_str_disp(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; + int rb = inst & 0xf; + int rs = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s13 = (inst >> 4) & 0x1fff; + + if (s13 & 0x1000) + s13 |= 0xffffe000; + + NAJA_PRINTF("str%c %s, [%s, %d]\n", __naja_size[size], __naja_reg[rs], __naja_reg[rb], s13 << size); int64_t addr = naja->regs[rb]; int64_t offset = 0; @@ -698,62 +667,83 @@ static int __naja_fpush(scf_vm_t* vm, uint32_t inst) if (ret < 0) return ret; + offset += s13 << size; + if (data == naja->stack) { offset = -offset; - assert(offset >= 0); - - offset += 1 << SH; + assert(offset > 0); if (naja->size < offset) { - data = realloc(naja->stack, offset + STACK_INC); - if (!data) - return -ENOMEM; - - naja->stack = data; - naja->size = offset + STACK_INC; + scf_loge("offset0: %ld, size: %ld\n", offset, naja->size); + return -EINVAL; } - offset -= 1 << SH; + offset -= 1 << size; } - switch (SH) { - case 2: - *(float*)(data + offset) = naja->fvec[rd].d[0]; - - NAJA_PRINTF("fpush f%d, [r%d]\n", rd, rb); + switch (size) { + case 0: + *(uint8_t*)(data + offset) = naja->regs[rs]; break; - case 3: - *(double*)(data + offset) = naja->fvec[rd].d[0]; + case 1: + *(uint16_t*)(data + offset) = naja->regs[rs]; + break; - NAJA_PRINTF("fpush d%d, [r%d]\n", rd, rb); + case 2: + *(uint32_t*)(data + offset) = naja->regs[rs]; break; default: - scf_loge("SH: %d\n", SH); - return -1; + *(uint64_t*)(data + offset) = naja->regs[rs]; break; }; - naja->regs[rb] -= 1 << SH; - naja->ip += 4; return 0; } -static int __naja_fldr_disp(scf_vm_t* vm, uint32_t inst) +static int __naja_or(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s13 = (inst >> 5) & 0x1fff; + int rs0 = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int SH = (inst >> 16) & 0x3; - if (s13 & 0x1000) - s13 |= 0xffffe000; + if (0x3 == SH) { + uint64_t uimm12 = (inst >> 4) & 0xfff; + + NAJA_PRINTF("or%c %s, %s, %#lx\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12); + + naja->regs[rd] = naja->regs[rs0] | uimm12; + } else { + uint64_t uimm6 = (inst >> 10) & 0x3f; + int rs1 = (inst >> 4) & 0xf; + uint64_t v1 = naja->regs[rs1]; + + NAJA_PRINTF("or%c %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6); - scf_logd("rd: %d, rb: %d, s13: %d, SH: %d\n", rd, rb, s13, SH); + if (0 == SH) + naja->regs[rd] = naja->regs[rs0] | (v1 << uimm6); + else if (1 == SH) + naja->regs[rd] = naja->regs[rs0] | (v1 >> uimm6); + else + naja->regs[rd] = naja->regs[rs0] | (((int64_t)scf_sign_extend(v1, 8 << size)) >> uimm6); + } + + naja->ip += 4; + return 0; +} + +static int __naja_pop(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rb = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int s = (inst >> 17) & 0x1; int64_t addr = naja->regs[rb]; int64_t offset = 0; @@ -763,10 +753,8 @@ static int __naja_fldr_disp(scf_vm_t* vm, uint32_t inst) if (ret < 0) return ret; - offset += s13 << SH; - if (data == naja->stack) { - offset = -offset; + offset = -offset; scf_logd("offset0: %ld, size: %ld\n", offset, naja->size); assert(offset > 0); @@ -776,39 +764,32 @@ static int __naja_fldr_disp(scf_vm_t* vm, uint32_t inst) return -EINVAL; } - offset -= 1 << SH; + offset -= 8; } - switch (SH) { - case 2: - naja->fvec[rd].d[0] = *(float*)(data + offset); + if (s) { + NAJA_PRINTF("fpop d%d, [%s]\n", rd, __naja_reg[rb]); - NAJA_PRINTF("fldr f%d, [r%d, %d], rd: %lg, rb: %ld, %p\n", rd, rb, s13 << 2, naja->fvec[rd].d[0], naja->regs[rb], data + offset); - break; - case 3: - naja->fvec[rd].d[0] = *(double*)(data + offset); + naja->fvec[rd].d[0] = *(double*)(data + offset); + } else { + naja->regs[rd] = *(uint64_t*)(data + offset); - NAJA_PRINTF("fldr d%d, [r%d, %d], rd: %lg, rb: %ld, %p\n", rd, rb, s13 << 3, naja->fvec[rd].d[0], naja->regs[rb], data + offset); - break; - default: - scf_loge("SH: %d\n", SH); - return -1; - break; - }; + NAJA_PRINTF("pop %s, [%s], offset: %ld, value: %#lx\n", __naja_reg[rd], __naja_reg[rb], offset, naja->regs[rd]); + } + + naja->regs[rb] += 8; naja->ip += 4; return 0; } -static int __naja_fpop(scf_vm_t* vm, uint32_t inst) +static int __naja_push(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - - scf_logd("rd: %d, rb: %d, SH: %d\n", rd, rb, SH); + int rb = inst & 0xf; + int rs = (inst >> 21) & 0xf; + int s = (inst >> 17) & 0x1; int64_t addr = naja->regs[rb]; int64_t offset = 0; @@ -822,53 +803,51 @@ static int __naja_fpop(scf_vm_t* vm, uint32_t inst) offset = -offset; scf_logd("offset0: %ld, size: %ld\n", offset, naja->size); - assert(offset > 0); + + assert(offset >= 0); + + offset += 8; if (naja->size < offset) { - scf_loge("offset: %ld, size: %ld\n", offset, naja->size); - return -EINVAL; + data = realloc(naja->stack, offset + STACK_INC); + if (!data) + return -ENOMEM; + + naja->stack = data; + naja->size = offset + STACK_INC; } - offset -= 1 << SH; + offset -= 8; } - switch (SH) { - case 2: - naja->fvec[rd].d[0] = *(float*)(data + offset); + if (s) { + NAJA_PRINTF("fpush d%d, [%s]\n", rs, __naja_reg[rb]); - NAJA_PRINTF("fldr f%d, [r%d], rd: %lg, rb: %ld, %p\n", rd, rb, naja->fvec[rd].d[0], naja->regs[rb], data + offset); - break; - case 3: - naja->fvec[rd].d[0] = *(double*)(data + offset); + *(double*)(data + offset) = naja->fvec[rs].d[0]; + } else { + *(uint64_t*)(data + offset) = naja->regs[rs]; - NAJA_PRINTF("fldr d%d, [r%d], rd: %lg, rb: %ld, %p\n", rd, rb, naja->fvec[rd].d[0], naja->regs[rb], data + offset); - break; - default: - scf_loge("SH: %d\n", SH); - return -1; - break; - }; + NAJA_PRINTF("push %s, [%s], offset: %ld, value: %#lx\n", __naja_reg[rs], __naja_reg[rb], offset, naja->regs[rs]); + } - naja->regs[rb] += 1 << SH; + naja->regs[rb] -= 8; naja->ip += 4; return 0; } -static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst) +static int __naja_ldr_sib(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s = (inst >> 18) & 0x1; - int s13 = (inst >> 5) & 0x1fff; - - if (s13 & 0x1000) - s13 |= 0xffffe000; + int rb = inst & 0xf; + int ri = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + int uimm6 = (inst >> 10) & 0x3f; - scf_logd("rd: %d, rb: %d, s13: %d, SH: %d\n", rd, rb, s13, SH); + NAJA_PRINTF("ldr%s%c %s, [%s, %s, %d]\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rb], __naja_reg[ri], uimm6); int64_t addr = naja->regs[rb]; int64_t offset = 0; @@ -878,63 +857,44 @@ static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst) if (ret < 0) return ret; - offset += s13 << SH; + offset += (naja->regs[ri] << uimm6); if (data == naja->stack) { offset = -offset; - scf_logd("offset0: %ld, size: %ld\n", offset, naja->size); assert(offset >= 0); if (naja->size < offset) { - scf_loge("offset: %ld, size: %ld\n", offset, naja->size); - return -EINVAL; + scf_loge("\n"); + return -1; } - offset -= 1 << SH; + offset -= 1 << size; } - switch (SH) { + switch (size) { case 0: - if (s) { + if (s) naja->regs[rd] = *(int8_t*)(data + offset); - - NAJA_PRINTF("ldrsb r%d, [r%d, %d]\n", rd, rb, s13); - } else { + else naja->regs[rd] = *(uint8_t*)(data + offset); - - NAJA_PRINTF("ldrb r%d, [r%d, %d]\n", rd, rb, s13); - } break; case 1: - if (s) { + if (s) naja->regs[rd] = *(int16_t*)(data + offset); - - NAJA_PRINTF("ldrsw r%d, [r%d, %d]\n", rd, rb, s13 << 1); - } else { + else naja->regs[rd] = *(uint16_t*)(data + offset); - - NAJA_PRINTF("ldrw r%d, [r%d, %d]\n", rd, rb, s13 << 1); - } break; case 2: - if (s) { + if (s) naja->regs[rd] = *(int32_t*)(data + offset); - - NAJA_PRINTF("ldrsl r%d, [r%d, %d]\n", rd, rb, s13 << 2); - } else { + else naja->regs[rd] = *(uint32_t*)(data + offset); - - NAJA_PRINTF("ldrl r%d, [r%d, %d], %ld, %p\n", rd, rb, s13 << 2, naja->regs[rd], data + offset); - } break; - default: naja->regs[rd] = *(uint64_t*)(data + offset); - - NAJA_PRINTF("ldr r%d, [r%d, %d]\n", rd, rb, s13 << 3); break; }; @@ -942,14 +902,21 @@ static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst) return 0; } -static int __naja_pop(scf_vm_t* vm, uint32_t inst) +static int __naja_str_sib(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s = (inst >> 18) & 0x1; + int rb = inst & 0xf; + int ri = (inst >> 4) & 0xf; + int rs = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + int uimm6 = (inst >> 10) & 0x3f; + + if (s) + NAJA_PRINTF("fstr.%d d%d, [%s, %s, %d]\n", 1 << size, rs, __naja_reg[rb], __naja_reg[ri], uimm6); + else + NAJA_PRINTF("str%c %s, [%s, %s, %d]\n", __naja_size[size], __naja_reg[rs], __naja_reg[rb], __naja_reg[ri], uimm6); int64_t addr = naja->regs[rb]; int64_t offset = 0; @@ -959,144 +926,146 @@ static int __naja_pop(scf_vm_t* vm, uint32_t inst) if (ret < 0) return ret; + offset += naja->regs[ri] << uimm6; + if (data == naja->stack) { - offset = -offset; + offset = -offset; - scf_logd("offset0: %ld, size: %ld\n", offset, naja->size); - assert(offset > 0); + assert(offset >= 0); if (naja->size < offset) { - scf_loge("offset: %ld, size: %ld\n", offset, naja->size); - return -EINVAL; + scf_loge("\n"); + return -1; } - offset -= 1 << SH; + offset -= 1 << size; } - switch (SH) { + switch (size) { case 0: - if (s) { - naja->regs[rd] = *(int8_t*)(data + offset); - - NAJA_PRINTF("popsb r%d, [r%d]\n", rd, rb); - } else { - naja->regs[rd] = *(uint8_t*)(data + offset); - - NAJA_PRINTF("popb r%d, [r%d]\n", rd, rb); - } + *(uint8_t*)(data + offset) = naja->regs[rs]; break; case 1: - if (s) { - naja->regs[rd] = *(int16_t*)(data + offset); - - NAJA_PRINTF("popsw r%d, [r%d]\n", rd, rb); - } else { - naja->regs[rd] = *(uint16_t*)(data + offset); - - NAJA_PRINTF("popw r%d, [r%d]\n", rd, rb); - } + *(uint16_t*)(data + offset) = naja->regs[rs]; break; case 2: - if (s) { - naja->regs[rd] = *(int32_t*)(data + offset); - - NAJA_PRINTF("popsl r%d, [r%d]\n", rd, rb); - } else { - naja->regs[rd] = *(uint32_t*)(data + offset); - - NAJA_PRINTF("popl r%d, [r%d], %ld, %p\n", rd, rb, naja->regs[rd], data + offset); - } + *(uint32_t*)(data + offset) = naja->regs[rs]; break; default: - naja->regs[rd] = *(uint64_t*)(data + offset); - - NAJA_PRINTF("popq r%d, [r%d]\n", rd, rb); + *(uint64_t*)(data + offset) = naja->regs[rs]; break; }; - naja->regs[rb] += 1 << SH; - naja->ip += 4; return 0; } -static int __naja_ldr_sib(scf_vm_t* vm, uint32_t inst) +static int __naja_mov(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int ri = (inst >> 5) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s = (inst >> 18) & 0x1; - int u8 = (inst >> 10) & 0xff; - - int64_t addr = naja->regs[rb]; - int64_t offset = 0; - uint8_t* data = NULL; - - int ret = __naja_mem(vm, addr, &data, &offset); - if (ret < 0) - return ret; + int rs = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int SH = (inst >> 16) & 0x3; + int uimm6 = (inst >> 10) & 0x3f; - offset += (naja->regs[ri] << u8); + if (0xf == rs1) { + if (0 == uimm6) + NAJA_PRINTF("mov%c %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]); + else + NAJA_PRINTF("mov%c %s, %s %s %d\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs], __naja_SH[SH], uimm6); + } else + NAJA_PRINTF("mov%c %s, %s %s %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs], __naja_SH[SH], __naja_reg[rs1]); - if (data == naja->stack) { - offset = -offset; + uint64_t v = naja->regs[rs]; - assert(offset >= 0); + if (0xf != rs1) + uimm6 = naja->regs[rs1] & 0x3f; - if (naja->size < offset) { + switch (SH) { + case 0: + naja->regs[rd] = v << uimm6; + break; + case 1: + naja->regs[rd] = v >> uimm6; + break; + case 2: + naja->regs[rd] = (int64_t)scf_sign_extend(v, 8 << size) >> uimm6; + break; + default: scf_loge("\n"); return -1; - } + break; + }; + + naja->ip += 4; + return 0; +} + +static int __naja_movx(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rs = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + + if (s) { + NAJA_PRINTF("movs%cq %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]); + + naja->regs[rd] = scf_sign_extend(naja->regs[rs], 8 << size); + } else { + naja->regs[rd] = scf_zero_extend(naja->regs[rs], 8 << size); - offset -= 1 << SH; + NAJA_PRINTF("movz%cq %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]); } + naja->ip += 4; + return 0; +} + +static int __naja_not(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rs = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int SH = (inst >> 16) & 0x3; + int u16 = inst & 0xffff; + switch (SH) { case 0: - if (s) { - NAJA_PRINTF("ldrsb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - - naja->regs[rd] = *(int8_t*)(data + offset); - } else { - NAJA_PRINTF("ldrb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + NAJA_PRINTF("neg%c %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]); - naja->regs[rd] = *(uint8_t*)(data + offset); - } + naja->regs[rd] = -scf_zero_extend(naja->regs[rs], 8 << size); break; - case 1: - if (s) { - NAJA_PRINTF("ldrsw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - - naja->regs[rd] = *(int16_t*)(data + offset); - } else { - NAJA_PRINTF("ldrw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + naja->regs[rd] = ~scf_zero_extend(naja->regs[rs], 8 << size); - naja->regs[rd] = *(uint16_t*)(data + offset); - } + NAJA_PRINTF("not%c %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]); break; - case 2: - if (s) { - NAJA_PRINTF("ldrsl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + if (0 == size) { + NAJA_PRINTF("mov %s, %d\n", __naja_reg[rd], u16); - naja->regs[rd] = *(int32_t*)(data + offset); + naja->regs[rd] = u16; } else { - NAJA_PRINTF("ldrl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + naja->regs[rd] |= u16 << size; - naja->regs[rd] = *(uint32_t*)(data + offset); + NAJA_PRINTF("movt %s, %d LSL %d\n", __naja_reg[rd], u16, 16 << size); } break; default: - NAJA_PRINTF("ldr r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + naja->regs[rd] = ~u16; - naja->regs[rd] = *(uint64_t*)(data + offset); + NAJA_PRINTF("mvn%c %s, %d\n", __naja_size[size], __naja_reg[rd], u16); break; }; @@ -1104,128 +1073,252 @@ static int __naja_ldr_sib(scf_vm_t* vm, uint32_t inst) return 0; } -static int __naja_fldr_sib(scf_vm_t* vm, uint32_t inst) +static int __naja_fadd(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int ri = (inst >> 5) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int u8 = (inst >> 10) & 0xff; + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int vlen = (inst >> 10) & 0x3; + int N = 1; + int i; - int64_t addr = naja->regs[rb]; - int64_t offset = 0; - uint8_t* data = NULL; + if (V) { + N = 1 << (3 + vlen - size); - int ret = __naja_mem(vm, addr, &data, &offset); - if (ret < 0) - return ret; + NAJA_PRINTF("vadd.f%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + } else + NAJA_PRINTF("fadd.%d d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1); - offset += naja->regs[ri] << u8; + for (i = 0; i < N; i++) { + switch (size) { + case 2: + naja->fvec[rd].f[i] = naja->fvec[rs0].f[i] + naja->fvec[rs1].f[i]; + break; + case 3: + naja->fvec[rd].d[i] = naja->fvec[rs0].d[i] + naja->fvec[rs1].d[i]; + break; + default: + scf_loge("\n"); + return -1; + break; + }; + } - if (data == naja->stack) { - offset = -offset; + naja->ip += 4; + return 0; +} - assert(offset > 0); +static int __naja_fsub(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - if (naja->size < offset) { - scf_loge("\n"); - return -1; - } + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int cmp = (inst >> 16) & 0x1; + int vlen = (inst >> 10) & 0x3; + int N = 1; + int i; - offset -= 1 << SH; + if (V) { + N = 1 << (3 + vlen - size); + + if (cmp) + NAJA_PRINTF("vcmp.f%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + else + NAJA_PRINTF("vsub.f%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + } else { + if (cmp) + NAJA_PRINTF("fcmp.%d d%d, d%d\n", 1 << size, rs0, rs1); + else + NAJA_PRINTF("fsub.%d d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1); } - switch (SH) { - case 2: - NAJA_PRINTF("fldr f%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + for (i = 0; i < N; i++) { + double d; - naja->fvec[rd].d[0] = *(float*)(data + offset); - break; + switch (size) { + case 2: + d = naja->fvec[rs0].f[i] - naja->fvec[rs1].f[i]; - case 3: - NAJA_PRINTF("fldr d%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + if (!cmp) + naja->fvec[rd].f[i] = d; + break; - naja->fvec[rd].d[0] = *(double*)(data + offset); - break; - default: - scf_loge("\n"); - return -1; - break; - }; + case 3: + d = naja->fvec[rs0].d[i] - naja->fvec[rs1].d[i]; + if (!cmp) + naja->fvec[rd].d[i] = d; + break; + default: + scf_loge("\n"); + return -1; + break; + }; + + if (cmp) { + uint32_t flags; + + if (d > 0.0) + flags = 0x4; + else if (d < 0.0) + flags = 0x2; + else + flags = 0x1; + + if (V) + naja->fvec[rd].l[i] = flags; + else + naja->flags = flags; + } + } naja->ip += 4; return 0; } -static int __naja_fstr_sib(scf_vm_t* vm, uint32_t inst) +static int __naja_fmul(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int ri = (inst >> 5) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int u8 = (inst >> 10) & 0xff; - - int64_t addr = naja->regs[rb]; - int64_t offset = 0; - uint8_t* data = NULL; + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rs2 = (inst >> 12) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int A = (inst >> 16) & 0x1; + int vlen = (inst >> 10) & 0x3; + int N = 1; + int i; - int ret = __naja_mem(vm, addr, &data, &offset); - if (ret < 0) - return ret; + if (V) { + N = 1 << (3 + vlen - size); - offset += naja->regs[ri] << u8; + if (0xf == rs2) + NAJA_PRINTF("vmul.f%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + else { + if (A) + NAJA_PRINTF("vmsub.f%dx%d X%d, X%d, X%d, X%d\n", 1 << size, N, rd, rs2, rs0, rs1); + else + NAJA_PRINTF("vmadd.f%dx%d X%d, X%d, X%d, X%d\n", 1 << size, N, rd, rs2, rs0, rs1); + } + } else { + if (0xf == rs2) + NAJA_PRINTF("fmul.%d d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1); + else { + if (A) + NAJA_PRINTF("fmsub.%d d%d, d%d, d%d, d%d\n", 1 << size, rd, rs2, rs0, rs1); + else + NAJA_PRINTF("fmadd.%d d%d, d%d, d%d, d%d\n", 1 << size, rd, rs2, rs0, rs1); + } + } - if (data == naja->stack) { - offset = -offset; + for (i = 0; i < N; i++) { + switch (size) { + case 2: + naja->fvec[rd].f[i] = naja->fvec[rs0].f[i] * naja->fvec[rs1].f[i]; - assert(offset > 0); + if (0xf != rs2) { + if (A) + naja->fvec[rd].f[i] = naja->fvec[rs2].f[i] - naja->fvec[rd].f[i]; + else + naja->fvec[rd].f[i] += naja->fvec[rs2].f[i]; + } + break; + case 3: + naja->fvec[rd].d[i] = naja->fvec[rs0].d[i] * naja->fvec[rs1].d[i]; + + if (0xf != rs2) { + if (A) + naja->fvec[rd].d[i] = naja->fvec[rs2].d[i] - naja->fvec[rd].d[i]; + else + naja->fvec[rd].d[i] += naja->fvec[rs2].d[i]; + } + break; + default: + scf_loge("\n"); + return -1; + break; + }; + } - if (naja->size < offset) { - scf_loge("\n"); - return -1; - } + naja->ip += 4; + return 0; +} - offset -= 1 << SH; - } +static int __naja_fdiv(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - switch (SH) { - case 2: - NAJA_PRINTF("fstr f%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int vlen = (inst >> 10) & 0x3; + int N = 1; + int i; - *(float*)(data + offset) = naja->fvec[rd].d[0]; - break; + if (V) { + N = 1 << (3 + vlen - size); - case 3: - NAJA_PRINTF("fstr d%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + NAJA_PRINTF("vdiv.f%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + } else + NAJA_PRINTF("fdiv.%d d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1); - *(double*)(data + offset) = naja->fvec[rd].d[0]; - break; - default: - scf_loge("\n"); - return -1; - break; - }; + for (i = 0; i < N; i++) { + switch (size) { + case 2: + naja->fvec[rd].f[i] = naja->fvec[rs0].f[i] / naja->fvec[rs1].f[i]; + break; + case 3: + naja->fvec[rd].d[i] = naja->fvec[rs0].d[i] / naja->fvec[rs1].d[i]; + break; + default: + scf_loge("\n"); + return -1; + break; + }; + } naja->ip += 4; return 0; } -static int __naja_str_disp(scf_vm_t* vm, uint32_t inst) +static int __naja_fldr_disp(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s13 = (inst >> 5) & 0x1fff; + int rb = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int A = (inst >> 16) & 0x1; + int vlen = (inst >> 10) & 0x3; + int s13 = (inst >> 4) & 0x1fff; + int N = 1; + int i; if (s13 & 0x1000) s13 |= 0xffffe000; + if (V) { + N = 1 << (3 + vlen - size); + + if (A) + NAJA_PRINTF("vldr.f%dx%d X%d, [%s]!\n", 1 << size, N, rd, __naja_reg[rb]); + else + NAJA_PRINTF("vldr.f%dx%d X%d, [%s]\n", 1 << size, N, rd, __naja_reg[rb]); + } else + NAJA_PRINTF("fldr.%d d%d, [%s, %d]\n", 1 << size, rd, __naja_reg[rb], s13 << size); + int64_t addr = naja->regs[rb]; int64_t offset = 0; uint8_t* data = NULL; @@ -1234,58 +1327,127 @@ static int __naja_str_disp(scf_vm_t* vm, uint32_t inst) if (ret < 0) return ret; - offset += s13 << SH; + offset += s13 << size; if (data == naja->stack) { offset = -offset; + scf_logd("offset0: %ld, size: %ld\n", offset, naja->size); assert(offset > 0); if (naja->size < offset) { - scf_loge("offset0: %ld, size: %ld\n", offset, naja->size); + scf_loge("offset: %ld, size: %ld\n", offset, naja->size); return -EINVAL; } - offset -= 1 << SH; + offset -= N << size; } - switch (SH) { - case 0: - *(uint8_t*)(data + offset) = naja->regs[rd]; + for (i = 0; i < N; i++) { + switch (size) { + case 2: + naja->fvec[rd].f[i] = *(float*)(data + offset + (i << 2)); + break; + case 3: + naja->fvec[rd].d[i] = *(double*)(data + offset + (i << 3)); + break; + default: + scf_loge("size: %d\n", size); + return -1; + break; + }; + } - NAJA_PRINTF("strb r%d, [r%d, %d]\n", rd, rb, s13); - break; + if (A) + naja->regs[rb] += offset + (N << size); - case 1: - *(uint16_t*)(data + offset) = naja->regs[rd]; + naja->ip += 4; + return 0; +} - NAJA_PRINTF("strw r%d, [r%d, %d]\n", rd, rb, s13 << 1); - break; +static int __naja_fstr_disp(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - case 2: - *(uint32_t*)(data + offset) = naja->regs[rd]; + int rb = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int A = (inst >> 16) & 0x1; + int vlen = (inst >> 10) & 0x3; + int s13 = (inst >> 4) & 0x1fff; + int N = 1; + int i; - NAJA_PRINTF("strl r%d, [r%d, %d], s13: %d, %d, %p\n", rd, rb, s13 << 2, s13, *(uint32_t*)(data + offset), data + offset); - break; + if (s13 & 0x1000) + s13 |= 0xffffe000; - default: - *(uint64_t*)(data + offset) = naja->regs[rd]; + if (V) { + N = 1 << (3 + vlen - size); - NAJA_PRINTF("str r%d, [r%d, %d]\n", rd, rb, s13 << 3); - break; - }; + if (A) + NAJA_PRINTF("vstr.f%dx%d X%d, [%s]!\n", 1 << size, N, rd, __naja_reg[rb]); + else + NAJA_PRINTF("vstr.f%dx%d X%d, [%s]\n", 1 << size, N, rd, __naja_reg[rb]); + } else + NAJA_PRINTF("fstr.%d d%d, [%s, %d]\n", 1 << size, rd, __naja_reg[rb], s13 << size); + + int64_t addr = naja->regs[rb]; + int64_t offset = 0; + uint8_t* data = NULL; + + int ret = __naja_mem(vm, addr, &data, &offset); + if (ret < 0) + return ret; + + offset += s13 << size; + + if (data == naja->stack) { + offset = -offset; + + assert(offset > 0); + + if (naja->size < offset) { + scf_loge("offset0: %ld, size: %ld\n", offset, naja->size); + return -EINVAL; + } + + offset -= N << size; + } + + for (i = 0; i < N; i++) { + switch (size) { + case 2: + *(float*)(data + offset + (i << 2)) = naja->fvec[rd].f[i]; + break; + case 3: + *(double*)(data + offset + (i << 3)) = naja->fvec[rd].d[i]; + break; + default: + scf_loge("size: %d\n", size); + return -1; + break; + }; + } + + if (A) + naja->regs[rb] += offset + (N << size); naja->ip += 4; return 0; } -static int __naja_push(scf_vm_t* vm, uint32_t inst) +static int __naja_fldr_sib(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; + int rb = inst & 0xf; + int ri = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int uimm6 = (inst >> 10) & 0x3f; + + NAJA_PRINTF("fldr.%d d%d, [%s, %s, %d]\n", 1 << size, rd, __naja_reg[rb], __naja_reg[ri], uimm6); int64_t addr = naja->regs[rb]; int64_t offset = 0; @@ -1295,178 +1457,822 @@ static int __naja_push(scf_vm_t* vm, uint32_t inst) if (ret < 0) return ret; + offset += naja->regs[ri] << uimm6; + if (data == naja->stack) { offset = -offset; - scf_logd("offset0: %ld, size: %ld\n", offset, naja->size); + assert(offset > 0); - assert(offset >= 0); + if (naja->size < offset) { + scf_loge("\n"); + return -1; + } - offset += 1 << SH; + offset -= 1 << size; + } - if (naja->size < offset) { - data = realloc(naja->stack, offset + STACK_INC); - if (!data) - return -ENOMEM; + switch (size) { + case 2: + naja->fvec[rd].f[0] = *(float*)(data + offset); + break; + case 3: + naja->fvec[rd].d[0] = *(double*)(data + offset); + break; + default: + scf_loge("\n"); + return -1; + break; + }; - naja->stack = data; - naja->size = offset + STACK_INC; - } + naja->ip += 4; + return 0; +} - offset -= 1 << SH; +static int __naja_fmov(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rs = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int vlen = (inst >> 10) & 0x3; + int N = 1; + int i; + + if (V) { + N = 1 << (3 + vlen - size); + + NAJA_PRINTF("vmov.f%dx%d X%d, X%d\n", 1 << size, N, rd, rs); + } else + NAJA_PRINTF("fmov.%d d%d, d%d\n", 1 << size, rd, rs); + + for (i = 0; i < N; i++) { + switch (size) { + case 2: + naja->fvec[rd].f[i] = naja->fvec[rs].f[i]; + break; + case 3: + naja->fvec[rd].d[i] = naja->fvec[rs].d[i]; + break; + default: + scf_loge("size: %d\n", size); + return -1; + break; + }; } - switch (SH) { - case 0: - *(uint8_t*)(data + offset) = naja->regs[rd]; + naja->ip += 4; + return 0; +} - NAJA_PRINTF("pushb r%d, [r%d]\n", rd, rb); - break; +static uint64_t __naja_to_u64(scf_vm_naja_t* naja, int i, int r, int sign, int size) +{ + uint64_t ret; + switch (size) { + case 0: + ret = naja->fvec[r].b[i]; + break; case 1: - *(uint16_t*)(data + offset) = naja->regs[rd]; + ret = naja->fvec[r].w[i]; + break; + case 2: + ret = naja->fvec[r].l[i]; + break; + default: + ret = naja->fvec[r].q[i]; + break; + }; + + if (sign) + return scf_sign_extend(ret, 8 << size); + return scf_zero_extend(ret, 8 << size); +} - NAJA_PRINTF("pushw r%d, [r%d]\n", rd, rb); +static void __naja_u64_to_int(scf_vm_naja_t* naja, int i, int r, int size, uint64_t src) +{ + switch (size) { + case 0: + naja->fvec[r].b[i] = src; break; + case 1: + naja->fvec[r].w[i] = src; + break; + case 2: + naja->fvec[r].l[i] = src; + break; + default: + naja->fvec[r].q[i] = src; + break; + }; +} +static void __naja_u64_to_float(scf_vm_naja_t* naja, int i, int r, int size, uint64_t src) +{ + switch (size) { case 2: - *(uint32_t*)(data + offset) = naja->regs[rd]; + naja->fvec[r].f[i] = src; + break; + case 3: + naja->fvec[r].d[i] = src; + break; + default: + break; + }; +} + +static double __naja_to_double(scf_vm_naja_t* naja, int i, int r, int size) +{ + double ret; - NAJA_PRINTF("pushl r%d, [r%d], %d, %p\n", rd, rb, *(uint32_t*)(data + offset), data + offset); + switch (size) { + case 2: + ret = naja->fvec[r].f[i]; + break; + case 3: + ret = naja->fvec[r].d[i]; break; + default: + ret = 0.0; + break; + }; + return ret; +} + +static void __naja_double_to_int(scf_vm_naja_t* naja, int i, int r, int size, double src) +{ + switch (size) { + case 0: + naja->fvec[r].b[i] = src; + break; + case 1: + naja->fvec[r].w[i] = src; + break; + case 2: + naja->fvec[r].l[i] = src; + break; default: - *(uint64_t*)(data + offset) = naja->regs[rd]; + naja->fvec[r].q[i] = src; + break; + }; +} - NAJA_PRINTF("pushq r%d, [r%d]\n", rd, rb); +static void __naja_double_to_float(scf_vm_naja_t* naja, int i, int r, int size, double src) +{ + switch (size) { + case 2: + naja->fvec[r].f[i] = src; + break; + case 3: + naja->fvec[r].d[i] = src; + break; + default: break; }; +} - naja->regs[rb] -= 1 << SH; +static int __naja_fcvt(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rs = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int dsize = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int Id = (inst >> 13) & 0x1; + int sd = (inst >> 12) & 0x1; + int vlen = (inst >> 10) & 0x3; + int Is = (inst >> 7) & 0x1; + int ss = (inst >> 6) & 0x1; + int ssize = (inst >> 4) & 0x3; + + static char IS_array[2][2] = { + 'F', 'F', + 'U', 'I' + }; + + static char R_array[2] = {'d', 'r'}; + + if (V) { + int N = 1 << (3 + vlen - dsize); + int i; + + NAJA_PRINTF("vcvt%c%dto%c%dx%d X%d, X%d\n", + IS_array[Is][ss], 1 << ssize, + IS_array[Id][sd], 1 << dsize, + N, rd, rs); + + for (i = 0; i < N; i++) { + if (Is) { + uint64_t src = __naja_to_u64(naja, i, rs, ss, ssize); + if (Id) + __naja_u64_to_int(naja, i, rd, dsize, src); + else + __naja_u64_to_float(naja, i, rd, dsize, src); + + } else { + double src = __naja_to_double(naja, i, rs, ssize); + if (Id) + __naja_double_to_int(naja, i, rd, dsize, src); + else + __naja_double_to_float(naja, i, rd, dsize, src); + } + } + } else { + NAJA_PRINTF("fcvt%c%dto%c%d %c%d, %c%d\n", + IS_array[Is][ss], 1 << ssize, + IS_array[Id][sd], 1 << dsize, + R_array[Id], rd, R_array[Is], rs); + + if (Is) { + uint64_t src; + if (ss) + src = scf_sign_extend(naja->regs[rs], 8 << ssize); + else + src = scf_zero_extend(naja->regs[rs], 8 << ssize); + + if (Id) + naja->regs[rd] = src; + else + __naja_u64_to_float(naja, 0, rd, dsize, src); + + } else { + double src = __naja_to_double(naja, 0, rs, ssize); + + if (Id) + naja->regs[rd] = src; + else + __naja_u64_to_float(naja, 0, rd, dsize, src); + } + } - naja->ip += 4; return 0; } -static int __naja_str_sib(scf_vm_t* vm, uint32_t inst) +static int __naja_fneg(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int ri = (inst >> 5) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int u8 = (inst >> 10) & 0xff; + int rs = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int vlen = (inst >> 10) & 0x3; + int N = 1; + int i; - int64_t addr = naja->regs[rb]; - int64_t offset = 0; - uint8_t* data = NULL; + if (V) { + N = 1 << (3 + vlen - size); - int ret = __naja_mem(vm, addr, &data, &offset); - if (ret < 0) - return ret; + NAJA_PRINTF("vneg.f%dx%d X%d, X%d\n", 1 << size, N, rd, rs); + } else + NAJA_PRINTF("fneg.%d d%d, d%d\n", 1 << size, rd, rs); + + for (i = 0; i < N; i++) { + switch (size) { + case 2: + naja->fvec[rd].f[i] = -naja->fvec[rs].f[i]; + break; + case 3: + naja->fvec[rd].d[i] = -naja->fvec[rs].d[i]; + break; + default: + scf_loge("\n"); + return -1; + break; + }; + } - offset += naja->regs[ri] << u8; + return 0; +} - if (data == naja->stack) { - offset = -offset; +static int __naja_vadd(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - assert(offset >= 0); + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int vlen = (inst >> 10) & 0x3; - if (naja->size < offset) { - scf_loge("\n"); - return -1; - } + int N = 1 << (3 + vlen - size); + int i; + + NAJA_PRINTF("vadd.u%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + + for (i = 0; i < N; i++) { + switch (size) { + case 0: + naja->fvec[rd].b[i] = naja->fvec[rs0].b[i] + naja->fvec[rs1].b[i]; + break; + case 1: + naja->fvec[rd].w[i] = naja->fvec[rs0].w[i] + naja->fvec[rs1].w[i]; + break; + case 2: + naja->fvec[rd].l[i] = naja->fvec[rs0].l[i] + naja->fvec[rs1].l[i]; + break; + case 3: + naja->fvec[rd].q[i] = naja->fvec[rs0].q[i] + naja->fvec[rs1].q[i]; + break; + default: + scf_loge("\n"); + return -1; + break; + }; + } + + return 0; +} + +static int __naja_vsub(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int cmp = (inst >> 16) & 0x1; + int vlen = (inst >> 10) & 0x3; + + int N = 1 << (3 + vlen - size); + int i; + + if (cmp) + NAJA_PRINTF("vcmp.u%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + else + NAJA_PRINTF("vsub.u%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + + for (i = 0; i < N; i++) { + switch (size) { + case 0: + naja->fvec[rd].b[i] = naja->fvec[rs0].b[i] - naja->fvec[rs1].b[i]; + if (cmp) { + int8_t i = naja->fvec[rd].b[i]; + if (0 == i) + naja->fvec[rd].b[i] = 0x1; + else if (i > 0) + naja->fvec[rd].b[i] = 0x4; + else + naja->fvec[rd].b[i] = 0x2; + } + break; + case 1: + naja->fvec[rd].w[i] = naja->fvec[rs0].w[i] - naja->fvec[rs1].w[i]; + if (cmp) { + int16_t i = naja->fvec[rd].w[i]; + if (0 == i) + naja->fvec[rd].w[i] = 0x1; + else if (i > 0) + naja->fvec[rd].w[i] = 0x4; + else + naja->fvec[rd].w[i] = 0x2; + } + break; + case 2: + naja->fvec[rd].l[i] = naja->fvec[rs0].l[i] - naja->fvec[rs1].l[i]; + if (cmp) { + int32_t i = naja->fvec[rd].l[i]; + if (0 == i) + naja->fvec[rd].l[i] = 0x1; + else if (i > 0) + naja->fvec[rd].l[i] = 0x4; + else + naja->fvec[rd].l[i] = 0x2; + } + break; + case 3: + naja->fvec[rd].q[i] = naja->fvec[rs0].q[i] - naja->fvec[rs1].q[i]; + if (cmp) { + int64_t i = naja->fvec[rd].q[i]; + if (0 == i) + naja->fvec[rd].q[i] = 0x1; + else if (i > 0) + naja->fvec[rd].q[i] = 0x4; + else + naja->fvec[rd].q[i] = 0x2; + } + break; + default: + scf_loge("\n"); + return -1; + break; + }; + } + + return 0; +} + +static int __naja_vmul(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rs2 = (inst >> 12) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + int A = (inst >> 16) & 0x1; + int vlen = (inst >> 10) & 0x3; + + int N = 1 << (3 + vlen - size); + int i; + + static char s_array[2] = {'u', 'i'}; + static char* A_array[2] = {"madd", "msub"}; + + if (0xf == rs2) + NAJA_PRINTF("vmul.%c%dx%d X%d, X%d, X%d\n", s_array[s], 1 << size, N, rd, rs0, rs1); + else + NAJA_PRINTF("v%s.%c%dx%d X%d, X%d, X%d, X%d\n", A_array[A], s_array[s], 1 << size, N, rd, rs2, rs0, rs1); + + for (i = 0; i < N; i++) { + switch (size) { + case 0: + naja->fvec[rd].b[i] = naja->fvec[rs0].b[i] * naja->fvec[rs1].b[i]; + if (0xf != rs2) { + if (A) + naja->fvec[rd].b[i] = naja->fvec[rs2].b[i] - naja->fvec[rd].b[i]; + else + naja->fvec[rd].b[i] += naja->fvec[rs2].b[i]; + } + break; + case 1: + naja->fvec[rd].w[i] = naja->fvec[rs0].w[i] * naja->fvec[rs1].w[i]; + if (0xf != rs2) { + if (A) + naja->fvec[rd].w[i] = naja->fvec[rs2].w[i] - naja->fvec[rd].w[i]; + else + naja->fvec[rd].w[i] += naja->fvec[rs2].w[i]; + } + break; + case 2: + naja->fvec[rd].l[i] = naja->fvec[rs0].l[i] * naja->fvec[rs1].l[i]; + if (0xf != rs2) { + if (A) + naja->fvec[rd].l[i] = naja->fvec[rs2].l[i] - naja->fvec[rd].l[i]; + else + naja->fvec[rd].l[i] += naja->fvec[rs2].l[i]; + } + break; + case 3: + naja->fvec[rd].q[i] = naja->fvec[rs0].q[i] * naja->fvec[rs1].q[i]; + if (0xf != rs2) { + if (A) + naja->fvec[rd].q[i] = naja->fvec[rs2].q[i] - naja->fvec[rd].q[i]; + else + naja->fvec[rd].q[i] += naja->fvec[rs2].q[i]; + } + break; + default: + scf_loge("\n"); + return -1; + break; + }; + } + + return 0; +} + +static int __naja_vdiv(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + int vlen = (inst >> 10) & 0x3; + + int N = 1 << (3 + vlen - size); + int i; + + if (s) + NAJA_PRINTF("vdiv.i%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + else + NAJA_PRINTF("vdiv.u%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + + for (i = 0; i < N; i++) { + switch (size) { + case 0: + naja->fvec[rd].b[i] = naja->fvec[rs0].b[i] / naja->fvec[rs1].b[i]; + break; + case 1: + naja->fvec[rd].w[i] = naja->fvec[rs0].w[i] / naja->fvec[rs1].w[i]; + break; + case 2: + naja->fvec[rd].l[i] = naja->fvec[rs0].l[i] / naja->fvec[rs1].l[i]; + break; + case 3: + naja->fvec[rd].q[i] = naja->fvec[rs0].q[i] / naja->fvec[rs1].q[i]; + break; + default: + scf_loge("\n"); + return -1; + break; + }; + } + + return 0; +} + +static int __naja_vand(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int teq = (inst >> 16) & 0x1; + int vlen = (inst >> 10) & 0x3; + + int N = 1 << (3 + vlen - size); + int i; + + if (teq) + NAJA_PRINTF("vteq.u%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + else + NAJA_PRINTF("vand.u%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + + for (i = 0; i < N; i++) { + switch (size) { + case 0: + naja->fvec[rd].b[i] = naja->fvec[rs0].b[i] & naja->fvec[rs1].b[i]; + if (teq) + naja->fvec[rd].b[i] = !!naja->fvec[rd].b[i]; + break; + case 1: + naja->fvec[rd].w[i] = naja->fvec[rs0].w[i] & naja->fvec[rs1].w[i]; + if (teq) + naja->fvec[rd].w[i] = !!naja->fvec[rd].w[i]; + break; + case 2: + naja->fvec[rd].l[i] = naja->fvec[rs0].l[i] & naja->fvec[rs1].l[i]; + if (teq) + naja->fvec[rd].l[i] = !!naja->fvec[rd].l[i]; + break; + case 3: + naja->fvec[rd].q[i] = naja->fvec[rs0].q[i] & naja->fvec[rs1].q[i]; + if (teq) + naja->fvec[rd].q[i] = !!naja->fvec[rd].q[i]; + break; + default: + scf_loge("\n"); + return -1; + break; + }; + } + + return 0; +} + +static int __naja_vor(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - offset -= 1 << SH; - } + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int vlen = (inst >> 10) & 0x3; - switch (SH) { - case 0: - NAJA_PRINTF("strb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + int N = 1 << (3 + vlen - size); + int i; - *(uint8_t*)(data + offset) = naja->regs[rd]; - break; + NAJA_PRINTF("vor.u%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); - case 1: - NAJA_PRINTF("strw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + for (i = 0; i < N; i++) { + switch (size) { + case 0: + naja->fvec[rd].b[i] = naja->fvec[rs0].b[i] | naja->fvec[rs1].b[i]; + break; + case 1: + naja->fvec[rd].w[i] = naja->fvec[rs0].w[i] | naja->fvec[rs1].w[i]; + break; + case 2: + naja->fvec[rd].l[i] = naja->fvec[rs0].l[i] | naja->fvec[rs1].l[i]; + break; + case 3: + naja->fvec[rd].q[i] = naja->fvec[rs0].q[i] | naja->fvec[rs1].q[i]; + break; + default: + scf_loge("\n"); + return -1; + break; + }; + } - *(uint16_t*)(data + offset) = naja->regs[rd]; - break; + return 0; +} - case 2: - NAJA_PRINTF("strl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); +static int __naja_vmov(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - *(uint32_t*)(data + offset) = naja->regs[rd]; - break; + int rs = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int SH = (inst >> 16) & 0x3; + int IMM = (inst >> 15) & 0x3; + int vlen = (inst >> 10) & 0x3; + int uimm6 = (inst >> 4) & 0x3f; - default: - NAJA_PRINTF("str r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + int N = 1 << (3 + vlen - size); + int i; - *(uint64_t*)(data + offset) = naja->regs[rd]; - break; - }; + if (IMM) { + if (0 == uimm6) + NAJA_PRINTF("vmov.u%dx%d X%d, X%d\n", 1 << size, N, rd, rs); + else + NAJA_PRINTF("vmov.u%dx%d X%d, X%d %s %d\n", 1 << size, N, rd, rs, __naja_SH[SH], uimm6); + } else + NAJA_PRINTF("vmov.u%dx%d X%d, X%d %s %s\n", 1 << size, N, rd, rs, __naja_SH[SH], __naja_reg[rs1]); + + for (i = 0; i < N; i++) { + switch (size) { + case 0: + if (!IMM) + uimm6 = naja->fvec[rs1].b[i]; + + if (0 == SH) + naja->fvec[rd].b[i] = naja->fvec[rs].b[i] << uimm6; + else if (1 == SH) + naja->fvec[rd].b[i] = naja->fvec[rs].b[i] >> uimm6; + else if (2 == SH) + naja->fvec[rd].b[i] = (int8_t)naja->fvec[rs].b[i] >> uimm6; + else { + scf_loge("\n"); + return -1; + } + break; + case 1: + if (!IMM) + uimm6 = naja->fvec[rs1].w[i]; + + if (0 == SH) + naja->fvec[rd].w[i] = naja->fvec[rs].w[i] << uimm6; + else if (1 == SH) + naja->fvec[rd].w[i] = naja->fvec[rs].w[i] >> uimm6; + else if (2 == SH) + naja->fvec[rd].w[i] = (int8_t)naja->fvec[rs].w[i] >> uimm6; + else { + scf_loge("\n"); + return -1; + } + break; + case 2: + if (!IMM) + uimm6 = naja->fvec[rs1].l[i]; + + if (0 == SH) + naja->fvec[rd].l[i] = naja->fvec[rs].l[i] << uimm6; + else if (1 == SH) + naja->fvec[rd].l[i] = naja->fvec[rs].l[i] >> uimm6; + else if (2 == SH) + naja->fvec[rd].l[i] = (int8_t)naja->fvec[rs].l[i] >> uimm6; + else { + scf_loge("\n"); + return -1; + } + break; + case 3: + if (!IMM) + uimm6 = naja->fvec[rs1].q[i]; + + if (0 == SH) + naja->fvec[rd].q[i] = naja->fvec[rs].q[i] << uimm6; + else if (1 == SH) + naja->fvec[rd].q[i] = naja->fvec[rs].q[i] >> uimm6; + else if (2 == SH) + naja->fvec[rd].q[i] = (int8_t)naja->fvec[rs].q[i] >> uimm6; + else { + scf_loge("\n"); + return -1; + } + break; + default: + scf_loge("\n"); + return -1; + break; + }; + } - naja->ip += 4; return 0; } -static int __naja_and(scf_vm_t* vm, uint32_t inst) +static int __naja_vnot(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; + int rs = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int A = (inst >> 16) & 0x3; + int vlen = (inst >> 10) & 0x3; - if (0x3 == SH) { - uint64_t uimm14 = (inst >> 5) & 0x3fff; + int N = 1 << (3 + vlen - size); + int i; - naja->regs[rd] = naja->regs[rs0] & uimm14; - } else { - uint64_t uimm9 = (inst >> 10) & 0x1ff; - int rs1 = (inst >> 5) & 0x1f; + if (A) + NAJA_PRINTF("vnot.u%dx%d X%d, X%d\n", 1 << size, N, rd, rs); + else + NAJA_PRINTF("vneg.u%dx%d X%d, X%d\n", 1 << size, N, rd, rs); - if (0 == SH) - naja->regs[rd] = naja->regs[rs0] & (naja->regs[rs1] << uimm9); - else if (1 == SH) - naja->regs[rd] = naja->regs[rs0] & (naja->regs[rs1] >> uimm9); - else - naja->regs[rd] = naja->regs[rs0] & (((int64_t)naja->regs[rs1]) >> uimm9); + for (i = 0; i < N; i++) { + switch (size) { + case 0: + if (A) + naja->fvec[rd].b[i] = ~naja->fvec[rs].b[i]; + else + naja->fvec[rd].b[i] = -naja->fvec[rs].b[i]; + break; + case 1: + if (A) + naja->fvec[rd].w[i] = ~naja->fvec[rs].w[i]; + else + naja->fvec[rd].w[i] = -naja->fvec[rs].w[i]; + break; + case 2: + if (A) + naja->fvec[rd].l[i] = ~naja->fvec[rs].l[i]; + else + naja->fvec[rd].l[i] = -naja->fvec[rs].l[i]; + break; + case 3: + if (A) + naja->fvec[rd].q[i] = ~naja->fvec[rs].q[i]; + else + naja->fvec[rd].q[i] = -naja->fvec[rs].q[i]; + break; + default: + scf_loge("\n"); + return -1; + break; + }; } - if (31 == rd) - naja->flags = !naja->regs[rd]; - - naja->ip += 4; return 0; } -static int __naja_or(scf_vm_t* vm, uint32_t inst) +static int __naja_vmov_imm(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; + int u16 = inst & 0xffff; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int vlen = (inst >> 16) & 0x3; + int mvn = (inst >> 25) & 0x1; - if (0x3 == SH) { - uint64_t uimm14 = (inst >> 5) & 0x3fff; + int N = 1 << (3 + vlen - size); + int i; - naja->regs[rd] = naja->regs[rs0] | uimm14; - } else { - uint64_t uimm9 = (inst >> 10) & 0x1ff; - int rs1 = (inst >> 5) & 0x1f; + if (mvn) + NAJA_PRINTF("vmvn.u%dx%d X%d, %#x\n", 1 << size, N, rd, u16); + else + NAJA_PRINTF("vmov.u%dx%d X%d, %#x\n", 1 << size, N, rd, u16); - if (0 == SH) - naja->regs[rd] = naja->regs[rs0] | (naja->regs[rs1] << uimm9); - else if (1 == SH) - naja->regs[rd] = naja->regs[rs0] | (naja->regs[rs1] >> uimm9); - else - naja->regs[rd] = naja->regs[rs0] | (((int64_t)naja->regs[rs1]) >> uimm9); + for (i = 0; i < N; i++) { + switch (size) { + case 0: + if (mvn) + naja->fvec[rd].b[i] = ~u16; + else + naja->fvec[rd].b[i] = u16; + break; + case 1: + if (mvn) + naja->fvec[rd].w[i] = ~u16; + else + naja->fvec[rd].w[i] = u16; + break; + case 2: + if (mvn) + naja->fvec[rd].l[i] = ~u16; + else + naja->fvec[rd].l[i] = u16; + break; + case 3: + if (mvn) + naja->fvec[rd].q[i] = ~u16; + else + naja->fvec[rd].q[i] = u16; + break; + default: + scf_loge("\n"); + return -1; + break; + }; } - naja->ip += 4; return 0; } @@ -1570,8 +2376,6 @@ static int __naja_jmp_reg(scf_vm_t* vm, uint32_t inst) naja->regs[3], naja->regs[4], naja->regs[5], - naja->regs[6], - naja->regs[7], naja->fvec[0].d[0], naja->fvec[1].d[0], naja->fvec[2].d[0], @@ -1592,7 +2396,6 @@ static int __naja_jmp_reg(scf_vm_t* vm, uint32_t inst) return 0; } - static int __naja_call_reg(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; @@ -1626,8 +2429,6 @@ static int __naja_call_reg(scf_vm_t* vm, uint32_t inst) naja->regs[3], naja->regs[4], naja->regs[5], - naja->regs[6], - naja->regs[7], naja->fvec[0].d[0], naja->fvec[1].d[0], naja->fvec[2].d[0], @@ -1646,17 +2447,52 @@ static int __naja_call_reg(scf_vm_t* vm, uint32_t inst) return 0; } +static int __naja_setcc(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rd = (inst >> 21) & 0x1f; + int cc = (inst >> 1) & 0xf; + + naja->regs[rd] = 0 == (cc & naja->flags); + + if (SCF_VM_Z == cc) + NAJA_PRINTF("setz r%d\n", rd); + + else if (SCF_VM_NZ == cc) + NAJA_PRINTF("setnz r%d\n", rd); + + else if (SCF_VM_GE == cc) + NAJA_PRINTF("setge r%d\n", rd); + + else if (SCF_VM_GT == cc) + NAJA_PRINTF("setgt r%d\n", rd); + + else if (SCF_VM_LT == cc) + NAJA_PRINTF("setlt r%d\n", rd); + + else if (SCF_VM_LE == cc) + NAJA_PRINTF("setle r%d\n", rd); + else { + scf_loge("inst: %#x\n", inst); + return -EINVAL; + } + + naja->ip += 4; + return 0; +} + static int __naja_adrp(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rd = (inst >> 21) & 0x1f; + int rd = (inst >> 21) & 0xf; int s21 = inst & 0x1fffff; if (s21 & 0x100000) s21 |= ~0x1fffff; - naja->regs[rd] = (naja->ip + ((int64_t)s21 << 14)) & ~0x3fffULL; + naja->regs[rd] = (naja->ip + ((int64_t)s21 << 12)) & ~0xfffULL; if (naja->regs[rd] >= 0x800000) naja->regs[rd] = naja->regs[rd] - vm->data->addr + (uint64_t)vm->data->data; @@ -1698,222 +2534,63 @@ static int __naja_ret(scf_vm_t* vm, uint32_t inst) return 0; } -static int __naja_setcc(scf_vm_t* vm, uint32_t inst) +static int __naja_spop(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rd = (inst >> 21) & 0x1f; - int cc = (inst >> 1) & 0xf; - - naja->regs[rd] = 0 == (cc & naja->flags); - - if (SCF_VM_Z == cc) - NAJA_PRINTF("setz r%d\n", rd); - - else if (SCF_VM_NZ == cc) - NAJA_PRINTF("setnz r%d\n", rd); - - else if (SCF_VM_GE == cc) - NAJA_PRINTF("setge r%d\n", rd); - - else if (SCF_VM_GT == cc) - NAJA_PRINTF("setgt r%d\n", rd); - - else if (SCF_VM_LT == cc) - NAJA_PRINTF("setlt r%d\n", rd); - - else if (SCF_VM_LE == cc) - NAJA_PRINTF("setle r%d\n", rd); - else { - scf_loge("inst: %#x\n", inst); - return -EINVAL; - } + int rb = inst & 0xf; + int sr = (inst >> 21) & 0xf; - naja->ip += 4; + NAJA_PRINTF("spop sr%d, [%s]\n", sr, __naja_reg[rb]); return 0; } -static int __naja_mov(scf_vm_t* vm, uint32_t inst) +static int __naja_spush(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s = (inst >> 18) & 0x1; - int opt = (inst >> 16) & 0x3; - - if (0 == opt) { - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; - - if (0 == SH) { - naja->regs[rd] = naja->regs[rs0] << naja->regs[rs1]; - - NAJA_PRINTF("mov r%d, r%d LSL r%d\n", rd, rs0, rs1); - - } else if (1 == SH) { - naja->regs[rd] = naja->regs[rs0] >> naja->regs[rs1]; - - NAJA_PRINTF("mov r%d, r%d LSR r%d\n", rd, rs0, rs1); - } else { - naja->regs[rd] = (int64_t)naja->regs[rs0] >> naja->regs[rs1]; - - NAJA_PRINTF("mov r%d, r%d ASR r%d\n", rd, rs0, rs1); - } - - } else if (1 == opt) { - int rs0 = inst & 0x1f; - int u11 = (inst >> 5) & 0x7ff; - - if (0 == SH) { - naja->regs[rd] = naja->regs[rs0] << u11; - - if (0 == u11) - NAJA_PRINTF("mov r%d, r%d\n", rd, rs0); - else - NAJA_PRINTF("mov r%d, r%d LSL %d\n", rd, rs0, u11); - - } else if (1 == SH) { - naja->regs[rd] = naja->regs[rs0] >> u11; - - NAJA_PRINTF("mov r%d, r%d LSR %d\n", rd, rs0, u11); - } else { - naja->regs[rd] = (int64_t)naja->regs[rs0] >> u11; - - NAJA_PRINTF("mov r%d, r%d ASR %d\n", rd, rs0, u11); - } - - } else if (2 == opt) { - int rs = inst & 0x1f; - - switch (SH) { - case 0: - if (s) { - NAJA_PRINTF("movsb r%d, r%d\n", rd, rs); - - naja->regs[rd] = (int8_t)naja->regs[rs]; - } else { - naja->regs[rd] = (uint8_t)naja->regs[rs]; - - NAJA_PRINTF("movzb r%d, r%d\n", rd, rs); - } - break; - - case 1: - if (s) { - NAJA_PRINTF("movsw r%d, r%d\n", rd, rs); - - naja->regs[rd] = (int16_t)naja->regs[rs]; - } else { - naja->regs[rd] = (uint16_t)naja->regs[rs]; - - NAJA_PRINTF("movzw r%d, r%d\n", rd, rs); - } - break; - - case 2: - if (s) { - NAJA_PRINTF("movsl r%d, r%d\n", rd, rs); - - naja->regs[rd] = (int32_t)naja->regs[rs]; - } else { - naja->regs[rd] = (uint32_t)naja->regs[rs]; - - NAJA_PRINTF("movzl r%d, r%d\n", rd, rs); - } - break; - default: - if (s) { - NAJA_PRINTF("NEG r%d, r%d\n", rd, rs); - - naja->regs[rd] = -naja->regs[rs]; - } else { - naja->regs[rd] = ~naja->regs[rs]; - - NAJA_PRINTF("NOT r%d, r%d\n", rd, rs); - } - break; - }; - - } else { - uint64_t u16 = inst & 0xffff; - - if (s) { - naja->regs[rd] = ~u16; - - NAJA_PRINTF("mvn r%d, %#lx\n", rd, u16); - } else { - if (0 == SH) { - NAJA_PRINTF("mov r%d, %#lx\n", rd, u16); - - naja->regs[rd] = u16; - } else { - naja->regs[rd] |= u16 << SH; - - NAJA_PRINTF("mov r%d, %#lx << %d\n", rd, u16, 16 << SH); - } - } - } + int rb = inst & 0xf; + int sr = (inst >> 21) & 0xf; - naja->ip += 4; + NAJA_PRINTF("spush sr%d, [%s]\n", sr, __naja_reg[rb]); return 0; } -static int __naja_fmov(scf_vm_t* vm, uint32_t inst) +static int __naja_in(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s = (inst >> 18) & 0x1; - int opt = (inst >> 16) & 0x3; - - if (0 == opt) { - if (2 == SH) { - naja->fvec[rd].d[0] = naja->fvec[rs].d[0]; - - NAJA_PRINTF("fss2sd d%d, f%d\n", rd, rs); - - } else if (3 == SH) { - naja->fvec[rd].d[0] = naja->fvec[rs].d[0]; - - NAJA_PRINTF("fsd2ss f%d, d%d\n", rd, rs); - } else { - scf_loge("\n"); - return -EINVAL; - } - - } else if (1 == opt) { - if (s) { - naja->regs[rd] = (int64_t)naja->fvec[rs].d[0]; - - NAJA_PRINTF("cvtss2si r%d, f%d\n", rd, rs); - } else { - naja->regs[rd] = (uint64_t)naja->fvec[rs].d[0]; - - NAJA_PRINTF("cvtss2ui r%d, f%d\n", rd, rs); - } - - } else if (2 == opt) { + int u16 = inst & 0xffff; + int rd = (inst >> 21) & 0xf; + int D = (inst >> 17) & 0xf; - naja->fvec[rd].d[0] = (double)naja->regs[rs]; + if (D) + NAJA_PRINTF("out %s, %#x\n", __naja_reg[rd], u16); + else + NAJA_PRINTF("in %s, %#x\n", __naja_reg[rd], u16); + return 0; +} - NAJA_PRINTF("cvtsi2ss f%d, r%d\n", rd, rs); +static int __naja_smov(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - } else { - if (s) { - NAJA_PRINTF("fneg d%d, d%d\n", rd, rs); + int sr = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int D = (inst >> 17) & 0xf; - naja->fvec[rd].d[0] = -naja->fvec[rs].d[0]; - } else { - naja->fvec[rd].d[0] = naja->fvec[rs].d[0]; + if (D) + NAJA_PRINTF("smov sr%d, %s\n", sr, __naja_reg[rd]); + else + NAJA_PRINTF("smov %s, sr%d\n", __naja_reg[rd], sr); + return 0; +} - NAJA_PRINTF("fmov d%d, d%d\n", rd, rs); - } - } +static int __naja_iret(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - naja->ip += 4; + NAJA_PRINTF("iret\n"); return 0; } @@ -1925,19 +2602,20 @@ static naja_opcode_pt naja_opcodes[64] = __naja_div, // 3 __naja_ldr_disp, // 4 - __naja_pop, // 5 + __naja_and, // 5 __naja_str_disp, // 6 - __naja_push, // 7 + __naja_or, // 7 - __naja_and, // 8 - __naja_or, // 9 - __naja_jmp_disp, // 10 - __naja_jmp_reg, // 11 - __naja_setcc, // 12 - __naja_ldr_sib, // 13 - __naja_str_sib, // 14 - __naja_mov, // 15 + __naja_pop, // 8 + __naja_push, // 9 + + __naja_ldr_sib, // 10 + __naja_str_sib, // 11 + __naja_mov, // 12 + __naja_movx, // 13 + __naja_not, // 14 + NULL, // 15 __naja_fadd, // 16 __naja_fsub, // 17 @@ -1945,52 +2623,52 @@ static naja_opcode_pt naja_opcodes[64] = __naja_fdiv, // 19 __naja_fldr_disp,// 20 - __naja_fpop, // 21 + NULL, // 21 __naja_fstr_disp,// 22 - __naja_fpush, // 23 + NULL, // 23 NULL, // 24 NULL, // 25 - __naja_call_disp,// 26 - __naja_call_reg, // 27 - NULL, // 28 - __naja_fldr_sib, // 29 - __naja_fstr_sib, // 30 - __naja_fmov, // 31 - - NULL, // 32 - NULL, // 33 - NULL, // 34 - NULL, // 35 + __naja_fldr_sib, // 26 + NULL, // 27 + __naja_fmov, // 28 + __naja_fcvt, // 29 + __naja_fneg, // 30 + NULL, // 31 + + __naja_vadd, // 32 + __naja_vsub, // 33 + __naja_vmul, // 34 + __naja_vdiv, // 35 NULL, // 36 - NULL, // 37 + __naja_vand, // 37 NULL, // 38 - NULL, // 39 + __naja_vor, // 39 NULL, // 40 NULL, // 41 - __naja_adrp, // 42 + NULL, // 42 NULL, // 43 - NULL, // 44 + __naja_vmov, // 44 NULL, // 45 - NULL, // 46 - NULL, // 47 - - NULL, // 48 - NULL, // 49 - NULL, // 50 - NULL, // 51 - NULL, // 52 - NULL, // 53 - NULL, // 54 + __naja_vnot, // 46 + __naja_vmov_imm, // 47 + + __naja_jmp_disp, // 48 + __naja_call_disp,// 49 + __naja_jmp_reg, // 50 + __naja_call_reg, // 51 + __naja_setcc, // 52 + __naja_adrp, // 53 + __naja_ret, // 54 NULL, // 55 - __naja_ret, // 56 - NULL, // 57 - NULL, // 58 + __naja_spop, // 56 + __naja_spush, // 57 + __naja_in, // 58 NULL, // 59 - NULL, // 60 + __naja_smov, // 60 NULL, // 61 - NULL, // 62 + __naja_iret, // 62 NULL, // 63 }; @@ -2042,6 +2720,8 @@ static int __naja_vm_run(scf_vm_t* vm, const char* path, const char* sys) naja->regs[NAJA_REG_LR] = (uint64_t)__naja_vm_exit; + scf_logw("naja->regs[NAJA_REG_LR]: %#lx\n", naja->regs[NAJA_REG_LR]); + int n = 0; while ((uint64_t)__naja_vm_exit != naja->ip) { diff --git a/vm/scf_vm_naja_asm.c b/vm/scf_vm_naja_asm.c index 9f39624..3881645 100644 --- a/vm/scf_vm_naja_asm.c +++ b/vm/scf_vm_naja_asm.c @@ -1,31 +1,41 @@ #include"scf_vm.h" +static char* __naja_sign[] = {"", "s"}; +static char __naja_size[] = {'b', 'w', 'l', 'q'}; +static char __naja_float[] = {'B', 'H', 'S', 'D'}; + +static char* __naja_SH[] = { + "LSL", + "LSR", + "ASR", + "IMM" +}; + +static char* __naja_reg[] = +{ + "r0", "r1", "r2", "r3", "r4", + "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "fp", "lr", "sp", + "null" +}; + static int __naja_add(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; + int rs0 = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int SH = (inst >> 16) & 0x3; if (0x3 == SH) { - uint64_t uimm14 = (inst >> 5) & 0x3fff; - printf("add r%d, r%d, %lu\n", rd, rs0, uimm14); + uint64_t uimm12 = (inst >> 4) & 0xfff; + printf("add%c %s, %s, %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12); } else { - uint64_t uimm9 = (inst >> 10) & 0x1ff; - int rs1 = (inst >> 5) & 0x1f; - - switch (SH) { - case 0: - printf("add r%d, r%d, r%d LSL %lu\n", rd, rs0, rs1, uimm9); - break; - case 1: - printf("add r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm9); - break; - default: - printf("add r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm9); - break; - }; + uint64_t uimm6 = (inst >> 10) & 0x3f; + int rs1 = (inst >> 4) & 0xf; + + printf("add%c %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6); } return 0; @@ -35,43 +45,26 @@ static int __naja_sub(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; + int rs0 = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int SH = (inst >> 16) & 0x3; if (0x3 == SH) { - uint64_t uimm14 = (inst >> 5) & 0x3fff; + uint64_t uimm12 = (inst >> 4) & 0xfff; - if (31 == rd) - printf("cmp r%d, %lu\n", rs0, uimm14); + if (0xf == rd) + printf("cmp%c %s, %lu\n", __naja_size[size], __naja_reg[rs0], uimm12); else - printf("sub r%d, r%d, %lu\n", rd, rs0, uimm14); + printf("sub%c %s, %s, %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12); } else { - uint64_t uimm9 = (inst >> 10) & 0x1ff; - int rs1 = (inst >> 5) & 0x1f; - - switch (SH) { - case 0: - if (31 == rd) - printf("cmp r%d, r%d << %lu\n", rs0, rs1, uimm9); - else - printf("sub r%d, r%d, r%d << %lu\n", rd, rs0, rs1, uimm9); - break; - - case 1: - if (31 == rd) - printf("cmp r%d, r%d LSR %lu\n", rs0, rs1, uimm9); - else - printf("sub r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm9); - break; - - default: - if (31 == rd) - printf("cmp r%d, r%d ASR %lu\n", rs0, rs1, uimm9); - else - printf("sub r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm9); - break; - }; + uint64_t uimm6 = (inst >> 10) & 0x3f; + int rs1 = (inst >> 4) & 0xf; + + if (0xf == rd) + printf("cmp%c %s, %s %s %lu\n", __naja_size[size], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6); + else + printf("sub%c %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6); } return 0; @@ -81,27 +74,21 @@ static int __naja_mul(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; - int rs2 = (inst >> 10) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int S = (inst >> 18) & 0x1; - int opt = (inst >> 19) & 0x3; - - if (S) { - if (0 == opt) - printf("smadd r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1); - else if (1 == opt) - printf("smsub r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1); - else - printf("smul r%d, r%d, r%d\n", rd, rs0, rs1); - } else { - if (0 == opt) - printf("madd r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1); - else if (1 == opt) - printf("msub r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1); + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rs2 = (inst >> 12) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + int A = (inst >> 16) & 0x1; + + if (0xf == rs2) + printf("%smul%c %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1]); + else { + if (0 == A) + printf("%smadd%c %s, %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs2], __naja_reg[rs0], __naja_reg[rs1]); else - printf("mul r%d, r%d, r%d\n", rd, rs0, rs1); + printf("%smsub%c %s, %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs2], __naja_reg[rs0], __naja_reg[rs1]); } return 0; @@ -111,71 +98,99 @@ static int __naja_div(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; - int rs2 = (inst >> 10) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int S = (inst >> 18) & 0x1; - int opt = (inst >> 19) & 0x3; - - if (S) { - if (0 == opt) - printf("sdadd r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1); - else if (1 == opt) - printf("sdsub r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1); + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rs2 = (inst >> 12) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + int A = (inst >> 16) & 0x1; + + printf("%sdiv%c %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1]); + return 0; +} + +static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rb = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + int s13 = (inst >> 4) & 0x1fff; + + if (s13 & 0x1000) + s13 |= 0xffffe000; + + printf("ldr%s%c %s, [%s, %d]\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rb], s13 << size); + return 0; +} + +static int __naja_and(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rs0 = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int SH = (inst >> 16) & 0x3; + + if (0x3 == SH) { + uint64_t uimm12 = (inst >> 4) & 0xfff; + + if (0xf == rd) + printf("teq%c %s, %#lx\n", __naja_size[size], __naja_reg[rs0], uimm12); else - printf("sdiv r%d, r%d, r%d\n", rd, rs0, rs1); + printf("and%c %s, %s, %#lx\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12); } else { - if (0 == opt) - printf("dadd r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1); - else if (1 == opt) - printf("dsub r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1); + uint64_t uimm6 = (inst >> 10) & 0x3f; + int rs1 = (inst >> 4) & 0xf; + + if (0xf == rd) + printf("teq%c %s, %s %s %lu\n", __naja_size[size], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6); else - printf("div r%d, r%d, r%d\n", rd, rs0, rs1); + printf("and%c %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6); } return 0; } -static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst) +static int __naja_str_disp(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s = (inst >> 18) & 0x1; - int s13 = (inst >> 5) & 0x1fff; + int rb = inst & 0xf; + int rs = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s13 = (inst >> 4) & 0x1fff; if (s13 & 0x1000) s13 |= 0xffffe000; - switch (SH) { - case 0: - if (s) - printf("ldrsb r%d, [r%d, %d]\n", rd, rb, s13); - else - printf("ldrb r%d, [r%d, %d]\n", rd, rb, s13); - break; + printf("str%c %s, [%s, %d]\n", __naja_size[size], __naja_reg[rs], __naja_reg[rb], s13 << size); + return 0; +} - case 1: - if (s) - printf("ldrsw r%d, [r%d, %d]\n", rd, rb, s13 << 1); - else - printf("ldrw r%d, [r%d, %d]\n", rd, rb, s13 << 1); - break; +static int __naja_or(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - case 2: - if (s) - printf("ldrsl r%d, [r%d, %d]\n", rd, rb, s13 << 2); - else - printf("ldrl r%d, [r%d, %d]\n", rd, rb, s13 << 2); - break; + int rs0 = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int SH = (inst >> 16) & 0x3; - default: - printf("ldr r%d, [r%d, %d]\n", rd, rb, s13 << 3); - break; - }; + if (0x3 == SH) { + uint64_t uimm12 = (inst >> 4) & 0xfff; + + printf("or%c %s, %s, %#lx\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12); + } else { + uint64_t uimm6 = (inst >> 10) & 0x3f; + int rs1 = (inst >> 4) & 0xf; + + printf("or%c %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6); + } return 0; } @@ -184,38 +199,29 @@ static int __naja_pop(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s = (inst >> 18) & 0x1; - - switch (SH) { - case 0: - if (s) - printf("popsb r%d, [r%d]\n", rd, rb); - else - printf("popb r%d, [r%d]\n", rd, rb); - break; + int rb = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int s = (inst >> 17) & 0x1; - case 1: - if (s) - printf("popsw r%d, [r%d]\n", rd, rb); - else - printf("popw r%d, [r%d]\n", rd, rb); - break; + if (s) + printf("fpop d%d, [%s]\n", rd, __naja_reg[rb]); + else + printf("pop %s, [%s]\n", __naja_reg[rd], __naja_reg[rb]); + return 0; +} - case 2: - if (s) - printf("popsl r%d, [r%d]\n", rd, rb); - else - printf("popl r%d, [r%d]\n", rd, rb); - break; +static int __naja_push(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - default: - printf("popq r%d, [r%d]\n", rd, rb); - break; - }; + int rb = inst & 0xf; + int rs = (inst >> 21) & 0xf; + int s = (inst >> 17) & 0x1; + if (s) + printf("fpush d%d, [%s]\n", rs, __naja_reg[rb]); + else + printf("push %s, [%s]\n", __naja_reg[rs], __naja_reg[rb]); return 0; } @@ -223,698 +229,728 @@ static int __naja_ldr_sib(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int ri = (inst >> 5) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s = (inst >> 18) & 0x1; - int u8 = (inst >> 10) & 0xff; + int rb = inst & 0xf; + int ri = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + int uimm6 = (inst >> 10) & 0x3f; - switch (SH) { - case 0: - if (s) - printf("ldrsb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - else - printf("ldrb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - break; + printf("ldr%s%c %s, [%s, %s LSL %d]\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rb], __naja_reg[ri], uimm6); + return 0; +} - case 1: - if (s) - printf("ldrsw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - else - printf("ldrw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - break; +static int __naja_str_sib(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - case 2: - if (s) - printf("ldrsl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - else - printf("ldrl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - break; - - default: - printf("ldr r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - break; - }; + int rb = inst & 0xf; + int ri = (inst >> 4) & 0xf; + int rs = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + int uimm6 = (inst >> 10) & 0x3f; + if (s) + printf("fstr.%d d%d, [%s, %s, %d]\n", 1 << size, rs, __naja_reg[rb], __naja_reg[ri], uimm6); + else + printf("str%c %s, [%s, %s, %d]\n", __naja_size[size], __naja_reg[rs], __naja_reg[rb], __naja_reg[ri], uimm6); return 0; } -static int __naja_str_disp(scf_vm_t* vm, uint32_t inst) +static int __naja_mov(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s13 = (inst >> 5) & 0x1fff; - - if (s13 & 0x1000) - s13 |= 0xffffe000; - - switch (SH) { - case 0: - printf("strb r%d, [r%d, %d]\n", rd, rb, s13); - break; + int rs = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int SH = (inst >> 16) & 0x3; + int uimm6 = (inst >> 10) & 0x3f; - case 1: - printf("strw r%d, [r%d, %d]\n", rd, rb, s13 << 1); - break; + if (0xf == rs1) { + if (0 == uimm6) + printf("mov%c %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]); + else + printf("mov%c %s, %s %s %d\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs], __naja_SH[SH], uimm6); + } else + printf("mov%c %s, %s %s %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs], __naja_SH[SH], __naja_reg[rs1]); + return 0; +} - case 2: - printf("strl r%d, [r%d, %d]\n", rd, rb, s13 << 2); - break; +static int __naja_movx(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - default: - printf("str r%d, [r%d, %d]\n", rd, rb, s13 << 3); - break; - }; + int rs = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + if (s) + printf("movs%cq %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]); + else + printf("movz%cq %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]); return 0; } -static int __naja_push(scf_vm_t* vm, uint32_t inst) +static int __naja_not(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; + int rs = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int SH = (inst >> 16) & 0x3; + int u16 = inst & 0xffff; switch (SH) { case 0: - printf("pushb r%d, [r%d]\n", rd, rb); + printf("neg%c %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]); break; - case 1: - printf("pushw r%d, [r%d]\n", rd, rb); + printf("not%c %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]); break; - case 2: - printf("pushl r%d, [r%d]\n", rd, rb); + if (0 == size) + printf("mov %s, %d\n", __naja_reg[rd], u16); + else + printf("movt %s, %d LSL %d\n", __naja_reg[rd], u16, 16 << size); break; - default: - printf("pushq r%d, [r%d]\n", rd, rb); + printf("mvn%c %s, %d\n", __naja_size[size], __naja_reg[rd], u16); break; }; - return 0; } -static int __naja_str_sib(scf_vm_t* vm, uint32_t inst) +static int __naja_fadd(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int ri = (inst >> 5) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int u8 = (inst >> 10) & 0xff; + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int vlen = (inst >> 10) & 0x3; - switch (SH) { - case 0: - printf("strb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - break; + if (V) { + int N = 1 << (3 + vlen - size); - case 1: - printf("strw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - break; - - case 2: - printf("strl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - break; - - default: - printf("str r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - break; - }; + printf("vadd.f%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + } else + printf("fadd.%d d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1); return 0; } -static int __naja_and(scf_vm_t* vm, uint32_t inst) +static int __naja_fsub(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int cmp = (inst >> 16) & 0x1; + int vlen = (inst >> 10) & 0x3; - if (0x3 == SH) { - uint32_t uimm14 = (inst >> 5) & 0x3fff; + if (V) { + int N = 1 << (3 + vlen - size); - if (31 == rd) - printf("teq r%d, %#x\n", rs0, uimm14); + if (cmp) + printf("vcmp.f%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); else - printf("and r%d, r%d, %#x\n", rd, rs0, uimm14); + printf("vsub.f%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); } else { - uint32_t uimm9 = (inst >> 10) & 0x1ff; - int rs1 = (inst >> 5) & 0x1f; - - switch (SH) { - case 0: - if (31 == rd) - printf("teq r%d, r%d LSL %#x\n", rs0, rs1, uimm9); - else - printf("and r%d, r%d, r%d LSL %#x\n", rd, rs0, rs1, uimm9); - break; - - case 1: - if (31 == rd) - printf("teq r%d, r%d LSR %#x\n", rs0, rs1, uimm9); - else - printf("and r%d, r%d, r%d LSR %#x\n", rd, rs0, rs1, uimm9); - break; - - default: - if (31 == rd) - printf("teq r%d, r%d ASR %#x\n", rs0, rs1, uimm9); - else - printf("and r%d, r%d, r%d ASR %#x\n", rd, rs0, rs1, uimm9); - break; - }; + if (cmp) + printf("fcmp.%d d%d, d%d\n", 1 << size, rs0, rs1); + else + printf("fsub.%d d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1); } - return 0; } -static int __naja_or(scf_vm_t* vm, uint32_t inst) +static int __naja_fmul(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rs2 = (inst >> 12) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int A = (inst >> 16) & 0x1; + int vlen = (inst >> 10) & 0x3; - if (0x3 == SH) { - uint32_t uimm14 = (inst >> 5) & 0x3fff; + if (V) { + int N = 1 << (3 + vlen - size); - printf("or r%d, r%d, %#x\n", rd, rs0, uimm14); + if (0xf == rs2) + printf("vmul.f%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + else { + if (A) + printf("vmsub.f%dx%d X%d, X%d, X%d, X%d\n", 1 << size, N, rd, rs2, rs0, rs1); + else + printf("vmadd.f%dx%d X%d, X%d, X%d, X%d\n", 1 << size, N, rd, rs2, rs0, rs1); + } } else { - uint32_t uimm9 = (inst >> 10) & 0x1ff; - int rs1 = (inst >> 5) & 0x1f; - - if (0 == SH) - printf("or r%d, r%d, r%d LSL %#x\n", rd, rs0, rs1, uimm9); - else if (1 == SH) - printf("or r%d, r%d, r%d LSR %#x\n", rd, rs0, rs1, uimm9); - else - printf("or r%d, r%d, r%d ASR %#x\n", rd, rs0, rs1, uimm9); + if (0xf == rs2) + printf("fmul.%d d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1); + else { + if (A) + printf("fmsub.%d d%d, d%d, d%d, d%d\n", 1 << size, rd, rs2, rs0, rs1); + else + printf("fmadd.%d d%d, d%d, d%d, d%d\n", 1 << size, rd, rs2, rs0, rs1); + } } - return 0; } -static int __naja_jmp_disp(scf_vm_t* vm, uint32_t inst) +static int __naja_fdiv(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int simm26 = inst & 0x3ffffff; + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int vlen = (inst >> 10) & 0x3; - if (simm26 & 0x2000000) - simm26 |= 0xfc000000; + if (V) { + int N = 1 << (3 + vlen - size); - uint64_t ip = naja->ip + (simm26 << 2); - printf("jmp %#lx\n", ip); + printf("vdiv.f%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + } else + printf("fdiv.%d d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1); return 0; } -static int __naja_call_disp(scf_vm_t* vm, uint32_t inst) +static int __naja_fldr_disp(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int simm26 = inst & 0x3ffffff; + int rb = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int A = (inst >> 16) & 0x1; + int vlen = (inst >> 10) & 0x3; + int s13 = (inst >> 4) & 0x1fff; - if (simm26 & 0x2000000) - simm26 |= 0xfc000000; + if (s13 & 0x1000) + s13 |= 0xffffe000; - uint64_t ip = naja->ip + (simm26 << 2); - printf("call %#lx\n", ip); + if (V) { + int N = 1 << (3 + vlen - size); + + if (A) + printf("vldr.f%dx%d X%d, [%s]!\n", 1 << size, N, rd, __naja_reg[rb]); + else + printf("vldr.f%dx%d X%d, [%s]\n", 1 << size, N, rd, __naja_reg[rb]); + } else + printf("fldr.%d d%d, [%s, %d]\n", 1 << size, rd, __naja_reg[rb], s13 << size); return 0; } -static int __naja_jmp_reg(scf_vm_t* vm, uint32_t inst) +static int __naja_fstr_disp(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - if (inst & 0x1) { + int rb = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int A = (inst >> 16) & 0x1; + int vlen = (inst >> 10) & 0x3; + int s13 = (inst >> 4) & 0x1fff; - int cc = (inst >> 1) & 0xf; - int s21 = (inst >> 5) & 0x1fffff; + if (s13 & 0x1000) + s13 |= 0xffffe000; - if (s21 & 0x100000) - s21 |= 0xffe00000; + if (V) { + int N = 1 << (3 + vlen - size); - s21 <<= 2; + if (A) + printf("vstr.f%dx%d X%d, [%s]!\n", 1 << size, N, rd, __naja_reg[rb]); + else + printf("vstr.f%dx%d X%d, [%s]\n", 1 << size, N, rd, __naja_reg[rb]); + } else + printf("fstr.%d d%d, [%s, %d]\n", 1 << size, rd, __naja_reg[rb], s13 << size); + return 0; +} - uint64_t ip = naja->ip + s21; +static int __naja_fldr_sib(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - if (0 == cc) - printf("jz %#lx\n", ip); + int rb = inst & 0xf; + int ri = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int uimm6 = (inst >> 10) & 0x3f; - else if (1 == cc) - printf("jnz %#lx\n", ip); + printf("fldr.%d d%d, [%s, %s, %d]\n", 1 << size, rd, __naja_reg[rb], __naja_reg[ri], uimm6); + return 0; +} - else if (2 == cc) - printf("jge %#lx\n", ip); +static int __naja_fmov(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - else if (3 == cc) - printf("jgt %#lx\n", ip); + int rs = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int vlen = (inst >> 10) & 0x3; - else if (4 == cc) - printf("jle %#lx\n", ip); + if (V) { + int N = 1 << (3 + vlen - size); - else if (5 == cc) - printf("jlt %#lx\n", ip); - else { - scf_loge("\n"); - return -EINVAL; - } + printf("vmov.f%dx%d X%d, X%d\n", 1 << size, N, rd, rs); + } else + printf("fmov.%d d%d, d%d\n", 1 << size, rd, rs); + return 0; +} - } else { - int rd = (inst >> 21) & 0x1f; +static int __naja_fcvt(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rs = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int dsize = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int Id = (inst >> 13) & 0x1; + int sd = (inst >> 12) & 0x1; + int vlen = (inst >> 10) & 0x3; + int Is = (inst >> 7) & 0x1; + int ss = (inst >> 6) & 0x1; + int ssize = (inst >> 4) & 0x3; + + static char IS_array[2][2] = { + 'F', 'F', + 'U', 'I' + }; - printf("jmp *r%d\n", rd); + static char R_array[2] = {'d', 'r'}; + + if (V) { + int N = 1 << (3 + vlen - dsize); + + printf("vcvt%c%dto%c%dx%d X%d, X%d\n", + IS_array[Is][ss], 1 << ssize, + IS_array[Id][sd], 1 << dsize, + N, rd, rs); + } else { + printf("fcvt%c%dto%c%d %c%d, %c%d\n", + IS_array[Is][ss], 1 << ssize, + IS_array[Id][sd], 1 << dsize, + R_array[Id], rd, R_array[Is], rs); } return 0; } -static int __naja_call_reg(scf_vm_t* vm, uint32_t inst) +static int __naja_fneg(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rd = (inst >> 21) & 0x1f; + int rs = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int V = (inst >> 17) & 0x1; + int vlen = (inst >> 10) & 0x3; - printf("call r%d\n", rd); + if (V) { + int N = 1 << (3 + vlen - size); + printf("vneg.f%dx%d X%d, X%d\n", 1 << size, N, rd, rs); + } else + printf("fneg.%d d%d, d%d\n", 1 << size, rd, rs); return 0; } -static int __naja_adrp(scf_vm_t* vm, uint32_t inst) +static int __naja_vadd(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rd = (inst >> 21) & 0x1f; - int s21 = inst & 0x1fffff; + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int vlen = (inst >> 10) & 0x3; - if (s21 & 0x100000) - s21 |= ~0x1fffff; - - printf("adrp r%d, [rip, %d]\n", rd, s21); + int N = 1 << (3 + vlen - size); + printf("vadd.u%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); return 0; } -static int __naja_ret(scf_vm_t* vm, uint32_t inst) +static int __naja_vsub(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - printf("ret\n"); + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int cmp = (inst >> 16) & 0x1; + int vlen = (inst >> 10) & 0x3; + + int N = 1 << (3 + vlen - size); + + if (cmp) + printf("vcmp.u%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + else + printf("vsub.u%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); return 0; } -static int __naja_setcc(scf_vm_t* vm, uint32_t inst) +static int __naja_vmul(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rd = (inst >> 21) & 0x1f; - int cc = (inst >> 1) & 0xf; + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rs2 = (inst >> 12) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + int A = (inst >> 16) & 0x1; + int vlen = (inst >> 10) & 0x3; - if (SCF_VM_Z == cc) - printf("setz r%d\n", rd); + int N = 1 << (3 + vlen - size); - else if (SCF_VM_NZ == cc) - printf("setnz r%d\n", rd); + static char s_array[2] = {'u', 'i'}; + static char* A_array[2] = {"madd", "msub"}; - else if (SCF_VM_GE == cc) - printf("setge r%d\n", rd); + if (0xf == rs2) + printf("vmul.%c%dx%d X%d, X%d, X%d\n", s_array[s], 1 << size, N, rd, rs0, rs1); + else + printf("v%s.%c%dx%d X%d, X%d, X%d, X%d\n", A_array[A], s_array[s], 1 << size, N, rd, rs2, rs0, rs1); + return 0; +} - else if (SCF_VM_GT == cc) - printf("setgt r%d\n", rd); +static int __naja_vdiv(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - else if (SCF_VM_LT == cc) - printf("setlt r%d\n", rd); + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int s = (inst >> 17) & 0x1; + int vlen = (inst >> 10) & 0x3; - else if (SCF_VM_LE == cc) - printf("setle r%d\n", rd); - else { - scf_loge("inst: %#x\n", inst); - return -EINVAL; - } + int N = 1 << (3 + vlen - size); + if (s) + printf("vdiv.i%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + else + printf("vdiv.u%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); return 0; } -static int __naja_mov(scf_vm_t* vm, uint32_t inst) +static int __naja_vand(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s = (inst >> 18) & 0x1; - int opt = (inst >> 16) & 0x3; + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int teq = (inst >> 16) & 0x1; + int vlen = (inst >> 10) & 0x3; - if (0 == opt) { - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; + int N = 1 << (3 + vlen - size); - if (0 == SH) - printf("mov r%d, r%d LSL r%d\n", rd, rs0, rs1); - else if (1 == SH) - printf("mov r%d, r%d LSR r%d\n", rd, rs0, rs1); - else - printf("mov r%d, r%d ASR r%d\n", rd, rs0, rs1); + if (teq) + printf("vteq.u%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + else + printf("vand.u%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + return 0; +} - } else if (1 == opt) { - int rs0 = inst & 0x1f; - int u11 = (inst >> 5) & 0x7ff; +static int __naja_vor(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - if (0 == SH) { - if (0 == u11) - printf("mov r%d, r%d\n", rd, rs0); - else - printf("mov r%d, r%d LSL %d\n", rd, rs0, u11); + int rs0 = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int vlen = (inst >> 10) & 0x3; - } else if (1 == SH) - printf("mov r%d, r%d LSR %d\n", rd, rs0, u11); - else - printf("mov r%d, r%d ASR %d\n", rd, rs0, u11); - - } else if (2 == opt) { - int rs = inst & 0x1f; - - switch (SH) { - case 0: - if (s) - printf("movsb r%d, r%d\n", rd, rs); - else - printf("movzb r%d, r%d\n", rd, rs); - break; - - case 1: - if (s) - printf("movsw r%d, r%d\n", rd, rs); - else - printf("movzw r%d, r%d\n", rd, rs); - break; - - case 2: - if (s) - printf("movsl r%d, r%d\n", rd, rs); - else - printf("movzl r%d, r%d\n", rd, rs); - break; - default: - if (s) - printf("NEG r%d, r%d\n", rd, rs); - else - printf("NOT r%d, r%d\n", rd, rs); - break; - }; + int N = 1 << (3 + vlen - size); - } else { - uint64_t u16 = inst & 0xffff; + printf("vor.u%dx%d X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1); + return 0; +} - if (s) - printf("mvn r%d, %#lx\n", rd, u16); - else { - if (0 == SH) - printf("mov r%d, %#lx\n", rd, u16); - else - printf("mov r%d, %#lx << %d\n", rd, u16, 16 << SH); - } - } +static int __naja_vmov(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rs = inst & 0xf; + int rs1 = (inst >> 4) & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int SH = (inst >> 16) & 0x3; + int IMM = (inst >> 15) & 0x3; + int vlen = (inst >> 10) & 0x3; + int uimm6 = (inst >> 4) & 0x3f; + int N = 1 << (3 + vlen - size); + + if (IMM) { + if (0 == uimm6) + printf("vmov.u%dx%d X%d, X%d\n", 1 << size, N, rd, rs); + else + printf("vmov.u%dx%d X%d, X%d %s %d\n", 1 << size, N, rd, rs, __naja_SH[SH], uimm6); + } else + printf("vmov.u%dx%d X%d, X%d %s %s\n", 1 << size, N, rd, rs, __naja_SH[SH], __naja_reg[rs1]); return 0; } -static int __naja_fadd(scf_vm_t* vm, uint32_t inst) +static int __naja_vnot(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; - int rd = (inst >> 21) & 0x1f; + int rs = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int A = (inst >> 16) & 0x3; + int vlen = (inst >> 10) & 0x3; + + int N = 1 << (3 + vlen - size); - printf("fadd r%d, r%d, r%d\n", rd, rs0, rs1); + if (A) + printf("vnot.u%dx%d X%d, X%d\n", 1 << size, N, rd, rs); + else + printf("vneg.u%dx%d X%d, X%d\n", 1 << size, N, rd, rs); return 0; } -static int __naja_fsub(scf_vm_t* vm, uint32_t inst) +static int __naja_vmov_imm(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; - int rd = (inst >> 21) & 0x1f; + int u16 = inst & 0xffff; + int rd = (inst >> 21) & 0xf; + int size = (inst >> 18) & 0x3; + int vlen = (inst >> 16) & 0x3; + int mvn = (inst >> 25) & 0x1; - if (31 == rd) - printf("fcmp d%d, d%d\n", rs0, rs1); - else - printf("fsub r%d, r%d, r%d\n", rd, rs0, rs1); + int N = 1 << (3 + vlen - size); + if (mvn) + printf("vmvn.u%dx%d X%d, %#x\n", 1 << size, N, rd, u16); + else + printf("vmov.u%dx%d X%d, %#x\n", 1 << size, N, rd, u16); return 0; } -static int __naja_fmul(scf_vm_t* vm, uint32_t inst) +static int __naja_jmp_disp(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; - int rs2 = (inst >> 10) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int opt = (inst >> 18) & 0x3; + int simm26 = inst & 0x3ffffff; - if (0 == opt) - printf("fmadd d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1); - else if (1 == opt) - printf("fmsub d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1); - else - printf("fmul d%d, d%d, d%d", rd, rs0, rs1); + if (simm26 & 0x2000000) + simm26 |= 0xfc000000; + uint64_t ip = naja->ip + (simm26 << 2); + printf("jmp %#lx\n", ip); return 0; } -static int __naja_fdiv(scf_vm_t* vm, uint32_t inst) +static int __naja_call_disp(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; - int rs2 = (inst >> 10) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int opt = (inst >> 18) & 0x3; + int simm26 = inst & 0x3ffffff; - if (0 == opt) - printf("fdadd d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1); - else if (1 == opt) - printf("fdsub d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1); - else - printf("fdiv d%d, d%d, d%d", rd, rs0, rs1); + if (simm26 & 0x2000000) + simm26 |= 0xfc000000; + uint64_t ip = naja->ip + (simm26 << 2); + printf("call %#lx\n", ip); return 0; } -static int __naja_fstr_disp(scf_vm_t* vm, uint32_t inst) +static int __naja_jmp_reg(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s13 = (inst >> 5) & 0x1fff; + if (inst & 0x1) { + int cc = (inst >> 1) & 0xf; + int s21 = (inst >> 5) & 0x1fffff; + + if (s21 & 0x100000) + s21 |= 0xffe00000; - if (s13 & 0x1000) - s13 |= 0xffffe000; + s21 <<= 2; - switch (SH) { - case 2: - printf("fstr f%d, [r%d, %d]\n", rd, rb, s13 << 2); - break; + uint64_t ip = naja->ip + s21; - case 3: - printf("fstr d%d, [r%d, %d]\n", rd, rb, s13 << 3); - break; - default: - scf_loge("SH: %d\n", SH); - return -1; - break; - }; + if (0 == cc) + printf("jz %#lx\n", ip); + + else if (1 == cc) + printf("jnz %#lx\n", ip); + + else if (2 == cc) + printf("jge %#lx\n", ip); + + else if (3 == cc) + printf("jgt %#lx\n", ip); + + else if (4 == cc) + printf("jle %#lx\n", ip); + + else if (5 == cc) + printf("jlt %#lx\n", ip); + else { + scf_loge("\n"); + return -EINVAL; + } + } else { + int rd = (inst >> 21) & 0xf; + printf("jmp *%s\n", __naja_reg[rd]); + } return 0; } -static int __naja_fpush(scf_vm_t* vm, uint32_t inst) +static int __naja_call_reg(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; + int rd = (inst >> 21) & 0xf; - switch (SH) { - case 2: - printf("fpush f%d, [r%d]\n", rd, rb); - break; - - case 3: - printf("fpush d%d, [r%d]\n", rd, rb); - break; - default: - scf_loge("SH: %d\n", SH); - return -1; - break; - }; + printf("call *%s\n", __naja_reg[rd]); return 0; } -static int __naja_fldr_disp(scf_vm_t* vm, uint32_t inst) +static int __naja_setcc(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s13 = (inst >> 5) & 0x1fff; + int rd = (inst >> 21) & 0xf; + int cc = (inst >> 1) & 0xf; - if (s13 & 0x1000) - s13 |= 0xffffe000; + if (SCF_VM_Z == cc) + printf("setz %s\n", __naja_reg[rd]); - switch (SH) { - case 2: - printf("fldr f%d, [r%d, %d]\n", rd, rb, s13 << 2); - break; + else if (SCF_VM_NZ == cc) + printf("setnz %s\n", __naja_reg[rd]); - case 3: - printf("fldr d%d, [r%d, %d]\n", rd, rb, s13 << 3); - break; - default: - scf_loge("SH: %d\n", SH); - return -1; - break; - }; + else if (SCF_VM_GE == cc) + printf("setge %s\n", __naja_reg[rd]); + + else if (SCF_VM_GT == cc) + printf("setgt %s\n", __naja_reg[rd]); + + else if (SCF_VM_LT == cc) + printf("setlt %s\n", __naja_reg[rd]); + + else if (SCF_VM_LE == cc) + printf("setle %s\n", __naja_reg[rd]); + else { + scf_loge("inst: %#x\n", inst); + return -EINVAL; + } return 0; } -static int __naja_fpop(scf_vm_t* vm, uint32_t inst) +static int __naja_adrp(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; + int rd = (inst >> 21) & 0xf; + int s21 = inst & 0x1fffff; - switch (SH) { - case 2: - printf("fldr f%d, [r%d]\n", rd, rb); - break; - case 3: - printf("fldr d%d, [r%d]\n", rd, rb); - break; - default: - scf_loge("SH: %d\n", SH); - return -1; - break; - }; + if (s21 & 0x100000) + s21 |= ~0x1fffff; + printf("adrp %s, [rip, %d]\n", __naja_reg[rd], s21); return 0; } -static int __naja_fldr_sib(scf_vm_t* vm, uint32_t inst) +static int __naja_ret(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int ri = (inst >> 5) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int u8 = (inst >> 10) & 0xff; + printf("ret\n"); + return 0; +} - switch (SH) { - case 2: - printf("fldr f%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - break; - case 3: - printf("fldr d%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - break; - default: - scf_loge("\n"); - return -1; - break; - }; +static int __naja_spop(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rb = inst & 0xf; + int sr = (inst >> 21) & 0xf; + printf("spop sr%d, [%s]\n", sr, __naja_reg[rb]); return 0; } -static int __naja_fstr_sib(scf_vm_t* vm, uint32_t inst) +static int __naja_spush(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rb = inst & 0x1f; - int ri = (inst >> 5) & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int u8 = (inst >> 10) & 0xff; - - switch (SH) { - case 2: - printf("fstr f%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - break; - case 3: - printf("fstr d%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - break; - default: - scf_loge("\n"); - return -1; - break; - }; + int rb = inst & 0xf; + int sr = (inst >> 21) & 0xf; + printf("spush sr%d, [%s]\n", sr, __naja_reg[rb]); return 0; } -static int __naja_fmov(scf_vm_t* vm, uint32_t inst) +static int __naja_in(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; - int rs = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int SH = (inst >> 19) & 0x3; - int s = (inst >> 18) & 0x1; - int opt = (inst >> 16) & 0x3; - - if (0 == opt) { - if (2 == SH) - printf("fss2sd d%d, f%d\n", rd, rs); - else if (3 == SH) - printf("fsd2ss f%d, d%d\n", rd, rs); - else { - scf_loge("\n"); - return -EINVAL; - } + int u16 = inst & 0xffff; + int rd = (inst >> 21) & 0xf; + int D = (inst >> 17) & 0xf; - } else if (1 == opt) { - if (s) - printf("cvtss2si r%d, f%d\n", rd, rs); - else - printf("cvtss2ui r%d, f%d\n", rd, rs); + if (D) + printf("out %s, %#x\n", __naja_reg[rd], u16); + else + printf("in %s, %#x\n", __naja_reg[rd], u16); + return 0; +} - } else if (2 == opt) { - printf("cvtsi2ss f%d, r%d\n", rd, rs); +static int __naja_smov(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - } else { - if (s) - printf("fneg d%d, d%d\n", rd, rs); - else - printf("fmov d%d, d%d\n", rd, rs); - } + int sr = inst & 0xf; + int rd = (inst >> 21) & 0xf; + int D = (inst >> 17) & 0xf; + if (D) + printf("smov sr%d, %s\n", sr, __naja_reg[rd]); + else + printf("smov %s, sr%d\n", __naja_reg[rd], sr); return 0; } +static int __naja_iret(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + printf("iret\n"); + return 0; +} static naja_opcode_pt naja_opcodes[64] = { @@ -924,19 +960,20 @@ static naja_opcode_pt naja_opcodes[64] = __naja_div, // 3 __naja_ldr_disp, // 4 - __naja_pop, // 5 + __naja_and, // 5 __naja_str_disp, // 6 - __naja_push, // 7 + __naja_or, // 7 + + __naja_pop, // 8 + __naja_push, // 9 - __naja_and, // 8 - __naja_or, // 9 - __naja_jmp_disp, // 10 - __naja_jmp_reg, // 11 - __naja_setcc, // 12 - __naja_ldr_sib, // 13 - __naja_str_sib, // 14 - __naja_mov, // 15 + __naja_ldr_sib, // 10 + __naja_str_sib, // 11 + __naja_mov, // 12 + __naja_movx, // 13 + __naja_not, // 14 + NULL, // 15 __naja_fadd, // 16 __naja_fsub, // 17 @@ -944,52 +981,52 @@ static naja_opcode_pt naja_opcodes[64] = __naja_fdiv, // 19 __naja_fldr_disp,// 20 - __naja_fpop, // 21 + NULL, // 21 __naja_fstr_disp,// 22 - __naja_fpush, // 23 + NULL, // 23 NULL, // 24 NULL, // 25 - __naja_call_disp,// 26 - __naja_call_reg, // 27 - NULL, // 28 - __naja_fldr_sib, // 29 - __naja_fstr_sib, // 30 - __naja_fmov, // 31 - - NULL, // 32 - NULL, // 33 - NULL, // 34 - NULL, // 35 + __naja_fldr_sib, // 26 + NULL, // 27 + __naja_fmov, // 28 + __naja_fcvt, // 29 + __naja_fneg, // 30 + NULL, // 31 + + __naja_vadd, // 32 + __naja_vsub, // 33 + __naja_vmul, // 34 + __naja_vdiv, // 35 NULL, // 36 - NULL, // 37 + __naja_vand, // 37 NULL, // 38 - NULL, // 39 + __naja_vor, // 39 NULL, // 40 NULL, // 41 - __naja_adrp, // 42 + NULL, // 42 NULL, // 43 - NULL, // 44 + __naja_vmov, // 44 NULL, // 45 - NULL, // 46 - NULL, // 47 - - NULL, // 48 - NULL, // 49 - NULL, // 50 - NULL, // 51 - NULL, // 52 - NULL, // 53 - NULL, // 54 + __naja_vnot, // 46 + __naja_vmov_imm, // 47 + + __naja_jmp_disp, // 48 + __naja_call_disp,// 49 + __naja_jmp_reg, // 50 + __naja_call_reg, // 51 + __naja_setcc, // 52 + __naja_adrp, // 53 + __naja_ret, // 54 NULL, // 55 - __naja_ret, // 56 - NULL, // 57 - NULL, // 58 + __naja_spop, // 56 + __naja_spush, // 57 + __naja_in, // 58 NULL, // 59 - NULL, // 60 + __naja_smov, // 60 NULL, // 61 - NULL, // 62 + __naja_iret, // 62 NULL, // 63 }; -- 2.25.1