- 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
------------------------------------------------------------------------------------------------
- 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,
------------------------------------------------------------------------------------------------
|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
------------------------------------------------------------------------------------------------
--- /dev/null
+ 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
+------------------------------------------------------------------------------------------------
--- /dev/null
+ 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
+------------------------------------------------------------------------------------------------
case R_AARCH64_ADR_PREL_PG_HI21:
- offset >>= 14;
+ offset >>= 12;
offset &= 0x1fffff;
*(uint32_t*)(s->data + rela->r_offset) |= offset;
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:
#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
};
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);
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);
#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;
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);
}
}
// 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);
}
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);
}
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);
}
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);
} 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);
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) {
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);
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) {
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);
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);
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;
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) {
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);
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;
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) {
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);
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);
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);
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);
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;
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);
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);
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);
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);
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;
}
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;
}
scf_instruction_t* inst;
uint32_t opcode;
- opcode = 0x38 << 26;
+ opcode = 0x36 << 26;
inst = risc_make_inst(c, opcode);
return inst;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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);
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;
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;
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;
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;
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;
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;
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;
scf_instruction_t* inst;
uint32_t opcode;
- opcode = 0xa << 26;
+ opcode = 0x30 << 26;
inst = risc_make_inst(c, opcode);
return inst;
scf_instruction_t* inst;
uint32_t opcode;
- opcode = (0xb << 26) | 1;
+ opcode = (0x32 << 26) | 1;
inst = risc_make_inst(c, opcode);
return inst;
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;
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;
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;
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;
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;
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;
inst->code[3] |= 0x3 & (bytes >> 24);
} else {
- assert(0xa == (opcode >> 26));
+ assert(0x30 == (opcode >> 26));
bytes >>= 2;
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;
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:
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;
void risc_call_rabi(int* p_nints, int* p_nfloats, scf_3ac_code_t* c, scf_function_t* f);
#endif
-
#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[] =
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[] =
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)
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)
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);
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))
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);
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) {
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)
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)
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)
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))
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))
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))
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))
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)
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)
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) {
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);
#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,
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,
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
-
#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;
} 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;
{"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,
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;
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],
{
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;
};
}
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;
{
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;
{
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;
scf_loge("\n");
return -1;
}
-
} else {
data = naja->stack;
offset = addr;
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;
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;
};
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;
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;
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);
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;
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;
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;
};
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;
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;
};
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;
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;
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;
}
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],
return 0;
}
-
static int __naja_call_reg(scf_vm_t* vm, uint32_t inst)
{
scf_vm_naja_t* naja = vm->priv;
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],
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;
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;
}
__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
__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
};
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) {
#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;
{
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;
{
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;
{
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;
}
{
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;
}
{
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] =
{
__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
__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
};