update Naja byte code, add some instructions to it
authoryu.dongliang <18588496441@163.com>
Mon, 22 Dec 2025 15:43:59 +0000 (23:43 +0800)
committeryu.dongliang <18588496441@163.com>
Mon, 22 Dec 2025 15:56:33 +0000 (23:56 +0800)
14 files changed:
docs/Naja_float.txt
docs/Naja_int.txt
docs/Naja_sys.txt [new file with mode: 0644]
docs/Naja_vector.txt [new file with mode: 0644]
elf/scf_elf_naja.c
elf/scf_elf_naja_so.c
native/risc/scf_naja.c
native/risc/scf_risc_inst.c
native/risc/scf_risc_reg.h
native/risc/scf_risc_reg_naja.c
native/risc/scf_risc_util.h
vm/scf_vm.h
vm/scf_vm_naja.c
vm/scf_vm_naja_asm.c

index f5e345219bba241061c6d6bf04099772e671fa90..cbbb452516fa81e7b3d52e4973cd83ad0acbcfa2 100644 (file)
-                                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
 ------------------------------------------------------------------------------------------------
index fc63fa026ce2ef973435f6c9bb5bcb227284e06a..1457b4dde7236afc074121cc0b4eda1937b8da1c 100644 (file)
-                                Naja interger instructions
+                                Naja instructions
+------------------------------------------------------------------------------------------------
+                                opcode format
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| type|   opcode  | 0|<-- rd --->| 0| size| SH  |<---- uimm6 ---->| 0  0|<-- rs1 -->|<-- rs0 -->|
 
+type: 0 = integer, 1 = float,  2 = vector, 3 = system
+size: 0 = 8bits,   1 = 16bits, 2 = 32bits, 3 = 64bits
+SH  : 0 = LSL,     1 = LSR,    2 = ASR,   (3 = reserved)
+   0: reserved
+------------------------------------------------------------------------------------------------
 
 0, add, +, +=,                  opcode = 0
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  0  0  0  0|<---- rd ---->| SH  |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->|
+| 0  0| 0  0  0  0| 0|<-- rd --->| 0| size| SH  |<---- uimm6 ---->| 0  0|<-- rs1 -->|<-- rs0 -->|
 
-rd = rs0 + (rs1 << uimm9);  // SH = 0, LSL
-rd = rs0 + (rs1 >> uimm9);  // SH = 1, LSR
-rd = rs0 + (rs1 >> uimm9);  // SH = 2, ASR
+rd = rs0 + (rs1 << uimm6);  // SH = 0, LSL
+rd = rs0 + (rs1 >> uimm6);  // SH = 1, LSR
+rd = rs0 + (rs1 >> uimm6);  // SH = 2, ASR
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  0  0  0  0|<---- rd ---->| 1  1|<----------------- uimm14 -------------->|<--- rs0 ---->|
+| 0  0| 0  0  0  0| 0|<-- rd --->| 0| size| 1  1|<------------- uimm12 ------------>|<-- rs0 -->|
 
-rd = rs0 + (uint64_t)uimm14; // SH = 3, IMM
+rd = rs0 + (uint64_t)uimm12; // SH = 3, IMM
 ------------------------------------------------------------------------------------------------
 
 1, sub, -, -=,                  opcode = 1
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  0  0  0  1|<---- rd ---->| SH  |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->|
+| 0  0| 0  0  0  1| 0|<-- rd --->| 0| size| SH  |<---- uimm6 ---->| 0  0|<-- rs1 -->|<-- rs0 -->|
 
-rd = rs0 - (rs1 << uimm9);  // SH = 0, LSL
-rd = rs0 - (rs1 >> uimm9);  // SH = 1, LSR
-rd = rs0 - (rs1 >> uimm9);  // SH = 2, ASR
+rd = rs0 - (rs1 << uimm6);  // SH = 0, LSL
+rd = rs0 - (rs1 >> uimm6);  // SH = 1, LSR
+rd = rs0 - (rs1 >> uimm6);  // SH = 2, ASR
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  0  0  0  1|<---- rd ---->| 1  1|<----------------- uimm14 -------------->|<--- rs0 ---->|
+| 0  0| 0  0  0  1| 0|<-- rd --->| 0| size| 1  1|<------------- uimm12 ------------>|<-- rs0 -->|
 
-rd = rs0 - (uint64_t)uimm14; // SH = 3, IMM
+rd = rs0 - (uint64_t)uimm12; // SH = 3, IMM
 ------------------------------------------------------------------------------------------------
 
 cmp, >, >=, <, <=, ==, !=,      opcode = 1
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  0  0  0  1| 1  1  1  1  1| SH  |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->|
+| 0  0| 0  0  0  1| 0| 1  1  1  1| 0| size| SH  |<---- uimm6 ---->| 0  0|<-- rs1 -->|<-- rs0 -->|
 
-flags = rs0 - (rs1 << uimm9);  // SH = 0, LSL, rd = 31
-flags = rs0 - (rs1 >> uimm9);  // SH = 1, LSR, rd = 31
-flags = rs0 - (rs1 >> uimm9);  // SH = 2, ASR, rd = 31
+flags = rs0 - (rs1 << uimm6);  // SH = 0, LSL, rd = 15
+flags = rs0 - (rs1 >> uimm6);  // SH = 1, LSR, rd = 15
+flags = rs0 - (rs1 >> uimm6);  // SH = 2, ASR, rd = 15
 
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  0  0  0  1| 1  1  1  1  1| 1  1|<----------------- uimm14 -------------->|<--- rs0 ---->|
+| 0  0| 0  0  0  1| 0| 1  1  1  1| 0| size| 1  1|<------------- uimm12 ------------>|<-- rs0 -->|
 
-flags = rs0 - (uint64_t)uimm14; // SH = 3, IMM, rd = 31
+flags = rs0 - (uint64_t)uimm12; // SH = 3, IMM, rd = 15
 ------------------------------------------------------------------------------------------------
 
 2, mul, *, *=,                  opcode = 2
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  0  0  1  0|<---- rd ---->| opt | s| 0  0  0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->|
+| 0  0| 0  0  1  0| 0|<-- rd --->| 0| size| s| A|<-- rs2 -->| 0  0| 0  0|<-- rs1 -->|<-- rs0 -->|
 
 s = 0, unsigned mul.
 s = 1,   signed mul.
 
-rd = rs2 + rs0 * rs1; // opt = 0
-rd = rs2 - rs0 * rs1; // opt = 1
-rd =       rs0 * rs1; // opt = 2
-------------------------------------------------------------------------------------------------
-
-3, div, *, *=,                  opcode = 3
-------------------------------------------------------------------------------------------------
-|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  0  0  1  1|<--- rd ----->| opt | s| 0  0  0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->|
-
-s = 0, unsigned div.
-s = 1,   signed div.
-
-rd = rs2 + rs0 / rs1; // opt = 0
-rd = rs2 - rs0 / rs1; // opt = 1
-rd =       rs0 / rs1; // opt = 2
-------------------------------------------------------------------------------------------------
+rd = rs2 + rs0 * rs1; // A = 0
+rd = rs2 - rs0 * rs1; // A = 1
 
-4, ldr, b[i]                    opcode = 4
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  0  1  0  0|<--- rd ----->| SH  | s|<----------- simm13 ----------------->|<---- rb ---->|
+| 0  0| 0  0  1  0| 0|<-- rd --->| 0| size| s| 0| 1  1  1  1| 0  0| 0  0|<-- rs1 -->|<-- rs0 -->|
 
-rd = *(uint8_t* )(rb +  (int64_t)simm13);        // SH = 0, s = 0, zbq
-rd = *(uint16_t*)(rb + ((int64_t)simm13 << 1));  // SH = 1, s = 0, zwq
-rd = *(uint32_t*)(rb + ((int64_t)simm13 << 2));  // SH = 2, s = 0, zlq
-
-rd = *(uint64_t*)(rb + ((int64_t)simm13 << 3));  // SH = 3, s = 0, keep
+s = 0, unsigned mul.
+s = 1,   signed mul.
 
-rd = *( int8_t* )(rb +  (int64_t)simm13);        // SH = 0, s = 1, sbq
-rd = *( int16_t*)(rb + ((int64_t)simm13 << 1));  // SH = 1, s = 1, swq
-rd = *( int32_t*)(rb + ((int64_t)simm13 << 2));  // SH = 2, s = 1, slq
+rd = rs0 * rs1; // A = 0, rs2 = 0xf = 15
 ------------------------------------------------------------------------------------------------
 
-5, pop, b[i]                    opcode = 5
+3, div, *, *=,                  opcode = 3
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  0  1  0  1|<--- rd ----->| SH  | s| 0  0  0  0  0  0  0  0  0  0  0  0  0|<---- rb ---->|
-
-rd = *(uint8_t* )rb;  // SH = 0, s = 0, zbq
-rd = *(uint16_t*)rb;  // SH = 1, s = 0, zwq
-rd = *(uint32_t*)rb;  // SH = 2, s = 0, zlq
-
-rd = *(uint64_t*)rb;  // SH = 3, s = 0, keep
+| 0  0| 0  0  1  1| 0|<-- rd --->| 0| size| s| 0| 0  0  0  0| 0  0| 0  0|<-- rs1 -->|<-- rs0 -->|
 
-rd = *( int8_t* )rb;  // SH = 0, s = 1, sbq
-rd = *( int16_t*)rb;  // SH = 1, s = 1, swq
-rd = *( int32_t*)rb;  // SH = 2, s = 1, slq
+s = 0, unsigned div.
+s = 1,   signed div.
 
-rb += 1 << SH
+rd = rs0 / rs1; // A = 0, rs2 = 0xf = 15
 ------------------------------------------------------------------------------------------------
 
-6, str, b[i]                    opcode = 6
+4, ldr, [b + disp]              opcode = 4
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  0  1  1  0|<--- rs ----->| SH  | 0|<----------- simm13 ----------------->|<---- rb ---->|
+| 0  0| 0  1  0  0| 0|<-- rd --->| 0| size| s|<---------------- simm13 ------------>|<-- rb --->|
 
-*(uint8_t* )(rb +  (int64_t)simm13)       = rs;  // SH = 0, zbq
-*(uint16_t*)(rb + ((int64_t)simm13 << 1)) = rs;  // SH = 1, zwq
-*(uint32_t*)(rb + ((int64_t)simm13 << 2)) = rs;  // SH = 2, zlq
-*(uint64_t*)(rb + ((int64_t)simm13 << 3)) = rs;  // SH = 3, keep
-------------------------------------------------------------------------------------------------
-
-7, push, b[i]                   opcode = 7
-------------------------------------------------------------------------------------------------
-|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  0  1  1  1|<---- rs ---->| SH  | s| 0  0  0  0  0  0  0  0  0  0  0  0  0|<---- rb ---->|
+rd = *(uint8_t* )(rb +  (int64_t)simm13);        // size = 0, s = 0, zbq
+rd = *(uint16_t*)(rb + ((int64_t)simm13 << 1));  // size = 1, s = 0, zwq
+rd = *(uint32_t*)(rb + ((int64_t)simm13 << 2));  // size = 2, s = 0, zlq
 
-*(uint8_t* )rb = rs;  // SH = 0, s = 0, zbq
-*(uint16_t*)rb = rs;  // SH = 1, s = 0, zwq
-*(uint32_t*)rb = rs;  // SH = 2, s = 0, zlq
-*(uint64_t*)rb = rs;  // SH = 3, s = 0, keep
+rd = *(uint64_t*)(rb + ((int64_t)simm13 << 3));  // size = 3, s = 0, keep
 
-rb -= 1 << SH
+rd = *( int8_t* )(rb +  (int64_t)simm13);        // size = 0, s = 1, sbq
+rd = *( int16_t*)(rb + ((int64_t)simm13 << 1));  // size = 1, s = 1, swq
+rd = *( int32_t*)(rb + ((int64_t)simm13 << 2));  // size = 2, s = 1, slq
 ------------------------------------------------------------------------------------------------
 
-8, and, &, &=,                  opcode = 8
+5, and, &, &=,                  opcode = 5
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  0  0  0|<---- rd ---->| SH  |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->|
+| 0  0| 0  1  0  1| 0|<-- rd --->| 0| size| SH  |<---- uimm6 ---->| 0  0|<-- rs1 -->|<-- rs0 -->|
 
-rd = rs0 & (rs1 << uimm9);  // SH = 0, LSL
-rd = rs0 & (rs1 >> uimm9);  // SH = 1, LSR
-rd = rs0 & (rs1 >> uimm9);  // SH = 2, ASR
+rd = rs0 & (rs1 << uimm6);  // SH = 0, LSL
+rd = rs0 & (rs1 >> uimm6);  // SH = 1, LSR
+rd = rs0 & (rs1 >> uimm6);  // SH = 2, ASR
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  0  0  0|<---- rd ---->| 1  1|<---------------- uimm14 --------------->|<--- rs0 ---->|
+| 0  0| 0  1  0  1| 0|<-- rd --->| 0| size| 1  1|<------------- uimm12 ------------>|<-- rs0 -->|
 
-rd = rs0 & (uint64_t)uimm14; // SH = 3, IMM
+rd = rs0 & (uint64_t)uimm12; // SH = 3, IMM
 ------------------------------------------------------------------------------------------------
 
 teq, !,                         opcode = 8
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  0  0  0| 1  1  1  1  1| SH  |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->|
+| 0  0| 0  1  0  1| 0| 1  1  1  1| 0| size| SH  |<---- uimm6 ---->| 0  0|<-- rs1 -->|<-- rs0 -->|
 
-ZF = rs0 & (rs1 << uimm9);  // SH = 0, LSL
-ZF = rs0 & (rs1 >> uimm9);  // SH = 1, LSR
-ZF = rs0 & (rs1 >> uimm9);  // SH = 2, ASR
+ZF = rs0 & (rs1 << uimm6);  // SH = 0, LSL
+ZF = rs0 & (rs1 >> uimm6);  // SH = 1, LSR
+ZF = rs0 & (rs1 >> uimm6);  // SH = 2, ASR
 
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  0  0  0| 1  1  1  1  1| 1  1|<---------------- uimm14 --------------->|<--- rs0 ---->|
+| 0  0| 0  1  0  1| 0| 1  1  1  1| 0| size| 1  1|<------------- uimm12 ------------>|<-- rs0 -->|
 
-ZF = rs0 & (uint64_t)uimm14; // SH = 3, IMM
+ZF = rs0 & (uint64_t)uimm12; // SH = 3, IMM
 ------------------------------------------------------------------------------------------------
 
-9, or, |, |=,                   opcode = 9
+6, str, [b + disp]              opcode = 6
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  0  0  1|<---- rd ---->| SH  |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->|
+| 0  0| 0  1  1  0| 0|<-- rs --->| 0| size| 0|<---------------- simm13 ------------>|<-- rb --->|
 
-rd = rs0 | (rs1 << uimm8);  // SH = 0, LSL
-rd = rs0 | (rs1 >> uimm8);  // SH = 1, LSR
-rd = rs0 | (rs1 >> uimm8);  // SH = 2, ASR
+*(uint8_t* )(rb +  (int64_t)simm13)       = rs;  // size = 0, zbq
+*(uint16_t*)(rb + ((int64_t)simm13 << 1)) = rs;  // size = 1, zwq
+*(uint32_t*)(rb + ((int64_t)simm13 << 2)) = rs;  // size = 2, zlq
+*(uint64_t*)(rb + ((int64_t)simm13 << 3)) = rs;  // size = 3, keep
+------------------------------------------------------------------------------------------------
 
+7, or, |, |=,                   opcode = 7
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  0  1  1  1|<---- rd ---->| 1  1|<---------------- uimm14 --------------->|<--- rs0 ---->|
+| 0  0| 0  1  1  1| 0|<-- rd --->| 0| size| SH  |<---- uimm6 ---->| 0  0|<-- rs1 -->|<-- rs0 -->|
 
-rd = rs0 | (uint64_t)uimm14; // SH = 3, IMM
-------------------------------------------------------------------------------------------------
+rd = rs0 | (rs1 << uimm6);  // SH = 0, LSL
+rd = rs0 | (rs1 >> uimm6);  // SH = 1, LSR
+rd = rs0 | (rs1 >> uimm6);  // SH = 2, ASR
 
-10, jmp, disp                   opcode = 10
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  0  1  0|<-------------------------------- simm26:00 -------------------------------->|
+| 0  0| 0  1  1  1| 0|<-- rd --->| 0| size| 1  1|<------------- uimm12 ------------>|<-- rs0 -->|
 
-jmp disp; // -128M ~ 128M
+rd = rs0 | (uint64_t)uimm12; // SH = 3, IMM
 ------------------------------------------------------------------------------------------------
 
-11, jmp, reg,                   opcode = 11
+8, pop, b[0]                    opcode = 8
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  0  1  1|<---- rd ---->| 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0|
+| 0  0| 1  0  0  0| 0|<-- rd --->| 0| 1  1| s| 0  0  0  0  0  0  0  0  0  0  0  0  0|<-- rb --->|
 
-jmp *rd;
-------------------------------------------------------------------------------------------------
-|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  0  1  1|<----------------------------- simm21:00 -------------------->|<--- cc -->| 1|
+rd = *(uint64_t*)rb;  // size = 3, s = 0,
+rd = *(uint64_t*)rb;  // size = 3, s = 1, fpop
 
-jcc simm21:00; // -4M ~ +4M
-cc = 0,  z,
-cc = 1, nz,
-cc = 2, ge,
-cc = 3, gt,
-cc = 4, le,
-cc = 5, lt,
+rb += 1 << size
 ------------------------------------------------------------------------------------------------
 
-12, setcc, &&,||,               opcode = 12
+9, push, b[0]                   opcode = 9
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  1  0  0|<---- rd ---->| 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0| 0|<--- cc -->| 0|
+| 0  0| 1  0  0  1| 0|<-- rs --->| 0| 1  1| s| 0  0  0  0  0  0  0  0  0  0  0  0  0|<-- rb --->|
+
+*(uint64_t*)rb = rs;  // size = 3, s = 0,
+*(uint64_t*)rb = rs;  // size = 3, s = 1, fpush
 
-cc = 0,  z,
-cc = 1, nz,
-cc = 2, ge,
-cc = 3, gt,
-cc = 4, le,
-cc = 5, lt,
+rb -= 1 << size 
 ------------------------------------------------------------------------------------------------
 
-13, ldr, b[i << s]              opcode = 13
+10, ldr, b[i << s]              opcode = 10
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  1  0  1|<--- rd ----->| SH  | s|<-------- uimm8 ------>|<---- ri ---->|<---- rb ---->|
+| 0  0| 1  0  1  0| 0|<-- rd --->| 0| size| s| 0|<---- uimm6 ---->| 0  0|<-- ri --->|<-- rb --->|
 
-rd = *(uint8_t* )(rb + (ri << uimm8));  // SH = 0, s = 0, zbq
-rd = *(uint16_t*)(rb + (ri << uimm8));  // SH = 1, s = 0, zwq
-rd = *(uint32_t*)(rb + (ri << uimm8));  // SH = 2, s = 0, zlq
+rd = *(uint8_t* )(rb + (ri << uimm6));  // size = 0, s = 0, zbq
+rd = *(uint16_t*)(rb + (ri << uimm6));  // size = 1, s = 0, zwq
+rd = *(uint32_t*)(rb + (ri << uimm6));  // size = 2, s = 0, zlq
 
-rd = *(uint64_t*)(rb + (ri << uimm8));  // SH = 3, s = 0, keep
+rd = *(uint64_t*)(rb + (ri << uimm6));  // size = 3, s = 0, keep
 
-rd = *( int8_t* )(rb + (ri << uimm8));  // SH = 0, s = 1, sbq
-rd = *( int16_t*)(rb + (ri << uimm8));  // SH = 1, s = 1, swq
-rd = *( int32_t*)(rb + (ri << uimm8));  // SH = 2, s = 1, slq
+rd = *( int8_t* )(rb + (ri << uimm6));  // size = 0, s = 1, sbq
+rd = *( int16_t*)(rb + (ri << uimm6));  // size = 1, s = 1, swq
+rd = *( int32_t*)(rb + (ri << uimm6));  // size = 2, s = 1, slq
 ------------------------------------------------------------------------------------------------
 
-14, str, b[i << s]              opcode = 14
+11, str, b[i << s]              opcode = 11
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  1  1  0|<---- rs ---->| SH  | s|<-------- uimm8 ------>|<---- ri ---->|<---- rb ---->|
+| 0  0| 1  0  1  1| 0|<-- rs --->| 0| size| s| 0|<---- uimm6 ---->| 0  0|<-- ri --->|<-- rb --->|
 
-*(uint8_t* )(rb + (ri << uimm8)) = rs;  // SH = 0, s = 0, zbq
-*(uint16_t*)(rb + (ri << uimm8)) = rs;  // SH = 1, s = 0, zwq
-*(uint32_t*)(rb + (ri << uimm8)) = rs;  // SH = 2, s = 0, zlq
-*(uint64_t*)(rb + (ri << uimm8)) = rs;  // SH = 3, s = 0, keep
-------------------------------------------------------------------------------------------------
+*(uint8_t* )(rb + (ri << uimm8)) = rs;  // size = 0, s = 0,
+*(uint16_t*)(rb + (ri << uimm8)) = rs;  // size = 1, s = 0,
+*(uint32_t*)(rb + (ri << uimm8)) = rs;  // size = 2, s = 0,
+*(uint64_t*)(rb + (ri << uimm8)) = rs;  // size = 3, s = 0,
 
+*(float *  )(rb + (ri << uimm8)) = rs;  // size = 2, s = 1,
+*(double*  )(rb + (ri << uimm8)) = rs;  // size = 3, s = 1,
+------------------------------------------------------------------------------------------------
 
-15, mov, =, ~, -,                opcode = 15
+12, mov,                        opcode = 12
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  1  1  1|<--- rd  ---->| SH  | 0| 0  0| 0  0  0  0  0  0|<--- rs1 ---->|<---- rs0---->|
+| 0  0| 1  1  0  0| 0|<-- rd --->| 0| size| SH  | 0  0  0  0  0  0| 0  0|<-- rs1 -->|<-- rs --->|
 
 rd =  rs << rs1; // SH = 0 LSL,
 rd =  rs >> rs1; // SH = 1 LSR,
@@ -257,71 +226,52 @@ rd =  rs >> rs1; // SH = 2 ASR,
 
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  1  1  1|<--- rd  ---->| SH  | 0| 0  1|<------------- uimm11 --------->|<---- rs ---->|
-
-rd = rs;           // SH = 0 LSL, uimm11 = 0
-rd = rs << uimm11; // SH = 0 LSL,
-rd = rs >> uimm11; // SH = 1 LSR,
-rd = rs >> uimm11; // SH = 2 ASR,
+| 0  0| 1  1  0  0| 0|<-- rd --->| 0| size| SH  |<---- uimm6 ---->| 0  0| 1  1  1  1|<-- rs --->|
 
+rd = rs;          // SH = 0 LSL, uimm6 = 0
+rd = rs << uimm6; // SH = 0 LSL,
+rd = rs >> uimm6; // SH = 1 LSR,
+rd = rs >> uimm6; // SH = 2 ASR,
 ------------------------------------------------------------------------------------------------
-|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  1  1  1|<--- rd  ---->| SH  | s| 1  0| 0  0  0  0  0  0  0  0  0  0  0|<---- rs ---->|
-
-rd =  uint8_t(rs);  // SH = 0, s = 0, zbq,
-rd = uint16_t(rs);  // SH = 1, s = 0, zwq,
-rd = uint32_t(rs);  // SH = 2, s = 0, zlq
 
-rd =   int8_t(rs);  // SH = 0, s = 1, sbq,
-rd =  int16_t(rs);  // SH = 1, s = 1, swq
-rd =  int32_t(rs);  // SH = 2, s = 1, slq
-
-rd = ~rs;           // SH = 3, s = 0, NOT,
-rd = -rs;           // SH = 3, s = 1, NEG,
+13, movx,                       opcode = 13
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  1  1  1|<--- rd  ---->| SH  | 0| 1  1|<------------------ uimm16 ------------------->|
+| 0  0| 1  1  0  1| 0|<-- rd --->| 0| size| s| 0| 0  0  0  0  0  0| 0  0| 0  0  0  0|<-- rs --->|
 
-rd = uint64_t(imm16);       // SH = 0, IMM
-rd = uint64_t(imm16) << 16; // SH = 1, IMM
-rd = uint64_t(imm16) << 32; // SH = 2, IMM
-rd = uint64_t(imm16) << 48; // SH = 3, IMM
+rd =  uint8_t(rs);  // size = 0, s = 0, zbq,
+rd = uint16_t(rs);  // size = 1, s = 0, zwq,
+rd = uint32_t(rs);  // size = 2, s = 0, zlq
 
-------------------------------------------------------------------------------------------------
-|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  0  1  1  1  1|<--- rd  ---->| 0  0| 1| 1  1|<------------------ uimm16 ------------------->|
+rd =   int8_t(rs);  // size = 0, s = 1, sbq,
+rd =  int16_t(rs);  // size = 1, s = 1, swq
+rd =  int32_t(rs);  // size = 2, s = 1, slq
 
-rd = uint64_t(imm16); // NOT
-------------------------------------------------------------------------------------------------
-
-26, call, disp                  opcode = 26
+14, not,                        opcode = 14
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  1  1  0  1  0|<-------------------------------- simm26:00 -------------------------------->|
+| 0  0| 1  1  1  0| 0|<-- rd --->| 0| size| 0  0| 0  0  0  0  0  0| 0  0| 0  0  0  0|<-- rs --->|
 
-call disp; // -128M ~ 128M
-------------------------------------------------------------------------------------------------
+rd = -rs; // NEG,
 
-27, call, reg,                  opcode = 27
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 0  1  1  0  1  1|<---- rd ---->| 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0|
+| 0  0| 1  1  1  0| 0|<-- rd --->| 0| size| 0  1| 0  0  0  0  0  0| 0  0| 0  0  0  0|<-- rs --->|
 
-call *rd;
-------------------------------------------------------------------------------------------------
+rd = ~rs; // NOT,
 
-42, adrp, reg,                  opcode = 42
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 1  0  1  0  1  0|<--- rd  ---->|<--------------------   simm21   ---------------------------->|
+| 0  0| 1  1  1  0| 0|<-- rd --->| 0| size| 1  0|<------------------ uimm16 ------------------->|
 
-rd = RIP + ((int64_t)simm21 << 14); // load address' high 21 bits relative to current RIP, -16G:+16G
-------------------------------------------------------------------------------------------------
+rd = uimm16;       // size = 0, IMM
+rd = uimm16 << 16; // size = 1, IMM
+rd = uimm16 << 32; // size = 2, IMM
+rd = uimm16 << 48; // size = 3, IMM
 
-56, ret,                        opcode = 56
 ------------------------------------------------------------------------------------------------
 |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
-| 1  1  1  0  0  0|<-------------------------------- 00        -------------------------------->|
+| 0  0| 1  1  1  0| 0|<-- rd --->| 0| size| 1  1|<------------------ uimm16 ------------------->|
 
-ret
+rd = ~uimm16; // MVN
 ------------------------------------------------------------------------------------------------
diff --git a/docs/Naja_sys.txt b/docs/Naja_sys.txt
new file mode 100644 (file)
index 0000000..fe5a334
--- /dev/null
@@ -0,0 +1,138 @@
+                                Naja instructions
+------------------------------------------------------------------------------------------------
+                                opcode format
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| type| S| opcode | 0|<-- rd --->| 0| size| D  0| 0  0  0  0  0  0  0  0  0  0  0  0|<-- rs0 -->|
+
+type: 0 = integer, 1 = float,  2 = vector, 3 = system
+SH  : 0 = LSL,     1 = LSR,    2 = ASR,   (3 = reserved)
+   D: 0 = read,    1 = write
+   S: 0 = user,    1 = kernel
+   0: reserved
+------------------------------------------------------------------------------------------------
+
+48, jmp, disp                   opcode = 48
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  1| 0  0  0  0|<------------------------------- simm26:00 --------------------------------->|
+
+jmp disp; // -128M ~ 128M
+------------------------------------------------------------------------------------------------
+
+49, call, disp                  opcode = 49
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  1| 0  0  0  1|<------------------------------- simm26:00 --------------------------------->|
+
+call disp; // -128M ~ 128M
+------------------------------------------------------------------------------------------------
+
+50, jmp, reg                    opcode = 50
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  1| 0  0  1  0| 0|<-- rd --->| 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0|
+
+jmp *rd;
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  1| 0  0  1  0| 0|<----------------------- simm21:00 ----------------------->|<-- cc --->| 1|
+
+jcc simm21:00; // -4M ~ +4M
+cc = 0,  z,
+cc = 1, nz,
+cc = 2, ge,
+cc = 3, gt,
+cc = 4, le,
+cc = 5, lt,
+------------------------------------------------------------------------------------------------
+
+51, call, reg                   opcode = 51
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  1| 0  0  1  1| 0|<-- rd --->| 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0|
+
+call *rd;
+------------------------------------------------------------------------------------------------
+
+52, setcc                       opcode = 52
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  1| 0  1  0  0| 0|<-- rd --->| 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0|<-- cc --->| 0|
+
+cc = 0,  z,
+cc = 1, nz,
+cc = 2, ge,
+cc = 3, gt,
+cc = 4, le,
+cc = 5, lt,
+------------------------------------------------------------------------------------------------
+
+53, adrp, reg                   opcode = 53
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  1| 0  1  0  1| 0|<-- rd --->|<-------------------------- simm21 -------------------------->|
+
+rd = RIP + ((int64_t)simm21 << 12); // load address' high 21 bits relative to current RIP, -4G:+4G
+------------------------------------------------------------------------------------------------
+
+54, ret,                        opcode = 54
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  1| 0  1  1  0| 0| 0  0  0  0| 0| 0  0| 0  0| 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0|
+
+ret
+------------------------------------------------------------------------------------------------
+
+56, spop,                       opcode = 56
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  1| 1  0  0  0| 0|<-- sr --->| 0| 1  1| 0| 0  0  0  0  0  0  0  0  0  0  0  0  0|<-- rb --->|
+
+// S = 1
+sr = *(uint64_t*)rb; // sr: system register
+
+rb += 8
+------------------------------------------------------------------------------------------------
+
+57, spush,                      opcode = 57
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  1| 1  0  0  1| 0|<-- sr --->| 0| 1  1| 0| 0  0  0  0  0  0  0  0  0  0  0  0  0|<-- rb --->|
+
+// S = 1
+*(uint64_t*)rb = sr; // sr: system register
+
+rb -= 8
+------------------------------------------------------------------------------------------------
+
+58, in, disp                    opcode = 58
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  1| 1  0  1  0| 0|<-- rd --->| 0| size| D  0|<---------------- uimm16 --------------------->|
+
+// S = 1
+in  rd, uimm16 port; // D = 0,
+out rs, uimm16 port; // D = 1,
+------------------------------------------------------------------------------------------------
+
+60, smov,                       opcode = 60
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  1| 1  1  0  0| 0|<-- rd --->| 0| 0  0| D  0| 0  0  0  0  0  0| 0  0| 0  0  0  0|<-- sr --->|
+
+//  S = 1
+// sr: system register
+
+smov rd, sr // D = 0, sr --> rd 
+smov sr, rd // D = 1, rd --> sr
+------------------------------------------------------------------------------------------------
+
+62, iret,                       opcode = 62
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  1| 1  1  1  0| 0| 0  0  0  0| 0| 0  0| 0  0| 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0|
+
+// S = 1
+iret
+------------------------------------------------------------------------------------------------
diff --git a/docs/Naja_vector.txt b/docs/Naja_vector.txt
new file mode 100644 (file)
index 0000000..dac5f0c
--- /dev/null
@@ -0,0 +1,190 @@
+                                Naja instructions
+------------------------------------------------------------------------------------------------
+                                integer vector opcode format
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| type|   opcode  | 0|<-- rd --->| 0| size| s A |<-- rs2 -->| vlen| 0  0|<-- rs1 -->|<-- rs0 -->|
+
+type: 0 = integer,  1 = float,   2 = vector,  3 =  system
+size: 0 = 8bits,    1 = 16bits,  2 = 32bits,  3 =  64bits
+   s: 0 = unsigned, 1 = signed
+   A: 0 = add,      1 = sub
+vlen: 0 = 64bits,   1 = 128bits, 2 = 256bits, 3 = 512bits
+   0: reserved
+------------------------------------------------------------------------------------------------
+
+32, vadd, +, +=,                opcode = 32
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  0| 0  0  0  0| 0|<-- rd --->| 0| size| 0  0| 0  0  0  0| vlen| 0  0|<-- rs1 -->|<-- rs0 -->|
+
+rd[i] = rs0[i] + rs1[i]; // N = vlen / size, i = 0 ~ N - 1
+------------------------------------------------------------------------------------------------
+
+33, vsub, -, -=,                opcode = 33
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  0| 0  0  0  1| 0|<-- rd --->| 0| size| 0  0| 0  0  0  0| vlen| 0  0|<-- rs1 -->|<-- rs0 -->|
+
+rd[i] = rs0[i] - rs1[i]; // N = vlen / size, i = 0 ~ N - 1
+------------------------------------------------------------------------------------------------
+
+vcmp, >, >=, <, <=, ==, !=,     opcode = 33
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  0| 0  0  0  1| 0|<-- rd --->| 0| size| 0  1| 0  0  0  0| vlen| 0  0|<-- rs1 -->|<-- rs0 -->|
+
+rd[i] = flags(rs0[i] - rs1[i]); // N = vlen / size, i = 0 ~ N - 1
+
+flags = 0,  z,
+flags = 1, nz,
+flags = 2, ge,
+flags = 3, gt,
+flags = 4, le,
+flags = 5, lt,
+------------------------------------------------------------------------------------------------
+
+34, vmul, *, *=,                opcode = 34
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  0| 0  0  1  0| 0|<-- rd --->| 0| size| s  A|<-- rs2 -->| vlen| 0  0|<-- rs1 -->|<-- rs0 -->|
+
+s = 0, unsigned mul.
+s = 1,   signed mul.
+
+rd[i] = rs2[i] + rs0[i] * rs1[i]; // A = 0, N = vlen / size, i = 0 ~ N - 1
+rd[i] = rs2[i] - rs0[i] * rs1[i]; // A = 1, N = vlen / size, i = 0 ~ N - 1
+
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  0| 0  0  1  0| 0|<-- rd --->| 0| size| s  0| 1  1  1  1| vlen| 0  0|<-- rs1 -->|<-- rs0 -->|
+
+rd[i] = rs0[i] * rs1[i]; // A = 0, rs2 = 0xf = 15, N = vlen / size, i = 0 ~ N - 1
+------------------------------------------------------------------------------------------------
+
+35, vdiv, /, /=,                opcode = 35
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  0| 0  0  1  1| 0|<-- rd --->| 0| size| s  0| 0  0  0  0| vlen| 0  0|<-- rs1 -->|<-- rs0 -->|
+
+s = 0, unsigned div.
+s = 1,   signed div.
+
+rd[i] = rs0[i] / rs1[i]; // A = 0, N = vlen / size, i = 0 ~ N - 1
+------------------------------------------------------------------------------------------------
+
+20, vldr = fldr, [b + disp]     opcode = 20
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1| 0  1  0  0| 0|<-- rd --->| 0| size| 1  A| 0  0  0  0| vlen| 0  0| 0  0  0  0|<-- rb --->|
+
+rd[i] = rb[i], // V = 1, N = vlen / size, i = 0 ~ N - 1
+
+rb += vlen; // A = 1
+------------------------------------------------------------------------------------------------
+
+22, vstr = fstr, [b + disp]     opcode = 22
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1| 0  1  1  0| 0|<-- rd --->| 0| size| 1  A| 0  0  0  0| vlen| 0  0| 0  0  0  0|<-- rb --->|
+
+rb[i] = rd[i], // V = 1, N = vlen / size, i = 0 ~ N - 1
+
+rb += vlen; // A = 1
+------------------------------------------------------------------------------------------------
+
+37, vand, &, &=,                opcode = 37
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  0| 0  1  0  1| 0|<-- rd --->| 0| size| 0  0| 0  0  0  0| vlen| 0  0|<-- rs1 -->|<-- rs0 -->|
+
+rd[i] = rs0[i] & rs1[i]; // N = vlen / size, i = 0 ~ N - 1
+------------------------------------------------------------------------------------------------
+
+vteq, >, >=, <, <=, ==, !=,     opcode = 37
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  0| 0  1  0  1| 0|<-- rd --->| 0| size| 0  1| 0  0  0  0| vlen| 0  0|<-- rs1 -->|<-- rs0 -->|
+
+rd[i] = flags(rs0[i] - rs1[i]); // N = vlen / size, i = 0 ~ N - 1
+
+flags = 0,  z,
+flags = 1, nz,
+flags = 2, ge,
+flags = 3, gt,
+flags = 4, le,
+flags = 5, lt,
+------------------------------------------------------------------------------------------------
+
+39, vor, &, &=,                 opcode = 39
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  0| 0  1  1  1| 0|<-- rd --->| 0| size| 0  0| 0  0  0  0| vlen| 0  0|<-- rs1 -->|<-- rs0 -->|
+
+rd[i] = rs0[i] | rs1[i]; // N = vlen / size, i = 0 ~ N - 1
+------------------------------------------------------------------------------------------------
+
+28, vmov = fmov,                opcode = 28
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1| 1  1  0  0| 0|<-- rd --->| 0| size| 1  0| 0  0  0  0| vlen| 0  0| 0  0  0  0|<-- rs --->|
+
+rd[i] = rs[i]; // V = 1, N = vlen / size, i = 0 ~ N - 1
+------------------------------------------------------------------------------------------------
+
+44, vmov,                       opcode = 44
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  0| 1  1  0  0| 0|<-- rd --->| 0| size| SH  | 0  0  0  0| vlen| 0  0|<-- rs1 -->|<-- rs --->|
+
+rd[i] =  rs[i] << rs1[i]; // SH = 0 LSL,
+rd[i] =  rs[i] >> rs1[i]; // SH = 1 LSR,
+rd[i] =  rs[i] >> rs1[i]; // SH = 2 ASR,
+
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  0| 1  1  0  0| 0|<-- rd --->| 0| size| SH  | 1  0  0  0| vlen|<---- uimm6 ---->|<-- rs --->|
+
+rd[i] =  rs[i];          // SH = 0 LSL, uimm6 = 0
+rd[i] =  rs[i] << uimm6; // SH = 0 LSL,
+rd[i] =  rs[i] >> uimm6; // SH = 1 LSR,
+rd[i] =  rs[i] >> uimm6; // SH = 2 ASR,
+------------------------------------------------------------------------------------------------
+
+29, vcvt = fcvt,                opcode = 29
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 0  1| 1  1  0  1| 0|<-- rd --->| 0|dsize| 1  0| 0  0 Id sd| vlen| 0  0|Is ss|ssize|<-- rs --->|
+
+rd[i] = fcvt(rs[i]); // V = 1, N = vlen / size, i = 0 ~ N - 1
+
+dsize = rd size;
+ssize = rs size;
+sd    = rd sign;
+ss    = rs sign;
+Id    = rd int or float;
+Is    = rs int or float;
+------------------------------------------------------------------------------------------------
+
+46, vnot,                       opcode = 46
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  0| 1  1  1  0| 0|<-- rd --->| 0| size| 0  A| 0  0  0  0| vlen| 0  0| 0  0  0  0|<-- rs --->|
+
+rd[i] = -rs[i]; // NEG, A = 0, N = vlen / size, i = 0 ~ N - 1
+rd[i] = ~rs[i]; // NOT, A = 1, N = vlen / size, i = 0 ~ N - 1
+------------------------------------------------------------------------------------------------
+
+47, vmov, uimm16                opcode = 47
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  0| 1  1  1  1| 0|<-- rd --->| 0| size| vlen|<------------------ uimm16 ------------------->|
+
+rd[i] = uimm16; // N = vlen / size, i = 0 ~ N - 1
+
+------------------------------------------------------------------------------------------------
+|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+| 1  0| 1  1  1  1| 1|<-- rd --->| 0| size| vlen|<------------------ uimm16 ------------------->|
+
+rd[i] = ~uimm16; // N = vlen / size, i = 0 ~ N - 1
+------------------------------------------------------------------------------------------------
index a0ccf87d39dc9b6aed3d4bf349e207b9a237927b..d399243d40215f16826377bbcd67e50a243e7755 100644 (file)
@@ -60,7 +60,7 @@ static int _naja_elf_link_cs(elf_native_t* naja, elf_section_t* s, elf_section_t
 
                        case R_AARCH64_ADR_PREL_PG_HI21:
 
-                               offset >>= 14;
+                               offset >>= 12;
                                offset  &= 0x1fffff;
 
                                *(uint32_t*)(s->data + rela->r_offset) |= offset;
@@ -68,7 +68,7 @@ static int _naja_elf_link_cs(elf_native_t* naja, elf_section_t* s, elf_section_t
 
                        case R_AARCH64_ADD_ABS_LO12_NC:
 
-                               *(uint32_t*)(s->data + rela->r_offset) |= (sym->sym.st_value & 0x3fff) << 5;
+                               *(uint32_t*)(s->data + rela->r_offset) |= (sym->sym.st_value & 0xfff) << 4;
                                break;
 
                        default:
index 04d800c354afc32c00d7614cd5c8a91f248989fe..073e9629ab90be259624f7a7c821fc310e15d395 100644 (file)
@@ -1,24 +1,25 @@
 #include"scf_elf_naja.h"
 #include"scf_elf_link.h"
 
-static uint32_t naja_plt_lazy[8] = {
-       // str  x16, lr, [sp, #-16]!
-       (7    << 26) | (16 << 21) | (3 << 19) | 0x1e,
-       (7    << 26) | (29 << 21) | (3 << 19) | 0x1e,
-       (0x2a << 26) | (16 << 21),                  // adrp  x16, 0
-       (0    << 26) | (16 << 21) | (3 << 19) | 16, // add   x16,  x16, #0
-
-       (4    << 26) | (17 << 21) | (3 << 19) | 16, // ldr   x17, [x16, #0]
-       (0xb  << 26) | (17 << 21),                  // jmp  *x17
-       (0xf  << 26) | (1  << 16),                  // nop, mov r0, r0
-       (0xf  << 26) | (1  << 16),                  // nop, mov r0, r0
+static uint32_t naja_plt_lazy[8] =
+{
+       (9    << 26) | (10 << 21) | (3 << 18) | 0xe,            // push  r10
+       (9    << 26) | (13 << 21) | (3 << 18) | 0xe,            // push  lr
+       (0x35 << 26) | (10 << 21),                              // adrp  r10, 0
+       (0    << 26) | (10 << 21) | (3 << 18) | (3 << 16) | 10, // add   r10,  r10, #0
+
+       (4    << 26) | (11 << 21) | (3 << 18) | 10,             // ldr   r11, [r10, #0]
+       (0x32 << 26) | (11 << 21),                              // jmp  *r11
+       (0xc  << 26) | (3  << 18) | (0xf << 4),                 // nop, mov r0, r0
+       (0xc  << 26) | (3  << 18) | (0xf << 4),                 // nop, mov r0, r0
 };
 
-static uint32_t naja_plt[4] = {
-       (0x2a << 26) | (16 << 21),                  // adrp  x16, 0
-       (0    << 26) | (16 << 21) | (3 << 19) | 16, // add   x16,  x16, #0
-       (4    << 26) | (17 << 21) | (3 << 19) | 16, // ldr   x17, [x16, #0]
-       (0xb  << 26) | (17 << 21),                  // jmp  *x17
+static uint32_t naja_plt[4] =
+{
+       (0x35 << 26) | (10 << 21),                              // adrp  r10, 0
+       (0    << 26) | (10 << 21) | (3 << 18) | (3 << 16) | 10, // add   r10,  r10, #0
+       (4    << 26) | (11 << 21) | (3 << 18) | 10,             // ldr   r11, [r10, #0]
+       (0x32 << 26) | (11 << 21),                              // jmp  *r11
 };
 
 
@@ -693,8 +694,8 @@ int __naja_elf_post_dyn(elf_native_t* naja, uint64_t rx_base, uint64_t rw_base,
 
        scf_logi("got_addr: %#lx, plt_addr: %#lx, offset: %d, %#x\n", got_addr, plt_addr, offset, offset);
 
-       plt[2] |=  (offset >> 14) & 0x1fffff;
-       plt[3] |=  (got_addr & 0x3fff) << 5;
+       plt[2] |=  (offset >> 12) & 0x1fffff;
+       plt[3] |=  (got_addr & 0xfff) << 4;
 
        got_addr += 8;
        plt_addr += sizeof(naja_plt_lazy);
@@ -712,8 +713,8 @@ int __naja_elf_post_dyn(elf_native_t* naja, uint64_t rx_base, uint64_t rw_base,
 
                scf_logi("i: %d, got_addr: %#lx, plt_addr: %#lx, offset: %d, %#x\n", i, got_addr, plt_addr, offset, offset);
 
-               plt[0] |= (offset >> 14) & 0x1fffff;
-               plt[1] |= (got_addr & 0x3fff) << 5;
+               plt[0] |= (offset >> 12) & 0x1fffff;
+               plt[1] |= (got_addr & 0xfff) << 4;
 
                plt += sizeof(naja_plt) / sizeof(naja_plt[0]);
                plt_addr += sizeof(naja_plt);
index 791519a167e7307b633893615e67411f7c140bd9..ef56dff56f9a3a091797fa3dc197097f46825cf6 100644 (file)
@@ -1,5 +1,16 @@
 #include"scf_risc.h"
 
+static uint32_t naja_shift(int bytes)
+{
+       if (bytes <= 1)
+               return 0;
+       else if (bytes <= 2)
+               return 1;
+       else if (bytes <= 4)
+               return 2;
+       return 3;
+}
+
 int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes)
 {
        scf_instruction_t* inst;
@@ -10,13 +21,13 @@ int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes
        if (0 == (invert >> 32)) {
 
                // mvn rd, invert[15:0]
-               opcode = (0xf << 26) | (rd->id << 21) | (1 << 18) | (0x3 << 16) | (invert & 0xffff);
+               opcode = (0xe << 26) | (rd->id << 21) | (0x3 << 18) | (0x3 << 16) | (invert & 0xffff);
                inst   = risc_make_inst(c, opcode);
                RISC_INST_ADD_CHECK(c->instructions, inst);
 
                if (invert >> 16) {
-                       // movk rd, imm[31:16]
-                       opcode = (0xf << 26) | (rd->id << 21) | (1 << 19) | (0x3 << 16)| ((imm >> 16) & 0xffff);
+                       // movt rd, imm[31:16]
+                       opcode = (0xe << 26) | (rd->id << 21) | (0x1 << 18) | (0x2 << 16)| ((imm >> 16) & 0xffff);
                        inst   = risc_make_inst(c, opcode);
                        RISC_INST_ADD_CHECK(c->instructions, inst);
                }
@@ -25,15 +36,15 @@ int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes
        }
 
        // mov rd, imm[15:0]
-       opcode = (0xf << 26) | (rd->id << 21) | (0x3 << 16) | (imm & 0xffff);
+       opcode = (0xe << 26) | (rd->id << 21) | (0x2 << 16) | (imm & 0xffff);
        inst   = risc_make_inst(c, opcode);
        RISC_INST_ADD_CHECK(c->instructions, inst);
 
        imm >>= 16;
        if (imm & 0xffff) {
 
-               // movk rd, imm[31:16]
-               opcode = (0xf << 26) | (rd->id << 21) | (1 << 19) | (0x3 << 16) | (imm & 0xffff);
+               // movt rd, imm[31:16]
+               opcode = (0xe << 26) | (rd->id << 21) | (1 << 18) | (0x2 << 16) | (imm & 0xffff);
                inst   = risc_make_inst(c, opcode);
                RISC_INST_ADD_CHECK(c->instructions, inst);
        }
@@ -42,7 +53,7 @@ int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes
        if (imm & 0xffff) {
 
                // movk rd, imm[47:32]
-               opcode = (0xf << 26) | (rd->id << 21) | (2 << 19) | (0x3 << 16) | (imm & 0xffff);
+               opcode = (0xe << 26) | (rd->id << 21) | (2 << 18) | (0x2 << 16) | (imm & 0xffff);
                inst   = risc_make_inst(c, opcode);
                RISC_INST_ADD_CHECK(c->instructions, inst);
        }
@@ -51,7 +62,7 @@ int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes
        if (imm & 0xffff) {
 
                // movk rd, imm[63:48]
-               opcode = (0xf << 26) | (rd->id << 21) | (3 << 19) | (0x3 << 16) | (imm & 0xffff);
+               opcode = (0xe << 26) | (rd->id << 21) | (3 << 18) | (0x2 << 16) | (imm & 0xffff);
                inst   = risc_make_inst(c, opcode);
                RISC_INST_ADD_CHECK(c->instructions, inst);
        }
@@ -76,20 +87,20 @@ int naja_inst_ADR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, sc
 
                offset = vs->bp_offset;
 
-               if (offset >= 0 && offset <= 0x3fff)
+               if (offset >= 0 && offset <= 0xfff)
 
-                       opcode = (0 << 26) | (rd->id << 21) | (0x3 << 19) | (offset << 5) | fp->id;
+                       opcode = (0 << 26) | (rd->id << 21) | (0x3 << 18) | (0x3 << 16) | (offset << 4) | fp->id;
 
                else if (offset < 0 && -offset <= 0x3fff)
 
-                       opcode = (1 << 26) | (rd->id << 21) | (0x3 << 19) | ((-offset) << 5) | fp->id;
+                       opcode = (1 << 26) | (rd->id << 21) | (0x3 << 18) | (0x3 << 16) | ((-offset) << 4) | fp->id;
 
                else {
                        int ret = naja_inst_I2G(c, rd, offset, 8);
                        if (ret < 0)
                                return ret;
 
-                       opcode = (0 << 26) | (rd->id << 21) | (rd->id << 5) | fp->id;
+                       opcode = (0 << 26) | (rd->id << 21) | (0x3 << 18) | (rd->id << 4) | fp->id;
                }
 
                inst   = risc_make_inst(c, opcode);
@@ -98,13 +109,13 @@ int naja_inst_ADR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, sc
        } else if (vs->global_flag) {
                offset = 0;
 
-               opcode = (0x2a << 26) | (rd->id << 21);
+               opcode = (0x35 << 26) | (rd->id << 21);
                inst   = risc_make_inst(c, opcode);
                RISC_INST_ADD_CHECK(c->instructions, inst);
                RISC_RELA_ADD_CHECK(f->data_relas, rela, c, vs, NULL);
                rela->type = R_AARCH64_ADR_PREL_PG_HI21;
 
-               opcode = (0 << 26) | (rd->id << 21) | (0x3 << 19) | rd->id;
+               opcode = (0 << 26) | (rd->id << 21) | (0x3 << 18) | (0x3 << 16) | rd->id;
                inst   = risc_make_inst(c, opcode);
                RISC_INST_ADD_CHECK(c->instructions, inst);
                RISC_RELA_ADD_CHECK(f->data_relas, rela, c, vs, NULL);
@@ -194,7 +205,7 @@ int naja_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_
 
 
        if (offset >= -0xfff && offset <= 0xfff)
-               opcode = (0x4 << 26) | ((offset & 0x1fff) << 5) | rb->id;
+               opcode = (0x4 << 26) | ((offset & 0x1fff) << 4) | rb->id;
        else {
                int ret = risc_select_free_reg(&ri, c, f, 0);
                if (ret < 0) {
@@ -206,18 +217,18 @@ int naja_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_
                if (ret < 0)
                        return ret;
 
-               opcode = (0xd << 26) | (SIZE << 10) | (ri->id << 5) | rb->id;
+               opcode = (0xa << 26) | (SIZE << 18) | (ri->id << 4) | rb->id;
        }
 
        if (rd->bytes > size && scf_variable_signed(vs))
-               opcode |= 0x1 << 18;
+               opcode |= 0x1 << 17;
 
-       else if (scf_variable_float(vs) && 4 == size)
-               opcode |= 0x1 << 18;
+//     else if (scf_variable_float(vs) && 4 == size)
+//             opcode |= 0x1 << 18;
 
        scf_loge("SIZE: %d, size: %d\n", SIZE, size);
 
-       opcode |= (rd->id << 21) | SIZE << 19;
+       opcode |= (rd->id << 21) | SIZE << 18;
        opcode |= RISC_COLOR_TYPE(rd->color) << 30;
 
        inst    = risc_make_inst(c, opcode);
@@ -308,7 +319,7 @@ int naja_inst_G2M(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_
        scf_loge("offset: %ld, SIZE: %d\n", offset, SIZE);
 
        if (offset >= -0xfff && offset <= 0xfff)
-               opcode = (0x6 << 26) | ((offset & 0x1fff) << 5) | rb->id;
+               opcode = (0x6 << 26) | ((offset & 0x1fff) << 4) | rb->id;
        else {
                int ret = risc_select_free_reg(&ri, c, f, 0);
                if (ret < 0) {
@@ -320,14 +331,14 @@ int naja_inst_G2M(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_
                if (ret < 0)
                        return ret;
 
-               opcode = (0xe << 26) | (SIZE << 10) | (ri->id << 5) | rb->id;
+               opcode = (0xb << 26) | (SIZE << 18) | (ri->id << 4) | rb->id;
        }
 
-       opcode |= (rs->id << 21) | SIZE << 19;
+       opcode |= (rs->id << 21) | SIZE << 18;
        opcode |= RISC_COLOR_TYPE(rs->color) << 30;
 
-       if (scf_variable_float(vs) && 4 == size)
-               opcode |= (1 << 18);
+//     if (scf_variable_float(vs) && 4 == size)
+//             opcode |= (1 << 18);
 
        inst    = risc_make_inst(c, opcode);
        RISC_INST_ADD_CHECK(c->instructions, inst);
@@ -351,13 +362,13 @@ int naja_inst_ISTR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, s
 
        uint32_t opcode;
 
-       opcode = (0x2a << 26) | (rd->id << 21);
+       opcode = (0x35 << 26) | (rd->id << 21);
        inst   = risc_make_inst(c, opcode);
        RISC_INST_ADD_CHECK(c->instructions, inst);
        RISC_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
        rela->type = R_AARCH64_ADR_PREL_PG_HI21;
 
-       opcode = (0 << 26) | (rd->id << 21) | (0x3 << 19) | rd->id;
+       opcode = (0 << 26) | (rd->id << 21) | (0x3 << 18) | (0x3 << 16) | rd->id;
        inst   = risc_make_inst(c, opcode);
        RISC_INST_ADD_CHECK(c->instructions, inst);
        RISC_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL);
@@ -368,8 +379,8 @@ int naja_inst_ISTR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, s
 
 int naja_inst_G2P(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_register_t* rb, int32_t offset, int size)
 {
-       scf_register_t* ri   = NULL;
-       scf_instruction_t*    inst = NULL;
+       scf_register_t*     ri   = NULL;
+       scf_instruction_t*  inst = NULL;
 
        uint32_t opcode;
        uint32_t SIZE = 0;
@@ -413,7 +424,7 @@ int naja_inst_G2P(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_
                return -EINVAL;
 
        if (offset >= -0xfff && offset <= 0xfff)
-               opcode = (0x6 << 26) | ((offset & 0x1fff) << 5) | rb->id;
+               opcode = (0x6 << 26) | ((offset & 0x1fff) << 4) | rb->id;
        else {
                int ret = risc_select_free_reg(&ri, c, f, 0);
                if (ret < 0) {
@@ -425,10 +436,10 @@ int naja_inst_G2P(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_
                if (ret < 0)
                        return ret;
 
-               opcode = (0xe << 26) | (SIZE << 10) | (ri->id << 5) | rb->id;
+               opcode = (0xb << 26) | (SIZE << 18) | (ri->id << 4) | rb->id;
        }
 
-       opcode |= (rs->id << 21) | SIZE << 19;
+       opcode |= (rs->id << 21) | SIZE << 18;
        opcode |= RISC_COLOR_TYPE(rs->color) << 30;
 
        inst    = risc_make_inst(c, opcode);
@@ -439,8 +450,8 @@ int naja_inst_G2P(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_
 
 int naja_inst_P2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_register_t* rb, int32_t offset, int size)
 {
-       scf_register_t* ri   = NULL;
-       scf_instruction_t*    inst = NULL;
+       scf_register_t*     ri   = NULL;
+       scf_instruction_t*  inst = NULL;
 
        uint32_t opcode;
        uint32_t SIZE = 0;
@@ -484,7 +495,7 @@ int naja_inst_P2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_
                return -EINVAL;
 
        if (offset >= -0xfff && offset <= 0xfff)
-               opcode = (0x4 << 26) | ((offset & 0x1fff) << 5) | rb->id;
+               opcode = (0x4 << 26) | ((offset & 0x1fff) << 4) | rb->id;
        else {
                int ret = risc_select_free_reg(&ri, c, f, 0);
                if (ret < 0) {
@@ -496,10 +507,10 @@ int naja_inst_P2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_
                if (ret < 0)
                        return ret;
 
-               opcode = (0xd << 26) | (SIZE << 10) | (ri->id << 5) | rb->id;
+               opcode = (0xa << 26) | (SIZE << 18) | (ri->id << 4) | rb->id;
        }
 
-       opcode |= (rd->id << 21) | SIZE << 19;
+       opcode |= (rd->id << 21) | SIZE << 18;
        opcode |= RISC_COLOR_TYPE(rd->color) << 30;
 
        inst    = risc_make_inst(c, opcode);
@@ -514,11 +525,11 @@ int naja_inst_ADRP2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, s
 
        uint32_t opcode = 0;
 
-       if (offset >= 0 && offset <= 0x3fff)
-               opcode = (0 << 26) | (rd->id << 21) | (3 << 19) | (offset << 5) | rb->id;
+       if (offset >= 0 && offset <= 0xfff)
+               opcode = (0 << 26) | (rd->id << 21) | (3 << 18) | (3 << 16) | (offset << 4) | rb->id;
 
-       else if (offset < 0 && offset >= -0x3fff)
-               opcode = (1 << 26) | (rd->id << 21) | (3 << 19) | ((-offset) << 5) | rb->id;
+       else if (offset < 0 && offset >= -0xfff)
+               opcode = (1 << 26) | (rd->id << 21) | (3 << 18) | (3 << 16) | ((-offset) << 4) | rb->id;
 
        else {
                int ret = risc_select_free_reg(&r, c, f, 0);
@@ -529,7 +540,7 @@ int naja_inst_ADRP2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, s
                if (ret < 0)
                        return ret;
 
-               opcode = (0 << 26) | (rd->id << 21) | (r->id << 5) | rb->id;
+               opcode = (0 << 26) | (rd->id << 21) | (3 << 18) | (r->id << 4) | rb->id;
        }
 
        inst   = risc_make_inst(c, opcode);
@@ -539,9 +550,9 @@ int naja_inst_ADRP2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, s
 
 int naja_inst_ADRSIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_sib_t* sib)
 {
-       scf_register_t* rb   = sib->base;
-       scf_register_t* ri   = sib->index;
-       scf_instruction_t*    inst = NULL;
+       scf_register_t*     rb   = sib->base;
+       scf_register_t*     ri   = sib->index;
+       scf_instruction_t*  inst = NULL;
 
        assert(0 == sib->disp);
 
@@ -565,7 +576,7 @@ int naja_inst_ADRSIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd,
        else
                return -EINVAL;
 
-       opcode = (0 << 26) | (rd->id << 21) | (SH << 10) | (ri->id << 5) | rb->id;
+       opcode = (0 << 26) | (rd->id << 21) | (3 << 18) | (SH << 16) | (ri->id << 4) | rb->id;
        inst   = risc_make_inst(c, opcode);
        RISC_INST_ADD_CHECK(c->instructions, inst);
        return 0;
@@ -573,9 +584,9 @@ int naja_inst_ADRSIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd,
 
 int naja_inst_SIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_sib_t* sib)
 {
-       scf_register_t* rb   = sib->base;
-       scf_register_t* ri   = sib->index;
-       scf_instruction_t*    inst = NULL;
+       scf_register_t*     rb   = sib->base;
+       scf_register_t*     ri   = sib->index;
+       scf_instruction_t*  inst = NULL;
 
        assert(0 == sib->disp);
 
@@ -602,8 +613,8 @@ int naja_inst_SIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, sc
        else
                return -EINVAL;
 
-       opcode  = (0xd << 26) | (rd->id << 21) | (SIZE << 10) | (ri->id << 5) | rb->id;
-       opcode |= SIZE << 19;
+       opcode  = (0xa << 26) | (rd->id << 21) | (SIZE << 10) | (ri->id << 4) | rb->id;
+       opcode |= SIZE << 18;
        opcode |= RISC_COLOR_TYPE(rd->color) << 30;
 
        inst    = risc_make_inst(c, opcode);
@@ -614,9 +625,9 @@ int naja_inst_SIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, sc
 
 int naja_inst_G2SIB(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_sib_t* sib)
 {
-       scf_register_t* rb   = sib->base;
-       scf_register_t* ri   = sib->index;
-       scf_instruction_t*    inst = NULL;
+       scf_register_t*     rb   = sib->base;
+       scf_register_t*     ri   = sib->index;
+       scf_instruction_t*  inst = NULL;
 
        assert(0 == sib->disp);
 
@@ -643,9 +654,9 @@ int naja_inst_G2SIB(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, sc
        else
                return -EINVAL;
 
-       opcode  = (0xe << 26) | (rs->id << 21) | (SIZE << 10) | (ri->id << 5) | rb->id;
-       opcode |= SIZE << 19;
-       opcode |= RISC_COLOR_TYPE(rs->color) << 26;
+       opcode  = (0xb << 26) | (rs->id << 21) | (SIZE << 10) | (ri->id << 4) | rb->id;
+       opcode |= SIZE << 18;
+       opcode |= RISC_COLOR_TYPE(rs->color) << 16;
 
        inst    = risc_make_inst(c, opcode);
        RISC_INST_ADD_CHECK(c->instructions, inst);
@@ -663,8 +674,9 @@ scf_instruction_t* naja_inst_PUSH(scf_3ac_code_t* c, scf_register_t* r)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x7 << 26) | (r->id << 21) | (3 << 19) | 0x1e;
-       inst   = risc_make_inst(c, opcode);
+       opcode  = (0x9 << 26) | (r->id << 21) | (3 << 18) | 0xe;
+       opcode |= RISC_COLOR_TYPE(r->color) << 17;
+       inst    = risc_make_inst(c, opcode);
 
        return inst;
 }
@@ -674,8 +686,9 @@ scf_instruction_t* naja_inst_POP(scf_3ac_code_t* c, scf_register_t* r)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x5 << 26) | (r->id << 21) | (3 << 19) | 0x1e;
-       inst   = risc_make_inst(c, opcode);
+       opcode  = (0x8 << 26) | (r->id << 21) | (3 << 18) | 0xe;
+       opcode |= RISC_COLOR_TYPE(r->color) << 17;
+       inst    = risc_make_inst(c, opcode);
 
        return inst;
 }
@@ -685,7 +698,7 @@ scf_instruction_t* naja_inst_RET(scf_3ac_code_t* c)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = 0x38 << 26;
+       opcode = 0x36 << 26;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -696,7 +709,7 @@ scf_instruction_t* naja_inst_MOV_SP(scf_3ac_code_t* c, scf_register_t* rd, scf_r
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0xf << 26) | (rd->id << 21) | (0x1 << 16) | rs->id;
+       opcode = (0xc << 26) | (rd->id << 21) | (3 << 18) | (0xf << 4) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -707,7 +720,7 @@ scf_instruction_t* naja_inst_MOV_G(scf_3ac_code_t* c, scf_register_t* rd, scf_re
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0xf << 26) | (rd->id << 21) | (0x1 << 16) | rs->id;
+       opcode = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (0xf << 4) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -718,7 +731,7 @@ scf_instruction_t* naja_inst_MVN(scf_3ac_code_t* c, scf_register_t* rd, scf_regi
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0xf << 26) | (rd->id << 21) | (0x3 << 19) | (0x2 << 16) | rs->id;
+       opcode = (0xe << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (1 << 16) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -729,7 +742,7 @@ scf_instruction_t* naja_inst_FMOV_G(scf_3ac_code_t* c, scf_register_t* rd, scf_r
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x1f << 26) | (rd->id << 21) | (0x3 << 19) | (0x3 << 16) | rs->id;
+       opcode = (0x1c << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -750,7 +763,7 @@ scf_instruction_t* naja_inst_MOVSX(scf_3ac_code_t* c, scf_register_t* rd, scf_re
        else
                return NULL;
 
-       opcode = (0xf << 26) | (rd->id << 21) | (SH << 19) | (1 << 18) | (0x2 << 16) | rs->id;
+       opcode = (0xd << 26) | (rd->id << 21) | (SH << 18) | (1 << 17) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -771,7 +784,7 @@ scf_instruction_t* naja_inst_MOVZX(scf_3ac_code_t* c, scf_register_t* rd, scf_re
        else
                return NULL;
 
-       opcode = (0xf << 26) | (rd->id << 21) | (SH << 19) | (0x2 << 16)| rs->id;
+       opcode = (0xd << 26) | (rd->id << 21) | (SH << 18) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -783,7 +796,7 @@ scf_instruction_t* naja_inst_CVTSS2SD(scf_3ac_code_t* c, scf_register_t* rd, scf
        uint32_t           opcode;
        uint32_t           S;
 
-       opcode = (0x1f << 26) | (rd->id << 21) | (2 << 19) | rs->id;
+       opcode = (0x1d << 26) | (rd->id << 21) | (3 << 18) | (1 << 12) | (1 << 6) | (2 << 4) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -794,7 +807,7 @@ scf_instruction_t* naja_inst_CVTSD2SS(scf_3ac_code_t* c, scf_register_t* rd, scf
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x1f << 26) | (rd->id << 21) | (3 << 19) | rs->id;
+       opcode = (0x1d << 26) | (rd->id << 21) | (2 << 18) | (1 << 12) | (1 << 6) | (3 << 4) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -811,7 +824,7 @@ scf_instruction_t* naja_inst_CVTF2SI(scf_3ac_code_t* c, scf_register_t* rd, scf_
        else
                SH = 3;
 
-       opcode = (0x1f << 26) | (rd->id << 21) | (SH << 19) | (1 << 18) | (0x1 << 16) | rs->id;
+       opcode = (0x1d << 26) | (rd->id << 21) | (SH << 18) | (3 << 12) | (1 << 6) | (naja_shift(rs->bytes) << 4) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -828,7 +841,7 @@ scf_instruction_t* naja_inst_CVTF2UI(scf_3ac_code_t* c, scf_register_t* rd, scf_
        else
                SH = 3;
 
-       opcode = (0x1f << 26) | (rd->id << 21) | (SH << 19) | (0x1 << 16) | rs->id;
+       opcode = (0x1d << 26) | (rd->id << 21) | (SH << 18) | (2 << 12) | (1 << 6) | (naja_shift(rs->bytes) << 4) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -845,7 +858,7 @@ scf_instruction_t* naja_inst_CVTSI2F(scf_3ac_code_t* c, scf_register_t* rd, scf_
        else
                SH = 3;
 
-       opcode = (0x1f << 26) | (rd->id << 21) | (SH << 19) | (1 << 18) | (0x2 << 16) | rs->id;
+       opcode = (0x1d << 26) | (rd->id << 21) | (SH << 18) | (1 << 12) | (3 << 6) | (naja_shift(rs->bytes) << 4) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -862,7 +875,7 @@ scf_instruction_t* naja_inst_CVTUI2F(scf_3ac_code_t* c, scf_register_t* rd, scf_
        else
                SH = 3;
 
-       opcode = (0x1f << 26) | (rd->id << 21) | (SH << 19) | (0x2 << 16) | rs->id;
+       opcode = (0x1d << 26) | (rd->id << 21) | (SH << 18) | (1 << 12) | (2 << 6) | (naja_shift(rs->bytes) << 4) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -873,12 +886,12 @@ scf_instruction_t* naja_inst_SUB_IMM(scf_3ac_code_t* c, scf_function_t* f, scf_r
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       if (imm > 0x3fff) {
+       if (imm > 0xfff) {
                scf_loge("NOT support too big imm: %#lx\n", imm);
                return NULL;
        }
 
-       opcode = (1 << 26) | (rd->id << 21) | (3 << 19) | (imm << 5) | rs->id;
+       opcode = (1 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (3 << 16) | (imm << 4) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -889,12 +902,12 @@ scf_instruction_t* naja_inst_CMP_IMM(scf_3ac_code_t* c, scf_function_t* f, scf_r
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       if (imm > 0x3fff) {
+       if (imm > 0xfff) {
                scf_loge("NOT support too big imm: %#lx\n", imm);
                return NULL;
        }
 
-       opcode = (1 << 26) | (0x1f << 21) | (3 << 19) | (imm << 5) | rs->id;
+       opcode = (1 << 26) | (0xf << 21) | (naja_shift(rs->bytes) << 18) | (3 << 16) | (imm << 4) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -905,12 +918,12 @@ scf_instruction_t* naja_inst_ADD_IMM(scf_3ac_code_t* c, scf_function_t* f, scf_r
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       if (imm > 0x3fff) {
+       if (imm > 0xfff) {
                scf_loge("NOT support too big imm: %#lx\n", imm);
                return NULL;
        }
 
-       opcode = (0 << 26) | (rd->id << 21) | (3 << 19) | (imm << 5) | rs->id;
+       opcode = (0 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (3 << 16) | (imm << 4) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -921,7 +934,7 @@ scf_instruction_t* naja_inst_ADD_G(scf_3ac_code_t* c, scf_register_t* rd, scf_re
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode  = (0 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id;
+       opcode  = (0 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -932,7 +945,7 @@ scf_instruction_t* naja_inst_SHL(scf_3ac_code_t* c, scf_register_t* rd, scf_regi
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode  = (0xf << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id;
+       opcode  = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -943,7 +956,7 @@ scf_instruction_t* naja_inst_SHR(scf_3ac_code_t* c, scf_register_t* rd, scf_regi
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode  = (0xf << 26) | (rd->id << 21) | (1 << 19) | (rs1->id << 5) | rs0->id;
+       opcode  = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (1 << 16) | (rs1->id << 4) | rs0->id;
        inst    = risc_make_inst(c, opcode);
 
        return inst;
@@ -954,7 +967,7 @@ scf_instruction_t* naja_inst_ASR(scf_3ac_code_t* c, scf_register_t* rd, scf_regi
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode  = (0xf << 26) | (rd->id << 21) | (2 << 19) | (rs1->id << 5) | rs0->id;
+       opcode  = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (2 << 16) | (rs1->id << 4) | rs0->id;
        inst    = risc_make_inst(c, opcode);
 
        return inst;
@@ -965,7 +978,7 @@ scf_instruction_t* naja_inst_AND_G(scf_3ac_code_t* c, scf_register_t* rd, scf_re
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x8 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id;
+       opcode = (0x5 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -976,7 +989,7 @@ scf_instruction_t* naja_inst_OR_G(scf_3ac_code_t* c, scf_register_t* rd, scf_reg
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x9 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id;
+       opcode = (0x7 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -987,7 +1000,7 @@ scf_instruction_t* naja_inst_SUB_G(scf_3ac_code_t* c, scf_register_t* rd, scf_re
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x1 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id;
+       opcode = (1 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -998,7 +1011,7 @@ scf_instruction_t* naja_inst_CMP_G(scf_3ac_code_t* c, scf_register_t* rs0, scf_r
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x1 << 26) | (0x1f << 21) | (rs1->id << 5) | rs0->id;
+       opcode = (1 << 26) | (0xf << 21) | (naja_shift(rs0->bytes) << 18) | (rs1->id << 4) | rs0->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1009,7 +1022,7 @@ scf_instruction_t* naja_inst_FCMP(scf_3ac_code_t* c, scf_register_t* rs0, scf_re
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x11 << 26) | (0x1f << 21) | (rs1->id << 5) | rs0->id;
+       opcode = (0x11 << 26) | (0xf << 21) | (naja_shift(rs0->bytes) << 18) | (1 << 16) | (rs1->id << 4) | rs0->id;
        inst    = risc_make_inst(c, opcode);
 
        return inst;
@@ -1020,7 +1033,7 @@ scf_instruction_t* naja_inst_NEG(scf_3ac_code_t* c, scf_register_t* rd, scf_regi
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0xf << 26) | (rd->id << 21) | (0x7 << 18) | (0x2 << 16) | rs->id;
+       opcode = (0xe << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1031,7 +1044,7 @@ scf_instruction_t* naja_inst_TEQ(scf_3ac_code_t* c, scf_register_t* rs)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x8 << 26) | (0x1f << 21) | (rs->id << 5) | rs->id;
+       opcode = (0x5 << 26) | (0xf << 21) | (naja_shift(rs->bytes) << 18) | (rs->id << 4) | rs->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1042,7 +1055,7 @@ scf_instruction_t* naja_inst_FADD(scf_3ac_code_t* c, scf_register_t* rd, scf_reg
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x10 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id;
+       opcode = (0x10 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
        inst    = risc_make_inst(c, opcode);
 
        return inst;
@@ -1053,7 +1066,7 @@ scf_instruction_t* naja_inst_FSUB(scf_3ac_code_t* c, scf_register_t* rd, scf_reg
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x11 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id;
+       opcode = (0x11 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
        inst    = risc_make_inst(c, opcode);
 
        return inst;
@@ -1064,7 +1077,7 @@ scf_instruction_t* naja_inst_MUL(scf_3ac_code_t* c, scf_register_t* rd, scf_regi
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x2 << 26) | (rd->id << 21) | (2 << 19) | (rs1->id << 5) | rs0->id;
+       opcode = (2 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (0xf << 12) | (rs1->id << 4) | rs0->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1075,7 +1088,7 @@ scf_instruction_t* naja_inst_FMUL(scf_3ac_code_t* c, scf_register_t* rd, scf_reg
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x12 << 26) | (rd->id << 21) | (2 << 19) | (1 << 18) | (rs1->id << 5) | rs0->id;
+       opcode = (0x12 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (0xf << 12) | (rs1->id << 4) | rs0->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1086,7 +1099,7 @@ scf_instruction_t* naja_inst_FDIV(scf_3ac_code_t* c, scf_register_t* rd, scf_reg
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x13 << 26) | (rd->id << 21) | (2 << 19) | (1 << 18) | (rs1->id << 5) | rs0->id;
+       opcode = (0x13 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
        inst    = risc_make_inst(c, opcode);
 
        return inst;
@@ -1097,7 +1110,7 @@ scf_instruction_t* naja_inst_DIV(scf_3ac_code_t* c, scf_register_t* rd, scf_regi
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x3 << 26) | (rd->id << 21) | (2 << 19) | (rs1->id << 5) | rs0->id;
+       opcode = (3 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1108,7 +1121,7 @@ scf_instruction_t* naja_inst_SDIV(scf_3ac_code_t* c, scf_register_t* rd, scf_reg
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x3 << 26) | (rd->id << 21) | (2 << 19) | (1 << 18) | (rs1->id << 5) | rs0->id;
+       opcode = (3 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (1 << 17) | (rs1->id << 4) | rs0->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1119,7 +1132,7 @@ scf_instruction_t* naja_inst_MSUB(scf_3ac_code_t* c, scf_register_t* rd, scf_reg
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x2 << 26) | (rd->id << 21) | (1 << 19) | (1 << 18) | (ra->id << 10) | (rm->id << 5) | rn->id;
+       opcode = (2 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (1 << 16) | (ra->id << 12) | (rm->id << 4) | rn->id;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1131,7 +1144,7 @@ int naja_inst_BL(scf_3ac_code_t* c, scf_function_t* f, scf_function_t* pf)
        scf_rela_t*        rela;
        uint32_t           opcode;
 
-       opcode = (0x1a << 26);
+       opcode = (0x31 << 26);
        inst   = risc_make_inst(c, opcode);
 
        RISC_INST_ADD_CHECK(c->instructions, inst);
@@ -1146,7 +1159,7 @@ scf_instruction_t* naja_inst_BLR(scf_3ac_code_t* c, scf_register_t* r)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0x1b << 26) | (r->id << 21);
+       opcode = (0x33 << 26) | (r->id << 21);
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1158,7 +1171,7 @@ scf_instruction_t* naja_inst_SETZ(scf_3ac_code_t* c, scf_register_t* rd)
        uint32_t           opcode;
        uint32_t           cc = 1;
 
-       opcode = (0xc << 26) | (rd->id << 21);
+       opcode = (0x34 << 26) | (rd->id << 21);
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1169,7 +1182,7 @@ scf_instruction_t* naja_inst_SETNZ(scf_3ac_code_t* c, scf_register_t* rd)
        uint32_t           opcode;
        uint32_t           cc = 0;
 
-       opcode = (0xc << 26) | (rd->id << 21) | (1 << 1);
+       opcode = (0x34 << 26) | (rd->id << 21) | (1 << 1);
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1179,7 +1192,7 @@ scf_instruction_t* naja_inst_SETGT(scf_3ac_code_t* c, scf_register_t* rd)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0xc << 26) | (rd->id << 21) | (3 << 1);
+       opcode = (0x34 << 26) | (rd->id << 21) | (3 << 1);
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1189,7 +1202,7 @@ scf_instruction_t* naja_inst_SETGE(scf_3ac_code_t* c, scf_register_t* rd)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0xc << 26) | (rd->id << 21) | (2 << 1);
+       opcode = (0x34 << 26) | (rd->id << 21) | (2 << 1);
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1199,7 +1212,7 @@ scf_instruction_t* naja_inst_SETLT(scf_3ac_code_t* c, scf_register_t* rd)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0xb << 26) | (rd->id << 21) | (5 << 1);
+       opcode = (0x34 << 26) | (rd->id << 21) | (5 << 1);
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1209,7 +1222,7 @@ scf_instruction_t* naja_inst_SETLE(scf_3ac_code_t* c, scf_register_t* rd)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0xb << 26) | (rd->id << 21) | (4 << 1);
+       opcode = (0x34 << 26) | (rd->id << 21) | (4 << 1);
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1220,7 +1233,7 @@ scf_instruction_t* naja_inst_JMP(scf_3ac_code_t* c)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = 0xa << 26;
+       opcode = 0x30 << 26;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1231,7 +1244,7 @@ scf_instruction_t* naja_inst_JZ(scf_3ac_code_t* c)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0xb << 26) | 1;
+       opcode = (0x32 << 26) | 1;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1242,7 +1255,7 @@ scf_instruction_t* naja_inst_JNZ(scf_3ac_code_t* c)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0xb << 26) | (1 << 1) | 1;
+       opcode = (0x32 << 26) | (1 << 1) | 1;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1253,7 +1266,7 @@ scf_instruction_t* naja_inst_JGT(scf_3ac_code_t* c)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0xb << 26) | (3 << 1) | 1;
+       opcode = (0x32 << 26) | (3 << 1) | 1;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1264,7 +1277,7 @@ scf_instruction_t* naja_inst_JGE(scf_3ac_code_t* c)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0xb << 26) | (2 << 1) | 1;
+       opcode = (0x32 << 26) | (2 << 1) | 1;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1275,7 +1288,7 @@ scf_instruction_t* naja_inst_JLT(scf_3ac_code_t* c)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0xb << 26) | (5 << 1) | 1;
+       opcode = (0x32 << 26) | (5 << 1) | 1;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1286,7 +1299,7 @@ scf_instruction_t* naja_inst_JLE(scf_3ac_code_t* c)
        scf_instruction_t* inst;
        uint32_t           opcode;
 
-       opcode = (0xb << 26) | (4 << 1) | 1;
+       opcode = (0x32 << 26) | (4 << 1) | 1;
        inst   = risc_make_inst(c, opcode);
 
        return inst;
@@ -1318,7 +1331,7 @@ void naja_set_jmp_offset(scf_instruction_t* inst, int32_t bytes)
        opcode |= inst->code[2] << 16;
        opcode |= inst->code[3] << 24;
 
-       if (0xb == (opcode >> 26) && 1 == (opcode & 1)) {
+       if (0x32 == (opcode >> 26) && 1 == (opcode & 1)) {
 
                if (bytes  >= 0 && bytes < (0x1 << 20)) {
                        bytes >>= 2;
@@ -1338,7 +1351,7 @@ void naja_set_jmp_offset(scf_instruction_t* inst, int32_t bytes)
                inst->code[3] |= 0x3  & (bytes >> 24);
 
        } else {
-               assert(0xa == (opcode >> 26));
+               assert(0x30 == (opcode >> 26));
 
                bytes >>= 2;
 
@@ -1354,8 +1367,8 @@ void naja_set_jmp_offset(scf_instruction_t* inst, int32_t bytes)
 int naja_cmp_update(scf_3ac_code_t* c, scf_function_t* f, scf_instruction_t* cmp)
 {
        scf_instruction_t* inst;
-       scf_register_t*    r16 = f->rops->find_register_type_id_bytes(0, 16, 8);
-       scf_register_t*    r17 = f->rops->find_register_type_id_bytes(0, 17, 8);
+       scf_register_t*    r10 = f->rops->find_register_type_id_bytes(0, 10, 8);
+       scf_register_t*    r11 = f->rops->find_register_type_id_bytes(0, 11, 8);
        scf_register_t*    r0;
 
        uint32_t opcode;
@@ -1371,34 +1384,34 @@ int naja_cmp_update(scf_3ac_code_t* c, scf_function_t* f, scf_instruction_t* cmp
 
        switch (opcode >> 21) {
 
-               case 0x3f:
-                       SH = (opcode >> 19) & 0x3;
+               case 0x2f:
+                       SH = (opcode >> 16) & 0x3;
 
                        if (0x3 == SH) {
-                               i0   = opcode & 0x1f;
+                               i0   = opcode & 0xf;
                                r0   = f->rops->find_register_type_id_bytes(0, i0, 8);
-                               inst = f->iops->MOV_G(c, r16, r0);  // use r16 to backup r0
+                               inst = f->iops->MOV_G(c, r10, r0);  // use r10 to backup r0
                                RISC_INST_ADD_CHECK(c->instructions, inst);
 
-                               opcode &= ~0x1f;
-                               opcode |=  0x10;
+                               opcode &= ~0xf;
+                               opcode |=  0xa;
                        } else {
-                               i0   =  opcode & 0x1f;
-                               i1   = (opcode >> 5) & 0x1f;
+                               i0   =  opcode & 0xf;
+                               i1   = (opcode >> 4) & 0xf;
 
                                r0   = f->rops->find_register_type_id_bytes(0, i0, 8);
-                               inst = f->iops->MOV_G(c, r16, r0);  // use r16 to backup r0
+                               inst = f->iops->MOV_G(c, r10, r0);  // use r10 to backup r0
                                RISC_INST_ADD_CHECK(c->instructions, inst);
 
                                r0   = f->rops->find_register_type_id_bytes(0, i1, 8);
-                               inst = f->iops->MOV_G(c, r17, r0);  // use r17 to backup r1
+                               inst = f->iops->MOV_G(c, r11, r0);  // use r11 to backup r1
                                RISC_INST_ADD_CHECK(c->instructions, inst);
 
-                               opcode &= ~0x1f;
-                               opcode |=  0x10;
+                               opcode &= ~0xf;
+                               opcode |=  0xa;
 
-                               opcode &= ~(0x1f << 5);
-                               opcode |=  (0x11 << 5);
+                               opcode &= ~(0xf << 4);
+                               opcode |=  (0xb << 4);
                        }
                        break;
                default:
index 221af0e4cd39b6c635d60ffa12d90e69c0db6ce1..2d64b8d84369f50e49e4954ce622b68e1cc1c92f 100644 (file)
@@ -442,6 +442,9 @@ static int _risc_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c)
        scf_register_t* sp  = f->rops->find_register("sp");
        scf_register_t* x0  = f->rops->find_register("x0");
 
+       if (!x0)
+               x0 = f->rops->find_register("r0");
+
        lr->used = 1;
        sp->used = 1;
 
index 4a43cc77b5069f52d85b4c3b4df70c410b6ed41d..abc0d7c64e7cc7497206d0fb938945a177223d91 100644 (file)
@@ -56,4 +56,3 @@ int                 risc_array_index_reg(scf_sib_t* sib, scf_dag_node_t* base, s
 void                risc_call_rabi(int* p_nints, int* p_nfloats, scf_3ac_code_t* c, scf_function_t* f);
 
 #endif
-
index bd3c8acf70078bc269497623dce26ddf3bb06575..9b6ff13ff85c5860e0953e652d089fdeb96502f7 100644 (file)
 #include"scf_risc.h"
 
-#define SCF_RISC_REG_FP   28
-#define SCF_RISC_REG_LR   29
-#define SCF_RISC_REG_SP   30
-#define SCF_RISC_REG_NULL 31
-
-scf_register_t naja_registers[] = {
-
-       {0, 4, "w0",    RISC_COLOR(0, 0, 0xf),  NULL, 0, 0},
-       {0, 8, "x0",    RISC_COLOR(0, 0, 0xff), NULL, 0, 0},
-
-       {1, 4, "w1",    RISC_COLOR(0, 1, 0xf),  NULL, 0, 0},
-       {1, 8, "x1",    RISC_COLOR(0, 1, 0xff), NULL, 0, 0},
-
-       {2, 4, "w2",    RISC_COLOR(0, 2, 0xf),  NULL, 0, 0},
-       {2, 8, "x2",    RISC_COLOR(0, 2, 0xff), NULL, 0, 0},
-
-       {3, 4, "w3",    RISC_COLOR(0, 3, 0xf),  NULL, 0, 0},
-       {3, 8, "x3",    RISC_COLOR(0, 3, 0xff), NULL, 0, 0},
-
-       {4, 4, "w4",    RISC_COLOR(0, 4, 0xf),  NULL, 0, 0},
-       {4, 8, "x4",    RISC_COLOR(0, 4, 0xff), NULL, 0, 0},
-
-       {5, 4, "w5",    RISC_COLOR(0, 5, 0xf),  NULL, 0, 0},
-       {5, 8, "x5",    RISC_COLOR(0, 5, 0xff), NULL, 0, 0},
-
-       {6, 4, "w6",    RISC_COLOR(0, 6, 0xf),  NULL, 0, 0},
-       {6, 8, "x6",    RISC_COLOR(0, 6, 0xff), NULL, 0, 0},
-
-       {7, 4, "w7",    RISC_COLOR(0, 7, 0xf),  NULL, 0, 0},
-       {7, 8, "x7",    RISC_COLOR(0, 7, 0xff), NULL, 0, 0},
-
-// not use x8
-
-//     {8, 4, "w8",    RISC_COLOR(0, 8,  0xf),  NULL, 0},
-//     {8, 8, "x8",    RISC_COLOR(0, 8,  0xff), NULL, 0},
-
-       {9, 4, "w9",    RISC_COLOR(0, 9,  0xf),  NULL, 0, 0},
-       {9, 8, "x9",    RISC_COLOR(0, 9,  0xff), NULL, 0, 0},
-
-       {10, 4, "w10",  RISC_COLOR(0, 10, 0xf),  NULL, 0, 0},
-       {10, 8, "x10",  RISC_COLOR(0, 10, 0xff), NULL, 0, 0},
-
-       {11, 4, "w11",  RISC_COLOR(0, 11, 0xf),  NULL, 0, 0},
-       {11, 8, "x11",  RISC_COLOR(0, 11, 0xff), NULL, 0, 0},
-
-       {12, 4, "w12",  RISC_COLOR(0, 12, 0xf),  NULL, 0, 0},
-       {12, 8, "x12",  RISC_COLOR(0, 12, 0xff), NULL, 0, 0},
-
-       {13, 4, "w13",  RISC_COLOR(0, 13, 0xf),  NULL, 0, 0},
-       {13, 8, "x13",  RISC_COLOR(0, 13, 0xff), NULL, 0, 0},
-
-       {14, 4, "w14",  RISC_COLOR(0, 14, 0xf),  NULL, 0, 0},
-       {14, 8, "x14",  RISC_COLOR(0, 14, 0xff), NULL, 0, 0},
-
-       {15, 4, "w15",  RISC_COLOR(0, 15, 0xf),  NULL, 0, 0},
-       {15, 8, "x15",  RISC_COLOR(0, 15, 0xff), NULL, 0, 0},
-
-// not use x16, x17, x18
-
-       {16, 4, "w16",  RISC_COLOR(0, 16, 0xf),  NULL, 0, 0},
-       {16, 8, "x16",  RISC_COLOR(0, 16, 0xff), NULL, 0, 0},
-
-       {17, 4, "w17",  RISC_COLOR(0, 17, 0xf),  NULL, 0, 0},
-       {17, 8, "x17",  RISC_COLOR(0, 17, 0xff), NULL, 0, 0},
-
-//     {18, 4, "w18",  RISC_COLOR(0, 18, 0xf),  NULL, 0, 0},
-//     {18, 8, "x18",  RISC_COLOR(0, 18, 0xff), NULL, 0, 0},
-
-       {19, 4, "w19",  RISC_COLOR(0, 19, 0xf),  NULL, 0, 0},
-       {19, 8, "x19",  RISC_COLOR(0, 19, 0xff), NULL, 0, 0},
-
-       {20, 4, "w20",  RISC_COLOR(0, 20, 0xf),  NULL, 0, 0},
-       {20, 8, "x20",  RISC_COLOR(0, 20, 0xff), NULL, 0, 0},
-
-       {21, 4, "w21",  RISC_COLOR(0, 21, 0xf),  NULL, 0, 0},
-       {21, 8, "x21",  RISC_COLOR(0, 21, 0xff), NULL, 0, 0},
-
-       {22, 4, "w22",  RISC_COLOR(0, 22, 0xf),  NULL, 0, 0},
-       {22, 8, "x22",  RISC_COLOR(0, 22, 0xff), NULL, 0, 0},
-
-       {23, 4, "w23",  RISC_COLOR(0, 23, 0xf),  NULL, 0, 0},
-       {23, 8, "x23",  RISC_COLOR(0, 23, 0xff), NULL, 0, 0},
-
-       {24, 4, "w24",  RISC_COLOR(0, 24, 0xf),  NULL, 0, 0},
-       {24, 8, "x24",  RISC_COLOR(0, 24, 0xff), NULL, 0, 0},
-
-       {25, 4, "w25",  RISC_COLOR(0, 25, 0xf),  NULL, 0, 0},
-       {25, 8, "x25",  RISC_COLOR(0, 25, 0xff), NULL, 0, 0},
-
-       {26, 4, "w26",  RISC_COLOR(0, 26, 0xf),  NULL, 0, 0},
-       {26, 8, "x26",  RISC_COLOR(0, 26, 0xff), NULL, 0, 0},
-
-       {27, 4, "w27",  RISC_COLOR(0, 27, 0xf),  NULL, 0, 0},
-       {27, 8, "x27",  RISC_COLOR(0, 27, 0xff), NULL, 0, 0},
-
-// fp = x28 = bp
-       {28, 4, "w28",  RISC_COLOR(0, 28, 0xf),  NULL, 0, 0},
-       {28, 8, "fp",   RISC_COLOR(0, 28, 0xff), NULL, 0, 0},
-// lr = x29
-       {29, 4, "w29",  RISC_COLOR(0, 29, 0xf),  NULL, 0, 0},
-       {29, 8, "lr",   RISC_COLOR(0, 29, 0xff), NULL, 0, 0},
-       {30, 8, "sp",   RISC_COLOR(0, 30, 0xff), NULL, 0, 0},
-//     {31, 8, "null", RISC_COLOR(0, 31, 0xff), NULL, 0, 0},
-
+#define SCF_RISC_REG_FP   12
+#define SCF_RISC_REG_LR   13
+#define SCF_RISC_REG_SP   14
+#define SCF_RISC_REG_NULL 15
 
+scf_register_t naja_registers[] =
+{
+       {0, 1, "r0b",   RISC_COLOR(0, 0, 0x1),  NULL, 0, 0},
+       {0, 2, "r0w",   RISC_COLOR(0, 0, 0x3),  NULL, 0, 0},
+       {0, 4, "r0d",   RISC_COLOR(0, 0, 0xf),  NULL, 0, 0},
+       {0, 8, "r0",    RISC_COLOR(0, 0, 0xff), NULL, 0, 0},
+
+       {1, 1, "r1b",   RISC_COLOR(0, 1, 0x1),  NULL, 0, 0},
+       {1, 2, "r1w",   RISC_COLOR(0, 1, 0x3),  NULL, 0, 0},
+       {1, 4, "r1d",   RISC_COLOR(0, 1, 0xf),  NULL, 0, 0},
+       {1, 8, "r1",    RISC_COLOR(0, 1, 0xff), NULL, 0, 0},
+
+       {2, 1, "r2b",   RISC_COLOR(0, 2, 0x1),  NULL, 0, 0},
+       {2, 2, "r2w",   RISC_COLOR(0, 2, 0x3),  NULL, 0, 0},
+       {2, 4, "r2d",   RISC_COLOR(0, 2, 0xf),  NULL, 0, 0},
+       {2, 8, "r2",    RISC_COLOR(0, 2, 0xff), NULL, 0, 0},
+
+       {3, 1, "r3b",   RISC_COLOR(0, 3, 0x1),  NULL, 0, 0},
+       {3, 2, "r3w",   RISC_COLOR(0, 3, 0x3),  NULL, 0, 0},
+       {3, 4, "r3d",   RISC_COLOR(0, 3, 0xf),  NULL, 0, 0},
+       {3, 8, "r3",    RISC_COLOR(0, 3, 0xff), NULL, 0, 0},
+
+       {4, 1, "r4b",   RISC_COLOR(0, 4, 0x1),  NULL, 0, 0},
+       {4, 2, "r4w",   RISC_COLOR(0, 4, 0x3),  NULL, 0, 0},
+       {4, 4, "r4d",   RISC_COLOR(0, 4, 0xf),  NULL, 0, 0},
+       {4, 8, "r4",    RISC_COLOR(0, 4, 0xff), NULL, 0, 0},
+
+       {5, 1, "r5b",   RISC_COLOR(0, 5, 0x1),  NULL, 0, 0},
+       {5, 2, "r5w",   RISC_COLOR(0, 5, 0x3),  NULL, 0, 0},
+       {5, 4, "r5d",   RISC_COLOR(0, 5, 0xf),  NULL, 0, 0},
+       {5, 8, "r5",    RISC_COLOR(0, 5, 0xff), NULL, 0, 0},
+
+       {6, 1, "r6b",   RISC_COLOR(0, 6, 0x1),  NULL, 0, 0},
+       {6, 2, "r6w",   RISC_COLOR(0, 6, 0x3),  NULL, 0, 0},
+       {6, 4, "r6d",   RISC_COLOR(0, 6, 0xf),  NULL, 0, 0},
+       {6, 8, "r6",    RISC_COLOR(0, 6, 0xff), NULL, 0, 0},
+
+       {7, 1, "r7b",   RISC_COLOR(0, 7, 0x1),  NULL, 0, 0},
+       {7, 2, "r7w",   RISC_COLOR(0, 7, 0x3),  NULL, 0, 0},
+       {7, 4, "r7d",   RISC_COLOR(0, 7, 0xf),  NULL, 0, 0},
+       {7, 8, "r7",    RISC_COLOR(0, 7, 0xff), NULL, 0, 0},
+
+       {8, 1, "r8b",   RISC_COLOR(0, 8, 0x1),  NULL, 0, 0},
+       {8, 2, "r8w",   RISC_COLOR(0, 8, 0x3),  NULL, 0, 0},
+       {8, 4, "r8d",   RISC_COLOR(0, 8, 0xf),  NULL, 0, 0},
+       {8, 8, "r8",    RISC_COLOR(0, 8, 0xff), NULL, 0, 0},
+
+       {9, 1, "r9b",   RISC_COLOR(0, 9, 0x1),  NULL, 0, 0},
+       {9, 2, "r9w",   RISC_COLOR(0, 9, 0x3),  NULL, 0, 0},
+       {9, 4, "r9d",   RISC_COLOR(0, 9, 0xf),  NULL, 0, 0},
+       {9, 8, "r9",    RISC_COLOR(0, 9, 0xff), NULL, 0, 0},
+
+// not use r10, r11
+       {10, 1, "r10b", RISC_COLOR(0, 10, 0x1),  NULL, 0, 0},
+       {10, 2, "r10w", RISC_COLOR(0, 10, 0x3),  NULL, 0, 0},
+       {10, 4, "r10d", RISC_COLOR(0, 10, 0xf),  NULL, 0, 0},
+       {10, 8, "r10",  RISC_COLOR(0, 10, 0xff), NULL, 0, 0},
+
+       {11, 1, "r11b", RISC_COLOR(0, 11, 0x1),  NULL, 0, 0},
+       {11, 2, "r11w", RISC_COLOR(0, 11, 0x3),  NULL, 0, 0},
+       {11, 4, "r11d", RISC_COLOR(0, 11, 0xf),  NULL, 0, 0},
+       {11, 8, "r11",  RISC_COLOR(0, 11, 0xff), NULL, 0, 0},
+
+       {12, 1, "r12b", RISC_COLOR(0, 12, 0x1),  NULL, 0, 0},
+       {12, 2, "r12w", RISC_COLOR(0, 12, 0x3),  NULL, 0, 0},
+       {12, 4, "r12d", RISC_COLOR(0, 12, 0xf),  NULL, 0, 0},
+       {12, 8, "fp",   RISC_COLOR(0, 12, 0xff), NULL, 0, 0},
+
+       {13, 1, "r13b", RISC_COLOR(0, 13, 0x1),  NULL, 0, 0},
+       {13, 2, "r13w", RISC_COLOR(0, 13, 0x3),  NULL, 0, 0},
+       {13, 4, "r13d", RISC_COLOR(0, 13, 0xf),  NULL, 0, 0},
+       {13, 8, "lr",   RISC_COLOR(0, 13, 0xff), NULL, 0, 0},
+
+       {14, 8, "sp",   RISC_COLOR(0, 14, 0xff), NULL, 0, 0},
+//     {15, 8, "null", RISC_COLOR(0, 15, 0xff), NULL, 0, 0},
+
+
+       {0, 1, "b0",    RISC_COLOR(1, 0, 0x1),  NULL, 0, 0},
        {0, 2, "h0",    RISC_COLOR(1, 0, 0x3),  NULL, 0, 0},
        {0, 4, "s0",    RISC_COLOR(1, 0, 0xf),  NULL, 0, 0},
        {0, 8, "d0",    RISC_COLOR(1, 0, 0xff), NULL, 0, 0},
 
+       {1, 1, "b1",    RISC_COLOR(1, 1, 0x1),  NULL, 0, 0},
        {1, 2, "h1",    RISC_COLOR(1, 1, 0x3),  NULL, 0, 0},
        {1, 4, "s1",    RISC_COLOR(1, 1, 0xf),  NULL, 0, 0},
        {1, 8, "d1",    RISC_COLOR(1, 1, 0xff), NULL, 0, 0},
 
+       {2, 1, "b2",    RISC_COLOR(1, 2, 0x1),  NULL, 0, 0},
        {2, 2, "h2",    RISC_COLOR(1, 2, 0x3),  NULL, 0, 0},
        {2, 4, "s2",    RISC_COLOR(1, 2, 0xf),  NULL, 0, 0},
        {2, 8, "d2",    RISC_COLOR(1, 2, 0xff), NULL, 0, 0},
 
+       {3, 1, "b3",    RISC_COLOR(1, 3, 0x1),  NULL, 0, 0},
        {3, 2, "h3",    RISC_COLOR(1, 3, 0x3),  NULL, 0, 0},
        {3, 4, "s3",    RISC_COLOR(1, 3, 0xf),  NULL, 0, 0},
        {3, 8, "d3",    RISC_COLOR(1, 3, 0xff), NULL, 0, 0},
 
+       {4, 1, "b4",    RISC_COLOR(1, 4, 0x1),  NULL, 0, 0},
        {4, 2, "h4",    RISC_COLOR(1, 4, 0x3),  NULL, 0, 0},
        {4, 4, "s4",    RISC_COLOR(1, 4, 0xf),  NULL, 0, 0},
        {4, 8, "d4",    RISC_COLOR(1, 4, 0xff), NULL, 0, 0},
 
+       {5, 1, "b5",    RISC_COLOR(1, 5, 0x1),  NULL, 0, 0},
        {5, 2, "h5",    RISC_COLOR(1, 5, 0x3),  NULL, 0, 0},
        {5, 4, "s5",    RISC_COLOR(1, 5, 0xf),  NULL, 0, 0},
        {5, 8, "d5",    RISC_COLOR(1, 5, 0xff), NULL, 0, 0},
 
+       {6, 1, "b6",    RISC_COLOR(1, 6, 0x1),  NULL, 0, 0},
        {6, 2, "h6",    RISC_COLOR(1, 6, 0x3),  NULL, 0, 0},
        {6, 4, "s6",    RISC_COLOR(1, 6, 0xf),  NULL, 0, 0},
        {6, 8, "d6",    RISC_COLOR(1, 6, 0xff), NULL, 0, 0},
 
+       {7, 1, "b7",    RISC_COLOR(1, 7, 0x1),  NULL, 0, 0},
        {7, 2, "h7",    RISC_COLOR(1, 7, 0x3),  NULL, 0, 0},
        {7, 4, "s7",    RISC_COLOR(1, 7, 0xf),  NULL, 0, 0},
        {7, 8, "d7",    RISC_COLOR(1, 7, 0xff), NULL, 0, 0},
 
+       {8, 1, "b8",    RISC_COLOR(1, 8, 0x1),  NULL, 0, 0},
        {8, 2, "h8",    RISC_COLOR(1, 8, 0x3),  NULL, 0, 0},
        {8, 4, "s8",    RISC_COLOR(1, 8, 0xf),  NULL, 0, 0},
        {8, 8, "d8",    RISC_COLOR(1, 8, 0xff), NULL, 0, 0},
 
+       {9, 1, "b9",    RISC_COLOR(1, 9, 0x1),  NULL, 0, 0},
        {9, 2, "h9",    RISC_COLOR(1, 9, 0x3),  NULL, 0, 0},
        {9, 4, "s9",    RISC_COLOR(1, 9, 0xf),  NULL, 0, 0},
        {9, 8, "d9",    RISC_COLOR(1, 9, 0xff), NULL, 0, 0},
 
+       {10, 1, "b10",    RISC_COLOR(1, 10, 0x1),  NULL, 0, 0},
        {10, 2, "h10",    RISC_COLOR(1, 10, 0x3),  NULL, 0, 0},
        {10, 4, "s10",    RISC_COLOR(1, 10, 0xf),  NULL, 0, 0},
        {10, 8, "d10",    RISC_COLOR(1, 10, 0xff), NULL, 0, 0},
 
+       {11, 1, "b11",    RISC_COLOR(1, 11, 0x1),  NULL, 0, 0},
        {11, 2, "h11",    RISC_COLOR(1, 11, 0x3),  NULL, 0, 0},
        {11, 4, "s11",    RISC_COLOR(1, 11, 0xf),  NULL, 0, 0},
        {11, 8, "d11",    RISC_COLOR(1, 11, 0xff), NULL, 0, 0},
 
+       {12, 1, "b12",    RISC_COLOR(1, 12, 0x1),  NULL, 0, 0},
        {12, 2, "h12",    RISC_COLOR(1, 12, 0x3),  NULL, 0, 0},
        {12, 4, "s12",    RISC_COLOR(1, 12, 0xf),  NULL, 0, 0},
        {12, 8, "d12",    RISC_COLOR(1, 12, 0xff), NULL, 0, 0},
 
+       {13, 1, "b13",    RISC_COLOR(1, 13, 0x1),  NULL, 0, 0},
        {13, 2, "h13",    RISC_COLOR(1, 13, 0x3),  NULL, 0, 0},
        {13, 4, "s13",    RISC_COLOR(1, 13, 0xf),  NULL, 0, 0},
        {13, 8, "d13",    RISC_COLOR(1, 13, 0xff), NULL, 0, 0},
 
+       {14, 1, "b14",    RISC_COLOR(1, 14, 0x1),  NULL, 0, 0},
        {14, 2, "h14",    RISC_COLOR(1, 14, 0x3),  NULL, 0, 0},
        {14, 4, "s14",    RISC_COLOR(1, 14, 0xf),  NULL, 0, 0},
        {14, 8, "d14",    RISC_COLOR(1, 14, 0xff), NULL, 0, 0},
 
+       {15, 1, "b15",    RISC_COLOR(1, 15, 0x1),  NULL, 0, 0},
        {15, 2, "h15",    RISC_COLOR(1, 15, 0x3),  NULL, 0, 0},
        {15, 4, "s15",    RISC_COLOR(1, 15, 0xf),  NULL, 0, 0},
        {15, 8, "d15",    RISC_COLOR(1, 15, 0xff), NULL, 0, 0},
-
-       {16, 2, "h16",    RISC_COLOR(1, 16, 0x3),  NULL, 0, 0},
-       {16, 4, "s16",    RISC_COLOR(1, 16, 0xf),  NULL, 0, 0},
-       {16, 8, "d16",    RISC_COLOR(1, 16, 0xff), NULL, 0, 0},
-
-       {17, 2, "h17",    RISC_COLOR(1, 17, 0x3),  NULL, 0, 0},
-       {17, 4, "s17",    RISC_COLOR(1, 17, 0xf),  NULL, 0, 0},
-       {17, 8, "d17",    RISC_COLOR(1, 17, 0xff), NULL, 0, 0},
-
-       {18, 2, "h18",    RISC_COLOR(1, 18, 0x3),  NULL, 0, 0},
-       {18, 4, "s18",    RISC_COLOR(1, 18, 0xf),  NULL, 0, 0},
-       {18, 8, "d18",    RISC_COLOR(1, 18, 0xff), NULL, 0, 0},
-
-       {19, 2, "h19",    RISC_COLOR(1, 19, 0x3),  NULL, 0, 0},
-       {19, 4, "s19",    RISC_COLOR(1, 19, 0xf),  NULL, 0, 0},
-       {19, 8, "d19",    RISC_COLOR(1, 19, 0xff), NULL, 0, 0},
-
-       {20, 2, "h20",    RISC_COLOR(1, 20, 0x3),  NULL, 0, 0},
-       {20, 4, "s20",    RISC_COLOR(1, 20, 0xf),  NULL, 0, 0},
-       {20, 8, "d20",    RISC_COLOR(1, 20, 0xff), NULL, 0, 0},
-
-       {21, 2, "h21",    RISC_COLOR(1, 21, 0x3),  NULL, 0, 0},
-       {21, 4, "s21",    RISC_COLOR(1, 21, 0xf),  NULL, 0, 0},
-       {21, 8, "d21",    RISC_COLOR(1, 21, 0xff), NULL, 0, 0},
-
-       {22, 2, "h22",    RISC_COLOR(1, 22, 0x3),  NULL, 0, 0},
-       {22, 4, "s22",    RISC_COLOR(1, 22, 0xf),  NULL, 0, 0},
-       {22, 8, "d22",    RISC_COLOR(1, 22, 0xff), NULL, 0, 0},
-
-       {23, 2, "h23",    RISC_COLOR(1, 23, 0x3),  NULL, 0, 0},
-       {23, 4, "s23",    RISC_COLOR(1, 23, 0xf),  NULL, 0, 0},
-       {23, 8, "d23",    RISC_COLOR(1, 23, 0xff), NULL, 0, 0},
-
-       {24, 2, "h24",    RISC_COLOR(1, 24, 0x3),  NULL, 0, 0},
-       {24, 4, "s24",    RISC_COLOR(1, 24, 0xf),  NULL, 0, 0},
-       {24, 8, "d24",    RISC_COLOR(1, 24, 0xff), NULL, 0, 0},
-
-       {25, 2, "h25",    RISC_COLOR(1, 25, 0x3),  NULL, 0, 0},
-       {25, 4, "s25",    RISC_COLOR(1, 25, 0xf),  NULL, 0, 0},
-       {25, 8, "d25",    RISC_COLOR(1, 25, 0xff), NULL, 0, 0},
-
-       {26, 2, "h26",    RISC_COLOR(1, 26, 0x3),  NULL, 0, 0},
-       {26, 4, "s26",    RISC_COLOR(1, 26, 0xf),  NULL, 0, 0},
-       {26, 8, "d26",    RISC_COLOR(1, 26, 0xff), NULL, 0, 0},
-
-       {27, 2, "h27",    RISC_COLOR(1, 27, 0x3),  NULL, 0, 0},
-       {27, 4, "s27",    RISC_COLOR(1, 27, 0xf),  NULL, 0, 0},
-       {27, 8, "d27",    RISC_COLOR(1, 27, 0xff), NULL, 0, 0},
-
-       {28, 2, "h28",    RISC_COLOR(1, 28, 0x3),  NULL, 0, 0},
-       {28, 4, "s28",    RISC_COLOR(1, 28, 0xf),  NULL, 0, 0},
-       {28, 8, "d28",    RISC_COLOR(1, 28, 0xff), NULL, 0, 0},
-
-       {29, 2, "h29",    RISC_COLOR(1, 29, 0x3),  NULL, 0, 0},
-       {29, 4, "s29",    RISC_COLOR(1, 29, 0xf),  NULL, 0, 0},
-       {29, 8, "d29",    RISC_COLOR(1, 29, 0xff), NULL, 0, 0},
-
-       {30, 2, "h30",    RISC_COLOR(1, 30, 0x3),  NULL, 0, 0},
-       {30, 4, "s30",    RISC_COLOR(1, 30, 0xf),  NULL, 0, 0},
-       {30, 8, "d30",    RISC_COLOR(1, 30, 0xff), NULL, 0, 0},
-
-       {31, 2, "h31",    RISC_COLOR(1, 31, 0x3),  NULL, 0, 0},
-       {31, 4, "s31",    RISC_COLOR(1, 31, 0xf),  NULL, 0, 0},
-       {31, 8, "d31",    RISC_COLOR(1, 31, 0xff), NULL, 0, 0},
 };
 
 static uint32_t naja_abi_regs[] =
@@ -242,8 +171,6 @@ static uint32_t naja_abi_regs[] =
        SCF_RISC_REG_X3,
        SCF_RISC_REG_X4,
        SCF_RISC_REG_X5,
-       SCF_RISC_REG_X6,
-       SCF_RISC_REG_X7,
 };
 
 static uint32_t naja_abi_float_regs[] =
@@ -274,31 +201,16 @@ static uint32_t naja_abi_caller_saves[] =
        SCF_RISC_REG_X3,
        SCF_RISC_REG_X4,
        SCF_RISC_REG_X5,
-       SCF_RISC_REG_X6,
-       SCF_RISC_REG_X7,
-
-       SCF_RISC_REG_X9,
-       SCF_RISC_REG_X10,
-       SCF_RISC_REG_X11,
-       SCF_RISC_REG_X12,
-       SCF_RISC_REG_X13,
-       SCF_RISC_REG_X14,
-       SCF_RISC_REG_X15,
 };
 
 static uint32_t naja_abi_callee_saves[] =
 {
-       SCF_RISC_REG_X19,
-       SCF_RISC_REG_X20,
-       SCF_RISC_REG_X21,
-       SCF_RISC_REG_X22,
-       SCF_RISC_REG_X23,
-       SCF_RISC_REG_X24,
-       SCF_RISC_REG_X25,
-       SCF_RISC_REG_X26,
-       SCF_RISC_REG_X27,
-       SCF_RISC_REG_X28,
-       SCF_RISC_REG_X29,
+       SCF_RISC_REG_X6,
+       SCF_RISC_REG_X7,
+       SCF_RISC_REG_X8,
+       SCF_RISC_REG_X9,
+       SCF_RISC_REG_FP,
+       SCF_RISC_REG_LR,
 };
 
 static int naja_color_conflict(intptr_t c0, intptr_t c1)
@@ -317,7 +229,7 @@ static int naja_variable_size(scf_variable_t* v)
        if (v->type >= SCF_STRUCT && 0 == v->nb_pointers)
                return 8;
 
-       return v->size < 4 ? 4 : v->size;
+       return v->size;
 }
 
 scf_register_t* naja_find_register(const char* name)
@@ -386,8 +298,8 @@ scf_vector_t* naja_register_colors()
                if (SCF_RISC_REG_SP == r->id
                                || SCF_RISC_REG_FP == r->id
                                || SCF_RISC_REG_LR == r->id
-                               || SCF_RISC_REG_X16 == r->id
-                               || SCF_RISC_REG_X17 == r->id)
+                               || SCF_RISC_REG_X10 == r->id
+                               || SCF_RISC_REG_X11 == r->id)
                        continue;
 
                int ret = scf_vector_add(colors, (void*)r->color);
@@ -421,8 +333,8 @@ int naja_reg_cached_vars(scf_register_t* r)
                if (SCF_RISC_REG_SP == r2->id
          || SCF_RISC_REG_FP == r2->id
          || SCF_RISC_REG_LR == r2->id
-                || SCF_RISC_REG_X16 == r2->id
-                || SCF_RISC_REG_X17 == r2->id)
+                || SCF_RISC_REG_X10 == r2->id
+                || SCF_RISC_REG_X11 == r2->id)
                        continue;
 
                if (!naja_color_conflict(r->color, r2->color))
@@ -444,8 +356,8 @@ int naja_registers_init()
                if (SCF_RISC_REG_SP == r->id
          || SCF_RISC_REG_FP == r->id
          || SCF_RISC_REG_LR == r->id
-                || SCF_RISC_REG_X16 == r->id
-                || SCF_RISC_REG_X17 == r->id)
+                || SCF_RISC_REG_X10 == r->id
+                || SCF_RISC_REG_X11 == r->id)
                        continue;
 
                assert(!r->dag_nodes);
@@ -470,8 +382,8 @@ void naja_registers_clear()
                if (SCF_RISC_REG_SP == r->id
          || SCF_RISC_REG_FP == r->id
          || SCF_RISC_REG_LR == r->id
-                || SCF_RISC_REG_X16 == r->id
-                || SCF_RISC_REG_X17 == r->id)
+                || SCF_RISC_REG_X10 == r->id
+                || SCF_RISC_REG_X11 == r->id)
                        continue;
 
                if (r->dag_nodes) {
@@ -534,8 +446,8 @@ int naja_caller_save_regs(scf_3ac_code_t* c, scf_function_t* f, uint32_t* regs,
                        if (SCF_RISC_REG_SP == r->id
              || SCF_RISC_REG_FP == r->id
                         || SCF_RISC_REG_LR == r->id
-                        || SCF_RISC_REG_X16 == r->id
-                        || SCF_RISC_REG_X17 == r->id)
+                        || SCF_RISC_REG_X10 == r->id
+                        || SCF_RISC_REG_X11 == r->id)
                                continue;
 
                        if (0 == r->dag_nodes->size)
@@ -607,8 +519,8 @@ int naja_pop_regs(scf_3ac_code_t* c, scf_function_t* f, scf_register_t** regs, i
                        if (SCF_RISC_REG_SP == r->id
              || SCF_RISC_REG_FP == r->id
              || SCF_RISC_REG_LR == r->id
-                        || SCF_RISC_REG_X16 == r->id
-                        || SCF_RISC_REG_X17 == r->id)
+                        || SCF_RISC_REG_X10 == r->id
+                        || SCF_RISC_REG_X11 == r->id)
                                continue;
 
                        if (0 == r->dag_nodes->size)
@@ -650,8 +562,8 @@ int naja_registers_reset()
                if (SCF_RISC_REG_SP == r->id
                                || SCF_RISC_REG_FP == r->id
                                || SCF_RISC_REG_LR == r->id
-                               || SCF_RISC_REG_X16 == r->id
-                               || SCF_RISC_REG_X17 == r->id)
+                               || SCF_RISC_REG_X10 == r->id
+                               || SCF_RISC_REG_X11 == r->id)
                        continue;
 
                if (!r->dag_nodes)
@@ -692,8 +604,8 @@ int naja_overflow_reg(scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f)
                if (SCF_RISC_REG_SP == r2->id
                                || SCF_RISC_REG_FP == r2->id
                                || SCF_RISC_REG_LR == r2->id
-                               || SCF_RISC_REG_X16 == r2->id
-                               || SCF_RISC_REG_X17 == r2->id)
+                               || SCF_RISC_REG_X10 == r2->id
+                               || SCF_RISC_REG_X11 == r2->id)
                        continue;
 
                if (!naja_color_conflict(r->color, r2->color))
@@ -725,8 +637,8 @@ int naja_overflow_reg2(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c,
                if (SCF_RISC_REG_SP == r2->id
                                || SCF_RISC_REG_FP == r2->id
                                || SCF_RISC_REG_LR == r2->id
-                               || SCF_RISC_REG_X16 == r2->id
-                               || SCF_RISC_REG_X17 == r2->id)
+                               || SCF_RISC_REG_X10 == r2->id
+                               || SCF_RISC_REG_X11 == r2->id)
                        continue;
 
                if (!naja_color_conflict(r->color, r2->color))
@@ -767,8 +679,8 @@ int naja_overflow_reg3(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c,
                if (SCF_RISC_REG_SP == r2->id
                                || SCF_RISC_REG_FP == r2->id
                                || SCF_RISC_REG_LR == r2->id
-                               || SCF_RISC_REG_X16 == r2->id
-                               || SCF_RISC_REG_X17 == r2->id)
+                               || SCF_RISC_REG_X10 == r2->id
+                               || SCF_RISC_REG_X11 == r2->id)
                        continue;
 
                if (!naja_color_conflict(r->color, r2->color))
@@ -830,8 +742,8 @@ int naja_reg_used(scf_register_t* r, scf_dag_node_t* dn)
                if (SCF_RISC_REG_SP == r2->id
                                || SCF_RISC_REG_FP == r2->id
                                || SCF_RISC_REG_LR == r2->id
-                               || SCF_RISC_REG_X16 == r2->id
-                               || SCF_RISC_REG_X17 == r2->id)
+                               || SCF_RISC_REG_X10 == r2->id
+                               || SCF_RISC_REG_X11 == r2->id)
                        continue;
 
                if (!naja_color_conflict(r->color, r2->color))
@@ -880,8 +792,8 @@ scf_register_t* naja_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c
                if (SCF_RISC_REG_SP == r->id
                                || SCF_RISC_REG_FP == r->id
                                || SCF_RISC_REG_LR == r->id
-                               || SCF_RISC_REG_X16 == r->id
-                               || SCF_RISC_REG_X17 == r->id)
+                               || SCF_RISC_REG_X10 == r->id
+                               || SCF_RISC_REG_X11 == r->id)
                        continue;
 
                if (r->bytes < bytes || RISC_COLOR_TYPE(r->color) != is_float)
@@ -920,8 +832,8 @@ scf_register_t* naja_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c
                if (SCF_RISC_REG_SP == r->id
                                || SCF_RISC_REG_FP == r->id
                                || SCF_RISC_REG_LR == r->id
-                               || SCF_RISC_REG_X16 == r->id
-                               || SCF_RISC_REG_X17 == r->id)
+                               || SCF_RISC_REG_X10 == r->id
+                               || SCF_RISC_REG_X11 == r->id)
                        continue;
 
                if (r->bytes < bytes || RISC_COLOR_TYPE(r->color) != is_float)
@@ -1057,6 +969,7 @@ int naja_push_callee_regs(scf_3ac_code_t* c, scf_function_t* f)
        int i;
        for (i = 0; i < f->rops->ABI_CALLEE_SAVES_NB; i++) {
 
+               scf_logi("f->rops->abi_callee_saves[%d]: %d\n", i, f->rops->abi_callee_saves[i]);
                r  = f->rops->find_register_type_id_bytes(0, f->rops->abi_callee_saves[i], 8);
 
                if (!r->used) {
@@ -1085,6 +998,8 @@ int naja_pop_callee_regs(scf_3ac_code_t* c, scf_function_t* f)
 
                r  = f->rops->find_register_type_id_bytes(0, f->rops->abi_callee_saves[i], 8);
 
+               scf_logi("r: %p, f->rops->abi_callee_saves[%d]: %d\n", r, i, f->rops->abi_callee_saves[i]);
+
                if (!r->used) {
                        r  = f->rops->find_register_type_id_bytes(0, f->rops->abi_callee_saves[i], 4);
 
index c64aa7ad3ca7b6dfe3608ef5f78436b16a68c6ad..d8209eb137ba570f72e41aa213fd43146b55f570 100644 (file)
@@ -3,8 +3,9 @@
 
 #include"scf_def.h"
 
-enum scf_risc_OpCode_types {
-       SCF_RISC_MOV            = 0,
+enum scf_risc_OpCode_types
+{
+       SCF_RISC_MOV = 0,
 
        SCF_RISC_MOVSX,
        SCF_RISC_MOVZX,
@@ -117,7 +118,8 @@ enum scf_risc_OpCode_types {
        SCF_RISC_NB
 };
 
-enum scf_risc_REGs {
+enum scf_risc_REGs
+{
        SCF_RISC_REG_W0 = 0,
        SCF_RISC_REG_X0 = 0,
        SCF_RISC_REG_S0 = 0,
@@ -238,15 +240,15 @@ enum scf_risc_REGs {
        SCF_RISC_REG_X31 = 31,
 };
 
-enum scf_risc_EG_types {
-       SCF_RISC_G      = 0,
-       SCF_RISC_I      = 1,
-       SCF_RISC_G2E    = 2,
+enum scf_risc_EG_types
+{
+       SCF_RISC_G   = 0,
+       SCF_RISC_I   = 1,
+       SCF_RISC_G2E = 2,
        SCF_RISC_E2G = 3,
        SCF_RISC_I2E = 4,
        SCF_RISC_I2G = 5,
-       SCF_RISC_E      = 6,
+       SCF_RISC_E   = 6,
 };
 
 #endif
-
index 98d32ed1a5cfa9f39f0368b906ad010804dbf38a..9a6dd3585d4758fb589e596c384202c258f40df6 100644 (file)
@@ -10,9 +10,9 @@
 #define NAJA_PRINTF
 #endif
 
-#define NAJA_REG_FP   28
-#define NAJA_REG_LR   29
-#define NAJA_REG_SP   30
+#define NAJA_REG_FP   12
+#define NAJA_REG_LR   13
+#define NAJA_REG_SP   14
 
 typedef struct scf_vm_s       scf_vm_t;
 typedef struct scf_vm_ops_s   scf_vm_ops_t;
@@ -67,8 +67,8 @@ typedef union {
 } fv256_t;
 
 typedef struct {
-       uint64_t  regs[32];
-       fv256_t   fvec[32];
+       uint64_t  regs[16];
+       fv256_t   fvec[16];
 
        uint64_t  ip;
        uint64_t  flags;
index bf1f0dfe41d2b8e9b948c28db39018a0e6f056f1..a840da0e258f905c1c40064c875ce7e5b6212fee 100644 (file)
@@ -6,14 +6,31 @@ static const char* somaps[][3] =
        {"x64", "libc.so.6",                   "/lib/x86_64-linux-gnu/libc.so.6"},
 };
 
+static char*  __naja_sign[]  = {"", "s"};
+static char   __naja_size[]  = {'b', 'w', 'l', 'q'};
+static char   __naja_float[] = {'B', 'H', 'S', 'D'};
+
+static char* __naja_SH[] = {
+       "LSL",
+       "LSR",
+       "ASR",
+       "IMM"
+};
+
+static char* __naja_reg[] =
+{
+       "r0",  "r1",  "r2", "r3", "r4",
+       "r5",  "r6",  "r7", "r8", "r9",
+       "r10", "r11", "fp", "lr", "sp",
+       "null"
+};
+
 typedef int (*dyn_func_pt)(uint64_t r0,
                uint64_t r1,
                uint64_t r2,
                uint64_t r3,
                uint64_t r4,
                uint64_t r5,
-               uint64_t r6,
-               uint64_t r7,
                double   d0,
                double   d1,
                double   d2,
@@ -56,21 +73,21 @@ static int naja_vm_dynamic_link(scf_vm_t* vm)
        int64_t  sp = naja->regs[NAJA_REG_SP];
 
        uint64_t lr  = *(uint64_t*)(naja->stack - (sp +  8));
-       uint64_t r16 = *(uint64_t*)(naja->stack - (sp + 16));
+       uint64_t r10 = *(uint64_t*)(naja->stack - (sp + 16));
 
-       scf_logw("sp: %ld, r16: %#lx, lr: %#lx, vm->jmprel_size: %ld\n", sp, r16, lr, vm->jmprel_size);
+       scf_logw("sp: %ld, r10: %#lx, lr: %#lx, vm->jmprel_size: %ld\n", sp, r10, lr, vm->jmprel_size);
 
-       if (r16  > (uint64_t)vm->data->data) {
-               r16 -= (uint64_t)vm->data->data;
-               r16 +=           vm->data->addr;
+       if (r10  > (uint64_t)vm->data->data) {
+               r10 -= (uint64_t)vm->data->data;
+               r10 +=           vm->data->addr;
        }
 
-       scf_logw("r16: %#lx, text: %p, rodata: %p, data: %p\n", r16, vm->text->data, vm->rodata->data, vm->data->data);
+       scf_logw("r10: %#lx, text: %p, rodata: %p, data: %p\n", r10, vm->text->data, vm->rodata->data, vm->data->data);
 
        int i;
        for (i = 0; i < vm->jmprel_size / sizeof(Elf64_Rela); i++) {
 
-               if (r16  == vm->jmprel[i].r_offset) {
+               if (r10  == vm->jmprel[i].r_offset) {
 
                        int   j     = ELF64_R_SYM(vm->jmprel[i].r_info);
                        char* fname = vm->dynstr + vm->dynsym[j].st_name;
@@ -103,8 +120,6 @@ static int naja_vm_dynamic_link(scf_vm_t* vm)
                                                naja->regs[3],
                                                naja->regs[4],
                                                naja->regs[5],
-                                               naja->regs[6],
-                                               naja->regs[7],
                                                naja->fvec[0].d[0],
                                                naja->fvec[1].d[0],
                                                naja->fvec[2].d[0],
@@ -294,36 +309,33 @@ static int __naja_add(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
+       int rs0  =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int SH   = (inst >> 16) & 0x3;
 
        if (0x3 == SH) {
-               uint64_t uimm14 = (inst >> 5) & 0x3fff;
+               uint64_t uimm12 = (inst >> 4) & 0xfff;
 
-               naja->regs[rd]  = naja->regs[rs0] + uimm14;
+               naja->regs[rd]  = naja->regs[rs0] + uimm12;
 
-               NAJA_PRINTF("add    r%d, r%d, %lu\n", rd, rs0, uimm14);
+               NAJA_PRINTF("add%c     %s, %s, %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12);
        } else {
-               uint64_t uimm9 = (inst >> 10) & 0x1ff;
-               int      rs1   = (inst >>  5) & 0x1f;
+               uint64_t uimm6 = (inst >> 10) & 0x3f;
+               int      rs1   = (inst >>  4) & 0xf;
+               uint64_t v1    = naja->regs[rs1];
+
+               NAJA_PRINTF("add%c     %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6);
 
                switch (SH) {
                        case 0:
-                               naja->regs[rd] = naja->regs[rs0] + (naja->regs[rs1] << uimm9);
-
-                               NAJA_PRINTF("add    r%d, r%d, r%d << %lu\n", rd, rs0, rs1, uimm9);
+                               naja->regs[rd] = naja->regs[rs0] + (scf_zero_extend(v1, 8 << size) << uimm6);
                                break;
-
                        case 1:
-                               naja->regs[rd] = naja->regs[rs0] + (naja->regs[rs1] >> uimm9);
-
-                               NAJA_PRINTF("add    r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm9);
+                               naja->regs[rd] = naja->regs[rs0] + (scf_zero_extend(v1, 8 << size) >> uimm6);
                                break;
                        default:
-                               naja->regs[rd] = naja->regs[rs0] + (((int64_t)naja->regs[rs1]) >> uimm9);
-
-                               NAJA_PRINTF("add    r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm9);
+                               naja->regs[rd] = naja->regs[rs0] + (((int64_t)scf_sign_extend(v1, 8 << size)) >> uimm6);
                                break;
                };
        }
@@ -332,90 +344,49 @@ static int __naja_add(scf_vm_t* vm, uint32_t inst)
        return 0;
 }
 
-static int __naja_fadd(scf_vm_t* vm, uint32_t inst)
-{
-       scf_vm_naja_t* naja = vm->priv;
-
-       int rs0 =  inst        & 0x1f;
-       int rs1 = (inst >>  5) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-
-       naja->fvec[rd].d[0]  = naja->fvec[rs0].d[0] + naja->fvec[rs1].d[0];
-
-       NAJA_PRINTF("fadd   d%d, d%d, d%d\n", rd, rs0, rs1);
-
-       naja->ip += 4;
-       return 0;
-}
-
-static int __naja_fsub(scf_vm_t* vm, uint32_t inst)
-{
-       scf_vm_naja_t* naja = vm->priv;
-
-       int rs0 =  inst        & 0x1f;
-       int rs1 = (inst >>  5) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-
-       naja->fvec[rd].d[0]  = naja->fvec[rs0].d[0] - naja->fvec[rs1].d[0];
-
-       if (31 == rd) {
-               double d = naja->fvec[rd].d[0];
-
-               if (d > 0.0)
-                       naja->flags = 0x4;
-               else if (d < 0.0)
-                       naja->flags = 0x2;
-               else
-                       naja->flags = 0x1;
-
-               NAJA_PRINTF("fcmp   d%d, d%d\n", rs0, rs1);
-       } else
-               NAJA_PRINTF("fsub   r%d, r%d, r%d\n", rd, rs0, rs1);
-
-       naja->ip += 4;
-       return 0;
-}
-
 static int __naja_sub(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
+       int rs0  =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int SH   = (inst >> 16) & 0x3;
 
        if (0x3 == SH) {
-               uint64_t uimm14 = (inst >> 5) & 0x3fff;
+               uint64_t uimm12 = (inst >> 4) & 0xfff;
 
-               naja->regs[rd]  = naja->regs[rs0] - uimm14;
+               naja->regs[rd]  = naja->regs[rs0] - uimm12;
 
-               NAJA_PRINTF("sub    r%d, r%d, %lu\n", rd, rs0, uimm14);
+               if (0xf == rd)
+                       NAJA_PRINTF("cmp%c     %s, %lu\n", __naja_size[size], __naja_reg[rs0], uimm12);
+               else
+                       NAJA_PRINTF("sub%c     %s, %s, %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12);
        } else {
-               uint64_t uimm9 = (inst >> 10) & 0x1ff;
-               int      rs1   = (inst >>  5) & 0x1f;
+               uint64_t uimm6 = (inst >> 10) & 0x3f;
+               int      rs1   = (inst >>  4) & 0xf;
+               uint64_t v1    = naja->regs[rs1];
+
+               if (0xf == rd)
+                       NAJA_PRINTF("cmp%c     %s, %s %s %lu\n", __naja_size[size], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6);
+               else
+                       NAJA_PRINTF("sub%c     %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6);
 
                switch (SH) {
                        case 0:
-                               naja->regs[rd] = naja->regs[rs0] - (naja->regs[rs1] << uimm9);
-
-                               NAJA_PRINTF("sub    r%d, r%d, r%d << %lu\n", rd, rs0, rs1, uimm9);
+                               naja->regs[rd] = naja->regs[rs0] - (scf_zero_extend(v1, 8 << size) << uimm6);
                                break;
-
                        case 1:
-                               naja->regs[rd] = naja->regs[rs0] - (naja->regs[rs1] >> uimm9);
-
-                               NAJA_PRINTF("sub    r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm9);
+                               naja->regs[rd] = naja->regs[rs0] - (scf_zero_extend(v1, 8 << size) >> uimm6);
                                break;
                        default:
-                               naja->regs[rd] = naja->regs[rs0] - (((int64_t)naja->regs[rs1]) >> uimm9);
-
-                               NAJA_PRINTF("sub    r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm9);
+                               naja->regs[rd] = naja->regs[rs0] - (((int64_t)scf_sign_extend(v1, 8 << size)) >> uimm6);
                                break;
                }
        }
 
-       if (31 == rd) { // cmp
-               int ret = naja->regs[rd];
+       if (0xf == rd) { // cmp
+               int ret = scf_sign_extend(naja->regs[rd], 8 << size);
 
                if (0 == ret)
                        naja->flags = 0x1;
@@ -433,88 +404,37 @@ static int __naja_mul(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rs1 = (inst >>  5) & 0x1f;
-       int rs2 = (inst >> 10) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int S   = (inst >> 18) & 0x1;
-       int opt = (inst >> 19) & 0x3;
-
-       if (S)
-               naja->regs[rd] = (int64_t)naja->regs[rs0] * (int64_t)naja->regs[rs1];
-       else
-               naja->regs[rd] = naja->regs[rs0] * naja->regs[rs1];
-
-       if (0 == opt) {
-               naja->regs[rd] += naja->regs[rs2];
-
-               NAJA_PRINTF("madd   r%d, r%d, r%d, r%d", rd, rs2, rs0, rs1);
-       } else if (1 == opt) {
-               naja->regs[rd]  = naja->regs[rs2] - naja->regs[rd];
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rs2  = (inst >> 12) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int s    = (inst >> 17) & 0x1;
+       int A    = (inst >> 16) & 0x1;
 
-               NAJA_PRINTF("msub   r%d, r%d, r%d, r%d", rd, rs2, rs0, rs1);
-       } else {
-               if (S)
-                       NAJA_PRINTF("smul   r%d, r%d, r%d", rd, rs0, rs1);
+       if (0xf == rs2)
+               NAJA_PRINTF("%smul%c     %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1]);
+       else {
+               if (0 == A)
+                       NAJA_PRINTF("%smadd%c    %s, %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs2], __naja_reg[rs0], __naja_reg[rs1]);
                else
-                       NAJA_PRINTF("mul    r%d, r%d, r%d", rd, rs0, rs1);
+                       NAJA_PRINTF("%smsub%c    %s, %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs2], __naja_reg[rs0], __naja_reg[rs1]);
        }
 
-       naja->ip += 4;
-       return 0;
-}
-
-static int __naja_fmul(scf_vm_t* vm, uint32_t inst)
-{
-       scf_vm_naja_t* naja = vm->priv;
-
-       int rs0 =  inst        & 0x1f;
-       int rs1 = (inst >>  5) & 0x1f;
-       int rs2 = (inst >> 10) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int opt = (inst >> 18) & 0x3;
-
-       naja->fvec[rd].d[0] = naja->fvec[rs0].d[0] * naja->fvec[rs1].d[0];
-
-       if (0 == opt) {
-               naja->fvec[rd].d[0] += naja->fvec[rs2].d[0];
-
-               NAJA_PRINTF("fmadd   d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1);
-
-       } else if (1 == opt) {
-               naja->fvec[rd].d[0]  = naja->fvec[rs2].d[0] - naja->fvec[rd].d[0];
+       uint64_t v0 = naja->regs[rs0];
+       uint64_t v1 = naja->regs[rs1];
 
-               NAJA_PRINTF("fmsub   d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1);
-       } else
-               NAJA_PRINTF("fmul    d%d, d%d, d%d", rd, rs0, rs1);
-
-       naja->ip += 4;
-       return 0;
-}
-
-static int __naja_fdiv(scf_vm_t* vm, uint32_t inst)
-{
-       scf_vm_naja_t* naja = vm->priv;
-
-       int rs0 =  inst        & 0x1f;
-       int rs1 = (inst >>  5) & 0x1f;
-       int rs2 = (inst >> 10) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int opt = (inst >> 18) & 0x3;
-
-       naja->fvec[rd].d[0] = naja->fvec[rs0].d[0] / naja->fvec[rs1].d[0];
-
-       if (0 == opt) {
-               naja->fvec[rd].d[0] += naja->fvec[rs2].d[0];
-
-               NAJA_PRINTF("fdadd   d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1);
-
-       } else if (1 == opt) {
-               naja->fvec[rd].d[0]  = naja->fvec[rs2].d[0] - naja->fvec[rd].d[0];
+       if (s)
+               naja->regs[rd] = (int64_t)scf_sign_extend(v0, 8 << size) * (int64_t)scf_sign_extend(v1, 8 << size);
+       else
+               naja->regs[rd] = v0 * v1;
 
-               NAJA_PRINTF("fdsub   d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1);
-       } else
-               NAJA_PRINTF("fdiv    d%d, d%d, d%d", rd, rs0, rs1);
+       if (0xf != rs2) {
+               if (0 == A)
+                       naja->regs[rd] += naja->regs[rs2];
+               else
+                       naja->regs[rd]  = naja->regs[rs2] - naja->regs[rd];
+       }
 
        naja->ip += 4;
        return 0;
@@ -524,33 +444,23 @@ static int __naja_div(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rs1 = (inst >>  5) & 0x1f;
-       int rs2 = (inst >> 10) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int S   = (inst >> 18) & 0x1;
-       int opt = (inst >> 19) & 0x3;
-
-       if (S)
-               naja->regs[rd] = (int64_t)naja->regs[rs0] / (int64_t)naja->regs[rs1];
-       else
-               naja->regs[rd] = naja->regs[rs0] / naja->regs[rs1];
-
-       if (0 == opt) {
-               naja->regs[rd] += naja->regs[rs2];
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rs2  = (inst >> 12) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int s    = (inst >> 17) & 0x1;
+       int A    = (inst >> 16) & 0x1;
 
-               NAJA_PRINTF("fdadd   d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1);
+       NAJA_PRINTF("%sdiv%c     %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1]);
 
-       } else if (1 == opt) {
-               naja->regs[rd]  = naja->regs[rs2] - naja->regs[rd];
+       uint64_t v0 = naja->regs[rs0];
+       uint64_t v1 = naja->regs[rs1];
 
-               NAJA_PRINTF("dsub   r%d, r%d, r%d, r%d", rd, rs2, rs0, rs1);
-       } else {
-               if (S)
-                       NAJA_PRINTF("sdiv   r%d, r%d, r%d", rd, rs0, rs1);
-               else
-                       NAJA_PRINTF("div    r%d, r%d, r%d", rd, rs0, rs1);
-       }
+       if (s)
+               naja->regs[rd] = (int64_t)scf_sign_extend(v0, 8 << size) / (int64_t)scf_sign_extend(v1, 8 << size);
+       else
+               naja->regs[rd] = scf_zero_extend(v0, 8 << size) / scf_zero_extend(v1, 8 << size);
 
        naja->ip += 4;
        return 0;
@@ -612,7 +522,6 @@ static int __naja_mem(scf_vm_t* vm, int64_t addr, uint8_t** pdata, int64_t* poff
                        scf_loge("\n");
                        return -1;
                }
-
        } else {
                data   = naja->stack;
                offset = addr;
@@ -623,19 +532,20 @@ static int __naja_mem(scf_vm_t* vm, int64_t addr, uint8_t** pdata, int64_t* poff
        return 0;
 }
 
-static int __naja_fstr_disp(scf_vm_t* vm, uint32_t inst)
+static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s13 = (inst >>  5) & 0x1fff;
+       int rb   =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int s    = (inst >> 17) & 0x1;
+       int s13  = (inst >>  4) & 0x1fff;
 
        if (s13  & 0x1000)
                s13 |= 0xffffe000;
 
-       scf_logd("rd: %d, rb: %d, s13: %d, SH: %d\n", rd, rb, s13, SH);
+       NAJA_PRINTF("ldr%s%c  %s, [%s, %d]\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rb], s13 << size);
 
        int64_t  addr   = naja->regs[rb];
        int64_t  offset = 0;
@@ -645,36 +555,46 @@ static int __naja_fstr_disp(scf_vm_t* vm, uint32_t inst)
        if (ret < 0)
                return ret;
 
-       offset += s13 << SH;
+       offset += s13 << size;
 
        if (data   == naja->stack) {
                offset = -offset;
 
-               assert(offset > 0);
+               scf_logd("offset0: %ld, size: %ld\n", offset, naja->size);
+               assert(offset >= 0);
 
                if (naja->size < offset) {
-                       scf_loge("offset0: %ld, size: %ld\n", offset, naja->size);
+                       scf_loge("offset: %ld, size: %ld\n", offset, naja->size);
                        return -EINVAL;
                }
 
-               offset -= 1 << SH;
+               offset -= 1 << size;
        }
 
-       switch (SH) {
-               case 2:
-                       *(float*)(data + offset) = naja->fvec[rd].d[0];
-
-                       NAJA_PRINTF("fstr   f%d, [r%d, %d]\n", rd, rb, s13 << 2);
+       switch (size) {
+               case 0:
+                       if (s)
+                               naja->regs[rd] = *(int8_t*)(data + offset);
+                       else
+                               naja->regs[rd] = *(uint8_t*)(data + offset);
                        break;
 
-               case 3:
-                       *(double*)(data + offset) = naja->fvec[rd].d[0];
+               case 1:
+                       if (s)
+                               naja->regs[rd] = *(int16_t*)(data + offset);
+                       else
+                               naja->regs[rd] = *(uint16_t*)(data + offset);
+                       break;
 
-                       NAJA_PRINTF("fstr    d%d, [r%d, %d]\n", rd, rb, s13 << 3);
+               case 2:
+                       if (s)
+                               naja->regs[rd] = *(int32_t*)(data + offset);
+                       else
+                               naja->regs[rd] = *(uint32_t*)(data + offset);
                        break;
+
                default:
-                       scf_loge("SH: %d\n", SH);
-                       return -1;
+                       naja->regs[rd] = *(uint64_t*)(data + offset);
                        break;
        };
 
@@ -682,13 +602,62 @@ static int __naja_fstr_disp(scf_vm_t* vm, uint32_t inst)
        return 0;
 }
 
-static int __naja_fpush(scf_vm_t* vm, uint32_t inst)
+static int __naja_and(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rs0  =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int SH   = (inst >> 16) & 0x3;
+
+       if (0x3 == SH) {
+               uint64_t uimm12 = (inst >> 4) & 0xfff;
+
+               if (0xf == rd)
+                       NAJA_PRINTF("teq%c   %s, %#lx\n", __naja_size[size], __naja_reg[rs0], uimm12);
+               else
+                       NAJA_PRINTF("and%c   %s, %s, %#lx\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12);
+
+               naja->regs[rd]  = naja->regs[rs0] & uimm12;
+       } else {
+               uint64_t uimm6 = (inst >> 10) & 0x3f;
+               int      rs1   = (inst >>  4) & 0xf;
+               uint64_t v1    = naja->regs[rs1];
+
+               if (0xf == rd)
+                       NAJA_PRINTF("teq%c   %s, %s %s %lu\n", __naja_size[size], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6);
+               else
+                       NAJA_PRINTF("and%c   %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6);
+
+               if (0 == SH)
+                       naja->regs[rd]  = naja->regs[rs0] & (v1 << uimm6);
+               else if (1 == SH)
+                       naja->regs[rd]  = naja->regs[rs0] & (v1 >> uimm6);
+               else
+                       naja->regs[rd]  = naja->regs[rs0] & (((int64_t)scf_sign_extend(v1, 8 << size)) >> uimm6);
+       }
+
+       if (0xf == rd)
+               naja->flags = !!scf_zero_extend(naja->regs[rd], 8 << size);
+
+       naja->ip += 4;
+       return 0;
+}
+
+static int __naja_str_disp(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
+       int rb   =  inst        & 0xf;
+       int rs   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int s13  = (inst >>  4) & 0x1fff;
+
+       if (s13  & 0x1000)
+               s13 |= 0xffffe000;
+
+       NAJA_PRINTF("str%c    %s, [%s, %d]\n", __naja_size[size], __naja_reg[rs], __naja_reg[rb], s13 << size);
 
        int64_t  addr   = naja->regs[rb];
        int64_t  offset = 0;
@@ -698,62 +667,83 @@ static int __naja_fpush(scf_vm_t* vm, uint32_t inst)
        if (ret < 0)
                return ret;
 
+       offset += s13 << size;
+
        if (data   == naja->stack) {
                offset = -offset;
 
-               assert(offset >= 0);
-
-               offset += 1 << SH;
+               assert(offset > 0);
 
                if (naja->size < offset) {
-                       data = realloc(naja->stack, offset + STACK_INC);
-                       if (!data)
-                               return -ENOMEM;
-
-                       naja->stack = data;
-                       naja->size  = offset + STACK_INC;
+                       scf_loge("offset0: %ld, size: %ld\n", offset, naja->size);
+                       return -EINVAL;
                }
 
-               offset -= 1 << SH;
+               offset -= 1 << size;
        }
 
-       switch (SH) {
-               case 2:
-                       *(float*)(data + offset) = naja->fvec[rd].d[0];
-
-                       NAJA_PRINTF("fpush   f%d, [r%d]\n", rd, rb);
+       switch (size) {
+               case 0:
+                       *(uint8_t*)(data + offset) = naja->regs[rs];
                        break;
 
-               case 3:
-                       *(double*)(data + offset) = naja->fvec[rd].d[0];
+               case 1:
+                       *(uint16_t*)(data + offset) = naja->regs[rs];
+                       break;
 
-                       NAJA_PRINTF("fpush   d%d, [r%d]\n", rd, rb);
+               case 2:
+                       *(uint32_t*)(data + offset) = naja->regs[rs];
                        break;
                default:
-                       scf_loge("SH: %d\n", SH);
-                       return -1;
+                       *(uint64_t*)(data + offset) = naja->regs[rs];
                        break;
        };
 
-       naja->regs[rb] -= 1 << SH;
-
        naja->ip += 4;
        return 0;
 }
 
-static int __naja_fldr_disp(scf_vm_t* vm, uint32_t inst)
+static int __naja_or(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s13 = (inst >>  5) & 0x1fff;
+       int rs0  =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int SH   = (inst >> 16) & 0x3;
 
-       if (s13  & 0x1000)
-               s13 |= 0xffffe000;
+       if (0x3 == SH) {
+               uint64_t uimm12 = (inst >> 4) & 0xfff;
+
+               NAJA_PRINTF("or%c    %s, %s, %#lx\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12);
+
+               naja->regs[rd]  = naja->regs[rs0] | uimm12;
+       } else {
+               uint64_t uimm6 = (inst >> 10) & 0x3f;
+               int      rs1   = (inst >>  4) & 0xf;
+               uint64_t v1    = naja->regs[rs1];
+
+               NAJA_PRINTF("or%c    %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6);
 
-       scf_logd("rd: %d, rb: %d, s13: %d, SH: %d\n", rd, rb, s13, SH);
+               if (0 == SH)
+                       naja->regs[rd]  = naja->regs[rs0] | (v1 << uimm6);
+               else if (1 == SH)
+                       naja->regs[rd]  = naja->regs[rs0] | (v1 >> uimm6);
+               else
+                       naja->regs[rd]  = naja->regs[rs0] | (((int64_t)scf_sign_extend(v1, 8 << size)) >> uimm6);
+       }
+
+       naja->ip += 4;
+       return 0;
+}
+
+static int __naja_pop(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rb =  inst        & 0xf;
+       int rd = (inst >> 21) & 0xf;
+       int s  = (inst >> 17) & 0x1;
 
        int64_t  addr   = naja->regs[rb];
        int64_t  offset = 0;
@@ -763,10 +753,8 @@ static int __naja_fldr_disp(scf_vm_t* vm, uint32_t inst)
        if (ret < 0)
                return ret;
 
-       offset += s13 << SH;
-
        if (data   == naja->stack) {
-               offset = -offset;
+               offset  = -offset;
 
                scf_logd("offset0: %ld, size: %ld\n", offset, naja->size);
                assert(offset > 0);
@@ -776,39 +764,32 @@ static int __naja_fldr_disp(scf_vm_t* vm, uint32_t inst)
                        return -EINVAL;
                }
 
-               offset -= 1 << SH;
+               offset -= 8;
        }
 
-       switch (SH) {
-               case 2:
-                       naja->fvec[rd].d[0] = *(float*)(data + offset);
+       if (s) {
+               NAJA_PRINTF("fpop     d%d, [%s]\n", rd, __naja_reg[rb]);
 
-                       NAJA_PRINTF("fldr    f%d, [r%d, %d], rd: %lg, rb: %ld, %p\n", rd, rb, s13 << 2, naja->fvec[rd].d[0], naja->regs[rb], data + offset);
-                       break;
-               case 3:
-                       naja->fvec[rd].d[0] = *(double*)(data + offset);
+               naja->fvec[rd].d[0] = *(double*)(data + offset);
+       } else {
+               naja->regs[rd] = *(uint64_t*)(data + offset);
 
-                       NAJA_PRINTF("fldr    d%d, [r%d, %d], rd: %lg, rb: %ld, %p\n", rd, rb, s13 << 3, naja->fvec[rd].d[0], naja->regs[rb], data + offset);
-                       break;
-               default:
-                       scf_loge("SH: %d\n", SH);
-                       return -1;
-                       break;
-       };
+               NAJA_PRINTF("pop      %s, [%s], offset: %ld, value: %#lx\n", __naja_reg[rd], __naja_reg[rb], offset, naja->regs[rd]);
+       }
+
+       naja->regs[rb] += 8;
 
        naja->ip += 4;
        return 0;
 }
 
-static int __naja_fpop(scf_vm_t* vm, uint32_t inst)
+static int __naja_push(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-
-       scf_logd("rd: %d, rb: %d, SH: %d\n", rd, rb, SH);
+       int rb =  inst        & 0xf;
+       int rs = (inst >> 21) & 0xf;
+       int s  = (inst >> 17) & 0x1;
 
        int64_t  addr   = naja->regs[rb];
        int64_t  offset = 0;
@@ -822,53 +803,51 @@ static int __naja_fpop(scf_vm_t* vm, uint32_t inst)
                offset = -offset;
 
                scf_logd("offset0: %ld, size: %ld\n", offset, naja->size);
-               assert(offset > 0);
+
+               assert(offset >= 0);
+
+               offset += 8;
 
                if (naja->size < offset) {
-                       scf_loge("offset: %ld, size: %ld\n", offset, naja->size);
-                       return -EINVAL;
+                       data = realloc(naja->stack, offset + STACK_INC);
+                       if (!data)
+                               return -ENOMEM;
+
+                       naja->stack = data;
+                       naja->size  = offset + STACK_INC;
                }
 
-               offset -= 1 << SH;
+               offset -= 8;
        }
 
-       switch (SH) {
-               case 2:
-                       naja->fvec[rd].d[0] = *(float*)(data + offset);
+       if (s) {
+               NAJA_PRINTF("fpush    d%d, [%s]\n", rs, __naja_reg[rb]);
 
-                       NAJA_PRINTF("fldr    f%d, [r%d], rd: %lg, rb: %ld, %p\n", rd, rb, naja->fvec[rd].d[0], naja->regs[rb], data + offset);
-                       break;
-               case 3:
-                       naja->fvec[rd].d[0] = *(double*)(data + offset);
+               *(double*)(data + offset) = naja->fvec[rs].d[0];
+       } else {
+               *(uint64_t*)(data + offset) = naja->regs[rs];
 
-                       NAJA_PRINTF("fldr    d%d, [r%d], rd: %lg, rb: %ld, %p\n", rd, rb, naja->fvec[rd].d[0], naja->regs[rb], data + offset);
-                       break;
-               default:
-                       scf_loge("SH: %d\n", SH);
-                       return -1;
-                       break;
-       };
+               NAJA_PRINTF("push     %s, [%s], offset: %ld, value: %#lx\n", __naja_reg[rs], __naja_reg[rb], offset, naja->regs[rs]);
+       }
 
-       naja->regs[rb] += 1 << SH;
+       naja->regs[rb] -= 8;
 
        naja->ip += 4;
        return 0;
 }
 
-static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst)
+static int __naja_ldr_sib(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s   = (inst >> 18) & 0x1;
-       int s13 = (inst >>  5) & 0x1fff;
-
-       if (s13  & 0x1000)
-               s13 |= 0xffffe000;
+       int rb    =  inst        & 0xf;
+       int ri    = (inst >>  4) & 0xf;
+       int rd    = (inst >> 21) & 0xf;
+       int size  = (inst >> 18) & 0x3;
+       int s     = (inst >> 17) & 0x1;
+       int uimm6 = (inst >> 10) & 0x3f;
 
-       scf_logd("rd: %d, rb: %d, s13: %d, SH: %d\n", rd, rb, s13, SH);
+       NAJA_PRINTF("ldr%s%c   %s, [%s, %s, %d]\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rb], __naja_reg[ri], uimm6);
 
        int64_t  addr   = naja->regs[rb];
        int64_t  offset = 0;
@@ -878,63 +857,44 @@ static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst)
        if (ret < 0)
                return ret;
 
-       offset += s13 << SH;
+       offset += (naja->regs[ri] << uimm6);
 
        if (data   == naja->stack) {
                offset = -offset;
 
-               scf_logd("offset0: %ld, size: %ld\n", offset, naja->size);
                assert(offset >= 0);
 
                if (naja->size < offset) {
-                       scf_loge("offset: %ld, size: %ld\n", offset, naja->size);
-                       return -EINVAL;
+                       scf_loge("\n");
+                       return -1;
                }
 
-               offset -= 1 << SH;
+               offset -= 1 << size;
        }
 
-       switch (SH) {
+       switch (size) {
                case 0:
-                       if (s) {
+                       if (s)
                                naja->regs[rd] = *(int8_t*)(data + offset);
-
-                               NAJA_PRINTF("ldrsb  r%d, [r%d, %d]\n", rd, rb, s13);
-                       } else {
+                       else
                                naja->regs[rd] = *(uint8_t*)(data + offset);
-
-                               NAJA_PRINTF("ldrb   r%d, [r%d, %d]\n", rd, rb, s13);
-                       }
                        break;
 
                case 1:
-                       if (s) {
+                       if (s)
                                naja->regs[rd] = *(int16_t*)(data + offset);
-
-                               NAJA_PRINTF("ldrsw  r%d, [r%d, %d]\n", rd, rb, s13 << 1);
-                       } else {
+                       else
                                naja->regs[rd] = *(uint16_t*)(data + offset);
-
-                               NAJA_PRINTF("ldrw   r%d, [r%d, %d]\n", rd, rb, s13 << 1);
-                       }
                        break;
 
                case 2:
-                       if (s) {
+                       if (s)
                                naja->regs[rd] = *(int32_t*)(data + offset);
-
-                               NAJA_PRINTF("ldrsl  r%d, [r%d, %d]\n", rd, rb, s13 << 2);
-                       } else {
+                       else
                                naja->regs[rd] = *(uint32_t*)(data + offset);
-
-                               NAJA_PRINTF("ldrl   r%d, [r%d, %d],  %ld, %p\n", rd, rb, s13 << 2, naja->regs[rd], data + offset);
-                       }
                        break;
-
                default:
                        naja->regs[rd] = *(uint64_t*)(data + offset);
-
-                       NAJA_PRINTF("ldr    r%d, [r%d, %d]\n", rd, rb, s13 << 3);
                        break;
        };
 
@@ -942,14 +902,21 @@ static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst)
        return 0;
 }
 
-static int __naja_pop(scf_vm_t* vm, uint32_t inst)
+static int __naja_str_sib(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s   = (inst >> 18) & 0x1;
+       int rb    =  inst        & 0xf;
+       int ri    = (inst >>  4) & 0xf;
+       int rs    = (inst >> 21) & 0xf;
+       int size  = (inst >> 18) & 0x3;
+       int s     = (inst >> 17) & 0x1;
+       int uimm6 = (inst >> 10) & 0x3f;
+
+       if (s)
+               NAJA_PRINTF("fstr.%d   d%d, [%s, %s, %d]\n", 1 << size, rs, __naja_reg[rb], __naja_reg[ri], uimm6);
+       else
+               NAJA_PRINTF("str%c     %s, [%s, %s, %d]\n", __naja_size[size], __naja_reg[rs], __naja_reg[rb], __naja_reg[ri], uimm6);
 
        int64_t  addr   = naja->regs[rb];
        int64_t  offset = 0;
@@ -959,144 +926,146 @@ static int __naja_pop(scf_vm_t* vm, uint32_t inst)
        if (ret < 0)
                return ret;
 
+       offset += naja->regs[ri] << uimm6;
+
        if (data   == naja->stack) {
-               offset  = -offset;
+               offset = -offset;
 
-               scf_logd("offset0: %ld, size: %ld\n", offset, naja->size);
-               assert(offset > 0);
+               assert(offset >= 0);
 
                if (naja->size < offset) {
-                       scf_loge("offset: %ld, size: %ld\n", offset, naja->size);
-                       return -EINVAL;
+                       scf_loge("\n");
+                       return -1;
                }
 
-               offset -= 1 << SH;
+               offset -= 1 << size;
        }
 
-       switch (SH) {
+       switch (size) {
                case 0:
-                       if (s) {
-                               naja->regs[rd] = *(int8_t*)(data + offset);
-
-                               NAJA_PRINTF("popsb  r%d, [r%d]\n", rd, rb);
-                       } else {
-                               naja->regs[rd] = *(uint8_t*)(data + offset);
-
-                               NAJA_PRINTF("popb   r%d, [r%d]\n", rd, rb);
-                       }
+                       *(uint8_t*)(data + offset) = naja->regs[rs];
                        break;
 
                case 1:
-                       if (s) {
-                               naja->regs[rd] = *(int16_t*)(data + offset);
-
-                               NAJA_PRINTF("popsw  r%d, [r%d]\n", rd, rb);
-                       } else {
-                               naja->regs[rd] = *(uint16_t*)(data + offset);
-
-                               NAJA_PRINTF("popw   r%d, [r%d]\n", rd, rb);
-                       }
+                       *(uint16_t*)(data + offset) = naja->regs[rs];
                        break;
 
                case 2:
-                       if (s) {
-                               naja->regs[rd] = *(int32_t*)(data + offset);
-
-                               NAJA_PRINTF("popsl  r%d, [r%d]\n", rd, rb);
-                       } else {
-                               naja->regs[rd] = *(uint32_t*)(data + offset);
-
-                               NAJA_PRINTF("popl   r%d, [r%d],  %ld, %p\n", rd, rb, naja->regs[rd], data + offset);
-                       }
+                       *(uint32_t*)(data + offset) = naja->regs[rs];
                        break;
 
                default:
-                       naja->regs[rd] = *(uint64_t*)(data + offset);
-
-                       NAJA_PRINTF("popq   r%d, [r%d]\n", rd, rb);
+                       *(uint64_t*)(data + offset) = naja->regs[rs];
                        break;
        };
 
-       naja->regs[rb] += 1 << SH;
-
        naja->ip += 4;
        return 0;
 }
 
-static int __naja_ldr_sib(scf_vm_t* vm, uint32_t inst)
+static int __naja_mov(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int ri  = (inst >>  5) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s   = (inst >> 18) & 0x1;
-       int u8  = (inst >> 10) & 0xff;
-
-       int64_t  addr   = naja->regs[rb];
-       int64_t  offset = 0;
-       uint8_t* data   = NULL;
-
-       int ret = __naja_mem(vm, addr, &data, &offset);
-       if (ret < 0)
-               return ret;
+       int rs    =  inst        & 0xf;
+       int rs1   = (inst >>  4) & 0xf;
+       int rd    = (inst >> 21) & 0xf;
+       int size  = (inst >> 18) & 0x3;
+       int SH    = (inst >> 16) & 0x3;
+       int uimm6 = (inst >> 10) & 0x3f;
 
-       offset += (naja->regs[ri] << u8);
+       if (0xf == rs1) {
+               if (0 == uimm6)
+                       NAJA_PRINTF("mov%c     %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]);
+               else
+                       NAJA_PRINTF("mov%c     %s, %s %s %d\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs], __naja_SH[SH], uimm6);
+       } else
+               NAJA_PRINTF("mov%c     %s, %s %s %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs], __naja_SH[SH], __naja_reg[rs1]);
 
-       if (data   == naja->stack) {
-               offset = -offset;
+       uint64_t v = naja->regs[rs];
 
-               assert(offset >= 0);
+       if (0xf != rs1)
+               uimm6 = naja->regs[rs1] & 0x3f;
 
-               if (naja->size < offset) {
+       switch (SH) {
+               case 0:
+                       naja->regs[rd] = v << uimm6;
+                       break;
+               case 1:
+                       naja->regs[rd] = v >> uimm6;
+                       break;
+               case 2:
+                       naja->regs[rd] = (int64_t)scf_sign_extend(v, 8 << size) >> uimm6;
+                       break;
+               default:
                        scf_loge("\n");
                        return -1;
-               }
+                       break;
+       };
+
+       naja->ip += 4;
+       return 0;
+}
+
+static int __naja_movx(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rs    =  inst        & 0xf;
+       int rd    = (inst >> 21) & 0xf;
+       int size  = (inst >> 18) & 0x3;
+       int s     = (inst >> 17) & 0x1;
+
+       if (s) {
+               NAJA_PRINTF("movs%cq    %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]);
+
+               naja->regs[rd] = scf_sign_extend(naja->regs[rs], 8 << size);
+       } else {
+               naja->regs[rd] = scf_zero_extend(naja->regs[rs], 8 << size);
 
-               offset -= 1 << SH;
+               NAJA_PRINTF("movz%cq    %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]);
        }
 
+       naja->ip += 4;
+       return 0;
+}
+
+static int __naja_not(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rs   =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int SH   = (inst >> 16) & 0x3;
+       int u16  =  inst        & 0xffff;
+
        switch (SH) {
                case 0:
-                       if (s) {
-                               NAJA_PRINTF("ldrsb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-
-                               naja->regs[rd] = *(int8_t*)(data + offset);
-                       } else {
-                               NAJA_PRINTF("ldrb  r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
+                       NAJA_PRINTF("neg%c    %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]);
 
-                               naja->regs[rd] = *(uint8_t*)(data + offset);
-                       }
+                       naja->regs[rd] = -scf_zero_extend(naja->regs[rs], 8 << size);
                        break;
-
                case 1:
-                       if (s) {
-                               NAJA_PRINTF("ldrsw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-
-                               naja->regs[rd] = *(int16_t*)(data + offset);
-                       } else {
-                               NAJA_PRINTF("ldrw  r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
+                       naja->regs[rd] = ~scf_zero_extend(naja->regs[rs], 8 << size);
 
-                               naja->regs[rd] = *(uint16_t*)(data + offset);
-                       }
+                       NAJA_PRINTF("not%c    %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]);
                        break;
-
                case 2:
-                       if (s) {
-                               NAJA_PRINTF("ldrsl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
+                       if (0 == size) {
+                               NAJA_PRINTF("mov      %s, %d\n", __naja_reg[rd], u16);
 
-                               naja->regs[rd] = *(int32_t*)(data + offset);
+                               naja->regs[rd]  = u16;
                        } else {
-                               NAJA_PRINTF("ldrl  r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
+                               naja->regs[rd] |= u16 << size;
 
-                               naja->regs[rd] = *(uint32_t*)(data + offset);
+                               NAJA_PRINTF("movt     %s, %d LSL %d\n", __naja_reg[rd], u16, 16 << size);
                        }
                        break;
                default:
-                       NAJA_PRINTF("ldr   r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
+                       naja->regs[rd] = ~u16;
 
-                       naja->regs[rd] = *(uint64_t*)(data + offset);
+                       NAJA_PRINTF("mvn%c    %s, %d\n", __naja_size[size], __naja_reg[rd], u16);
                        break;
        };
 
@@ -1104,128 +1073,252 @@ static int __naja_ldr_sib(scf_vm_t* vm, uint32_t inst)
        return 0;
 }
 
-static int __naja_fldr_sib(scf_vm_t* vm, uint32_t inst)
+static int __naja_fadd(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int ri  = (inst >>  5) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int u8  = (inst >> 10) & 0xff;
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
+       int N    = 1;
+       int i;
 
-       int64_t  addr   = naja->regs[rb];
-       int64_t  offset = 0;
-       uint8_t* data   = NULL;
+       if (V) {
+               N = 1 << (3 + vlen - size);
 
-       int ret = __naja_mem(vm, addr, &data, &offset);
-       if (ret < 0)
-               return ret;
+               NAJA_PRINTF("vadd.f%dx%d   X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+       } else
+               NAJA_PRINTF("fadd.%d   d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1);
 
-       offset += naja->regs[ri] << u8;
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 2:
+                               naja->fvec[rd].f[i] = naja->fvec[rs0].f[i] + naja->fvec[rs1].f[i];
+                               break;
+                       case 3:
+                               naja->fvec[rd].d[i] = naja->fvec[rs0].d[i] + naja->fvec[rs1].d[i];
+                               break;
+                       default:
+                               scf_loge("\n");
+                               return -1;
+                               break;
+               };
+       }
 
-       if (data   == naja->stack) {
-               offset = -offset;
+       naja->ip += 4;
+       return 0;
+}
 
-               assert(offset > 0);
+static int __naja_fsub(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-               if (naja->size < offset) {
-                       scf_loge("\n");
-                       return -1;
-               }
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int cmp  = (inst >> 16) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
+       int N    = 1;
+       int i;
 
-               offset -= 1 << SH;
+       if (V) {
+               N = 1 << (3 + vlen - size);
+
+               if (cmp)
+                       NAJA_PRINTF("vcmp.f%dx%d   X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+               else
+                       NAJA_PRINTF("vsub.f%dx%d   X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+       } else {
+               if (cmp)
+                       NAJA_PRINTF("fcmp.%d   d%d, d%d\n", 1 << size, rs0, rs1);
+               else
+                       NAJA_PRINTF("fsub.%d   d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1);
        }
 
-       switch (SH) {
-               case 2:
-                       NAJA_PRINTF("fldr  f%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
+       for (i = 0; i < N; i++) {
+               double d;
 
-                       naja->fvec[rd].d[0] = *(float*)(data + offset);
-                       break;
+               switch (size) {
+                       case 2:
+                               d = naja->fvec[rs0].f[i] - naja->fvec[rs1].f[i];
 
-               case 3:
-                       NAJA_PRINTF("fldr  d%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
+                               if (!cmp)
+                                       naja->fvec[rd].f[i] = d;
+                               break;
 
-                       naja->fvec[rd].d[0] = *(double*)(data + offset);
-                       break;
-               default:
-                       scf_loge("\n");
-                       return -1;
-                       break;
-       };
+                       case 3:
+                               d = naja->fvec[rs0].d[i] - naja->fvec[rs1].d[i];
+                               if (!cmp)
+                                       naja->fvec[rd].d[i] = d;
+                               break;
+                       default:
+                               scf_loge("\n");
+                               return -1;
+                               break;
+               };
+
+               if (cmp) {
+                       uint32_t flags;
+
+                       if (d > 0.0)
+                               flags = 0x4;
+                       else if (d < 0.0)
+                               flags = 0x2;
+                       else
+                               flags = 0x1;
+
+                       if (V)
+                               naja->fvec[rd].l[i] = flags;
+                       else
+                               naja->flags = flags;
+               }
+       }
 
        naja->ip += 4;
        return 0;
 }
 
-static int __naja_fstr_sib(scf_vm_t* vm, uint32_t inst)
+static int __naja_fmul(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int ri  = (inst >>  5) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int u8  = (inst >> 10) & 0xff;
-
-       int64_t  addr   = naja->regs[rb];
-       int64_t  offset = 0;
-       uint8_t* data   = NULL;
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rs2  = (inst >> 12) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int A    = (inst >> 16) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
+       int N    = 1;
+       int i;
 
-       int ret = __naja_mem(vm, addr, &data, &offset);
-       if (ret < 0)
-               return ret;
+       if (V) {
+               N = 1 << (3 + vlen - size);
 
-       offset += naja->regs[ri] << u8;
+               if (0xf == rs2)
+                       NAJA_PRINTF("vmul.f%dx%d   X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+               else {
+                       if (A)
+                               NAJA_PRINTF("vmsub.f%dx%d   X%d, X%d, X%d, X%d\n", 1 << size, N, rd, rs2, rs0, rs1);
+                       else
+                               NAJA_PRINTF("vmadd.f%dx%d   X%d, X%d, X%d, X%d\n", 1 << size, N, rd, rs2, rs0, rs1);
+               }
+       } else {
+               if (0xf == rs2)
+                       NAJA_PRINTF("fmul.%d   d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1);
+               else {
+                       if (A)
+                               NAJA_PRINTF("fmsub.%d   d%d, d%d, d%d, d%d\n", 1 << size, rd, rs2, rs0, rs1);
+                       else
+                               NAJA_PRINTF("fmadd.%d   d%d, d%d, d%d, d%d\n", 1 << size, rd, rs2, rs0, rs1);
+               }
+       }
 
-       if (data   == naja->stack) {
-               offset = -offset;
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 2:
+                               naja->fvec[rd].f[i] = naja->fvec[rs0].f[i] * naja->fvec[rs1].f[i];
 
-               assert(offset > 0);
+                               if (0xf != rs2) {
+                                       if (A)
+                                               naja->fvec[rd].f[i] = naja->fvec[rs2].f[i] - naja->fvec[rd].f[i];
+                                       else
+                                               naja->fvec[rd].f[i] += naja->fvec[rs2].f[i];
+                               }
+                               break;
+                       case 3:
+                               naja->fvec[rd].d[i] = naja->fvec[rs0].d[i] * naja->fvec[rs1].d[i];
+
+                               if (0xf != rs2) {
+                                       if (A)
+                                               naja->fvec[rd].d[i] = naja->fvec[rs2].d[i] - naja->fvec[rd].d[i];
+                                       else
+                                               naja->fvec[rd].d[i] += naja->fvec[rs2].d[i];
+                               }
+                               break;
+                       default:
+                               scf_loge("\n");
+                               return -1;
+                               break;
+               };
+       }
 
-               if (naja->size < offset) {
-                       scf_loge("\n");
-                       return -1;
-               }
+       naja->ip += 4;
+       return 0;
+}
 
-               offset -= 1 << SH;
-       }
+static int __naja_fdiv(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-       switch (SH) {
-               case 2:
-                       NAJA_PRINTF("fstr  f%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
+       int N    = 1;
+       int i;
 
-                       *(float*)(data + offset) = naja->fvec[rd].d[0];
-                       break;
+       if (V) {
+               N = 1 << (3 + vlen - size);
 
-               case 3:
-                       NAJA_PRINTF("fstr  d%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
+               NAJA_PRINTF("vdiv.f%dx%d   X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+       } else
+               NAJA_PRINTF("fdiv.%d   d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1);
 
-                       *(double*)(data + offset) = naja->fvec[rd].d[0];
-                       break;
-               default:
-                       scf_loge("\n");
-                       return -1;
-                       break;
-       };
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 2:
+                               naja->fvec[rd].f[i] = naja->fvec[rs0].f[i] / naja->fvec[rs1].f[i];
+                               break;
+                       case 3:
+                               naja->fvec[rd].d[i] = naja->fvec[rs0].d[i] / naja->fvec[rs1].d[i];
+                               break;
+                       default:
+                               scf_loge("\n");
+                               return -1;
+                               break;
+               };
+       }
 
        naja->ip += 4;
        return 0;
 }
 
-static int __naja_str_disp(scf_vm_t* vm, uint32_t inst)
+static int __naja_fldr_disp(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s13 = (inst >>  5) & 0x1fff;
+       int rb   =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int A    = (inst >> 16) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
+       int s13  = (inst >>  4) & 0x1fff;
+       int N    = 1;
+       int i;
 
        if (s13  & 0x1000)
                s13 |= 0xffffe000;
 
+       if (V) {
+               N = 1 << (3 + vlen - size);
+
+               if (A)
+                       NAJA_PRINTF("vldr.f%dx%d  X%d, [%s]!\n", 1 << size, N, rd, __naja_reg[rb]);
+               else
+                       NAJA_PRINTF("vldr.f%dx%d  X%d, [%s]\n", 1 << size, N, rd, __naja_reg[rb]);
+       } else
+               NAJA_PRINTF("fldr.%d  d%d, [%s, %d]\n", 1 << size, rd, __naja_reg[rb], s13 << size);
+
        int64_t  addr   = naja->regs[rb];
        int64_t  offset = 0;
        uint8_t* data   = NULL;
@@ -1234,58 +1327,127 @@ static int __naja_str_disp(scf_vm_t* vm, uint32_t inst)
        if (ret < 0)
                return ret;
 
-       offset += s13 << SH;
+       offset += s13 << size;
 
        if (data   == naja->stack) {
                offset = -offset;
 
+               scf_logd("offset0: %ld, size: %ld\n", offset, naja->size);
                assert(offset > 0);
 
                if (naja->size < offset) {
-                       scf_loge("offset0: %ld, size: %ld\n", offset, naja->size);
+                       scf_loge("offset: %ld, size: %ld\n", offset, naja->size);
                        return -EINVAL;
                }
 
-               offset -= 1 << SH;
+               offset -= N << size;
        }
 
-       switch (SH) {
-               case 0:
-                       *(uint8_t*)(data + offset) = naja->regs[rd];
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 2:
+                               naja->fvec[rd].f[i] = *(float*)(data + offset + (i << 2));
+                               break;
+                       case 3:
+                               naja->fvec[rd].d[i] = *(double*)(data + offset + (i << 3));
+                               break;
+                       default:
+                               scf_loge("size: %d\n", size);
+                               return -1;
+                               break;
+               };
+       }
 
-                       NAJA_PRINTF("strb   r%d, [r%d, %d]\n", rd, rb, s13);
-                       break;
+       if (A)
+               naja->regs[rb] += offset + (N << size);
 
-               case 1:
-                       *(uint16_t*)(data + offset) = naja->regs[rd];
+       naja->ip += 4;
+       return 0;
+}
 
-                       NAJA_PRINTF("strw   r%d, [r%d, %d]\n", rd, rb, s13 << 1);
-                       break;
+static int __naja_fstr_disp(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-               case 2:
-                       *(uint32_t*)(data + offset) = naja->regs[rd];
+       int rb   =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int A    = (inst >> 16) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
+       int s13  = (inst >>  4) & 0x1fff;
+       int N    = 1;
+       int i;
 
-                       NAJA_PRINTF("strl   r%d, [r%d, %d],  s13: %d, %d, %p\n", rd, rb, s13 << 2, s13, *(uint32_t*)(data + offset), data + offset);
-                       break;
+       if (s13  & 0x1000)
+               s13 |= 0xffffe000;
 
-               default:
-                       *(uint64_t*)(data + offset) = naja->regs[rd];
+       if (V) {
+               N = 1 << (3 + vlen - size);
 
-                       NAJA_PRINTF("str    r%d, [r%d, %d]\n", rd, rb, s13 << 3);
-                       break;
-       };
+               if (A)
+                       NAJA_PRINTF("vstr.f%dx%d  X%d, [%s]!\n", 1 << size, N, rd, __naja_reg[rb]);
+               else
+                       NAJA_PRINTF("vstr.f%dx%d  X%d, [%s]\n", 1 << size, N, rd, __naja_reg[rb]);
+       } else
+               NAJA_PRINTF("fstr.%d  d%d, [%s, %d]\n", 1 << size, rd, __naja_reg[rb], s13 << size);
+
+       int64_t  addr   = naja->regs[rb];
+       int64_t  offset = 0;
+       uint8_t* data   = NULL;
+
+       int ret = __naja_mem(vm, addr, &data, &offset);
+       if (ret < 0)
+               return ret;
+
+       offset += s13 << size;
+
+       if (data   == naja->stack) {
+               offset = -offset;
+
+               assert(offset > 0);
+
+               if (naja->size < offset) {
+                       scf_loge("offset0: %ld, size: %ld\n", offset, naja->size);
+                       return -EINVAL;
+               }
+
+               offset -= N << size;
+       }
+
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 2:
+                               *(float*)(data + offset + (i << 2)) = naja->fvec[rd].f[i];
+                               break;
+                       case 3:
+                               *(double*)(data + offset + (i << 3)) = naja->fvec[rd].d[i];
+                               break;
+                       default:
+                               scf_loge("size: %d\n", size);
+                               return -1;
+                               break;
+               };
+       }
+
+       if (A)
+               naja->regs[rb] += offset + (N << size);
 
        naja->ip += 4;
        return 0;
 }
 
-static int __naja_push(scf_vm_t* vm, uint32_t inst)
+static int __naja_fldr_sib(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
+       int rb    =  inst        & 0xf;
+       int ri    = (inst >>  4) & 0xf;
+       int rd    = (inst >> 21) & 0xf;
+       int size  = (inst >> 18) & 0x3;
+       int uimm6 = (inst >> 10) & 0x3f;
+
+       NAJA_PRINTF("fldr.%d   d%d, [%s, %s, %d]\n", 1 << size, rd, __naja_reg[rb], __naja_reg[ri], uimm6);
 
        int64_t  addr   = naja->regs[rb];
        int64_t  offset = 0;
@@ -1295,178 +1457,822 @@ static int __naja_push(scf_vm_t* vm, uint32_t inst)
        if (ret < 0)
                return ret;
 
+       offset += naja->regs[ri] << uimm6;
+
        if (data   == naja->stack) {
                offset = -offset;
 
-               scf_logd("offset0: %ld, size: %ld\n", offset, naja->size);
+               assert(offset > 0);
 
-               assert(offset >= 0);
+               if (naja->size < offset) {
+                       scf_loge("\n");
+                       return -1;
+               }
 
-               offset += 1 << SH;
+               offset -= 1 << size;
+       }
 
-               if (naja->size < offset) {
-                       data = realloc(naja->stack, offset + STACK_INC);
-                       if (!data)
-                               return -ENOMEM;
+       switch (size) {
+               case 2:
+                       naja->fvec[rd].f[0] = *(float*)(data + offset);
+                       break;
+               case 3:
+                       naja->fvec[rd].d[0] = *(double*)(data + offset);
+                       break;
+               default:
+                       scf_loge("\n");
+                       return -1;
+                       break;
+       };
 
-                       naja->stack = data;
-                       naja->size  = offset + STACK_INC;
-               }
+       naja->ip += 4;
+       return 0;
+}
 
-               offset -= 1 << SH;
+static int __naja_fmov(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rs   =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
+       int N    = 1;
+       int i;
+
+       if (V) {
+               N = 1 << (3 + vlen - size);
+
+               NAJA_PRINTF("vmov.f%dx%d  X%d, X%d\n", 1 << size, N, rd, rs);
+       } else
+               NAJA_PRINTF("fmov.%d      d%d, d%d\n", 1 << size, rd, rs);
+
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 2:
+                               naja->fvec[rd].f[i] = naja->fvec[rs].f[i];
+                               break;
+                       case 3:
+                               naja->fvec[rd].d[i] = naja->fvec[rs].d[i];
+                               break;
+                       default:
+                               scf_loge("size: %d\n", size);
+                               return -1;
+                               break;
+               };
        }
 
-       switch (SH) {
-               case 0:
-                       *(uint8_t*)(data + offset) = naja->regs[rd];
+       naja->ip += 4;
+       return 0;
+}
 
-                       NAJA_PRINTF("pushb  r%d, [r%d]\n", rd, rb);
-                       break;
+static uint64_t __naja_to_u64(scf_vm_naja_t* naja, int i, int r, int sign, int size)
+{
+       uint64_t ret;
 
+       switch (size) {
+               case 0:
+                       ret = naja->fvec[r].b[i];
+                       break;
                case 1:
-                       *(uint16_t*)(data + offset) = naja->regs[rd];
+                       ret = naja->fvec[r].w[i];
+                       break;
+               case 2:
+                       ret = naja->fvec[r].l[i];
+                       break;
+               default:
+                       ret = naja->fvec[r].q[i];
+                       break;
+       };
+
+       if (sign)
+               return scf_sign_extend(ret, 8 << size);
+       return scf_zero_extend(ret, 8 << size);
+}
 
-                       NAJA_PRINTF("pushw  r%d, [r%d]\n", rd, rb);
+static void __naja_u64_to_int(scf_vm_naja_t* naja, int i, int r, int size, uint64_t src)
+{
+       switch (size) {
+               case 0:
+                       naja->fvec[r].b[i] = src;
                        break;
+               case 1:
+                       naja->fvec[r].w[i] = src;
+                       break;
+               case 2:
+                       naja->fvec[r].l[i] = src;
+                       break;
+               default:
+                       naja->fvec[r].q[i] = src;
+                       break;
+       };
+}
 
+static void __naja_u64_to_float(scf_vm_naja_t* naja, int i, int r, int size, uint64_t src)
+{
+       switch (size) {
                case 2:
-                       *(uint32_t*)(data + offset) = naja->regs[rd];
+                       naja->fvec[r].f[i] = src;
+                       break;
+               case 3:
+                       naja->fvec[r].d[i] = src;
+                       break;
+               default:
+                       break;
+       };
+}
+
+static double __naja_to_double(scf_vm_naja_t* naja, int i, int r, int size)
+{
+       double ret;
 
-                       NAJA_PRINTF("pushl  r%d, [r%d], %d, %p\n", rd, rb, *(uint32_t*)(data + offset), data + offset);
+       switch (size) {
+               case 2:
+                       ret = naja->fvec[r].f[i];
+                       break;
+               case 3:
+                       ret = naja->fvec[r].d[i];
                        break;
+               default:
+                       ret = 0.0;
+                       break;
+       };
 
+       return ret;
+}
+
+static void __naja_double_to_int(scf_vm_naja_t* naja, int i, int r, int size, double src)
+{
+       switch (size) {
+               case 0:
+                       naja->fvec[r].b[i] = src;
+                       break;
+               case 1:
+                       naja->fvec[r].w[i] = src;
+                       break;
+               case 2:
+                       naja->fvec[r].l[i] = src;
+                       break;
                default:
-                       *(uint64_t*)(data + offset) = naja->regs[rd];
+                       naja->fvec[r].q[i] = src;
+                       break;
+       };
+}
 
-                       NAJA_PRINTF("pushq  r%d, [r%d]\n", rd, rb);
+static void __naja_double_to_float(scf_vm_naja_t* naja, int i, int r, int size, double src)
+{
+       switch (size) {
+               case 2:
+                       naja->fvec[r].f[i] = src;
+                       break;
+               case 3:
+                       naja->fvec[r].d[i] = src;
+                       break;
+               default:
                        break;
        };
+}
 
-       naja->regs[rb] -= 1 << SH;
+static int __naja_fcvt(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rs    =  inst        & 0xf;
+       int rd    = (inst >> 21) & 0xf;
+       int dsize = (inst >> 18) & 0x3;
+       int V     = (inst >> 17) & 0x1;
+       int Id    = (inst >> 13) & 0x1;
+       int sd    = (inst >> 12) & 0x1;
+       int vlen  = (inst >> 10) & 0x3;
+       int Is    = (inst >>  7) & 0x1;
+       int ss    = (inst >>  6) & 0x1;
+       int ssize = (inst >>  4) & 0x3;
+
+       static char IS_array[2][2] = {
+               'F', 'F',
+               'U', 'I'
+       };
+
+       static char R_array[2] = {'d', 'r'};
+
+       if (V) {
+               int N = 1 << (3 + vlen - dsize);
+               int i;
+
+               NAJA_PRINTF("vcvt%c%dto%c%dx%d  X%d, X%d\n",
+                               IS_array[Is][ss], 1 << ssize,
+                               IS_array[Id][sd], 1 << dsize,
+                               N, rd, rs);
+
+               for (i = 0; i < N; i++) {
+                       if (Is) {
+                               uint64_t src = __naja_to_u64(naja, i, rs, ss, ssize);
+                               if (Id)
+                                       __naja_u64_to_int(naja, i, rd, dsize, src);
+                               else
+                                       __naja_u64_to_float(naja, i, rd, dsize, src);
+
+                       } else {
+                               double src = __naja_to_double(naja, i, rs, ssize);
+                               if (Id)
+                                       __naja_double_to_int(naja, i, rd, dsize, src);
+                               else
+                                       __naja_double_to_float(naja, i, rd, dsize, src);
+                       }
+               }
+       } else {
+               NAJA_PRINTF("fcvt%c%dto%c%d      %c%d, %c%d\n",
+                               IS_array[Is][ss], 1 << ssize,
+                               IS_array[Id][sd], 1 << dsize,
+                               R_array[Id], rd, R_array[Is], rs);
+
+               if (Is) {
+                       uint64_t src;
+                       if (ss)
+                               src = scf_sign_extend(naja->regs[rs], 8 << ssize);
+                       else
+                               src = scf_zero_extend(naja->regs[rs], 8 << ssize);
+
+                       if (Id)
+                               naja->regs[rd] = src;
+                       else
+                               __naja_u64_to_float(naja, 0, rd, dsize, src);
+
+               } else {
+                       double src = __naja_to_double(naja, 0, rs, ssize);
+
+                       if (Id)
+                               naja->regs[rd] = src;
+                       else
+                               __naja_u64_to_float(naja, 0, rd, dsize, src);
+               }
+       }
 
-       naja->ip += 4;
        return 0;
 }
 
-static int __naja_str_sib(scf_vm_t* vm, uint32_t inst)
+static int __naja_fneg(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int ri  = (inst >>  5) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int u8  = (inst >> 10) & 0xff;
+       int rs   =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
+       int N    = 1;
+       int i;
 
-       int64_t  addr   = naja->regs[rb];
-       int64_t  offset = 0;
-       uint8_t* data   = NULL;
+       if (V) {
+               N = 1 << (3 + vlen - size);
 
-       int ret = __naja_mem(vm, addr, &data, &offset);
-       if (ret < 0)
-               return ret;
+               NAJA_PRINTF("vneg.f%dx%d  X%d, X%d\n", 1 << size, N, rd, rs);
+       } else
+               NAJA_PRINTF("fneg.%d      d%d, d%d\n", 1 << size, rd, rs);
+
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 2:
+                               naja->fvec[rd].f[i] = -naja->fvec[rs].f[i];
+                               break;
+                       case 3:
+                               naja->fvec[rd].d[i] = -naja->fvec[rs].d[i];
+                               break;
+                       default:
+                               scf_loge("\n");
+                               return -1;
+                               break;
+               };
+       }
 
-       offset += naja->regs[ri] << u8;
+       return 0;
+}
 
-       if (data   == naja->stack) {
-               offset = -offset;
+static int __naja_vadd(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-               assert(offset >= 0);
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int vlen = (inst >> 10) & 0x3;
 
-               if (naja->size < offset) {
-                       scf_loge("\n");
-                       return -1;
-               }
+       int N = 1 << (3 + vlen - size);
+       int i;
+
+       NAJA_PRINTF("vadd.u%dx%d  X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 0:
+                               naja->fvec[rd].b[i] = naja->fvec[rs0].b[i] + naja->fvec[rs1].b[i];
+                               break;
+                       case 1:
+                               naja->fvec[rd].w[i] = naja->fvec[rs0].w[i] + naja->fvec[rs1].w[i];
+                               break;
+                       case 2:
+                               naja->fvec[rd].l[i] = naja->fvec[rs0].l[i] + naja->fvec[rs1].l[i];
+                               break;
+                       case 3:
+                               naja->fvec[rd].q[i] = naja->fvec[rs0].q[i] + naja->fvec[rs1].q[i];
+                               break;
+                       default:
+                               scf_loge("\n");
+                               return -1;
+                               break;
+               };
+       }
+
+       return 0;
+}
+
+static int __naja_vsub(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int cmp  = (inst >> 16) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
+
+       int N = 1 << (3 + vlen - size);
+       int i;
+
+       if (cmp)
+               NAJA_PRINTF("vcmp.u%dx%d  X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+       else
+               NAJA_PRINTF("vsub.u%dx%d  X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 0:
+                               naja->fvec[rd].b[i] = naja->fvec[rs0].b[i] - naja->fvec[rs1].b[i];
+                               if (cmp) {
+                                       int8_t i = naja->fvec[rd].b[i];
+                                       if (0 == i)
+                                               naja->fvec[rd].b[i] = 0x1;
+                                       else if (i > 0)
+                                               naja->fvec[rd].b[i] = 0x4;
+                                       else
+                                               naja->fvec[rd].b[i] = 0x2;
+                               }
+                               break;
+                       case 1:
+                               naja->fvec[rd].w[i] = naja->fvec[rs0].w[i] - naja->fvec[rs1].w[i];
+                               if (cmp) {
+                                       int16_t i = naja->fvec[rd].w[i];
+                                       if (0 == i)
+                                               naja->fvec[rd].w[i] = 0x1;
+                                       else if (i > 0)
+                                               naja->fvec[rd].w[i] = 0x4;
+                                       else
+                                               naja->fvec[rd].w[i] = 0x2;
+                               }
+                               break;
+                       case 2:
+                               naja->fvec[rd].l[i] = naja->fvec[rs0].l[i] - naja->fvec[rs1].l[i];
+                               if (cmp) {
+                                       int32_t i = naja->fvec[rd].l[i];
+                                       if (0 == i)
+                                               naja->fvec[rd].l[i] = 0x1;
+                                       else if (i > 0)
+                                               naja->fvec[rd].l[i] = 0x4;
+                                       else
+                                               naja->fvec[rd].l[i] = 0x2;
+                               }
+                               break;
+                       case 3:
+                               naja->fvec[rd].q[i] = naja->fvec[rs0].q[i] - naja->fvec[rs1].q[i];
+                               if (cmp) {
+                                       int64_t i = naja->fvec[rd].q[i];
+                                       if (0 == i)
+                                               naja->fvec[rd].q[i] = 0x1;
+                                       else if (i > 0)
+                                               naja->fvec[rd].q[i] = 0x4;
+                                       else
+                                               naja->fvec[rd].q[i] = 0x2;
+                               }
+                               break;
+                       default:
+                               scf_loge("\n");
+                               return -1;
+                               break;
+               };
+       }
+
+       return 0;
+}
+
+static int __naja_vmul(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rs2  = (inst >> 12) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int s    = (inst >> 17) & 0x1;
+       int A    = (inst >> 16) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
+
+       int N = 1 << (3 + vlen - size);
+       int i;
+
+       static char  s_array[2] = {'u',    'i'};
+       static char* A_array[2] = {"madd", "msub"};
+
+       if (0xf == rs2)
+               NAJA_PRINTF("vmul.%c%dx%d  X%d, X%d, X%d\n", s_array[s], 1 << size, N, rd, rs0, rs1);
+       else
+               NAJA_PRINTF("v%s.%c%dx%d  X%d, X%d, X%d, X%d\n", A_array[A], s_array[s], 1 << size, N, rd, rs2, rs0, rs1);
+
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 0:
+                               naja->fvec[rd].b[i] = naja->fvec[rs0].b[i] * naja->fvec[rs1].b[i];
+                               if (0xf != rs2) {
+                                       if (A)
+                                               naja->fvec[rd].b[i]  = naja->fvec[rs2].b[i] - naja->fvec[rd].b[i];
+                                       else
+                                               naja->fvec[rd].b[i] += naja->fvec[rs2].b[i];
+                               }
+                               break;
+                       case 1:
+                               naja->fvec[rd].w[i] = naja->fvec[rs0].w[i] * naja->fvec[rs1].w[i];
+                               if (0xf != rs2) {
+                                       if (A)
+                                               naja->fvec[rd].w[i]  = naja->fvec[rs2].w[i] - naja->fvec[rd].w[i];
+                                       else
+                                               naja->fvec[rd].w[i] += naja->fvec[rs2].w[i];
+                               }
+                               break;
+                       case 2:
+                               naja->fvec[rd].l[i] = naja->fvec[rs0].l[i] * naja->fvec[rs1].l[i];
+                               if (0xf != rs2) {
+                                       if (A)
+                                               naja->fvec[rd].l[i]  = naja->fvec[rs2].l[i] - naja->fvec[rd].l[i];
+                                       else
+                                               naja->fvec[rd].l[i] += naja->fvec[rs2].l[i];
+                               }
+                               break;
+                       case 3:
+                               naja->fvec[rd].q[i] = naja->fvec[rs0].q[i] * naja->fvec[rs1].q[i];
+                               if (0xf != rs2) {
+                                       if (A)
+                                               naja->fvec[rd].q[i]  = naja->fvec[rs2].q[i] - naja->fvec[rd].q[i];
+                                       else
+                                               naja->fvec[rd].q[i] += naja->fvec[rs2].q[i];
+                               }
+                               break;
+                       default:
+                               scf_loge("\n");
+                               return -1;
+                               break;
+               };
+       }
+
+       return 0;
+}
+
+static int __naja_vdiv(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int s    = (inst >> 17) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
+
+       int N = 1 << (3 + vlen - size);
+       int i;
+
+       if (s)
+               NAJA_PRINTF("vdiv.i%dx%d  X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+       else
+               NAJA_PRINTF("vdiv.u%dx%d  X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 0:
+                               naja->fvec[rd].b[i] = naja->fvec[rs0].b[i] / naja->fvec[rs1].b[i];
+                               break;
+                       case 1:
+                               naja->fvec[rd].w[i] = naja->fvec[rs0].w[i] / naja->fvec[rs1].w[i];
+                               break;
+                       case 2:
+                               naja->fvec[rd].l[i] = naja->fvec[rs0].l[i] / naja->fvec[rs1].l[i];
+                               break;
+                       case 3:
+                               naja->fvec[rd].q[i] = naja->fvec[rs0].q[i] / naja->fvec[rs1].q[i];
+                               break;
+                       default:
+                               scf_loge("\n");
+                               return -1;
+                               break;
+               };
+       }
+
+       return 0;
+}
+
+static int __naja_vand(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int teq  = (inst >> 16) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
+
+       int N = 1 << (3 + vlen - size);
+       int i;
+
+       if (teq)
+               NAJA_PRINTF("vteq.u%dx%d  X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+       else
+               NAJA_PRINTF("vand.u%dx%d  X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 0:
+                               naja->fvec[rd].b[i] = naja->fvec[rs0].b[i] & naja->fvec[rs1].b[i];
+                               if (teq)
+                                       naja->fvec[rd].b[i] = !!naja->fvec[rd].b[i];
+                               break;
+                       case 1:
+                               naja->fvec[rd].w[i] = naja->fvec[rs0].w[i] & naja->fvec[rs1].w[i];
+                               if (teq)
+                                       naja->fvec[rd].w[i] = !!naja->fvec[rd].w[i];
+                               break;
+                       case 2:
+                               naja->fvec[rd].l[i] = naja->fvec[rs0].l[i] & naja->fvec[rs1].l[i];
+                               if (teq)
+                                       naja->fvec[rd].l[i] = !!naja->fvec[rd].l[i];
+                               break;
+                       case 3:
+                               naja->fvec[rd].q[i] = naja->fvec[rs0].q[i] & naja->fvec[rs1].q[i];
+                               if (teq)
+                                       naja->fvec[rd].q[i] = !!naja->fvec[rd].q[i];
+                               break;
+                       default:
+                               scf_loge("\n");
+                               return -1;
+                               break;
+               };
+       }
+
+       return 0;
+}
+
+static int __naja_vor(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-               offset -= 1 << SH;
-       }
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int vlen = (inst >> 10) & 0x3;
 
-       switch (SH) {
-               case 0:
-                       NAJA_PRINTF("strb  r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
+       int N = 1 << (3 + vlen - size);
+       int i;
 
-                       *(uint8_t*)(data + offset) = naja->regs[rd];
-                       break;
+       NAJA_PRINTF("vor.u%dx%d   X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
 
-               case 1:
-                       NAJA_PRINTF("strw  r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 0:
+                               naja->fvec[rd].b[i] = naja->fvec[rs0].b[i] | naja->fvec[rs1].b[i];
+                               break;
+                       case 1:
+                               naja->fvec[rd].w[i] = naja->fvec[rs0].w[i] | naja->fvec[rs1].w[i];
+                               break;
+                       case 2:
+                               naja->fvec[rd].l[i] = naja->fvec[rs0].l[i] | naja->fvec[rs1].l[i];
+                               break;
+                       case 3:
+                               naja->fvec[rd].q[i] = naja->fvec[rs0].q[i] | naja->fvec[rs1].q[i];
+                               break;
+                       default:
+                               scf_loge("\n");
+                               return -1;
+                               break;
+               };
+       }
 
-                       *(uint16_t*)(data + offset) = naja->regs[rd];
-                       break;
+       return 0;
+}
 
-               case 2:
-                       NAJA_PRINTF("strl  r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
+static int __naja_vmov(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-                       *(uint32_t*)(data + offset) = naja->regs[rd];
-                       break;
+       int rs    =  inst        & 0xf;
+       int rs1   = (inst >>  4) & 0xf;
+       int rd    = (inst >> 21) & 0xf;
+       int size  = (inst >> 18) & 0x3;
+       int SH    = (inst >> 16) & 0x3;
+       int IMM   = (inst >> 15) & 0x3;
+       int vlen  = (inst >> 10) & 0x3;
+       int uimm6 = (inst >>  4) & 0x3f;
 
-               default:
-                       NAJA_PRINTF("str   r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
+       int N = 1 << (3 + vlen - size);
+       int i;
 
-                       *(uint64_t*)(data + offset) = naja->regs[rd];
-                       break;
-       };
+       if (IMM) {
+               if (0 == uimm6)
+                       NAJA_PRINTF("vmov.u%dx%d   X%d, X%d\n", 1 << size, N, rd, rs);
+               else
+                       NAJA_PRINTF("vmov.u%dx%d   X%d, X%d %s %d\n", 1 << size, N, rd, rs, __naja_SH[SH], uimm6);
+       } else
+               NAJA_PRINTF("vmov.u%dx%d   X%d, X%d %s %s\n", 1 << size, N, rd, rs, __naja_SH[SH], __naja_reg[rs1]);
+
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 0:
+                               if (!IMM)
+                                       uimm6 = naja->fvec[rs1].b[i];
+
+                               if (0 == SH)
+                                       naja->fvec[rd].b[i] = naja->fvec[rs].b[i] << uimm6;
+                               else if (1 == SH)
+                                       naja->fvec[rd].b[i] = naja->fvec[rs].b[i] >> uimm6;
+                               else if (2 == SH)
+                                       naja->fvec[rd].b[i] = (int8_t)naja->fvec[rs].b[i] >> uimm6;
+                               else {
+                                       scf_loge("\n");
+                                       return -1;
+                               }
+                               break;
+                       case 1:
+                               if (!IMM)
+                                       uimm6 = naja->fvec[rs1].w[i];
+
+                               if (0 == SH)
+                                       naja->fvec[rd].w[i] = naja->fvec[rs].w[i] << uimm6;
+                               else if (1 == SH)
+                                       naja->fvec[rd].w[i] = naja->fvec[rs].w[i] >> uimm6;
+                               else if (2 == SH)
+                                       naja->fvec[rd].w[i] = (int8_t)naja->fvec[rs].w[i] >> uimm6;
+                               else {
+                                       scf_loge("\n");
+                                       return -1;
+                               }
+                               break;
+                       case 2:
+                               if (!IMM)
+                                       uimm6 = naja->fvec[rs1].l[i];
+
+                               if (0 == SH)
+                                       naja->fvec[rd].l[i] = naja->fvec[rs].l[i] << uimm6;
+                               else if (1 == SH)
+                                       naja->fvec[rd].l[i] = naja->fvec[rs].l[i] >> uimm6;
+                               else if (2 == SH)
+                                       naja->fvec[rd].l[i] = (int8_t)naja->fvec[rs].l[i] >> uimm6;
+                               else {
+                                       scf_loge("\n");
+                                       return -1;
+                               }
+                               break;
+                       case 3:
+                               if (!IMM)
+                                       uimm6 = naja->fvec[rs1].q[i];
+
+                               if (0 == SH)
+                                       naja->fvec[rd].q[i] = naja->fvec[rs].q[i] << uimm6;
+                               else if (1 == SH)
+                                       naja->fvec[rd].q[i] = naja->fvec[rs].q[i] >> uimm6;
+                               else if (2 == SH)
+                                       naja->fvec[rd].q[i] = (int8_t)naja->fvec[rs].q[i] >> uimm6;
+                               else {
+                                       scf_loge("\n");
+                                       return -1;
+                               }
+                               break;
+                       default:
+                               scf_loge("\n");
+                               return -1;
+                               break;
+               };
+       }
 
-       naja->ip += 4;
        return 0;
 }
 
-static int __naja_and(scf_vm_t* vm, uint32_t inst)
+static int __naja_vnot(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
+       int rs   =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int A    = (inst >> 16) & 0x3;
+       int vlen = (inst >> 10) & 0x3;
 
-       if (0x3 == SH) {
-               uint64_t uimm14 = (inst >> 5) & 0x3fff;
+       int N = 1 << (3 + vlen - size);
+       int i;
 
-               naja->regs[rd]  = naja->regs[rs0] & uimm14;
-       } else {
-               uint64_t uimm9 = (inst >> 10) & 0x1ff;
-               int      rs1   = (inst >>  5) & 0x1f;
+       if (A)
+               NAJA_PRINTF("vnot.u%dx%d   X%d, X%d\n", 1 << size, N, rd, rs);
+       else
+               NAJA_PRINTF("vneg.u%dx%d   X%d, X%d\n", 1 << size, N, rd, rs);
 
-               if (0 == SH)
-                       naja->regs[rd]  = naja->regs[rs0] & (naja->regs[rs1] << uimm9);
-               else if (1 == SH)
-                       naja->regs[rd]  = naja->regs[rs0] & (naja->regs[rs1] >> uimm9);
-               else
-                       naja->regs[rd]  = naja->regs[rs0] & (((int64_t)naja->regs[rs1]) >> uimm9);
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 0:
+                               if (A)
+                                       naja->fvec[rd].b[i] = ~naja->fvec[rs].b[i];
+                               else
+                                       naja->fvec[rd].b[i] = -naja->fvec[rs].b[i];
+                               break;
+                       case 1:
+                               if (A)
+                                       naja->fvec[rd].w[i] = ~naja->fvec[rs].w[i];
+                               else
+                                       naja->fvec[rd].w[i] = -naja->fvec[rs].w[i];
+                               break;
+                       case 2:
+                               if (A)
+                                       naja->fvec[rd].l[i] = ~naja->fvec[rs].l[i];
+                               else
+                                       naja->fvec[rd].l[i] = -naja->fvec[rs].l[i];
+                               break;
+                       case 3:
+                               if (A)
+                                       naja->fvec[rd].q[i] = ~naja->fvec[rs].q[i];
+                               else
+                                       naja->fvec[rd].q[i] = -naja->fvec[rs].q[i];
+                               break;
+                       default:
+                               scf_loge("\n");
+                               return -1;
+                               break;
+               };
        }
 
-       if (31 == rd)
-               naja->flags = !naja->regs[rd];
-
-       naja->ip += 4;
        return 0;
 }
 
-static int __naja_or(scf_vm_t* vm, uint32_t inst)
+static int __naja_vmov_imm(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
+       int u16  =  inst        & 0xffff;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int vlen = (inst >> 16) & 0x3;
+       int mvn  = (inst >> 25) & 0x1;
 
-       if (0x3 == SH) {
-               uint64_t uimm14 = (inst >> 5) & 0x3fff;
+       int N = 1 << (3 + vlen - size);
+       int i;
 
-               naja->regs[rd]  = naja->regs[rs0] | uimm14;
-       } else {
-               uint64_t uimm9 = (inst >> 10) & 0x1ff;
-               int      rs1   = (inst >>  5) & 0x1f;
+       if (mvn)
+               NAJA_PRINTF("vmvn.u%dx%d   X%d, %#x\n", 1 << size, N, rd, u16);
+       else
+               NAJA_PRINTF("vmov.u%dx%d   X%d, %#x\n", 1 << size, N, rd, u16);
 
-               if (0 == SH)
-                       naja->regs[rd]  = naja->regs[rs0] | (naja->regs[rs1] << uimm9);
-               else if (1 == SH)
-                       naja->regs[rd]  = naja->regs[rs0] | (naja->regs[rs1] >> uimm9);
-               else
-                       naja->regs[rd]  = naja->regs[rs0] | (((int64_t)naja->regs[rs1]) >> uimm9);
+       for (i = 0; i < N; i++) {
+               switch (size) {
+                       case 0:
+                               if (mvn)
+                                       naja->fvec[rd].b[i] = ~u16;
+                               else
+                                       naja->fvec[rd].b[i] = u16;
+                               break;
+                       case 1:
+                               if (mvn)
+                                       naja->fvec[rd].w[i] = ~u16;
+                               else
+                                       naja->fvec[rd].w[i] = u16;
+                               break;
+                       case 2:
+                               if (mvn)
+                                       naja->fvec[rd].l[i] = ~u16;
+                               else
+                                       naja->fvec[rd].l[i] = u16;
+                               break;
+                       case 3:
+                               if (mvn)
+                                       naja->fvec[rd].q[i] = ~u16;
+                               else
+                                       naja->fvec[rd].q[i] = u16;
+                               break;
+                       default:
+                               scf_loge("\n");
+                               return -1;
+                               break;
+               };
        }
 
-       naja->ip += 4;
        return 0;
 }
 
@@ -1570,8 +2376,6 @@ static int __naja_jmp_reg(scf_vm_t* vm, uint32_t inst)
                                        naja->regs[3],
                                        naja->regs[4],
                                        naja->regs[5],
-                                       naja->regs[6],
-                                       naja->regs[7],
                                        naja->fvec[0].d[0],
                                        naja->fvec[1].d[0],
                                        naja->fvec[2].d[0],
@@ -1592,7 +2396,6 @@ static int __naja_jmp_reg(scf_vm_t* vm, uint32_t inst)
        return 0;
 }
 
-
 static int __naja_call_reg(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
@@ -1626,8 +2429,6 @@ static int __naja_call_reg(scf_vm_t* vm, uint32_t inst)
                                naja->regs[3],
                                naja->regs[4],
                                naja->regs[5],
-                               naja->regs[6],
-                               naja->regs[7],
                                naja->fvec[0].d[0],
                                naja->fvec[1].d[0],
                                naja->fvec[2].d[0],
@@ -1646,17 +2447,52 @@ static int __naja_call_reg(scf_vm_t* vm, uint32_t inst)
        return 0;
 }
 
+static int __naja_setcc(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rd = (inst >> 21) & 0x1f;
+       int cc = (inst >>  1) & 0xf;
+
+       naja->regs[rd] = 0 == (cc & naja->flags);
+
+       if (SCF_VM_Z == cc)
+               NAJA_PRINTF("setz   r%d\n", rd);
+
+       else if (SCF_VM_NZ == cc)
+               NAJA_PRINTF("setnz  r%d\n", rd);
+
+       else if (SCF_VM_GE == cc)
+               NAJA_PRINTF("setge  r%d\n", rd);
+
+       else if (SCF_VM_GT == cc)
+               NAJA_PRINTF("setgt  r%d\n", rd);
+
+       else if (SCF_VM_LT == cc)
+               NAJA_PRINTF("setlt  r%d\n", rd);
+
+       else if (SCF_VM_LE == cc)
+               NAJA_PRINTF("setle  r%d\n", rd);
+       else {
+               scf_loge("inst: %#x\n", inst);
+               return -EINVAL;
+       }
+
+       naja->ip  += 4;
+       return 0;
+}
+
 static int __naja_adrp(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rd  = (inst >> 21) & 0x1f;
+       int rd  = (inst >> 21) & 0xf;
        int s21 =  inst & 0x1fffff;
 
        if (s21  & 0x100000)
                s21 |= ~0x1fffff;
 
-       naja->regs[rd] = (naja->ip + ((int64_t)s21 << 14)) & ~0x3fffULL;
+       naja->regs[rd] = (naja->ip + ((int64_t)s21 << 12)) & ~0xfffULL;
 
        if (naja->regs[rd] >= 0x800000)
                naja->regs[rd]  = naja->regs[rd] - vm->data->addr + (uint64_t)vm->data->data;
@@ -1698,222 +2534,63 @@ static int __naja_ret(scf_vm_t* vm, uint32_t inst)
        return 0;
 }
 
-static int __naja_setcc(scf_vm_t* vm, uint32_t inst)
+static int __naja_spop(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rd = (inst >> 21) & 0x1f;
-       int cc = (inst >>  1) & 0xf;
-
-       naja->regs[rd] = 0 == (cc & naja->flags);
-
-       if (SCF_VM_Z == cc)
-               NAJA_PRINTF("setz   r%d\n", rd);
-
-       else if (SCF_VM_NZ == cc)
-               NAJA_PRINTF("setnz  r%d\n", rd);
-
-       else if (SCF_VM_GE == cc)
-               NAJA_PRINTF("setge  r%d\n", rd);
-
-       else if (SCF_VM_GT == cc)
-               NAJA_PRINTF("setgt  r%d\n", rd);
-
-       else if (SCF_VM_LT == cc)
-               NAJA_PRINTF("setlt  r%d\n", rd);
-
-       else if (SCF_VM_LE == cc)
-               NAJA_PRINTF("setle  r%d\n", rd);
-       else {
-               scf_loge("inst: %#x\n", inst);
-               return -EINVAL;
-       }
+       int rb =  inst        & 0xf;
+       int sr = (inst >> 21) & 0xf;
 
-       naja->ip  += 4;
+       NAJA_PRINTF("spop     sr%d, [%s]\n", sr, __naja_reg[rb]);
        return 0;
 }
 
-static int __naja_mov(scf_vm_t* vm, uint32_t inst)
+static int __naja_spush(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s   = (inst >> 18) & 0x1;
-       int opt = (inst >> 16) & 0x3;
-
-       if (0 == opt) {
-               int rs0 =  inst       & 0x1f;
-               int rs1 = (inst >> 5) & 0x1f;
-
-               if (0 == SH) {
-                       naja->regs[rd]  = naja->regs[rs0] << naja->regs[rs1];
-
-                       NAJA_PRINTF("mov    r%d, r%d LSL r%d\n", rd, rs0, rs1);
-
-               } else if (1 == SH) {
-                       naja->regs[rd]  = naja->regs[rs0] >> naja->regs[rs1];
-
-                       NAJA_PRINTF("mov    r%d, r%d LSR r%d\n", rd, rs0, rs1);
-               } else {
-                       naja->regs[rd]  = (int64_t)naja->regs[rs0] >> naja->regs[rs1];
-
-                       NAJA_PRINTF("mov    r%d, r%d ASR r%d\n", rd, rs0, rs1);
-               }
-
-       } else if (1 == opt) {
-               int rs0 =  inst       & 0x1f;
-               int u11 = (inst >> 5) & 0x7ff;
-
-               if (0 == SH) {
-                       naja->regs[rd]  = naja->regs[rs0] << u11;
-
-                       if (0 == u11)
-                               NAJA_PRINTF("mov    r%d, r%d\n", rd, rs0);
-                       else
-                               NAJA_PRINTF("mov    r%d, r%d LSL %d\n", rd, rs0, u11);
-
-               } else if (1 == SH) {
-                       naja->regs[rd]  = naja->regs[rs0] >> u11;
-
-                       NAJA_PRINTF("mov    r%d, r%d LSR %d\n", rd, rs0, u11);
-               } else {
-                       naja->regs[rd]  = (int64_t)naja->regs[rs0] >> u11;
-
-                       NAJA_PRINTF("mov    r%d, r%d ASR %d\n", rd, rs0, u11);
-               }
-
-       } else if (2 == opt) {
-               int rs = inst & 0x1f;
-
-               switch (SH) {
-                       case 0:
-                               if (s) {
-                                       NAJA_PRINTF("movsb  r%d, r%d\n", rd, rs);
-
-                                       naja->regs[rd] = (int8_t)naja->regs[rs];
-                               } else {
-                                       naja->regs[rd] = (uint8_t)naja->regs[rs];
-
-                                       NAJA_PRINTF("movzb  r%d, r%d\n", rd, rs);
-                               }
-                               break;
-
-                       case 1:
-                               if (s) {
-                                       NAJA_PRINTF("movsw  r%d, r%d\n", rd, rs);
-
-                                       naja->regs[rd] = (int16_t)naja->regs[rs];
-                               } else {
-                                       naja->regs[rd] = (uint16_t)naja->regs[rs];
-
-                                       NAJA_PRINTF("movzw  r%d, r%d\n", rd, rs);
-                               }
-                               break;
-
-                       case 2:
-                               if (s) {
-                                       NAJA_PRINTF("movsl  r%d, r%d\n", rd, rs);
-
-                                       naja->regs[rd] = (int32_t)naja->regs[rs];
-                               } else {
-                                       naja->regs[rd] = (uint32_t)naja->regs[rs];
-
-                                       NAJA_PRINTF("movzl  r%d, r%d\n", rd, rs);
-                               }
-                               break;
-                       default:
-                               if (s) {
-                                       NAJA_PRINTF("NEG    r%d, r%d\n", rd, rs);
-
-                                       naja->regs[rd] = -naja->regs[rs];
-                               } else {
-                                       naja->regs[rd] = ~naja->regs[rs];
-
-                                       NAJA_PRINTF("NOT    r%d, r%d\n", rd, rs);
-                               }
-                               break;
-               };
-
-       } else {
-               uint64_t u16 = inst & 0xffff;
-
-               if (s) {
-                       naja->regs[rd] = ~u16;
-
-                       NAJA_PRINTF("mvn    r%d, %#lx\n", rd, u16);
-               } else {
-                       if (0 == SH) {
-                               NAJA_PRINTF("mov    r%d, %#lx\n", rd, u16);
-
-                               naja->regs[rd] = u16;
-                       } else {
-                               naja->regs[rd] |= u16 << SH;
-
-                               NAJA_PRINTF("mov    r%d, %#lx << %d\n", rd, u16, 16 << SH);
-                       }
-               }
-       }
+       int rb =  inst        & 0xf;
+       int sr = (inst >> 21) & 0xf;
 
-       naja->ip += 4;
+       NAJA_PRINTF("spush    sr%d, [%s]\n", sr, __naja_reg[rb]);
        return 0;
 }
 
-static int __naja_fmov(scf_vm_t* vm, uint32_t inst)
+static int __naja_in(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs  =  inst & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s   = (inst >> 18) & 0x1;
-       int opt = (inst >> 16) & 0x3;
-
-       if (0 == opt) {
-               if (2 == SH) {
-                       naja->fvec[rd].d[0] = naja->fvec[rs].d[0];
-
-                       NAJA_PRINTF("fss2sd   d%d, f%d\n", rd, rs);
-
-               } else if (3 == SH) {
-                       naja->fvec[rd].d[0] = naja->fvec[rs].d[0];
-
-                       NAJA_PRINTF("fsd2ss   f%d, d%d\n", rd, rs);
-               } else {
-                       scf_loge("\n");
-                       return -EINVAL;
-               }
-
-       } else if (1 == opt) {
-               if (s) {
-                       naja->regs[rd] = (int64_t)naja->fvec[rs].d[0];
-
-                       NAJA_PRINTF("cvtss2si r%d, f%d\n", rd, rs);
-               } else {
-                       naja->regs[rd] = (uint64_t)naja->fvec[rs].d[0];
-
-                       NAJA_PRINTF("cvtss2ui r%d, f%d\n", rd, rs);
-               }
-
-       } else if (2 == opt) {
+       int u16 =  inst        & 0xffff;
+       int rd  = (inst >> 21) & 0xf;
+       int D   = (inst >> 17) & 0xf;
 
-               naja->fvec[rd].d[0] = (double)naja->regs[rs];
+       if (D)
+               NAJA_PRINTF("out      %s, %#x\n", __naja_reg[rd], u16);
+       else
+               NAJA_PRINTF("in       %s, %#x\n", __naja_reg[rd], u16);
+       return 0;
+}
 
-               NAJA_PRINTF("cvtsi2ss f%d, r%d\n", rd, rs);
+static int __naja_smov(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-       } else {
-               if (s) {
-                       NAJA_PRINTF("fneg     d%d, d%d\n", rd, rs);
+       int sr =  inst        & 0xf;
+       int rd = (inst >> 21) & 0xf;
+       int D  = (inst >> 17) & 0xf;
 
-                       naja->fvec[rd].d[0] = -naja->fvec[rs].d[0];
-               } else {
-                       naja->fvec[rd].d[0] =  naja->fvec[rs].d[0];
+       if (D)
+               NAJA_PRINTF("smov     sr%d, %s\n", sr, __naja_reg[rd]);
+       else
+               NAJA_PRINTF("smov     %s, sr%d\n", __naja_reg[rd], sr);
+       return 0;
+}
 
-                       NAJA_PRINTF("fmov     d%d, d%d\n", rd, rs);
-               }
-       }
+static int __naja_iret(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-       naja->ip += 4;
+       NAJA_PRINTF("iret\n");
        return 0;
 }
 
@@ -1925,19 +2602,20 @@ static naja_opcode_pt  naja_opcodes[64] =
        __naja_div,      // 3
 
        __naja_ldr_disp, // 4
-       __naja_pop,      // 5
+       __naja_and,      // 5
 
        __naja_str_disp, // 6
-       __naja_push,     // 7
+       __naja_or,       // 7
 
-       __naja_and,      // 8
-       __naja_or,       // 9
-       __naja_jmp_disp, // 10
-       __naja_jmp_reg,  // 11
-       __naja_setcc,    // 12
-       __naja_ldr_sib,  // 13
-       __naja_str_sib,  // 14
-       __naja_mov,      // 15
+       __naja_pop,      // 8
+       __naja_push,     // 9
+
+       __naja_ldr_sib,  // 10
+       __naja_str_sib,  // 11
+       __naja_mov,      // 12
+       __naja_movx,     // 13
+       __naja_not,      // 14
+       NULL,            // 15
 
        __naja_fadd,     // 16
        __naja_fsub,     // 17
@@ -1945,52 +2623,52 @@ static naja_opcode_pt  naja_opcodes[64] =
        __naja_fdiv,     // 19
 
        __naja_fldr_disp,// 20
-       __naja_fpop,     // 21
+       NULL,            // 21
 
        __naja_fstr_disp,// 22
-       __naja_fpush,    // 23
+       NULL,            // 23
 
        NULL,            // 24
        NULL,            // 25
-       __naja_call_disp,// 26
-       __naja_call_reg, // 27
-       NULL,            // 28
-       __naja_fldr_sib, // 29
-       __naja_fstr_sib, // 30
-       __naja_fmov,     // 31
-
-       NULL,            // 32
-       NULL,            // 33
-       NULL,            // 34
-       NULL,            // 35
+       __naja_fldr_sib, // 26
+       NULL,            // 27
+       __naja_fmov,     // 28
+       __naja_fcvt,     // 29
+       __naja_fneg,     // 30
+       NULL,            // 31
+
+       __naja_vadd,     // 32
+       __naja_vsub,     // 33
+       __naja_vmul,     // 34
+       __naja_vdiv,     // 35
        NULL,            // 36
-       NULL,            // 37
+       __naja_vand,     // 37
        NULL,            // 38
-       NULL,            // 39
+       __naja_vor,      // 39
        NULL,            // 40
        NULL,            // 41
-       __naja_adrp,     // 42
+       NULL,            // 42
        NULL,            // 43
-       NULL,            // 44
+       __naja_vmov,     // 44
        NULL,            // 45
-       NULL,            // 46
-       NULL,            // 47
-
-       NULL,            // 48
-       NULL,            // 49
-       NULL,            // 50
-       NULL,            // 51
-       NULL,            // 52
-       NULL,            // 53
-       NULL,            // 54
+       __naja_vnot,     // 46
+       __naja_vmov_imm, // 47
+
+       __naja_jmp_disp, // 48
+       __naja_call_disp,// 49
+       __naja_jmp_reg,  // 50
+       __naja_call_reg, // 51
+       __naja_setcc,    // 52
+       __naja_adrp,     // 53
+       __naja_ret,      // 54
        NULL,            // 55
-       __naja_ret,      // 56
-       NULL,            // 57
-       NULL,            // 58
+       __naja_spop,     // 56
+       __naja_spush,    // 57
+       __naja_in,       // 58
        NULL,            // 59
-       NULL,            // 60
+       __naja_smov,     // 60
        NULL,            // 61
-       NULL,            // 62
+       __naja_iret,     // 62
        NULL,            // 63
 };
 
@@ -2042,6 +2720,8 @@ static int __naja_vm_run(scf_vm_t* vm, const char* path, const char* sys)
 
        naja->regs[NAJA_REG_LR] = (uint64_t)__naja_vm_exit;
 
+       scf_logw("naja->regs[NAJA_REG_LR]: %#lx\n", naja->regs[NAJA_REG_LR]);
+
        int n = 0;
        while ((uint64_t)__naja_vm_exit != naja->ip) {
 
index 9f396247f71db7ae3743d753214dc534f3cb1f76..3881645e725d8f181451264f802bcfcfe3ec3287 100644 (file)
@@ -1,31 +1,41 @@
 #include"scf_vm.h"
 
+static char*  __naja_sign[]  = {"", "s"};
+static char   __naja_size[]  = {'b', 'w', 'l', 'q'};
+static char   __naja_float[] = {'B', 'H', 'S', 'D'};
+
+static char* __naja_SH[] = {
+       "LSL",
+       "LSR",
+       "ASR",
+       "IMM"
+};
+
+static char* __naja_reg[] =
+{
+       "r0",  "r1",  "r2", "r3", "r4",
+       "r5",  "r6",  "r7", "r8", "r9",
+       "r10", "r11", "fp", "lr", "sp",
+       "null"
+};
+
 static int __naja_add(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
+       int rs0  =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int SH   = (inst >> 16) & 0x3;
 
        if (0x3 == SH) {
-               uint64_t uimm14 = (inst >> 5) & 0x3fff;
-               printf("add      r%d, r%d, %lu\n", rd, rs0, uimm14);
+               uint64_t uimm12 = (inst >> 4) & 0xfff;
+               printf("add%c     %s, %s, %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12);
        } else {
-               uint64_t uimm9 = (inst >> 10) & 0x1ff;
-               int      rs1   = (inst >>  5) & 0x1f;
-
-               switch (SH) {
-                       case 0:
-                               printf("add      r%d, r%d, r%d LSL %lu\n", rd, rs0, rs1, uimm9);
-                               break;
-                       case 1:
-                               printf("add      r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm9);
-                               break;
-                       default:
-                               printf("add      r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm9);
-                               break;
-               };
+               uint64_t uimm6 = (inst >> 10) & 0x3f;
+               int      rs1   = (inst >>  4) & 0xf;
+
+               printf("add%c     %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6);
        }
 
        return 0;
@@ -35,43 +45,26 @@ static int __naja_sub(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
+       int rs0  =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int SH   = (inst >> 16) & 0x3;
 
        if (0x3 == SH) {
-               uint64_t uimm14 = (inst >> 5) & 0x3fff;
+               uint64_t uimm12 = (inst >> 4) & 0xfff;
 
-               if (31 == rd)
-                       printf("cmp      r%d, %lu\n", rs0, uimm14);
+               if (0xf == rd)
+                       printf("cmp%c     %s, %lu\n", __naja_size[size], __naja_reg[rs0], uimm12);
                else
-                       printf("sub      r%d, r%d, %lu\n", rd, rs0, uimm14);
+                       printf("sub%c     %s, %s, %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12);
        } else {
-               uint64_t uimm9 = (inst >> 10) & 0x1ff;
-               int      rs1   = (inst >>  5) & 0x1f;
-
-               switch (SH) {
-                       case 0:
-                               if (31 == rd)
-                                       printf("cmp      r%d, r%d << %lu\n", rs0, rs1, uimm9);
-                               else
-                                       printf("sub      r%d, r%d, r%d << %lu\n", rd, rs0, rs1, uimm9);
-                               break;
-
-                       case 1:
-                               if (31 == rd)
-                                       printf("cmp      r%d, r%d LSR %lu\n", rs0, rs1, uimm9);
-                               else
-                                       printf("sub      r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm9);
-                               break;
-
-                       default:
-                               if (31 == rd)
-                                       printf("cmp      r%d, r%d ASR %lu\n", rs0, rs1, uimm9);
-                               else
-                                       printf("sub      r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm9);
-                               break;
-               };
+               uint64_t uimm6 = (inst >> 10) & 0x3f;
+               int      rs1   = (inst >>  4) & 0xf;
+
+               if (0xf == rd)
+                       printf("cmp%c     %s, %s %s %lu\n", __naja_size[size], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6);
+               else
+                       printf("sub%c     %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6);
        }
 
        return 0;
@@ -81,27 +74,21 @@ static int __naja_mul(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rs1 = (inst >>  5) & 0x1f;
-       int rs2 = (inst >> 10) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int S   = (inst >> 18) & 0x1;
-       int opt = (inst >> 19) & 0x3;
-
-       if (S) {
-               if (0 == opt)
-                       printf("smadd    r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1);
-               else if (1 == opt)
-                       printf("smsub    r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1);
-               else
-                       printf("smul     r%d, r%d, r%d\n", rd, rs0, rs1);
-       } else {
-               if (0 == opt)
-                       printf("madd     r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1);
-               else if (1 == opt)
-                       printf("msub     r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1);
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rs2  = (inst >> 12) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int s    = (inst >> 17) & 0x1;
+       int A    = (inst >> 16) & 0x1;
+
+       if (0xf == rs2)
+               printf("%smul%c     %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1]);
+       else {
+               if (0 == A)
+                       printf("%smadd%c    %s, %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs2], __naja_reg[rs0], __naja_reg[rs1]);
                else
-                       printf("mul      r%d, r%d, r%d\n", rd, rs0, rs1);
+                       printf("%smsub%c    %s, %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs2], __naja_reg[rs0], __naja_reg[rs1]);
        }
 
        return 0;
@@ -111,71 +98,99 @@ static int __naja_div(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rs1 = (inst >>  5) & 0x1f;
-       int rs2 = (inst >> 10) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int S   = (inst >> 18) & 0x1;
-       int opt = (inst >> 19) & 0x3;
-
-       if (S) {
-               if (0 == opt)
-                       printf("sdadd    r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1);
-               else if (1 == opt)
-                       printf("sdsub    r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1);
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rs2  = (inst >> 12) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int s    = (inst >> 17) & 0x1;
+       int A    = (inst >> 16) & 0x1;
+
+       printf("%sdiv%c     %s, %s, %s\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1]);
+       return 0;
+}
+
+static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rb   =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int s    = (inst >> 17) & 0x1;
+       int s13  = (inst >>  4) & 0x1fff;
+
+       if (s13  & 0x1000)
+               s13 |= 0xffffe000;
+
+       printf("ldr%s%c  %s, [%s, %d]\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rb], s13 << size);
+       return 0;
+}
+
+static int __naja_and(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rs0  =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int SH   = (inst >> 16) & 0x3;
+
+       if (0x3 == SH) {
+               uint64_t uimm12 = (inst >> 4) & 0xfff;
+
+               if (0xf == rd)
+                       printf("teq%c   %s, %#lx\n", __naja_size[size], __naja_reg[rs0], uimm12);
                else
-                       printf("sdiv     r%d, r%d, r%d\n", rd, rs0, rs1);
+                       printf("and%c   %s, %s, %#lx\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12);
        } else {
-               if (0 == opt)
-                       printf("dadd     r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1);
-               else if (1 == opt)
-                       printf("dsub     r%d, r%d, r%d, r%d\n", rd, rs2, rs0, rs1);
+               uint64_t uimm6 = (inst >> 10) & 0x3f;
+               int      rs1   = (inst >>  4) & 0xf;
+
+               if (0xf == rd)
+                       printf("teq%c   %s, %s %s %lu\n", __naja_size[size], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6);
                else
-                       printf("div      r%d, r%d, r%d\n", rd, rs0, rs1);
+                       printf("and%c   %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6);
        }
 
        return 0;
 }
 
-static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst)
+static int __naja_str_disp(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s   = (inst >> 18) & 0x1;
-       int s13 = (inst >>  5) & 0x1fff;
+       int rb   =  inst        & 0xf;
+       int rs   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int s13  = (inst >>  4) & 0x1fff;
 
        if (s13  & 0x1000)
                s13 |= 0xffffe000;
 
-       switch (SH) {
-               case 0:
-                       if (s)
-                               printf("ldrsb    r%d, [r%d, %d]\n", rd, rb, s13);
-                       else
-                               printf("ldrb     r%d, [r%d, %d]\n", rd, rb, s13);
-                       break;
+       printf("str%c    %s, [%s, %d]\n", __naja_size[size], __naja_reg[rs], __naja_reg[rb], s13 << size);
+       return 0;
+}
 
-               case 1:
-                       if (s)
-                               printf("ldrsw    r%d, [r%d, %d]\n", rd, rb, s13 << 1);
-                       else
-                               printf("ldrw     r%d, [r%d, %d]\n", rd, rb, s13 << 1);
-                       break;
+static int __naja_or(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-               case 2:
-                       if (s)
-                               printf("ldrsl    r%d, [r%d, %d]\n", rd, rb, s13 << 2);
-                       else
-                               printf("ldrl     r%d, [r%d, %d]\n", rd, rb, s13 << 2);
-                       break;
+       int rs0  =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int SH   = (inst >> 16) & 0x3;
 
-               default:
-                       printf("ldr      r%d, [r%d, %d]\n", rd, rb, s13 << 3);
-                       break;
-       };
+       if (0x3 == SH) {
+               uint64_t uimm12 = (inst >> 4) & 0xfff;
+
+               printf("or%c    %s, %s, %#lx\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], uimm12);
+       } else {
+               uint64_t uimm6 = (inst >> 10) & 0x3f;
+               int      rs1   = (inst >>  4) & 0xf;
+
+               printf("or%c    %s, %s, %s %s %lu\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs0], __naja_reg[rs1], __naja_SH[SH], uimm6);
+       }
 
        return 0;
 }
@@ -184,38 +199,29 @@ static int __naja_pop(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s   = (inst >> 18) & 0x1;
-
-       switch (SH) {
-               case 0:
-                       if (s)
-                               printf("popsb    r%d, [r%d]\n", rd, rb);
-                       else
-                               printf("popb     r%d, [r%d]\n", rd, rb);
-                       break;
+       int rb =  inst        & 0xf;
+       int rd = (inst >> 21) & 0xf;
+       int s  = (inst >> 17) & 0x1;
 
-               case 1:
-                       if (s)
-                               printf("popsw    r%d, [r%d]\n", rd, rb);
-                       else
-                               printf("popw     r%d, [r%d]\n", rd, rb);
-                       break;
+       if (s)
+               printf("fpop     d%d, [%s]\n", rd, __naja_reg[rb]);
+       else
+               printf("pop      %s, [%s]\n", __naja_reg[rd], __naja_reg[rb]);
+       return 0;
+}
 
-               case 2:
-                       if (s)
-                               printf("popsl    r%d, [r%d]\n", rd, rb);
-                       else
-                               printf("popl     r%d, [r%d]\n", rd, rb);
-                       break;
+static int __naja_push(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-               default:
-                       printf("popq     r%d, [r%d]\n", rd, rb);
-                       break;
-       };
+       int rb =  inst        & 0xf;
+       int rs = (inst >> 21) & 0xf;
+       int s  = (inst >> 17) & 0x1;
 
+       if (s)
+               printf("fpush    d%d, [%s]\n", rs, __naja_reg[rb]);
+       else
+               printf("push     %s, [%s]\n", __naja_reg[rs], __naja_reg[rb]);
        return 0;
 }
 
@@ -223,698 +229,728 @@ static int __naja_ldr_sib(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int ri  = (inst >>  5) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s   = (inst >> 18) & 0x1;
-       int u8  = (inst >> 10) & 0xff;
+       int rb    =  inst        & 0xf;
+       int ri    = (inst >>  4) & 0xf;
+       int rd    = (inst >> 21) & 0xf;
+       int size  = (inst >> 18) & 0x3;
+       int s     = (inst >> 17) & 0x1;
+       int uimm6 = (inst >> 10) & 0x3f;
 
-       switch (SH) {
-               case 0:
-                       if (s)
-                               printf("ldrsb   r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-                       else
-                               printf("ldrb    r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-                       break;
+       printf("ldr%s%c   %s, [%s, %s LSL %d]\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rb], __naja_reg[ri], uimm6);
+       return 0;
+}
 
-               case 1:
-                       if (s)
-                               printf("ldrsw   r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-                       else
-                               printf("ldrw    r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-                       break;
+static int __naja_str_sib(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-               case 2:
-                       if (s)
-                               printf("ldrsl   r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-                       else
-                               printf("ldrl    r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-                       break;
-
-               default:
-                       printf("ldr     r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-                       break;
-       };
+       int rb    =  inst        & 0xf;
+       int ri    = (inst >>  4) & 0xf;
+       int rs    = (inst >> 21) & 0xf;
+       int size  = (inst >> 18) & 0x3;
+       int s     = (inst >> 17) & 0x1;
+       int uimm6 = (inst >> 10) & 0x3f;
 
+       if (s)
+               printf("fstr.%d   d%d, [%s, %s, %d]\n", 1 << size, rs, __naja_reg[rb], __naja_reg[ri], uimm6);
+       else
+               printf("str%c     %s, [%s, %s, %d]\n", __naja_size[size], __naja_reg[rs], __naja_reg[rb], __naja_reg[ri], uimm6);
        return 0;
 }
 
-static int __naja_str_disp(scf_vm_t* vm, uint32_t inst)
+static int __naja_mov(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s13 = (inst >>  5) & 0x1fff;
-
-       if (s13  & 0x1000)
-               s13 |= 0xffffe000;
-
-       switch (SH) {
-               case 0:
-                       printf("strb     r%d, [r%d, %d]\n", rd, rb, s13);
-                       break;
+       int rs    =  inst        & 0xf;
+       int rs1   = (inst >>  4) & 0xf;
+       int rd    = (inst >> 21) & 0xf;
+       int size  = (inst >> 18) & 0x3;
+       int SH    = (inst >> 16) & 0x3;
+       int uimm6 = (inst >> 10) & 0x3f;
 
-               case 1:
-                       printf("strw     r%d, [r%d, %d]\n", rd, rb, s13 << 1);
-                       break;
+       if (0xf == rs1) {
+               if (0 == uimm6)
+                       printf("mov%c     %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]);
+               else
+                       printf("mov%c     %s, %s %s %d\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs], __naja_SH[SH], uimm6);
+       } else
+               printf("mov%c     %s, %s %s %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs], __naja_SH[SH], __naja_reg[rs1]);
+       return 0;
+}
 
-               case 2:
-                       printf("strl     r%d, [r%d, %d]\n", rd, rb, s13 << 2);
-                       break;
+static int __naja_movx(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-               default:
-                       printf("str      r%d, [r%d, %d]\n", rd, rb, s13 << 3);
-                       break;
-       };
+       int rs    =  inst        & 0xf;
+       int rd    = (inst >> 21) & 0xf;
+       int size  = (inst >> 18) & 0x3;
+       int s     = (inst >> 17) & 0x1;
 
+       if (s)
+               printf("movs%cq    %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]);
+       else
+               printf("movz%cq    %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]);
        return 0;
 }
 
-static int __naja_push(scf_vm_t* vm, uint32_t inst)
+static int __naja_not(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
+       int rs   =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int SH   = (inst >> 16) & 0x3;
+       int u16  =  inst        & 0xffff;
 
        switch (SH) {
                case 0:
-                       printf("pushb    r%d, [r%d]\n", rd, rb);
+                       printf("neg%c    %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]);
                        break;
-
                case 1:
-                       printf("pushw    r%d, [r%d]\n", rd, rb);
+                       printf("not%c    %s, %s\n", __naja_size[size], __naja_reg[rd], __naja_reg[rs]);
                        break;
-
                case 2:
-                       printf("pushl    r%d, [r%d]\n", rd, rb);
+                       if (0 == size)
+                               printf("mov      %s, %d\n", __naja_reg[rd], u16);
+                       else
+                               printf("movt     %s, %d LSL %d\n", __naja_reg[rd], u16, 16 << size);
                        break;
-
                default:
-                       printf("pushq    r%d, [r%d]\n", rd, rb);
+                       printf("mvn%c    %s, %d\n", __naja_size[size], __naja_reg[rd], u16);
                        break;
        };
-
        return 0;
 }
 
-static int __naja_str_sib(scf_vm_t* vm, uint32_t inst)
+static int __naja_fadd(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int ri  = (inst >>  5) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int u8  = (inst >> 10) & 0xff;
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
 
-       switch (SH) {
-               case 0:
-                       printf("strb    r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-                       break;
+       if (V) {
+               int N = 1 << (3 + vlen - size);
 
-               case 1:
-                       printf("strw    r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-                       break;
-
-               case 2:
-                       printf("strl    r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-                       break;
-
-               default:
-                       printf("str     r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-                       break;
-       };
+               printf("vadd.f%dx%d   X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+       } else
+               printf("fadd.%d   d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1);
 
        return 0;
 }
 
-static int __naja_and(scf_vm_t* vm, uint32_t inst)
+static int __naja_fsub(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int cmp  = (inst >> 16) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
 
-       if (0x3 == SH) {
-               uint32_t uimm14 = (inst >> 5) & 0x3fff;
+       if (V) {
+               int N = 1 << (3 + vlen - size);
 
-               if (31 == rd)
-                       printf("teq     r%d, %#x\n", rs0, uimm14);
+               if (cmp)
+                       printf("vcmp.f%dx%d   X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
                else
-                       printf("and     r%d, r%d, %#x\n", rd, rs0, uimm14);
+                       printf("vsub.f%dx%d   X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
        } else {
-               uint32_t uimm9 = (inst >> 10) & 0x1ff;
-               int      rs1   = (inst >>  5) & 0x1f;
-
-               switch (SH) {
-                       case 0:
-                               if (31 == rd)
-                                       printf("teq     r%d, r%d LSL %#x\n", rs0, rs1, uimm9);
-                               else
-                                       printf("and     r%d, r%d, r%d LSL %#x\n", rd, rs0, rs1, uimm9);
-                               break;
-
-                       case 1:
-                               if (31 == rd)
-                                       printf("teq     r%d, r%d LSR %#x\n", rs0, rs1, uimm9);
-                               else
-                                       printf("and     r%d, r%d, r%d LSR %#x\n", rd, rs0, rs1, uimm9);
-                               break;
-
-                       default:
-                               if (31 == rd)
-                                       printf("teq     r%d, r%d ASR %#x\n", rs0, rs1, uimm9);
-                               else
-                                       printf("and     r%d, r%d, r%d ASR %#x\n", rd, rs0, rs1, uimm9);
-                               break;
-               };
+               if (cmp)
+                       printf("fcmp.%d   d%d, d%d\n", 1 << size, rs0, rs1);
+               else
+                       printf("fsub.%d   d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1);
        }
-
        return 0;
 }
 
-static int __naja_or(scf_vm_t* vm, uint32_t inst)
+static int __naja_fmul(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rs2  = (inst >> 12) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int A    = (inst >> 16) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
 
-       if (0x3 == SH) {
-               uint32_t uimm14 = (inst >> 5) & 0x3fff;
+       if (V) {
+               int N = 1 << (3 + vlen - size);
 
-               printf("or      r%d, r%d, %#x\n", rd, rs0, uimm14);
+               if (0xf == rs2)
+                       printf("vmul.f%dx%d   X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+               else {
+                       if (A)
+                               printf("vmsub.f%dx%d   X%d, X%d, X%d, X%d\n", 1 << size, N, rd, rs2, rs0, rs1);
+                       else
+                               printf("vmadd.f%dx%d   X%d, X%d, X%d, X%d\n", 1 << size, N, rd, rs2, rs0, rs1);
+               }
        } else {
-               uint32_t uimm9 = (inst >> 10) & 0x1ff;
-               int      rs1   = (inst >>  5) & 0x1f;
-
-               if (0 == SH)
-                       printf("or      r%d, r%d, r%d LSL %#x\n", rd, rs0, rs1, uimm9);
-               else if (1 == SH)
-                       printf("or      r%d, r%d, r%d LSR %#x\n", rd, rs0, rs1, uimm9);
-               else
-                       printf("or      r%d, r%d, r%d ASR %#x\n", rd, rs0, rs1, uimm9);
+               if (0xf == rs2)
+                       printf("fmul.%d   d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1);
+               else {
+                       if (A)
+                               printf("fmsub.%d   d%d, d%d, d%d, d%d\n", 1 << size, rd, rs2, rs0, rs1);
+                       else
+                               printf("fmadd.%d   d%d, d%d, d%d, d%d\n", 1 << size, rd, rs2, rs0, rs1);
+               }
        }
-
        return 0;
 }
 
-static int __naja_jmp_disp(scf_vm_t* vm, uint32_t inst)
+static int __naja_fdiv(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int simm26 = inst & 0x3ffffff;
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
 
-       if (simm26  & 0x2000000)
-               simm26 |= 0xfc000000;
+       if (V) {
+               int N = 1 << (3 + vlen - size);
 
-       uint64_t ip = naja->ip + (simm26 << 2);
-       printf("jmp    %#lx\n", ip);
+               printf("vdiv.f%dx%d   X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+       } else
+               printf("fdiv.%d   d%d, d%d, d%d\n", 1 << size, rd, rs0, rs1);
        return 0;
 }
 
-static int __naja_call_disp(scf_vm_t* vm, uint32_t inst)
+static int __naja_fldr_disp(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int simm26 = inst & 0x3ffffff;
+       int rb   =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int A    = (inst >> 16) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
+       int s13  = (inst >>  4) & 0x1fff;
 
-       if (simm26  & 0x2000000)
-               simm26 |= 0xfc000000;
+       if (s13  & 0x1000)
+               s13 |= 0xffffe000;
 
-       uint64_t ip = naja->ip + (simm26 << 2);
-       printf("call     %#lx\n", ip);
+       if (V) {
+               int N = 1 << (3 + vlen - size);
+
+               if (A)
+                       printf("vldr.f%dx%d  X%d, [%s]!\n", 1 << size, N, rd, __naja_reg[rb]);
+               else
+                       printf("vldr.f%dx%d  X%d, [%s]\n", 1 << size, N, rd, __naja_reg[rb]);
+       } else
+               printf("fldr.%d  d%d, [%s, %d]\n", 1 << size, rd, __naja_reg[rb], s13 << size);
        return 0;
 }
 
-static int __naja_jmp_reg(scf_vm_t* vm, uint32_t inst)
+static int __naja_fstr_disp(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       if (inst & 0x1) {
+       int rb   =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int A    = (inst >> 16) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
+       int s13  = (inst >>  4) & 0x1fff;
 
-               int cc  = (inst >> 1) & 0xf;
-               int s21 = (inst >> 5) & 0x1fffff;
+       if (s13  & 0x1000)
+               s13 |= 0xffffe000;
 
-               if (s21  & 0x100000)
-                       s21 |= 0xffe00000;
+       if (V) {
+               int N = 1 << (3 + vlen - size);
 
-               s21 <<= 2;
+               if (A)
+                       printf("vstr.f%dx%d  X%d, [%s]!\n", 1 << size, N, rd, __naja_reg[rb]);
+               else
+                       printf("vstr.f%dx%d  X%d, [%s]\n", 1 << size, N, rd, __naja_reg[rb]);
+       } else
+               printf("fstr.%d  d%d, [%s, %d]\n", 1 << size, rd, __naja_reg[rb], s13 << size);
+       return 0;
+}
 
-               uint64_t ip = naja->ip + s21;
+static int __naja_fldr_sib(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-               if (0 == cc)
-                       printf("jz       %#lx\n", ip);
+       int rb    =  inst        & 0xf;
+       int ri    = (inst >>  4) & 0xf;
+       int rd    = (inst >> 21) & 0xf;
+       int size  = (inst >> 18) & 0x3;
+       int uimm6 = (inst >> 10) & 0x3f;
 
-               else if (1 == cc)
-                       printf("jnz      %#lx\n", ip);
+       printf("fldr.%d   d%d, [%s, %s, %d]\n", 1 << size, rd, __naja_reg[rb], __naja_reg[ri], uimm6);
+       return 0;
+}
 
-               else if (2 == cc)
-                       printf("jge      %#lx\n", ip);
+static int __naja_fmov(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-               else if (3 == cc)
-                       printf("jgt      %#lx\n", ip);
+       int rs   =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
 
-               else if (4 == cc)
-                       printf("jle      %#lx\n", ip);
+       if (V) {
+               int N = 1 << (3 + vlen - size);
 
-               else if (5 == cc)
-                       printf("jlt      %#lx\n", ip);
-               else {
-                       scf_loge("\n");
-                       return -EINVAL;
-               }
+               printf("vmov.f%dx%d  X%d, X%d\n", 1 << size, N, rd, rs);
+       } else
+               printf("fmov.%d      d%d, d%d\n", 1 << size, rd, rs);
+       return 0;
+}
 
-       } else {
-               int rd = (inst >> 21) & 0x1f;
+static int __naja_fcvt(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rs    =  inst        & 0xf;
+       int rd    = (inst >> 21) & 0xf;
+       int dsize = (inst >> 18) & 0x3;
+       int V     = (inst >> 17) & 0x1;
+       int Id    = (inst >> 13) & 0x1;
+       int sd    = (inst >> 12) & 0x1;
+       int vlen  = (inst >> 10) & 0x3;
+       int Is    = (inst >>  7) & 0x1;
+       int ss    = (inst >>  6) & 0x1;
+       int ssize = (inst >>  4) & 0x3;
+
+       static char IS_array[2][2] = {
+               'F', 'F',
+               'U', 'I'
+       };
 
-               printf("jmp      *r%d\n", rd);
+       static char R_array[2] = {'d', 'r'};
+
+       if (V) {
+               int N = 1 << (3 + vlen - dsize);
+
+               printf("vcvt%c%dto%c%dx%d  X%d, X%d\n",
+                               IS_array[Is][ss], 1 << ssize,
+                               IS_array[Id][sd], 1 << dsize,
+                               N, rd, rs);
+       } else {
+               printf("fcvt%c%dto%c%d      %c%d, %c%d\n",
+                               IS_array[Is][ss], 1 << ssize,
+                               IS_array[Id][sd], 1 << dsize,
+                               R_array[Id], rd, R_array[Is], rs);
        }
        return 0;
 }
 
-static int __naja_call_reg(scf_vm_t* vm, uint32_t inst)
+static int __naja_fneg(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rd = (inst >> 21) & 0x1f;
+       int rs   =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int V    = (inst >> 17) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
 
-       printf("call    r%d\n", rd);
+       if (V) {
+               int N = 1 << (3 + vlen - size);
 
+               printf("vneg.f%dx%d  X%d, X%d\n", 1 << size, N, rd, rs);
+       } else
+               printf("fneg.%d      d%d, d%d\n", 1 << size, rd, rs);
        return 0;
 }
 
-static int __naja_adrp(scf_vm_t* vm, uint32_t inst)
+static int __naja_vadd(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rd  = (inst >> 21) & 0x1f;
-       int s21 =  inst & 0x1fffff;
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int vlen = (inst >> 10) & 0x3;
 
-       if (s21  & 0x100000)
-               s21 |= ~0x1fffff;
-
-       printf("adrp     r%d, [rip, %d]\n", rd, s21);
+       int N = 1 << (3 + vlen - size);
 
+       printf("vadd.u%dx%d  X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
        return 0;
 }
 
-static int __naja_ret(scf_vm_t* vm, uint32_t inst)
+static int __naja_vsub(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       printf("ret\n");
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int cmp  = (inst >> 16) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
+
+       int N = 1 << (3 + vlen - size);
+
+       if (cmp)
+               printf("vcmp.u%dx%d  X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+       else
+               printf("vsub.u%dx%d  X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
        return 0;
 }
 
-static int __naja_setcc(scf_vm_t* vm, uint32_t inst)
+static int __naja_vmul(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rd = (inst >> 21) & 0x1f;
-       int cc = (inst >>  1) & 0xf;
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rs2  = (inst >> 12) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int s    = (inst >> 17) & 0x1;
+       int A    = (inst >> 16) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
 
-       if (SCF_VM_Z == cc)
-               printf("setz     r%d\n", rd);
+       int N = 1 << (3 + vlen - size);
 
-       else if (SCF_VM_NZ == cc)
-               printf("setnz    r%d\n", rd);
+       static char  s_array[2] = {'u',    'i'};
+       static char* A_array[2] = {"madd", "msub"};
 
-       else if (SCF_VM_GE == cc)
-               printf("setge    r%d\n", rd);
+       if (0xf == rs2)
+               printf("vmul.%c%dx%d  X%d, X%d, X%d\n", s_array[s], 1 << size, N, rd, rs0, rs1);
+       else
+               printf("v%s.%c%dx%d  X%d, X%d, X%d, X%d\n", A_array[A], s_array[s], 1 << size, N, rd, rs2, rs0, rs1);
+       return 0;
+}
 
-       else if (SCF_VM_GT == cc)
-               printf("setgt    r%d\n", rd);
+static int __naja_vdiv(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-       else if (SCF_VM_LT == cc)
-               printf("setlt    r%d\n", rd);
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int s    = (inst >> 17) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
 
-       else if (SCF_VM_LE == cc)
-               printf("setle    r%d\n", rd);
-       else {
-               scf_loge("inst: %#x\n", inst);
-               return -EINVAL;
-       }
+       int N = 1 << (3 + vlen - size);
 
+       if (s)
+               printf("vdiv.i%dx%d  X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+       else
+               printf("vdiv.u%dx%d  X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
        return 0;
 }
 
-static int __naja_mov(scf_vm_t* vm, uint32_t inst)
+static int __naja_vand(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s   = (inst >> 18) & 0x1;
-       int opt = (inst >> 16) & 0x3;
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int teq  = (inst >> 16) & 0x1;
+       int vlen = (inst >> 10) & 0x3;
 
-       if (0 == opt) {
-               int rs0 =  inst       & 0x1f;
-               int rs1 = (inst >> 5) & 0x1f;
+       int N = 1 << (3 + vlen - size);
 
-               if (0 == SH)
-                       printf("mov      r%d, r%d LSL r%d\n", rd, rs0, rs1);
-               else if (1 == SH)
-                       printf("mov      r%d, r%d LSR r%d\n", rd, rs0, rs1);
-               else
-                       printf("mov      r%d, r%d ASR r%d\n", rd, rs0, rs1);
+       if (teq)
+               printf("vteq.u%dx%d  X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+       else
+               printf("vand.u%dx%d  X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+       return 0;
+}
 
-       } else if (1 == opt) {
-               int rs0 =  inst       & 0x1f;
-               int u11 = (inst >> 5) & 0x7ff;
+static int __naja_vor(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-               if (0 == SH) {
-                       if (0 == u11)
-                               printf("mov      r%d, r%d\n", rd, rs0);
-                       else
-                               printf("mov      r%d, r%d LSL %d\n", rd, rs0, u11);
+       int rs0  =  inst        & 0xf;
+       int rs1  = (inst >>  4) & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int vlen = (inst >> 10) & 0x3;
 
-               } else if (1 == SH)
-                       printf("mov      r%d, r%d LSR %d\n", rd, rs0, u11);
-               else
-                       printf("mov      r%d, r%d ASR %d\n", rd, rs0, u11);
-
-       } else if (2 == opt) {
-               int rs = inst & 0x1f;
-
-               switch (SH) {
-                       case 0:
-                               if (s)
-                                       printf("movsb    r%d, r%d\n", rd, rs);
-                               else
-                                       printf("movzb    r%d, r%d\n", rd, rs);
-                               break;
-
-                       case 1:
-                               if (s)
-                                       printf("movsw    r%d, r%d\n", rd, rs);
-                               else
-                                       printf("movzw    r%d, r%d\n", rd, rs);
-                               break;
-
-                       case 2:
-                               if (s)
-                                       printf("movsl    r%d, r%d\n", rd, rs);
-                               else
-                                       printf("movzl    r%d, r%d\n", rd, rs);
-                               break;
-                       default:
-                               if (s)
-                                       printf("NEG      r%d, r%d\n", rd, rs);
-                               else
-                                       printf("NOT      r%d, r%d\n", rd, rs);
-                               break;
-               };
+       int N = 1 << (3 + vlen - size);
 
-       } else {
-               uint64_t u16 = inst & 0xffff;
+       printf("vor.u%dx%d   X%d, X%d, X%d\n", 1 << size, N, rd, rs0, rs1);
+       return 0;
+}
 
-               if (s)
-                       printf("mvn      r%d, %#lx\n", rd, u16);
-               else {
-                       if (0 == SH)
-                               printf("mov      r%d, %#lx\n", rd, u16);
-                       else
-                               printf("mov      r%d, %#lx << %d\n", rd, u16, 16 << SH);
-               }
-       }
+static int __naja_vmov(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rs    =  inst        & 0xf;
+       int rs1   = (inst >>  4) & 0xf;
+       int rd    = (inst >> 21) & 0xf;
+       int size  = (inst >> 18) & 0x3;
+       int SH    = (inst >> 16) & 0x3;
+       int IMM   = (inst >> 15) & 0x3;
+       int vlen  = (inst >> 10) & 0x3;
+       int uimm6 = (inst >>  4) & 0x3f;
 
+       int N = 1 << (3 + vlen - size);
+
+       if (IMM) {
+               if (0 == uimm6)
+                       printf("vmov.u%dx%d   X%d, X%d\n", 1 << size, N, rd, rs);
+               else
+                       printf("vmov.u%dx%d   X%d, X%d %s %d\n", 1 << size, N, rd, rs, __naja_SH[SH], uimm6);
+       } else
+               printf("vmov.u%dx%d   X%d, X%d %s %s\n", 1 << size, N, rd, rs, __naja_SH[SH], __naja_reg[rs1]);
        return 0;
 }
 
-static int __naja_fadd(scf_vm_t* vm, uint32_t inst)
+static int __naja_vnot(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rs1 = (inst >>  5) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
+       int rs   =  inst        & 0xf;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int A    = (inst >> 16) & 0x3;
+       int vlen = (inst >> 10) & 0x3;
+
+       int N = 1 << (3 + vlen - size);
 
-       printf("fadd   r%d, r%d, r%d\n", rd, rs0, rs1);
+       if (A)
+               printf("vnot.u%dx%d   X%d, X%d\n", 1 << size, N, rd, rs);
+       else
+               printf("vneg.u%dx%d   X%d, X%d\n", 1 << size, N, rd, rs);
        return 0;
 }
 
-static int __naja_fsub(scf_vm_t* vm, uint32_t inst)
+static int __naja_vmov_imm(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rs1 = (inst >>  5) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
+       int u16  =  inst        & 0xffff;
+       int rd   = (inst >> 21) & 0xf;
+       int size = (inst >> 18) & 0x3;
+       int vlen = (inst >> 16) & 0x3;
+       int mvn  = (inst >> 25) & 0x1;
 
-       if (31 == rd)
-               printf("fcmp   d%d, d%d\n", rs0, rs1);
-       else
-               printf("fsub   r%d, r%d, r%d\n", rd, rs0, rs1);
+       int N = 1 << (3 + vlen - size);
 
+       if (mvn)
+               printf("vmvn.u%dx%d   X%d, %#x\n", 1 << size, N, rd, u16);
+       else
+               printf("vmov.u%dx%d   X%d, %#x\n", 1 << size, N, rd, u16);
        return 0;
 }
 
-static int __naja_fmul(scf_vm_t* vm, uint32_t inst)
+static int __naja_jmp_disp(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rs1 = (inst >>  5) & 0x1f;
-       int rs2 = (inst >> 10) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int opt = (inst >> 18) & 0x3;
+       int simm26 = inst & 0x3ffffff;
 
-       if (0 == opt)
-               printf("fmadd   d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1);
-       else if (1 == opt)
-               printf("fmsub   d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1);
-       else
-               printf("fmul    d%d, d%d, d%d", rd, rs0, rs1);
+       if (simm26  & 0x2000000)
+               simm26 |= 0xfc000000;
 
+       uint64_t ip = naja->ip + (simm26 << 2);
+       printf("jmp    %#lx\n", ip);
        return 0;
 }
 
-static int __naja_fdiv(scf_vm_t* vm, uint32_t inst)
+static int __naja_call_disp(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs0 =  inst        & 0x1f;
-       int rs1 = (inst >>  5) & 0x1f;
-       int rs2 = (inst >> 10) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int opt = (inst >> 18) & 0x3;
+       int simm26 = inst & 0x3ffffff;
 
-       if (0 == opt)
-               printf("fdadd   d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1);
-       else if (1 == opt)
-               printf("fdsub   d%d, d%d, d%d, d%d", rd, rs2, rs0, rs1);
-       else
-               printf("fdiv    d%d, d%d, d%d", rd, rs0, rs1);
+       if (simm26  & 0x2000000)
+               simm26 |= 0xfc000000;
 
+       uint64_t ip = naja->ip + (simm26 << 2);
+       printf("call     %#lx\n", ip);
        return 0;
 }
 
-static int __naja_fstr_disp(scf_vm_t* vm, uint32_t inst)
+static int __naja_jmp_reg(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s13 = (inst >>  5) & 0x1fff;
+       if (inst & 0x1) {
+               int cc  = (inst >> 1) & 0xf;
+               int s21 = (inst >> 5) & 0x1fffff;
+
+               if (s21  & 0x100000)
+                       s21 |= 0xffe00000;
 
-       if (s13  & 0x1000)
-               s13 |= 0xffffe000;
+               s21 <<= 2;
 
-       switch (SH) {
-               case 2:
-                       printf("fstr     f%d, [r%d, %d]\n", rd, rb, s13 << 2);
-                       break;
+               uint64_t ip = naja->ip + s21;
 
-               case 3:
-                       printf("fstr     d%d, [r%d, %d]\n", rd, rb, s13 << 3);
-                       break;
-               default:
-                       scf_loge("SH: %d\n", SH);
-                       return -1;
-                       break;
-       };
+               if (0 == cc)
+                       printf("jz       %#lx\n", ip);
+
+               else if (1 == cc)
+                       printf("jnz      %#lx\n", ip);
+
+               else if (2 == cc)
+                       printf("jge      %#lx\n", ip);
+
+               else if (3 == cc)
+                       printf("jgt      %#lx\n", ip);
+
+               else if (4 == cc)
+                       printf("jle      %#lx\n", ip);
+
+               else if (5 == cc)
+                       printf("jlt      %#lx\n", ip);
+               else {
+                       scf_loge("\n");
+                       return -EINVAL;
+               }
+       } else {
+               int rd = (inst >> 21) & 0xf;
 
+               printf("jmp      *%s\n", __naja_reg[rd]);
+       }
        return 0;
 }
 
-static int __naja_fpush(scf_vm_t* vm, uint32_t inst)
+static int __naja_call_reg(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
+       int rd = (inst >> 21) & 0xf;
 
-       switch (SH) {
-               case 2:
-                       printf("fpush    f%d, [r%d]\n", rd, rb);
-                       break;
-
-               case 3:
-                       printf("fpush    d%d, [r%d]\n", rd, rb);
-                       break;
-               default:
-                       scf_loge("SH: %d\n", SH);
-                       return -1;
-                       break;
-       };
+       printf("call     *%s\n", __naja_reg[rd]);
 
        return 0;
 }
 
-static int __naja_fldr_disp(scf_vm_t* vm, uint32_t inst)
+static int __naja_setcc(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s13 = (inst >>  5) & 0x1fff;
+       int rd = (inst >> 21) & 0xf;
+       int cc = (inst >>  1) & 0xf;
 
-       if (s13  & 0x1000)
-               s13 |= 0xffffe000;
+       if (SCF_VM_Z == cc)
+               printf("setz     %s\n", __naja_reg[rd]);
 
-       switch (SH) {
-               case 2:
-                       printf("fldr     f%d, [r%d, %d]\n", rd, rb, s13 << 2);
-                       break;
+       else if (SCF_VM_NZ == cc)
+               printf("setnz    %s\n", __naja_reg[rd]);
 
-               case 3:
-                       printf("fldr     d%d, [r%d, %d]\n", rd, rb, s13 << 3);
-                       break;
-               default:
-                       scf_loge("SH: %d\n", SH);
-                       return -1;
-                       break;
-       };
+       else if (SCF_VM_GE == cc)
+               printf("setge    %s\n", __naja_reg[rd]);
+
+       else if (SCF_VM_GT == cc)
+               printf("setgt    %s\n", __naja_reg[rd]);
+
+       else if (SCF_VM_LT == cc)
+               printf("setlt    %s\n", __naja_reg[rd]);
+
+       else if (SCF_VM_LE == cc)
+               printf("setle    %s\n", __naja_reg[rd]);
+       else {
+               scf_loge("inst: %#x\n", inst);
+               return -EINVAL;
+       }
 
        return 0;
 }
 
-static int __naja_fpop(scf_vm_t* vm, uint32_t inst)
+static int __naja_adrp(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
+       int rd  = (inst >> 21) & 0xf;
+       int s21 =  inst & 0x1fffff;
 
-       switch (SH) {
-               case 2:
-                       printf("fldr    f%d, [r%d]\n", rd, rb);
-                       break;
-               case 3:
-                       printf("fldr    d%d, [r%d]\n", rd, rb);
-                       break;
-               default:
-                       scf_loge("SH: %d\n", SH);
-                       return -1;
-                       break;
-       };
+       if (s21  & 0x100000)
+               s21 |= ~0x1fffff;
 
+       printf("adrp     %s, [rip, %d]\n", __naja_reg[rd], s21);
        return 0;
 }
 
-static int __naja_fldr_sib(scf_vm_t* vm, uint32_t inst)
+static int __naja_ret(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int ri  = (inst >>  5) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int u8  = (inst >> 10) & 0xff;
+       printf("ret\n");
+       return 0;
+}
 
-       switch (SH) {
-               case 2:
-                       printf("fldr  f%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-                       break;
-               case 3:
-                       printf("fldr  d%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-                       break;
-               default:
-                       scf_loge("\n");
-                       return -1;
-                       break;
-       };
+static int __naja_spop(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       int rb =  inst        & 0xf;
+       int sr = (inst >> 21) & 0xf;
 
+       printf("spop     sr%d, [%s]\n", sr, __naja_reg[rb]);
        return 0;
 }
 
-static int __naja_fstr_sib(scf_vm_t* vm, uint32_t inst)
+static int __naja_spush(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rb  =  inst        & 0x1f;
-       int ri  = (inst >>  5) & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int u8  = (inst >> 10) & 0xff;
-
-       switch (SH) {
-               case 2:
-                       printf("fstr  f%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-                       break;
-               case 3:
-                       printf("fstr  d%d, [r%d, r%d, %d]\n", rd, rb, ri, u8);
-                       break;
-               default:
-                       scf_loge("\n");
-                       return -1;
-                       break;
-       };
+       int rb =  inst        & 0xf;
+       int sr = (inst >> 21) & 0xf;
 
+       printf("spush    sr%d, [%s]\n", sr, __naja_reg[rb]);
        return 0;
 }
 
-static int __naja_fmov(scf_vm_t* vm, uint32_t inst)
+static int __naja_in(scf_vm_t* vm, uint32_t inst)
 {
        scf_vm_naja_t* naja = vm->priv;
 
-       int rs  =  inst & 0x1f;
-       int rd  = (inst >> 21) & 0x1f;
-       int SH  = (inst >> 19) & 0x3;
-       int s   = (inst >> 18) & 0x1;
-       int opt = (inst >> 16) & 0x3;
-
-       if (0 == opt) {
-               if (2 == SH)
-                       printf("fss2sd   d%d, f%d\n", rd, rs);
-               else if (3 == SH)
-                       printf("fsd2ss   f%d, d%d\n", rd, rs);
-               else {
-                       scf_loge("\n");
-                       return -EINVAL;
-               }
+       int u16 =  inst        & 0xffff;
+       int rd  = (inst >> 21) & 0xf;
+       int D   = (inst >> 17) & 0xf;
 
-       } else if (1 == opt) {
-               if (s)
-                       printf("cvtss2si r%d, f%d\n", rd, rs);
-               else
-                       printf("cvtss2ui r%d, f%d\n", rd, rs);
+       if (D)
+               printf("out      %s, %#x\n", __naja_reg[rd], u16);
+       else
+               printf("in       %s, %#x\n", __naja_reg[rd], u16);
+       return 0;
+}
 
-       } else if (2 == opt) {
-               printf("cvtsi2ss f%d, r%d\n", rd, rs);
+static int __naja_smov(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
 
-       } else {
-               if (s)
-                       printf("fneg     d%d, d%d\n", rd, rs);
-               else
-                       printf("fmov     d%d, d%d\n", rd, rs);
-       }
+       int sr =  inst        & 0xf;
+       int rd = (inst >> 21) & 0xf;
+       int D  = (inst >> 17) & 0xf;
 
+       if (D)
+               printf("smov     sr%d, %s\n", sr, __naja_reg[rd]);
+       else
+               printf("smov     %s, sr%d\n", __naja_reg[rd], sr);
        return 0;
 }
 
+static int __naja_iret(scf_vm_t* vm, uint32_t inst)
+{
+       scf_vm_naja_t* naja = vm->priv;
+
+       printf("iret\n");
+       return 0;
+}
 
 static naja_opcode_pt  naja_opcodes[64] =
 {
@@ -924,19 +960,20 @@ static naja_opcode_pt  naja_opcodes[64] =
        __naja_div,      // 3
 
        __naja_ldr_disp, // 4
-       __naja_pop,      // 5
+       __naja_and,      // 5
 
        __naja_str_disp, // 6
-       __naja_push,     // 7
+       __naja_or,       // 7
+
+       __naja_pop,      // 8
+       __naja_push,     // 9
 
-       __naja_and,      // 8
-       __naja_or,       // 9
-       __naja_jmp_disp, // 10
-       __naja_jmp_reg,  // 11
-       __naja_setcc,    // 12
-       __naja_ldr_sib,  // 13
-       __naja_str_sib,  // 14
-       __naja_mov,      // 15
+       __naja_ldr_sib,  // 10
+       __naja_str_sib,  // 11
+       __naja_mov,      // 12
+       __naja_movx,     // 13
+       __naja_not,      // 14
+       NULL,            // 15
 
        __naja_fadd,     // 16
        __naja_fsub,     // 17
@@ -944,52 +981,52 @@ static naja_opcode_pt  naja_opcodes[64] =
        __naja_fdiv,     // 19
 
        __naja_fldr_disp,// 20
-       __naja_fpop,     // 21
+       NULL,            // 21
 
        __naja_fstr_disp,// 22
-       __naja_fpush,    // 23
+       NULL,            // 23
 
        NULL,            // 24
        NULL,            // 25
-       __naja_call_disp,// 26
-       __naja_call_reg, // 27
-       NULL,            // 28
-       __naja_fldr_sib, // 29
-       __naja_fstr_sib, // 30
-       __naja_fmov,     // 31
-
-       NULL,            // 32
-       NULL,            // 33
-       NULL,            // 34
-       NULL,            // 35
+       __naja_fldr_sib, // 26
+       NULL,            // 27
+       __naja_fmov,     // 28
+       __naja_fcvt,     // 29
+       __naja_fneg,     // 30
+       NULL,            // 31
+
+       __naja_vadd,     // 32
+       __naja_vsub,     // 33
+       __naja_vmul,     // 34
+       __naja_vdiv,     // 35
        NULL,            // 36
-       NULL,            // 37
+       __naja_vand,     // 37
        NULL,            // 38
-       NULL,            // 39
+       __naja_vor,      // 39
        NULL,            // 40
        NULL,            // 41
-       __naja_adrp,     // 42
+       NULL,            // 42
        NULL,            // 43
-       NULL,            // 44
+       __naja_vmov,     // 44
        NULL,            // 45
-       NULL,            // 46
-       NULL,            // 47
-
-       NULL,            // 48
-       NULL,            // 49
-       NULL,            // 50
-       NULL,            // 51
-       NULL,            // 52
-       NULL,            // 53
-       NULL,            // 54
+       __naja_vnot,     // 46
+       __naja_vmov_imm, // 47
+
+       __naja_jmp_disp, // 48
+       __naja_call_disp,// 49
+       __naja_jmp_reg,  // 50
+       __naja_call_reg, // 51
+       __naja_setcc,    // 52
+       __naja_adrp,     // 53
+       __naja_ret,      // 54
        NULL,            // 55
-       __naja_ret,      // 56
-       NULL,            // 57
-       NULL,            // 58
+       __naja_spop,     // 56
+       __naja_spush,    // 57
+       __naja_in,       // 58
        NULL,            // 59
-       NULL,            // 60
+       __naja_smov,     // 60
        NULL,            // 61
-       NULL,            // 62
+       __naja_iret,     // 62
        NULL,            // 63
 };