asm: support simple asm code for x64 & naja
authoryu.dongliang <18588496441@163.com>
Wed, 21 Jan 2026 13:50:59 +0000 (21:50 +0800)
committeryu.dongliang <18588496441@163.com>
Wed, 21 Jan 2026 13:50:59 +0000 (21:50 +0800)
32 files changed:
asm/1.s
asm/Makefile
asm/main.c
asm/naja.s [new file with mode: 0644]
asm/scf_asm.c
asm/scf_asm.h
asm/scf_dfa_asm.c
asm/scf_dfa_naja.c [new file with mode: 0644]
asm/scf_dfa_x64.c [moved from asm/scf_dfa_inst.c with 77% similarity]
asm/shellcode.s [new file with mode: 0644]
elf/scf_elf.h
elf/scf_elf_arm32.c
elf/scf_elf_arm64.c
elf/scf_elf_naja.c
elf/scf_elf_x64.c
native/risc/scf_naja.c
native/risc/scf_naja_inst.c [new file with mode: 0644]
native/risc/scf_naja_reg.c [new file with mode: 0644]
native/risc/scf_risc.c
native/risc/scf_risc.h
native/risc/scf_risc_inst.c
native/risc/scf_risc_opcode.c
native/risc/scf_risc_opcode.h
native/risc/scf_risc_reg_naja.c
native/risc/scf_risc_util.h
native/scf_instruction.c
native/scf_instruction.h
native/x64/scf_x64_opcode.c
parse/scf_dfa_util.h
vm/scf_vm.h
vm/scf_vm_naja.c
vm/scf_vm_naja_asm.c

diff --git a/asm/1.s b/asm/1.s
index ab14439c3084e4d957db571e00ccd594d65ab15d..5f5edb81b3be68e31cb36d02a83300e9d9ddcb80 100644 (file)
--- a/asm/1.s
+++ b/asm/1.s
@@ -3,12 +3,13 @@
 
 main:
        push %rbp
-       movq pointer, %rdi
+       jmp 1f
+0:
+       pop  %rdi
        xorq %rax, %rax
        call printf
        pop  %rbp
        ret
-
-.data
-pointer: .quad hello
-hello: .asciz "hello world\n"
+1:
+       call 0b
+.asciz "hello world\n"
index 4610bf5fe8a966edb44b4e52e18ed8ed689af828..c6849f727c6249f9d68136259b804201ee44a3c0 100644 (file)
@@ -5,7 +5,8 @@ CFILES += ../lex/scf_lex_util.c
 CFILES += main.c
 CFILES += scf_asm.c
 CFILES += scf_dfa_asm.c
-CFILES += scf_dfa_inst.c
+CFILES += scf_dfa_x64.c
+CFILES += scf_dfa_naja.c
 
 CFILES += ../core/scf_lex_word.c
 CFILES += ../parse/scf_dfa.c
@@ -15,6 +16,7 @@ CFILES += ../native/scf_instruction.c
 CFILES += ../native/x64/scf_x64_opcode.c
 CFILES += ../native/x64/scf_x64_reg_util.c
 CFILES += ../native/x64/scf_x64_inst_util.c
+CFILES += ../native/risc/scf_risc_opcode.c
 
 CFILES += ../elf/scf_elf.c
 CFILES += ../elf/scf_elf_link.c
index bf01a06f872fc86a624968f0aa1b943b9ac12bf8..7036c12150026556bbbf138237f941e64d313c59 100644 (file)
@@ -90,7 +90,7 @@ int main(int argc, char* argv[])
 
        scf_asm_t*  _asm = NULL;
 
-       if (scf_asm_open(&_asm) < 0) {
+       if (scf_asm_open(&_asm, arch) < 0) {
                scf_loge("\n");
                return -1;
        }
diff --git a/asm/naja.s b/asm/naja.s
new file mode 100644 (file)
index 0000000..2aed373
--- /dev/null
@@ -0,0 +1,15 @@
+.text
+.global main, printf
+
+main:
+       push  lr
+       jmp   1f
+0:
+       movq  r0, lr
+       call  printf
+       mov   r0, 0
+       pop   lr
+       ret
+1:
+       call 0b
+       .asciz "hello world\n"
index 2cc9756fb601f7fb32997848f271890d7fd35057..46046bc7d676ff13a3c4fcecaf680d2eb02fddce 100644 (file)
@@ -2,8 +2,9 @@
 #include"scf_symtab.h"
 
 void _x64_set_offset_for_jmps(scf_vector_t* text);
+int _naja_set_offset_for_jmps(scf_vector_t* text);
 
-int    scf_asm_open(scf_asm_t** pasm)
+int scf_asm_open(scf_asm_t** pasm, const char* arch)
 {
        if (!pasm)
                return -EINVAL;
@@ -40,7 +41,7 @@ int   scf_asm_open(scf_asm_t** pasm)
        if (!_asm->symtab)
                goto symtab_error;
 
-       if (scf_asm_dfa_init(_asm) < 0) {
+       if (scf_asm_dfa_init(_asm, arch) < 0) {
                scf_loge("\n");
                goto dfa_error;
        }
@@ -150,12 +151,24 @@ static int __asm_add_text(scf_elf_context_t* elf, scf_asm_t* _asm)
        int ret;
        int i;
 
+       switch (elf->ops->arch)
+       {
+               case SCF_ELF_X64:
+                       _x64_set_offset_for_jmps(_asm->text);
+                       break;
+
+               case SCF_ELF_NAJA:
+                       _naja_set_offset_for_jmps(_asm->text);
+                       break;
+               default:
+                       scf_loge("%s NOT support\n", elf->ops->machine);
+                       break;
+       };
+
        text = scf_string_alloc();
        if (!text)
                return -ENOMEM;
 
-       _x64_set_offset_for_jmps(_asm->text);
-
        for (i = 0; i < _asm->text->size; i++) {
                inst      = _asm->text->data[i];
 
@@ -175,6 +188,16 @@ static int __asm_add_text(scf_elf_context_t* elf, scf_asm_t* _asm)
                }
        }
 
+       if (text->len & 0x7) {
+               size_t n = 8 - (text->len & 0x7);
+
+               ret = scf_string_fill_zero(text, n);
+               if (ret < 0) {
+                       scf_string_free(text);
+                       return ret;
+               }
+       }
+
        int end  = text->len;
        for (i   = _asm->text->size - 1; i >= 0; i--) {
                inst = _asm->text->data[i];
index dffcf9a09639ef437bc34847a92c8f1e45b1c64d..9cfeca17d9be3ee5650c87679e002d39131fafc0 100644 (file)
@@ -36,9 +36,8 @@ struct scf_asm_s
        scf_dwarf_t*       debug;
 };
 
-struct dfa_asm_s {
-       void**             module_datas;
-
+struct dfa_asm_s
+{
        scf_lex_word_t*    label;
        scf_lex_word_t*    global;
        scf_lex_word_t*    fill;
@@ -54,9 +53,9 @@ struct dfa_asm_s {
        int                n_rp;
 };
 
-int scf_asm_dfa_init(scf_asm_t*  _asm);
+int scf_asm_dfa_init(scf_asm_t* _asm, const char* arch);
 
-int scf_asm_open  (scf_asm_t** pasm);
+int scf_asm_open  (scf_asm_t** pasm, const char* arch);
 int scf_asm_close (scf_asm_t*  _asm);
 
 int scf_asm_file  (scf_asm_t*  _asm, const char* path);
index 5519325fadb7dfb764acab90f6d55574ac928f14..37e0a548b3ea61efdc6156aa18652f8400b260d6 100644 (file)
@@ -1,11 +1,13 @@
 #include"scf_asm.h"
 #include"scf_lex_word.h"
 
-extern scf_dfa_module_t  dfa_module_inst;
+extern scf_dfa_module_t  dfa_module_x64;
+extern scf_dfa_module_t  dfa_module_naja;
 
 static scf_dfa_module_t* asm_dfa_modules[] =
 {
-       &dfa_module_inst,
+       &dfa_module_x64,
+       &dfa_module_naja,
 };
 
 static void* dfa_pop_word(scf_dfa_t* dfa)
@@ -41,14 +43,14 @@ scf_dfa_ops_t dfa_ops_asm =
        .free_word = dfa_free_word,
 };
 
-int scf_asm_dfa_init(scf_asm_t* _asm)
+int scf_asm_dfa_init(scf_asm_t* _asm, const char* arch)
 {
        if (scf_dfa_open(&_asm->dfa, &dfa_ops_asm, _asm) < 0) {
                scf_loge("\n");
                return -1;
        }
 
-       int nb_modules  = sizeof(asm_dfa_modules) / sizeof(asm_dfa_modules[0]);
+       int nb_modules = sizeof(asm_dfa_modules) / sizeof(asm_dfa_modules[0]);
 
        _asm->dfa_data = calloc(1, sizeof(dfa_asm_t));
        if (!_asm->dfa_data) {
@@ -56,43 +58,29 @@ int scf_asm_dfa_init(scf_asm_t* _asm)
                return -1;
        }
 
-       _asm->dfa_data->module_datas = calloc(nb_modules, sizeof(void*));
-       if (!_asm->dfa_data->module_datas) {
-               scf_loge("\n");
-               return -1;
-       }
-
        int i;
        for (i = 0; i < nb_modules; i++) {
 
                scf_dfa_module_t* m = asm_dfa_modules[i];
-
                if (!m)
                        continue;
-
                m->index = i;
 
-               if (!m->init_module)
-                       continue;
-
-               if (m->init_module(_asm->dfa) < 0) {
-                       scf_loge("init module: %s\n", m->name);
-                       return -1;
-               }
-       }
-
-       for (i = 0; i < nb_modules; i++) {
+               if (!strcmp(m->name, arch))
+               {
+                       if (m->init_module && m->init_module(_asm->dfa) < 0) {
+                               scf_loge("init module: %s\n", m->name);
+                               return -1;
+                       }
 
-               scf_dfa_module_t* m = asm_dfa_modules[i];
-
-               if (!m || !m->init_syntax)
-                       continue;
+                       if (m->init_syntax && m->init_syntax(_asm->dfa) < 0) {
+                               scf_loge("init syntax: %s\n", m->name);
+                               return -1;
+                       }
 
-               if (m->init_syntax(_asm->dfa) < 0) {
-                       scf_loge("init syntax: %s\n", m->name);
-                       return -1;
+                       return 0;
                }
        }
 
-       return 0;
+       return -1;
 }
diff --git a/asm/scf_dfa_naja.c b/asm/scf_dfa_naja.c
new file mode 100644 (file)
index 0000000..3bb2633
--- /dev/null
@@ -0,0 +1,1053 @@
+#include"scf_dfa.h"
+#include"scf_dfa_util.h"
+#include"scf_asm.h"
+#include"scf_risc_opcode.h"
+#include"scf_naja_reg.c"
+#include"scf_naja_inst.c"
+
+extern scf_dfa_module_t  dfa_module_naja;
+
+
+static int _naja_is_opcode(scf_dfa_t* dfa, void* word)
+{
+       scf_lex_word_t* w = word;
+
+       return !!risc_find_OpCode_by_name(w->text->data);
+}
+
+static int _naja_is_reg(scf_dfa_t* dfa, void* word)
+{
+       scf_lex_word_t* w = word;
+
+       return !!naja_find_register(w->text->data);
+}
+
+static int _naja_action_text(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_asm_t*      _asm = dfa->priv;
+       dfa_asm_t*       d   = data;
+       scf_lex_word_t*  w   = words->data[words->size - 1];
+
+       _asm->current = _asm->text;
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _naja_action_data(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_asm_t*      _asm = dfa->priv;
+       dfa_asm_t*       d   = data;
+       scf_lex_word_t*  w   = words->data[words->size - 1];
+
+       _asm->current = _asm->data;
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _naja_action_global(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_asm_t*      _asm = dfa->priv;
+       dfa_asm_t*       d   = data;
+       scf_lex_word_t*  w   = words->data[words->size - 1];
+
+       d->global = w;
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _naja_action_fill(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_asm_t*      _asm = dfa->priv;
+       dfa_asm_t*       d   = data;
+       scf_lex_word_t*  w   = words->data[words->size - 1];
+
+       d->fill = w;
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _naja_action_type(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_asm_t*      _asm = dfa->priv;
+       dfa_asm_t*       d   = data;
+       scf_lex_word_t*  w   = words->data[words->size - 1];
+
+       d->type = w->type;
+
+       scf_logi("w: '%s'\n", w->text->data);
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _naja_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_asm_t*         _asm = dfa->priv;
+       dfa_asm_t*          d   = data;
+       scf_lex_word_t*     w   = words->data[words->size - 1];
+       scf_lex_word_t*     w2;
+       scf_instruction_t*  inst;
+
+       w2 = dfa->ops->pop_word(dfa);
+       dfa->ops->push_word(dfa, w2);
+
+       if (d->opcode) {
+               switch (w2->type) {
+                       case SCF_LEX_WORD_LP:
+                               d->operands[d->i].disp = w->data.u64;
+                               d->operands[d->i].flag = 1;
+                               break;
+
+                       case SCF_LEX_WORD_RP:
+                               d->operands[d->i].scale = w->data.i;
+                               d->operands[d->i].flag  = 1;
+                               break;
+
+                       case SCF_LEX_WORD_ID:
+                       case SCF_LEX_WORD_COMMA:
+                       case SCF_LEX_WORD_LF:
+                               if (d->n_lp != d->n_rp) {
+                                       scf_loge("'(' not equal to ')' in file: %s, line: %d\n", w->file->data, w->line);
+                                       return SCF_DFA_ERROR;
+                               }
+
+                               d->operands[d->i].imm      = w->data.u64;
+                               d->operands[d->i].imm_size = 8;
+                               d->operands[d->i].flag     = 0;
+
+                               if (SCF_RISC_CALL == d->opcode->type
+                                               || (SCF_RISC_JZ <= d->opcode->type && SCF_RISC_JMP >= d->opcode->type)) {
+                                       int flag = 0x1;
+
+                                       if (SCF_LEX_WORD_ID == w2->type) {
+                                               switch (w2->text->data[0]) {
+                                                       case 'b':
+                                                               break;
+                                                       case 'f':
+                                                               flag = 0x2;
+                                                               break;
+                                                       default:
+                                                               scf_loge("the char followed a number label MUST be 'b' or 'f', but real '%c' in file: %s, line: %d\n",
+                                                                               w2->text->data[0], w->file->data, w->line);
+                                                               return SCF_DFA_ERROR;
+                                                               break;
+                                               };
+
+                                               w2 = dfa->ops->pop_word(dfa);
+                                               dfa->ops->free_word(w2);
+                                               w2 = NULL;
+                                       }
+
+                                       d->operands[d->i].imm <<= 8;
+                                       d->operands[d->i].imm  |= flag;
+                               }
+
+                               d->i++;
+                               break;
+                       default:
+                               scf_loge("number '%s', w2: %s, file: %s, line: %d\n", w->text->data, w2->text->data, w->file->data, w->line);
+                               return -1;
+                               break;
+               };
+
+       } else if (d->fill) {
+               switch (w2->type) {
+                       case SCF_LEX_WORD_COMMA:
+                       case SCF_LEX_WORD_LF:
+                               if (d->n_lp != d->n_rp) {
+                                       scf_loge("'(' not equal to ')' in file: %s, line: %d\n", w->file->data, w->line);
+                                       return SCF_DFA_ERROR;
+                               }
+
+                               d->operands[d->i].imm  = w->data.u64;
+                               d->operands[d->i].flag = 0;
+                               d->i++;
+                               break;
+                       default:
+                               scf_loge("number '%s', w2: %s, file: %s, line: %d\n", w->text->data, w2->text->data, w->file->data, w->line);
+                               return -1;
+                               break;
+               };
+
+       } else if (SCF_LEX_WORD_LF == w2->type || SCF_LEX_WORD_COMMA == w2->type) {
+               int n;
+               switch (d->type) {
+                       case SCF_LEX_WORD_ASM_BYTE:
+                               n = 1;
+                               break;
+                       case SCF_LEX_WORD_ASM_WORD:
+                               n = 2;
+                               break;
+
+                       case SCF_LEX_WORD_ASM_LONG:
+                               n = 4;
+                               break;
+                       case SCF_LEX_WORD_ASM_QUAD:
+                               n = 8;
+                               break;
+                       default:
+                               scf_loge("const number '%s' MUST be '.byte', '.word', '.long' or '.quad' type, file: %s, line: %d\n",
+                                               w->text->data, w->file->data, w->line);
+                               return -1;
+                               break;
+               };
+
+               inst = calloc(1, sizeof(scf_instruction_t));
+               if (!inst)
+                       return -ENOMEM;
+
+               memcpy(inst->code, (uint8_t*)&w->data, n);
+               inst->len = n;
+
+               RISC_INST_ADD_CHECK(_asm->current, inst);
+               if (d->label) {
+                       inst->label = d->label;
+                       d   ->label = NULL;
+               }
+       }
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _naja_action_str(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_asm_t*         _asm = dfa->priv;
+       dfa_asm_t*          d   = data;
+       scf_lex_word_t*     w   = words->data[words->size - 1];
+       scf_instruction_t*  inst;
+
+       inst = calloc(1, sizeof(scf_instruction_t));
+       if (!inst)
+               return -ENOMEM;
+
+       int n;
+       switch (d->type) {
+               case SCF_LEX_WORD_ASM_ASCIZ:
+                       n = w->data.s->len + 1;
+                       break;
+
+               case SCF_LEX_WORD_ASM_ASCII:
+                       n = w->data.s->len;
+                       break;
+               default:
+                       scf_loge("const string '%s' MUST be '.asciz' or '.ascii' type, file: %s, line: %d\n",
+                                       w->text->data, w->file->data, w->line);
+
+                       scf_instruction_free(inst);
+                       return -1;
+                       break;
+       };
+
+       if (n <= sizeof(inst->code)) {
+               memcpy(inst->code, w->data.s->data, n);
+               inst->len = n;
+       } else {
+               inst->bin = scf_string_cstr_len(w->data.s->data, n);
+               if (!inst->bin) {
+                       scf_instruction_free(inst);
+                       return -ENOMEM;
+               }
+       }
+
+       RISC_INST_ADD_CHECK(_asm->current, inst);
+       if (d->label) {
+               inst->label = d->label;
+               d   ->label = NULL;
+       }
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _naja_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_asm_t*      _asm = dfa->priv;
+       dfa_asm_t*       d   = data;
+       scf_lex_word_t*  w   = words->data[words->size - 1];
+       scf_lex_word_t*  w2;
+
+       if (d->opcode) {
+               d->operands[d->i].label = w;
+               d->operands[d->i].flag  = 1;
+
+               w = dfa->ops->pop_word(dfa);
+               dfa->ops->push_word(dfa, w);
+
+               if (SCF_LEX_WORD_LF == w->type || SCF_LEX_WORD_COMMA == w->type) {
+                       if (d->n_lp != d->n_rp) {
+                               scf_loge("'(' not equal to ')' in file: %s, line: %d\n", w->file->data, w->line);
+                               return SCF_DFA_ERROR;
+                       }
+
+                       d->i++;
+               }
+
+       } else if (d->global) {
+               if (scf_vector_find_cmp(_asm->global, w, __lex_word_cmp))
+                       return SCF_DFA_NEXT_WORD;
+
+               w2 = scf_lex_word_clone(w);
+               if (!w2)
+                       return SCF_DFA_ERROR;
+
+               int ret = scf_vector_add(_asm->global, w2);
+               if (ret < 0) {
+                       scf_lex_word_free(w2);
+                       return ret;
+               }
+
+       } else {
+               w2 = dfa->ops->pop_word(dfa);
+               dfa->ops->push_word(dfa, w2);
+
+               if (SCF_LEX_WORD_LF == w2->type || SCF_LEX_WORD_COMMA == w2->type) {
+
+                       if (SCF_LEX_WORD_ASM_QUAD != d->type) {
+                               scf_loge("the type of label '%s' MUST be .quad, file: %s, line: %d\n",
+                                               w->text->data, w->file->data, w->line);
+                               return -1;
+                       }
+
+                       scf_instruction_t* inst = calloc(1, sizeof(scf_instruction_t));
+                       if (!inst)
+                               return -ENOMEM;
+                       inst->len = 8;
+                       RISC_INST_ADD_CHECK(_asm->current, inst);
+
+                       if (d->label) {
+                               inst->label = d->label;
+                               d   ->label = NULL;
+                       }
+
+                       scf_rela_t* rela = calloc(1, sizeof(scf_rela_t));
+                       if (!rela)
+                               return -ENOMEM;
+
+                       rela->name = scf_string_clone(w->text);
+                       if (!rela->name) {
+                               scf_rela_free(rela);
+                               return -ENOMEM;
+                       }
+
+                       rela->inst = inst;
+                       rela->type = R_X86_64_64;
+
+                       int ret;
+                       if (_asm->current == _asm->text)
+                               ret = scf_vector_add(_asm->text_relas, rela);
+                       else
+                               ret = scf_vector_add(_asm->data_relas, rela);
+
+                       if (ret < 0) {
+                               scf_rela_free(rela);
+                               return ret;
+                       }
+               }
+       }
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _naja_action_opcode(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_asm_t*      _asm = dfa->priv;
+       dfa_asm_t*       d   = data;
+       scf_lex_word_t*  w   = words->data[words->size - 1];
+
+       d->opcode = (scf_OpCode_t*)risc_find_OpCode_by_name(w->text->data);
+       if (!d->opcode) {
+               scf_loge("opcode '%s' NOT found\n", w->text->data);
+               return SCF_DFA_ERROR;
+       }
+
+       d->i       = 0;
+       d->n_comma = 0;
+       d->n_lp    = 0;
+       d->n_rp    = 0;
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _naja_action_reg(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_asm_t*      _asm = dfa->priv;
+       dfa_asm_t*       d   = data;
+       scf_lex_word_t*  w   = words->data[words->size - 1];
+       scf_register_t*  r   = naja_find_register(w->text->data);
+
+       if (!r) {
+               scf_loge("register '%s' NOT found\n", w->text->data);
+               return SCF_DFA_ERROR;
+       }
+
+       switch (d->n_comma) {
+               case 0:
+                       d->operands[d->i].base = r;
+                       break;
+               case 1:
+                       d->operands[d->i].index = r;
+                       break;
+               default:
+                       scf_loge("\n");
+                       return SCF_DFA_ERROR;
+                       break;
+       };
+
+       if (d->n_lp == d->n_rp)
+               d->i++;
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _naja_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       dfa_asm_t*  d = data;
+
+       d->n_lp++;
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _naja_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       dfa_asm_t*  d = data;
+
+       if (++d->n_rp == d->n_lp) {
+               d->operands[d->i].flag = 1;
+               d->i++;
+       }
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _naja_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_asm_t*      _asm = dfa->priv;
+       dfa_asm_t*       d   = data;
+       scf_lex_word_t*  w   = words->data[words->size - 1];
+
+       if (d->n_lp != d->n_rp)
+               d->n_comma++;
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _naja_action_colon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_asm_t*      _asm = dfa->priv;
+       dfa_asm_t*       d   = data;
+       scf_lex_word_t*  w   = words->data[words->size - 1];
+       scf_lex_word_t*  w0;
+
+       if (words->size < 2) {
+               scf_loge("no label before '%s', file: %s, line: %d\n", w->text->data, w->file->data, w->line);
+               return SCF_DFA_ERROR;
+       }
+
+       w = words->data[words->size - 2];
+
+       if (SCF_LEX_WORD_ID == w->type) {
+               w0 = scf_vector_find_cmp(_asm->labels, w, __lex_word_cmp);
+               if (w0) {
+                       scf_loge("repeated label '%s' in file: %s, line: %d, first in file: %s, line: %d\n",
+                                       w->text->data, w->file->data, w->line, w0->file->data, w0->line);
+                       return SCF_DFA_ERROR;
+               }
+
+               w0 = scf_lex_word_clone(w);
+               if (!w0)
+                       return -ENOMEM;
+
+               int ret = scf_vector_add(_asm->labels, w0);
+               if (ret < 0) {
+                       scf_lex_word_free(w0);
+                       return ret;
+               }
+       }
+
+       scf_logi("w->text->data: %s, w->data.u32: %d, w->type: %d\n", w->text->data, w->data.u32, w->type);
+       d->label = scf_lex_word_clone(w);
+       if (!d->label)
+               return -ENOMEM;
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int __asm_naja_ADD(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w)
+{
+       if (d->i < 3) {
+               scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+               return SCF_DFA_ERROR;
+       }
+
+       scf_instruction_t*  inst;
+       scf_inst_data_t*    id0    = &d->operands[0];
+       scf_inst_data_t*    id1    = &d->operands[1];
+       scf_inst_data_t*    id2    = &d->operands[2];
+       scf_rela_t*         rela   = NULL;
+
+       if (!__inst_data_is_reg(id0) || !__inst_data_is_reg(id1)) {
+               scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+               return SCF_DFA_ERROR;
+       }
+
+       if (__inst_data_is_reg(id2)) {
+               inst = naja_inst_ADD_G(NULL, id0->base, id1->base, id2->base);
+               RISC_INST_ADD_CHECK(_asm->current, inst);
+
+       } else if (__inst_data_is_const(id2)) {
+               inst = naja_inst_ADD_IMM(NULL, NULL, id0->base, id1->base, id2->imm);
+               RISC_INST_ADD_CHECK(_asm->current, inst);
+       } else {
+               inst = naja_inst_ADD_IMM(NULL, NULL, id0->base, id1->base, 0);
+
+               RISC_INST_ADD_CHECK(_asm->current, inst);
+               RISC_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id2->label->text);
+               rela->type = R_AARCH64_ADD_ABS_LO12_NC;
+       }
+
+       *__inst = inst;
+       return 0;
+}
+
+static int __asm_naja_RET(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w)
+{
+       scf_instruction_t*  inst;
+
+       inst = naja_inst_RET(NULL);
+       RISC_INST_ADD_CHECK(_asm->current, inst);
+
+       *__inst = inst;
+       return 0;
+}
+
+static int __asm_naja_JMP(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w)
+{
+       if (d->i < 1) {
+               scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+               return SCF_DFA_ERROR;
+       }
+
+       scf_instruction_t*  inst;
+       scf_inst_data_t*    id   = &d->operands[0];
+       scf_rela_t*         rela = NULL;
+
+       if (__inst_data_is_reg(id)) {
+               inst = naja_inst_BR(NULL, id->base);
+               RISC_INST_ADD_CHECK(_asm->current, inst);
+       } else {
+               uint32_t disp = 0;
+
+               if (!id->label)
+                       disp = id->imm;
+
+               inst = __naja_inst_JMP(NULL, disp);
+               RISC_INST_ADD_CHECK(_asm->current, inst);
+
+               if (id->label) {
+                       rela = calloc(1, sizeof(scf_rela_t));
+                       if (!rela)
+                               return -ENOMEM;
+
+                       RISC_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id->label->text);
+                       rela->type = R_AARCH64_CALL26;
+               }
+       }
+
+       *__inst = inst;
+       return 0;
+}
+
+static int __asm_naja_CALL(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w)
+{
+       if (d->i < 1) {
+               scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+               return SCF_DFA_ERROR;
+       }
+
+       scf_instruction_t*  inst;
+       scf_inst_data_t*    id   = &d->operands[0];
+       scf_rela_t*         rela = NULL;
+
+       if (__inst_data_is_reg(id)) {
+               inst = naja_inst_BLR(NULL, id->base);
+               RISC_INST_ADD_CHECK(_asm->current, inst);
+       } else {
+               uint32_t disp = 0;
+
+               if (!id->label)
+                       disp = id->imm;
+
+               inst = __naja_inst_BL(NULL, disp);
+               RISC_INST_ADD_CHECK(_asm->current, inst);
+
+               if (id->label) {
+                       rela = calloc(1, sizeof(scf_rela_t));
+                       if (!rela)
+                               return -ENOMEM;
+
+                       RISC_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id->label->text);
+                       rela->type = R_AARCH64_CALL26;
+               }
+       }
+
+       *__inst = inst;
+       return 0;
+}
+
+static int __asm_naja_ADRP(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w)
+{
+       if (d->i < 2) {
+               scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+               return -EINVAL;
+       }
+
+       scf_instruction_t*  inst;
+       scf_inst_data_t*    id0    = &d->operands[0];
+       scf_inst_data_t*    id1    = &d->operands[1];
+       scf_rela_t*         rela   = NULL;
+
+       if (!__inst_data_is_reg(id0) || !id1->label) {
+               scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+               return -EINVAL;
+       }
+
+       inst = __naja_inst_ADRP(NULL, id0->base);
+       RISC_INST_ADD_CHECK(_asm->current, inst);
+       RISC_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id1->label->text);
+       rela->type = R_AARCH64_ADR_PREL_PG_HI21;
+
+       *__inst = inst;
+       return 0;
+}
+
+static int __asm_naja_MOV(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w)
+{
+       if (d->i < 2) {
+               scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+               return -EINVAL;
+       }
+
+       scf_instruction_t*  inst;
+       scf_inst_data_t*    id0 = &d->operands[0];
+       scf_inst_data_t*    id1 = &d->operands[1];
+
+       if (!__inst_data_is_reg(id0)) {
+               scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+               return -EINVAL;
+       }
+
+       if (__inst_data_is_reg(id1)) {
+               inst = naja_inst_MOV_G(NULL, id0->base, id1->base);
+
+       } else if (__inst_data_is_const(id1))
+               inst = naja_inst_MOV_IMM(NULL, id0->base, id1->imm);
+       else {
+               scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+               return -EINVAL;
+       }
+       RISC_INST_ADD_CHECK(_asm->current, inst);
+
+       *__inst = inst;
+       return 0;
+}
+
+static int __asm_naja_PUSH(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w)
+{
+       if (d->i < 1) {
+               scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+               return -EINVAL;
+       }
+
+       scf_instruction_t*  inst;
+       scf_inst_data_t*    id = &d->operands[0];
+
+       if (!__inst_data_is_reg(id)) {
+               scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+               return -EINVAL;
+       }
+
+       inst = naja_inst_PUSH(NULL, id->base);
+       RISC_INST_ADD_CHECK(_asm->current, inst);
+
+       *__inst = inst;
+       return 0;
+}
+
+static int __asm_naja_POP(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w)
+{
+       if (d->i < 1) {
+               scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+               return -EINVAL;
+       }
+
+       scf_instruction_t*  inst;
+       scf_inst_data_t*    id = &d->operands[0];
+
+       if (!__inst_data_is_reg(id)) {
+               scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+               return -EINVAL;
+       }
+
+       inst = naja_inst_POP(NULL, id->base);
+       RISC_INST_ADD_CHECK(_asm->current, inst);
+
+       *__inst = inst;
+       return 0;
+}
+
+static int _naja_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_asm_t*         _asm  = dfa->priv;
+       dfa_asm_t*          d    = data;
+       scf_lex_word_t*     w    = words->data[words->size - 1];
+       scf_instruction_t*  inst = NULL;
+
+       if (d->opcode) {
+               int ret = 0;
+               switch (d->opcode->type)
+               {
+                       case SCF_RISC_PUSH:
+                               ret = __asm_naja_PUSH(&inst, _asm, d, w);
+                               break;
+                       case SCF_RISC_POP:
+                               ret = __asm_naja_POP(&inst, _asm, d, w);
+                               break;
+
+                       case SCF_RISC_MOV:
+                               ret = __asm_naja_MOV(&inst, _asm, d, w);
+                               break;
+
+                       case SCF_RISC_ADRP:
+                               ret = __asm_naja_ADRP(&inst, _asm, d, w);
+                               break;
+
+                       case SCF_RISC_ADD:
+                               ret = __asm_naja_ADD(&inst, _asm, d, w);
+                               break;
+
+                       case SCF_RISC_JMP:
+                               ret = __asm_naja_JMP(&inst, _asm, d, w);
+                               break;
+
+                       case SCF_RISC_CALL:
+                               ret = __asm_naja_CALL(&inst, _asm, d, w);
+                               break;
+
+                       case SCF_RISC_RET:
+                               ret = __asm_naja_RET(&inst, _asm, d, w);
+                               break;
+                       default:
+                               scf_loge("opcode '%s' NOT support, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+                               return -1;
+                               break;
+               };
+
+               if (ret < 0)
+                       return ret;
+
+               if (d->label) {
+                       inst->label = d->label;
+                       d   ->label = NULL;
+               }
+
+               scf_instruction_print(inst);
+               d->opcode = NULL;
+
+       } else if (d->fill) {
+               if (d->i < 3) {
+                       scf_loge(".fill needs 3 operands, file: %s, line: %d\n", d->fill->file->data, d->fill->line);
+                       return SCF_DFA_ERROR;
+               }
+
+               int64_t  n    = d->operands[0].imm;
+               int64_t  size = d->operands[1].imm;
+               uint64_t imm  = d->operands[2].imm;
+               int64_t  i;
+
+               inst = calloc(1, sizeof(scf_instruction_t));
+               if (!inst)
+                       return -ENOMEM;
+
+               if (n * size <= sizeof(inst->code)) {
+                       for (i = 0; i < n; i++)
+                               memcpy(inst->code + i * size, (uint8_t*)&imm, size);
+
+                       inst->len = n * size;
+               } else {
+                       inst->bin = scf_string_alloc();
+                       if (inst->bin) {
+                               scf_instruction_free(inst);
+                               return -ENOMEM;
+                       }
+
+                       for (i = 0; i < n; i++) {
+                               int ret = scf_string_cat_cstr_len(inst->bin, (uint8_t*)&imm, size);
+                               if (ret < 0) {
+                                       scf_instruction_free(inst);
+                                       return -ENOMEM;
+                               }
+                       }
+               }
+
+               RISC_INST_ADD_CHECK(_asm->current, inst);
+               d->fill = NULL;
+       }
+
+       for (int i = 0; i < 4; i++) {
+               d->operands[i].base  = NULL;
+               d->operands[i].index = NULL;
+               d->operands[i].scale = 0;
+               d->operands[i].disp  = 0;
+
+               d->operands[i].flag  = 0;
+               d->operands[i].label = NULL;
+               d->operands[i].imm   = 0;
+               d->operands[i].imm_size = 0;
+       }
+
+       d->global = NULL;
+
+       return SCF_DFA_OK;
+}
+
+static int _naja_action_hash(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_asm_t*      _asm = dfa->priv;
+       dfa_asm_t*       d   = data;
+       scf_lex_word_t*  w   = words->data[words->size - 1];
+
+       while (w = dfa->ops->pop_word(dfa))
+       {
+               if (SCF_LEX_WORD_LF == w->type) {
+                       dfa->ops->push_word(dfa, w);
+                       break;
+               }
+
+               dfa->ops->free_word(w);
+       }
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+int _naja_set_offset_for_jmps(scf_vector_t* text)
+{
+       scf_instruction_t*  inst;
+       scf_instruction_t*  dst;
+       int i;
+       int j;
+
+       for (i = 0; i < text->size; i++) {
+               inst      = text->data[i];
+
+               if (!inst->OpCode)
+                       continue;
+
+               uint32_t opcode;
+               uint32_t label;
+
+               opcode  = inst->code[0];
+               opcode |= inst->code[1] <<  8;
+               opcode |= inst->code[2] << 16;
+               opcode |= inst->code[3] << 24;
+
+               if (0x32 == (opcode >> 26) && 1 == (opcode & 1)) {
+                       label = (opcode >> 5) & 0x1fffff;
+
+               } else if (0x30 == (opcode >> 26)
+                               || 0x31 == (opcode >> 26)) {
+                       label = opcode & 0x3ffffff;
+               } else
+                       continue;
+
+               int32_t  bytes = 0;
+               uint32_t flag  = label & 0xff;
+               label >>= 8;
+
+               if (1 == flag) {
+                       for (j = i; j >= 0; j--) {
+                               dst = text->data[j];
+
+                               if (dst->label
+                                               && scf_lex_is_const_integer(dst->label)
+                                               && dst->label->data.u32 == label) {
+                                       inst->next = dst;
+                                       break;
+                               }
+                       }
+
+                       if (j < 0) {
+                               scf_loge("number label %d NOT found\n", label);
+                               return -1;
+                       }
+
+                       for ( ; j < i; j++) {
+                               dst = text->data[j];
+
+                               if (dst->len > 0)
+                                       bytes -= dst->len;
+                               else if (dst->bin)
+                                       bytes -= dst->bin->len;
+                       }
+
+               } else if (2 == flag) {
+                       for (j = i; j < text->size; j++) {
+                               dst       = text->data[j];
+
+                               if (dst->label
+                                               && scf_lex_is_const_integer(dst->label)
+                                               && dst->label->data.u32 == label) {
+                                       inst->next = dst;
+                                       break;
+                               }
+
+                               if (dst->len > 0)
+                                       bytes += dst->len;
+                               else if (dst->bin)
+                                       bytes += dst->bin->len;
+                       }
+
+                       if (j >= text->size) {
+                               scf_loge("number label %d NOT found\n", label);
+                               return -1;
+                       }
+               } else
+                       continue;
+
+               naja_set_jmp_offset(inst, bytes);
+       }
+
+       return 0;
+}
+
+static int _dfa_init_module_naja(scf_dfa_t* dfa)
+{
+       SCF_DFA_MODULE_NODE(dfa, naja, text,     scf_asm_is_text,      _naja_action_text);
+       SCF_DFA_MODULE_NODE(dfa, naja, data,     scf_asm_is_data,      _naja_action_data);
+       SCF_DFA_MODULE_NODE(dfa, naja, global,   scf_asm_is_global,    _naja_action_global);
+       SCF_DFA_MODULE_NODE(dfa, naja, fill,     scf_asm_is_fill,      _naja_action_fill);
+
+       SCF_DFA_MODULE_NODE(dfa, naja, type,     scf_asm_is_type,      _naja_action_type);
+       SCF_DFA_MODULE_NODE(dfa, naja, str,      scf_asm_is_str,       _naja_action_str);
+       SCF_DFA_MODULE_NODE(dfa, naja, number,   scf_asm_is_number,    _naja_action_number);
+
+       SCF_DFA_MODULE_NODE(dfa, naja, identity, scf_dfa_is_identity,  _naja_action_identity);
+       SCF_DFA_MODULE_NODE(dfa, naja, colon,    scf_dfa_is_colon,     _naja_action_colon);
+
+       SCF_DFA_MODULE_NODE(dfa, naja, opcode,   _naja_is_opcode,       _naja_action_opcode);
+       SCF_DFA_MODULE_NODE(dfa, naja, reg,      _naja_is_reg,          _naja_action_reg);
+
+       SCF_DFA_MODULE_NODE(dfa, naja, lp,       scf_dfa_is_lp,        _naja_action_lp);
+       SCF_DFA_MODULE_NODE(dfa, naja, rp,       scf_dfa_is_rp,        _naja_action_rp);
+
+       SCF_DFA_MODULE_NODE(dfa, naja, comma,    scf_dfa_is_comma,     _naja_action_comma);
+       SCF_DFA_MODULE_NODE(dfa, naja, LF,       scf_dfa_is_LF,        _naja_action_LF);
+       SCF_DFA_MODULE_NODE(dfa, naja, HASH,     scf_dfa_is_hash,      _naja_action_hash);
+
+       scf_asm_t*  _asm = dfa->priv;
+       dfa_asm_t*  d    = _asm->dfa_data;
+
+       d->type = SCF_LEX_WORD_ASM_BYTE;
+
+       return SCF_DFA_OK;
+}
+
+static int _dfa_init_syntax_naja(scf_dfa_t* dfa)
+{
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, text,      text);
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, data,      data);
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, global,    global);
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, fill,      fill);
+
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, identity,  identity);
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, colon,     colon);
+
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, type,      type);
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, str,       str);
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, number,    number);
+
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, opcode,    opcode);
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, reg,       reg);
+
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, lp,        lp);
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, rp,        rp);
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, comma,     comma);
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, LF,        LF);
+       SCF_DFA_GET_MODULE_NODE(dfa, naja, HASH,      HASH);
+
+       // asm syntax
+       scf_vector_add(dfa->syntaxes, text);
+       scf_vector_add(dfa->syntaxes, data);
+       scf_vector_add(dfa->syntaxes, global);
+       scf_vector_add(dfa->syntaxes, fill);
+
+       scf_vector_add(dfa->syntaxes, opcode);
+       scf_vector_add(dfa->syntaxes, identity);
+       scf_vector_add(dfa->syntaxes, number);
+
+       scf_vector_add(dfa->syntaxes, type);
+       scf_vector_add(dfa->syntaxes, HASH);
+       scf_vector_add(dfa->syntaxes, LF);
+
+       // .text .data
+       scf_dfa_node_add_child(text,      LF);
+       scf_dfa_node_add_child(data,      LF);
+
+       // label:
+       scf_dfa_node_add_child(identity,  colon);
+       scf_dfa_node_add_child(number,    colon);
+       scf_dfa_node_add_child(colon,     LF);
+
+       // .asciz
+       scf_dfa_node_add_child(type,      str);
+       scf_dfa_node_add_child(type,      number);
+       scf_dfa_node_add_child(type,      identity);
+
+       scf_dfa_node_add_child(str,       LF);
+       scf_dfa_node_add_child(number,    LF);
+       scf_dfa_node_add_child(identity,  LF);
+
+       // asm instruction
+       scf_dfa_node_add_child(opcode,    number);
+       scf_dfa_node_add_child(opcode,    reg);
+       scf_dfa_node_add_child(opcode,    identity);
+
+       scf_dfa_node_add_child(identity,  comma);
+       scf_dfa_node_add_child(number,    comma);
+       scf_dfa_node_add_child(reg,       comma);
+
+       scf_dfa_node_add_child(comma,     number);
+       scf_dfa_node_add_child(comma,     reg);
+       scf_dfa_node_add_child(comma,     identity);
+
+       scf_dfa_node_add_child(identity,  LF);
+       scf_dfa_node_add_child(number,    LF);
+       scf_dfa_node_add_child(reg,       LF);
+
+       // memory addr such as: (rax), 8(rax), disp(rax, rcx, 8),
+       scf_dfa_node_add_child(opcode,    lp);
+       scf_dfa_node_add_child(identity,  lp);
+       scf_dfa_node_add_child(number,    lp);
+
+       scf_dfa_node_add_child(lp,        reg);
+       scf_dfa_node_add_child(lp,        comma); // ( , rcx, 8), empty base == 0
+
+       scf_dfa_node_add_child(reg,       rp);
+       scf_dfa_node_add_child(number,    rp);
+       scf_dfa_node_add_child(rp,        comma);
+       scf_dfa_node_add_child(rp,        LF);
+
+       // .fill
+       scf_dfa_node_add_child(fill,      number);
+
+       // .global
+       scf_dfa_node_add_child(global,    identity);
+       scf_dfa_node_add_child(comma,     LF);
+       scf_dfa_node_add_child(global,    LF);
+
+       return SCF_DFA_OK;
+}
+
+scf_dfa_module_t dfa_module_naja = 
+{
+       .name        = "naja",
+       .init_module = _dfa_init_module_naja,
+       .init_syntax = _dfa_init_syntax_naja,
+};
similarity index 77%
rename from asm/scf_dfa_inst.c
rename to asm/scf_dfa_x64.c
index 509ab66b5dc08f254ec9a88871499296202a461b..b60eeb9613ba5ddba7a42d6ee2e5a3a56cbeea77 100644 (file)
@@ -4,79 +4,24 @@
 #include"scf_x64_opcode.h"
 #include"scf_x64_reg.h"
 
-extern scf_dfa_module_t  dfa_module_inst;
+extern scf_dfa_module_t  dfa_module_x64;
 
-static int _inst_is_text(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_ASM_TEXT == w->type;
-}
-
-static int _inst_is_data(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_ASM_DATA == w->type;
-}
-
-static int _inst_is_global(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_ASM_GLOBAL == w->type;
-}
-
-static int _inst_is_fill(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_ASM_FILL == w->type;
-}
-
-static int _inst_is_type(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_ASM_BYTE <= w->type && SCF_LEX_WORD_ASM_ASCIZ >= w->type;
-}
-
-static int _inst_is_number(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_CONST_CHAR <= w->type && SCF_LEX_WORD_CONST_DOUBLE >= w->type;
-}
-
-static int _inst_is_str(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_CONST_STRING == w->type;
-}
 
-static int _inst_is_percent(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
-
-       return SCF_LEX_WORD_MOD == w->type;
-}
-
-static int _inst_is_opcode(scf_dfa_t* dfa, void* word)
+static int _x64_is_opcode(scf_dfa_t* dfa, void* word)
 {
        scf_lex_word_t* w = word;
 
        return !!x64_find_OpCode_by_name(w->text->data);
 }
 
-static int _inst_is_reg(scf_dfa_t* dfa, void* word)
+static int _x64_is_reg(scf_dfa_t* dfa, void* word)
 {
        scf_lex_word_t* w = word;
 
        return !!x64_find_register(w->text->data);
 }
 
-static int _inst_action_text(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_text(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_asm_t*      _asm = dfa->priv;
        dfa_asm_t*       d   = data;
@@ -87,7 +32,7 @@ static int _inst_action_text(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _inst_action_data(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_data(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_asm_t*      _asm = dfa->priv;
        dfa_asm_t*       d   = data;
@@ -98,7 +43,7 @@ static int _inst_action_data(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _inst_action_global(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_global(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_asm_t*      _asm = dfa->priv;
        dfa_asm_t*       d   = data;
@@ -109,7 +54,7 @@ static int _inst_action_global(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _inst_action_fill(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_fill(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_asm_t*      _asm = dfa->priv;
        dfa_asm_t*       d   = data;
@@ -120,7 +65,7 @@ static int _inst_action_fill(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _inst_action_type(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_type(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_asm_t*      _asm = dfa->priv;
        dfa_asm_t*       d   = data;
@@ -133,7 +78,7 @@ static int _inst_action_type(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _inst_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_asm_t*         _asm = dfa->priv;
        dfa_asm_t*          d   = data;
@@ -168,31 +113,31 @@ static int _inst_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                                d->operands[d->i].imm_size = 8;
                                d->operands[d->i].flag     = 0;
 
-                               if (SCF_LEX_WORD_ID == w2->type) {
-                                       if (SCF_X64_JZ > d->opcode->type || SCF_X64_JMP < d->opcode->type) {
-                                               scf_loge("opcode '%s' MUST be jcc/jmp, in file: %s, line: %d\n", w->text->data, w->file->data, w->line);
-                                               return SCF_DFA_ERROR;
+                               if (SCF_X64_CALL == d->opcode->type
+                                               || (SCF_X64_JZ <= d->opcode->type && SCF_X64_JMP >= d->opcode->type)) {
+                                       int flag = 0x1;
+
+                                       if (SCF_LEX_WORD_ID == w2->type) {
+                                               switch (w2->text->data[0]) {
+                                                       case 'b':
+                                                               break;
+                                                       case 'f':
+                                                               flag = 0x2;
+                                                               break;
+                                                       default:
+                                                               scf_loge("the char followed a number label MUST be 'b' or 'f', but real '%c' in file: %s, line: %d\n",
+                                                                               w2->text->data[0], w->file->data, w->line);
+                                                               return SCF_DFA_ERROR;
+                                                               break;
+                                               };
+
+                                               w2 = dfa->ops->pop_word(dfa);
+                                               dfa->ops->free_word(w2);
+                                               w2 = NULL;
                                        }
 
-                                       switch (w2->text->data[0]) {
-                                               case 'b':
-                                                       d->operands[d->i].imm <<= 8;
-                                                       d->operands[d->i].imm  |= 0x1;
-                                                       break;
-                                               case 'f':
-                                                       d->operands[d->i].imm <<= 8;
-                                                       d->operands[d->i].imm  |= 0x2;
-                                                       break;
-                                               default:
-                                                       scf_loge("the char followed a number label MUST be 'b' or 'f', but real '%c' in file: %s, line: %d\n",
-                                                                       w2->text->data[0], w->file->data, w->line);
-                                                       return SCF_DFA_ERROR;
-                                                       break;
-                                       };
-
-                                       w2 = dfa->ops->pop_word(dfa);
-                                       dfa->ops->free_word(w2);
-                                       w2 = NULL;
+                                       d->operands[d->i].imm <<= 8;
+                                       d->operands[d->i].imm  |= flag;
                                }
 
                                d->i++;
@@ -262,7 +207,7 @@ static int _inst_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _inst_action_str(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_str(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_asm_t*         _asm = dfa->priv;
        dfa_asm_t*          d   = data;
@@ -311,7 +256,7 @@ static int _inst_action_str(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _inst_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_asm_t*      _asm = dfa->priv;
        dfa_asm_t*       d   = data;
@@ -400,7 +345,7 @@ static int _inst_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _inst_action_opcode(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_opcode(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_asm_t*      _asm = dfa->priv;
        dfa_asm_t*       d   = data;
@@ -420,7 +365,7 @@ static int _inst_action_opcode(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _inst_action_reg(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_reg(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_asm_t*      _asm = dfa->priv;
        dfa_asm_t*       d   = data;
@@ -451,7 +396,7 @@ static int _inst_action_reg(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _inst_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        dfa_asm_t*  d = data;
 
@@ -459,7 +404,7 @@ static int _inst_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _inst_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        dfa_asm_t*  d = data;
 
@@ -471,7 +416,7 @@ static int _inst_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _inst_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_asm_t*      _asm = dfa->priv;
        dfa_asm_t*       d   = data;
@@ -483,7 +428,7 @@ static int _inst_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _inst_action_colon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_colon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_asm_t*      _asm = dfa->priv;
        dfa_asm_t*       d   = data;
@@ -524,7 +469,7 @@ static int _inst_action_colon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int __inst_op2(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w)
+static int __x64_op2(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w)
 {
        scf_x64_OpCode_t*  opcode = (scf_x64_OpCode_t*)d->opcode;
        scf_instruction_t* inst   = NULL;
@@ -553,8 +498,39 @@ static int __inst_op2(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d,
                                inst = x64_make_inst_G2E(opcode, id1->base, id0->base);
                        } else
                                inst = x64_make_inst_E2G(opcode, id1->base, id0->base);
+                       X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+
+               } else if (__inst_data_is_const(id1)) {
+
+               } else {
+                       RegBytes = OpBytes;
 
+                       opcode = x64_find_OpCode(d->opcode->type, OpBytes, RegBytes, SCF_X64_G2E);
+                       if (!opcode) {
+                               scf_loge("find proper opcode '%s' failed, file: %s, line: %d\n", d->opcode->name, w->file->data, w->line);
+                               return SCF_DFA_ERROR;
+                       }
+
+                       int32_t disp = id1->disp;
+                       if (id1->label)
+                               disp = 0x1000; // make disp to 4bytes, only for disp from a label
+
+                       if (id1->index)
+                               inst = x64_make_inst_G2SIB(opcode, id1->base, id1->index, id1->scale, disp, id0->base);
+                       else
+                               inst = x64_make_inst_G2P(opcode, id1->base, disp, id0->base);
                        X64_INST_ADD_CHECK(_asm->current, inst, NULL);
+
+                       if (id0->label) {
+                               scf_rela_t* rela = calloc(1, sizeof(scf_rela_t));
+                               if (!rela)
+                                       return -ENOMEM;
+
+                               *(uint32_t*)(inst->code + inst->len - 4) = 0;
+
+                               rela->inst_offset = inst->len - 4;
+                               X64_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id0->label->text);
+                       }
                }
 
        } else if (__inst_data_is_const(id0)) {
@@ -640,7 +616,7 @@ static int __inst_op2(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d,
        return 0;
 }
 
-static int __inst_op1(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w)
+static int __x64_op1(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d, scf_lex_word_t* w)
 {
        scf_x64_OpCode_t*  opcode = (scf_x64_OpCode_t*)d->opcode;
        scf_instruction_t* inst   = NULL;
@@ -686,7 +662,6 @@ static int __inst_op1(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d,
                                        return -ENOMEM;
 
                                rela->inst_offset = inst->len - 4;
-                               scf_logw("rela->inst_offset: %d, inst->len: %d\n", rela->inst_offset, inst->len);
                                X64_RELA_ADD_LABEL(_asm->text_relas, rela, inst, id->label->text);
                        }
                } else {
@@ -706,7 +681,7 @@ static int __inst_op1(scf_instruction_t** __inst, scf_asm_t* _asm, dfa_asm_t* d,
        return 0;
 }
 
-static int _inst_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_asm_t*         _asm  = dfa->priv;
        dfa_asm_t*          d    = data;
@@ -724,10 +699,10 @@ static int _inst_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                int ret = 0;
                switch (d->i) {
                        case 2:
-                               ret = __inst_op2(&inst, _asm, d, w);
+                               ret = __x64_op2(&inst, _asm, d, w);
                                break;
                        case 1:
-                               ret = __inst_op1(&inst, _asm, d, w);
+                               ret = __x64_op1(&inst, _asm, d, w);
                                break;
                        case 0:
                                inst = x64_make_inst(opcode, 8);
@@ -805,7 +780,7 @@ static int _inst_action_LF(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_OK;
 }
 
-static int _inst_action_hash(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+static int _x64_action_hash(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_asm_t*      _asm = dfa->priv;
        dfa_asm_t*       d   = data;
@@ -956,32 +931,34 @@ int _x64_set_offset_for_jmps(scf_vector_t* text)
                if (0 == drop_bytes)
                        break;
        }
+
+       return 0;
 }
 
-static int _dfa_init_module_inst(scf_dfa_t* dfa)
+static int _dfa_init_module_x64(scf_dfa_t* dfa)
 {
-       SCF_DFA_MODULE_NODE(dfa, inst, text,     _inst_is_text,       _inst_action_text);
-       SCF_DFA_MODULE_NODE(dfa, inst, data,     _inst_is_data,       _inst_action_data);
-       SCF_DFA_MODULE_NODE(dfa, inst, global,   _inst_is_global,     _inst_action_global);
-       SCF_DFA_MODULE_NODE(dfa, inst, fill,     _inst_is_fill,       _inst_action_fill);
+       SCF_DFA_MODULE_NODE(dfa, x64, text,     scf_asm_is_text,      _x64_action_text);
+       SCF_DFA_MODULE_NODE(dfa, x64, data,     scf_asm_is_data,      _x64_action_data);
+       SCF_DFA_MODULE_NODE(dfa, x64, global,   scf_asm_is_global,    _x64_action_global);
+       SCF_DFA_MODULE_NODE(dfa, x64, fill,     scf_asm_is_fill,      _x64_action_fill);
 
-       SCF_DFA_MODULE_NODE(dfa, inst, type,     _inst_is_type,       _inst_action_type);
-       SCF_DFA_MODULE_NODE(dfa, inst, str,      _inst_is_str,        _inst_action_str);
-       SCF_DFA_MODULE_NODE(dfa, inst, number,   _inst_is_number,     _inst_action_number);
+       SCF_DFA_MODULE_NODE(dfa, x64, type,     scf_asm_is_type,      _x64_action_type);
+       SCF_DFA_MODULE_NODE(dfa, x64, str,      scf_asm_is_str,       _x64_action_str);
+       SCF_DFA_MODULE_NODE(dfa, x64, number,   scf_asm_is_number,    _x64_action_number);
 
-       SCF_DFA_MODULE_NODE(dfa, inst, identity, scf_dfa_is_identity, _inst_action_identity);
-       SCF_DFA_MODULE_NODE(dfa, inst, colon,    scf_dfa_is_colon,    _inst_action_colon);
+       SCF_DFA_MODULE_NODE(dfa, x64, identity, scf_dfa_is_identity,  _x64_action_identity);
+       SCF_DFA_MODULE_NODE(dfa, x64, colon,    scf_dfa_is_colon,     _x64_action_colon);
 
-       SCF_DFA_MODULE_NODE(dfa, inst, opcode,   _inst_is_opcode,     _inst_action_opcode);
-       SCF_DFA_MODULE_NODE(dfa, inst, reg,      _inst_is_reg,        _inst_action_reg);
-       SCF_DFA_MODULE_NODE(dfa, inst, percent,  _inst_is_percent,    scf_dfa_action_next);
+       SCF_DFA_MODULE_NODE(dfa, x64, opcode,   _x64_is_opcode,       _x64_action_opcode);
+       SCF_DFA_MODULE_NODE(dfa, x64, reg,      _x64_is_reg,          _x64_action_reg);
+       SCF_DFA_MODULE_NODE(dfa, x64, percent,  scf_asm_is_percent,   scf_dfa_action_next);
 
-       SCF_DFA_MODULE_NODE(dfa, inst, lp,       scf_dfa_is_lp,       _inst_action_lp);
-       SCF_DFA_MODULE_NODE(dfa, inst, rp,       scf_dfa_is_rp,       _inst_action_rp);
+       SCF_DFA_MODULE_NODE(dfa, x64, lp,       scf_dfa_is_lp,        _x64_action_lp);
+       SCF_DFA_MODULE_NODE(dfa, x64, rp,       scf_dfa_is_rp,        _x64_action_rp);
 
-       SCF_DFA_MODULE_NODE(dfa, inst, comma,    scf_dfa_is_comma,    _inst_action_comma);
-       SCF_DFA_MODULE_NODE(dfa, inst, LF,       scf_dfa_is_LF,       _inst_action_LF);
-       SCF_DFA_MODULE_NODE(dfa, inst, HASH,     scf_dfa_is_hash,     _inst_action_hash);
+       SCF_DFA_MODULE_NODE(dfa, x64, comma,    scf_dfa_is_comma,     _x64_action_comma);
+       SCF_DFA_MODULE_NODE(dfa, x64, LF,       scf_dfa_is_LF,        _x64_action_LF);
+       SCF_DFA_MODULE_NODE(dfa, x64, HASH,     scf_dfa_is_hash,      _x64_action_hash);
 
        scf_asm_t*  _asm = dfa->priv;
        dfa_asm_t*  d    = _asm->dfa_data;
@@ -991,29 +968,29 @@ static int _dfa_init_module_inst(scf_dfa_t* dfa)
        return SCF_DFA_OK;
 }
 
-static int _dfa_init_syntax_inst(scf_dfa_t* dfa)
+static int _dfa_init_syntax_x64(scf_dfa_t* dfa)
 {
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, text,      text);
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, data,      data);
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, global,    global);
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, fill,      fill);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, text,      text);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, data,      data);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, global,    global);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, fill,      fill);
 
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, identity,  identity);
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, colon,     colon);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, identity,  identity);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, colon,     colon);
 
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, type,      type);
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, str,       str);
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, number,    number);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, type,      type);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, str,       str);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, number,    number);
 
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, opcode,    opcode);
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, reg,       reg);
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, percent,   percent);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, opcode,    opcode);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, reg,       reg);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, percent,   percent);
 
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, lp,        lp);
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, rp,        rp);
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, comma,     comma);
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, LF,        LF);
-       SCF_DFA_GET_MODULE_NODE(dfa, inst, HASH,      HASH);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, lp,        lp);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, rp,        rp);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, comma,     comma);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, LF,        LF);
+       SCF_DFA_GET_MODULE_NODE(dfa, x64, HASH,      HASH);
 
        // asm syntax
        scf_vector_add(dfa->syntaxes, text);
@@ -1056,17 +1033,17 @@ static int _dfa_init_syntax_inst(scf_dfa_t* dfa)
        scf_dfa_node_add_child(identity,  LF);
 
        // asm instruction
-       scf_dfa_node_add_child(opcode,    identity);
        scf_dfa_node_add_child(opcode,    number);
        scf_dfa_node_add_child(opcode,    reg);
+       scf_dfa_node_add_child(opcode,    identity);
 
        scf_dfa_node_add_child(identity,  comma);
        scf_dfa_node_add_child(number,    comma);
        scf_dfa_node_add_child(reg,       comma);
 
-       scf_dfa_node_add_child(comma,     identity);
        scf_dfa_node_add_child(comma,     number);
        scf_dfa_node_add_child(comma,     reg);
+       scf_dfa_node_add_child(comma,     identity);
 
        scf_dfa_node_add_child(identity,  LF);
        scf_dfa_node_add_child(number,    LF);
@@ -1097,9 +1074,9 @@ static int _dfa_init_syntax_inst(scf_dfa_t* dfa)
        return SCF_DFA_OK;
 }
 
-scf_dfa_module_t dfa_module_inst = 
+scf_dfa_module_t dfa_module_x64 = 
 {
-       .name        = "inst",
-       .init_module = _dfa_init_module_inst,
-       .init_syntax = _dfa_init_syntax_inst,
+       .name        = "x64",
+       .init_module = _dfa_init_module_x64,
+       .init_syntax = _dfa_init_syntax_x64,
 };
diff --git a/asm/shellcode.s b/asm/shellcode.s
new file mode 100644 (file)
index 0000000..a54c623
--- /dev/null
@@ -0,0 +1,27 @@
+.text
+.global main
+
+main:
+       push %rbp
+       jmp 1f
+0:
+       pop  %rdi
+
+       mov  %rsp, %rbp
+       sub  $16, %rsp
+
+       mov  %rdi, (%rsp)
+       xor  %rdx,  %rdx
+       mov  %rdx, 8(%rsp)
+       mov  %rsp,  %rsi
+
+       xor  %rax,  %rax
+       movb $59, %al
+       syscall
+
+       mov  %rbp, %rsp
+       pop  %rbp
+       ret
+1:
+       call 0b
+.asciz "/bin/sh"
index b3599aa57326e2b9ffdc4c35e96b84943214a215..0a40786ec912cdd1e4456e176e373936a02d797a 100644 (file)
@@ -8,6 +8,16 @@
 typedef struct scf_elf_context_s       scf_elf_context_t;
 typedef struct scf_elf_ops_s           scf_elf_ops_t;
 
+enum scf_elf_archs
+{
+       SCF_ELF_X64,
+       SCF_ELF_ARM64,
+       SCF_ELF_ARM32,
+       SCF_ELF_NAJA,
+
+       SCF_ELF_N_ARCHS,
+};
+
 typedef struct {
        char*           name;
        uint64_t    st_size;
@@ -52,27 +62,28 @@ typedef struct {
 
 struct scf_elf_ops_s
 {
-       const char*             machine;
+       const char*     machine;
+       int             arch;
 
-       int                             (*open )(scf_elf_context_t* elf);
-       int                             (*close)(scf_elf_context_t* elf);
+       int             (*open )(scf_elf_context_t* elf);
+       int             (*close)(scf_elf_context_t* elf);
 
-       int                             (*add_sym   )(scf_elf_context_t* elf, const scf_elf_sym_t*  sym,   const char* sh_name);
-       int                             (*read_syms )(scf_elf_context_t* elf,       scf_vector_t*   syms,  const char* sh_name);
-       int                             (*read_relas)(scf_elf_context_t* elf,       scf_vector_t*   relas, const char* sh_name);
-       int                             (*read_phdrs)(scf_elf_context_t* elf,       scf_vector_t*   phdrs);
+       int             (*add_sym   )(scf_elf_context_t* elf, const scf_elf_sym_t*  sym,   const char* sh_name);
+       int             (*read_syms )(scf_elf_context_t* elf,       scf_vector_t*   syms,  const char* sh_name);
+       int             (*read_relas)(scf_elf_context_t* elf,       scf_vector_t*   relas, const char* sh_name);
+       int             (*read_phdrs)(scf_elf_context_t* elf,       scf_vector_t*   phdrs);
 
-       int                             (*add_section )(scf_elf_context_t* elf, const scf_elf_section_t*  section);
-       int                             (*read_section)(scf_elf_context_t* elf,       scf_elf_section_t** psection, const char* name);
+       int             (*add_section )(scf_elf_context_t* elf, const scf_elf_section_t*  section);
+       int             (*read_section)(scf_elf_context_t* elf,       scf_elf_section_t** psection, const char* name);
 
-       int                             (*add_rela_section)(scf_elf_context_t* elf, const scf_elf_section_t* section, scf_vector_t* relas);
+       int             (*add_rela_section)(scf_elf_context_t* elf, const scf_elf_section_t* section, scf_vector_t* relas);
 
-       int                             (*add_dyn_need)(scf_elf_context_t* elf, const char* soname);
+       int             (*add_dyn_need)(scf_elf_context_t* elf, const char* soname);
        int                 (*add_dyn_rela)(scf_elf_context_t* elf, const scf_elf_rela_t* rela);
 
-       int                             (*write_rel )(scf_elf_context_t* elf);
-       int                             (*write_dyn )(scf_elf_context_t* elf, const char* sysroot);
-       int                             (*write_exec)(scf_elf_context_t* elf, const char* sysroot);
+       int             (*write_rel )(scf_elf_context_t* elf);
+       int             (*write_dyn )(scf_elf_context_t* elf, const char* sysroot);
+       int             (*write_exec)(scf_elf_context_t* elf, const char* sysroot);
 };
 
 struct scf_elf_context_s {
index 6c85c87e0117d71bca3356d3546eab9f269da0e1..6e66b0f0fc2dfbe66c93f5a46d4c8933ee9aef77 100644 (file)
@@ -440,12 +440,13 @@ static int _arm32_elf_write_exec(scf_elf_context_t* elf, const char* sysroot)
 
 scf_elf_ops_t  elf_ops_arm32 =
 {
-       .machine              = "arm32",
+       .machine          = "arm32",
+       .arch             = SCF_ELF_ARM32,
 
-       .open                 = elf32_open,
-       .close                = elf32_close,
+       .open             = elf32_open,
+       .close            = elf32_close,
 
-       .add_sym              = elf32_add_sym,
+       .add_sym          = elf32_add_sym,
        .add_section      = elf32_add_section,
 
        .add_rela_section = elf32_add_rela_section,
@@ -457,6 +458,6 @@ scf_elf_ops_t       elf_ops_arm32 =
        .read_relas       = elf32_read_relas,
        .read_section     = elf32_read_section,
 
-       .write_rel            = _arm32_elf_write_rel,
+       .write_rel        = _arm32_elf_write_rel,
        .write_exec       = _arm32_elf_write_exec,
 };
index 318ee2eae25ff71e633c3347d8fd33e27d3fc5c2..3cfe50e5c27f93f2b1e43090f884295e0a3617b9 100644 (file)
@@ -452,12 +452,13 @@ static int _arm64_elf_write_exec(scf_elf_context_t* elf, const char* sysroot)
 
 scf_elf_ops_t  elf_ops_arm64 =
 {
-       .machine              = "arm64",
+       .machine          = "arm64",
+       .arch             = SCF_ELF_ARM64,
 
-       .open                 = elf_open,
-       .close                = elf_close,
+       .open             = elf_open,
+       .close            = elf_close,
 
-       .add_sym              = elf_add_sym,
+       .add_sym          = elf_add_sym,
        .add_section      = elf_add_section,
 
        .add_rela_section = elf_add_rela_section,
@@ -469,6 +470,6 @@ scf_elf_ops_t       elf_ops_arm64 =
        .read_relas       = elf_read_relas,
        .read_section     = elf_read_section,
 
-       .write_rel            = _arm64_elf_write_rel,
+       .write_rel        = _arm64_elf_write_rel,
        .write_exec       = _arm64_elf_write_exec,
 };
index d399243d40215f16826377bbcd67e50a243e7755..513910a8f9efdc08a167d6be42277666b6edc09b 100644 (file)
@@ -452,12 +452,13 @@ static int _naja_elf_write_exec(scf_elf_context_t* elf, const char* sysroot)
 
 scf_elf_ops_t  elf_ops_naja =
 {
-       .machine              = "naja",
+       .machine          = "naja",
+       .arch             = SCF_ELF_NAJA,
 
-       .open                 = elf_open,
-       .close                = elf_close,
+       .open             = elf_open,
+       .close            = elf_close,
 
-       .add_sym              = elf_add_sym,
+       .add_sym          = elf_add_sym,
        .add_section      = elf_add_section,
 
        .add_rela_section = elf_add_rela_section,
@@ -470,6 +471,6 @@ scf_elf_ops_t       elf_ops_naja =
        .read_section     = elf_read_section,
        .read_phdrs       = elf_read_phdrs,
 
-       .write_rel            = _naja_elf_write_rel,
+       .write_rel        = _naja_elf_write_rel,
        .write_exec       = _naja_elf_write_exec,
 };
index 4d28faca896903d666e75b7d217870e177132495..147d1e04bc083af32664f95a796c3a203e7d20f4 100644 (file)
@@ -653,6 +653,7 @@ static int _x64_elf_write_dyn(scf_elf_context_t* elf, const char* sysroot)
 scf_elf_ops_t  elf_ops_x64 =
 {
        .machine          = "x64",
+       .arch             = SCF_ELF_X64,
 
        .open             = elf_open,
        .close            = elf_close,
index ef56dff56f9a3a091797fa3dc197097f46825cf6..3dd88ab9898e85c8591f1f007abda8a7a274880e 100644 (file)
@@ -1,15 +1,5 @@
 #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;
-}
+#include"scf_naja_inst.c"
 
 int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes)
 {
@@ -36,8 +26,7 @@ int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes
        }
 
        // mov rd, imm[15:0]
-       opcode = (0xe << 26) | (rd->id << 21) | (0x2 << 16) | (imm & 0xffff);
-       inst   = risc_make_inst(c, opcode);
+       inst = naja_inst_MOV_IMM(c, rd, imm & 0xffff);
        RISC_INST_ADD_CHECK(c->instructions, inst);
 
        imm >>= 16;
@@ -91,7 +80,7 @@ int naja_inst_ADR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, sc
 
                        opcode = (0 << 26) | (rd->id << 21) | (0x3 << 18) | (0x3 << 16) | (offset << 4) | fp->id;
 
-               else if (offset < 0 && -offset <= 0x3fff)
+               else if (offset < 0 && -offset <= 0xfff)
 
                        opcode = (1 << 26) | (rd->id << 21) | (0x3 << 18) | (0x3 << 16) | ((-offset) << 4) | fp->id;
 
@@ -109,8 +98,7 @@ 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 = (0x35 << 26) | (rd->id << 21);
-               inst   = risc_make_inst(c, opcode);
+               inst = __naja_inst_ADRP(c, rd);
                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;
@@ -362,8 +350,7 @@ int naja_inst_ISTR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, s
 
        uint32_t opcode;
 
-       opcode = (0x35 << 26) | (rd->id << 21);
-       inst   = risc_make_inst(c, opcode);
+       inst = __naja_inst_ADRP(c, rd);
        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;
@@ -584,83 +571,17 @@ 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;
-
-       assert(0 == sib->disp);
-
-       if (!rb || !ri)
-               return -EINVAL;
-
-       int scale  = sib->scale;
-       int size   = sib->size;
-
-       uint32_t opcode;
-       uint32_t SIZE = 0;
-
-       if (1 == size)
-               SIZE = 0;
-
-       else if (2 == size)
-               SIZE = 1;
-
-       else if (4 == size)
-               SIZE = 2;
-
-       else if (8 == size)
-               SIZE = 3;
-       else
-               return -EINVAL;
+       scf_instruction_t* inst = __naja_inst_SIB2G(c, rd, sib);
 
-       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);
        RISC_INST_ADD_CHECK(c->instructions, inst);
-
        return 0;
 }
 
 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_instruction_t* inst = __naja_inst_G2SIB(c, rs, sib);
 
-       assert(0 == sib->disp);
-
-       if (!rb || !ri)
-               return -EINVAL;
-
-       int scale  = sib->scale;
-       int size   = sib->size;
-
-       uint32_t opcode;
-       uint32_t SIZE = 0;
-
-       if (1 == size)
-               SIZE = 0;
-
-       else if (2 == size)
-               SIZE = 1;
-
-       else if (4 == size)
-               SIZE = 2;
-
-       else if (8 == size)
-               SIZE = 3;
-       else
-               return -EINVAL;
-
-       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);
-
        return 0;
 }
 
@@ -669,483 +590,12 @@ int naja_inst_M2GF(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf
        return naja_inst_M2G(c, f, rd, rb, vs);
 }
 
-scf_instruction_t* naja_inst_PUSH(scf_3ac_code_t* c, scf_register_t* r)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode  = (0x9 << 26) | (r->id << 21) | (3 << 18) | 0xe;
-       opcode |= RISC_COLOR_TYPE(r->color) << 17;
-       inst    = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_POP(scf_3ac_code_t* c, scf_register_t* r)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode  = (0x8 << 26) | (r->id << 21) | (3 << 18) | 0xe;
-       opcode |= RISC_COLOR_TYPE(r->color) << 17;
-       inst    = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_RET(scf_3ac_code_t* c)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = 0x36 << 26;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_MOV_SP(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0xc << 26) | (rd->id << 21) | (3 << 18) | (0xf << 4) | rs->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_MOV_G(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (0xf << 4) | rs->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_MVN(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0xe << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (1 << 16) | rs->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_FMOV_G(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x1c << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | rs->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_MOVSX(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs, int size)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-       uint32_t           SH;
-
-       if (1 == size)
-               SH = 0;
-       else if (2 == size)
-               SH = 1;
-       else if (4 == size)
-               SH = 2;
-       else
-               return NULL;
-
-       opcode = (0xd << 26) | (rd->id << 21) | (SH << 18) | (1 << 17) | rs->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_MOVZX(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs, int size)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-       uint32_t           SH;
-
-       if (1 == size)
-               SH = 0;
-       else if (2 == size)
-               SH = 1;
-       else if (4 == size)
-               SH = 2;
-       else
-               return NULL;
-
-       opcode = (0xd << 26) | (rd->id << 21) | (SH << 18) | rs->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_CVTSS2SD(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-       uint32_t           S;
-
-       opcode = (0x1d << 26) | (rd->id << 21) | (3 << 18) | (1 << 12) | (1 << 6) | (2 << 4) | rs->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_CVTSD2SS(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x1d << 26) | (rd->id << 21) | (2 << 18) | (1 << 12) | (1 << 6) | (3 << 4) | rs->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_CVTF2SI(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-       uint32_t           SH;
-
-       if (4 == rd->bytes)
-               SH = 2;
-       else
-               SH = 3;
-
-       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;
-}
-
-scf_instruction_t* naja_inst_CVTF2UI(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-       uint32_t           SH;
-
-       if (4 == rd->bytes)
-               SH = 2;
-       else
-               SH = 3;
-
-       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;
-}
-
-scf_instruction_t* naja_inst_CVTSI2F(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-       uint32_t           SH;
-
-       if (4 == rd->bytes)
-               SH = 2;
-       else
-               SH = 3;
-
-       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;
-}
-
-scf_instruction_t* naja_inst_CVTUI2F(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-       uint32_t           SH;
-
-       if (4 == rd->bytes)
-               SH = 2;
-       else
-               SH = 3;
-
-       opcode = (0x1d << 26) | (rd->id << 21) | (SH << 18) | (1 << 12) | (2 << 6) | (naja_shift(rs->bytes) << 4) | rs->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_SUB_IMM(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_register_t* rs, uint64_t imm)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       if (imm > 0xfff) {
-               scf_loge("NOT support too big imm: %#lx\n", imm);
-               return NULL;
-       }
-
-       opcode = (1 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (3 << 16) | (imm << 4) | rs->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_CMP_IMM(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, uint64_t imm)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       if (imm > 0xfff) {
-               scf_loge("NOT support too big imm: %#lx\n", imm);
-               return NULL;
-       }
-
-       opcode = (1 << 26) | (0xf << 21) | (naja_shift(rs->bytes) << 18) | (3 << 16) | (imm << 4) | rs->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_ADD_IMM(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_register_t* rs, uint64_t imm)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       if (imm > 0xfff) {
-               scf_loge("NOT support too big imm: %#lx\n", imm);
-               return NULL;
-       }
-
-       opcode = (0 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (3 << 16) | (imm << 4) | rs->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_ADD_G(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode  = (0 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_SHL(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode  = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_SHR(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode  = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (1 << 16) | (rs1->id << 4) | rs0->id;
-       inst    = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_ASR(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode  = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (2 << 16) | (rs1->id << 4) | rs0->id;
-       inst    = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_AND_G(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x5 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_OR_G(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x7 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_SUB_G(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (1 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_CMP_G(scf_3ac_code_t* c, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (1 << 26) | (0xf << 21) | (naja_shift(rs0->bytes) << 18) | (rs1->id << 4) | rs0->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_FCMP(scf_3ac_code_t* c, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x11 << 26) | (0xf << 21) | (naja_shift(rs0->bytes) << 18) | (1 << 16) | (rs1->id << 4) | rs0->id;
-       inst    = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_NEG(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0xe << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | rs->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_TEQ(scf_3ac_code_t* c, scf_register_t* rs)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x5 << 26) | (0xf << 21) | (naja_shift(rs->bytes) << 18) | (rs->id << 4) | rs->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_FADD(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x10 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
-       inst    = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_FSUB(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x11 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
-       inst    = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_MUL(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (2 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (0xf << 12) | (rs1->id << 4) | rs0->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_FMUL(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x12 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (0xf << 12) | (rs1->id << 4) | rs0->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_FDIV(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x13 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
-       inst    = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_DIV(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (3 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_SDIV(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (3 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (1 << 17) | (rs1->id << 4) | rs0->id;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_MSUB(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rm, scf_register_t* rn, scf_register_t* ra)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       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;
-}
-
 int naja_inst_BL(scf_3ac_code_t* c, scf_function_t* f, scf_function_t* pf)
 {
        scf_instruction_t* inst;
        scf_rela_t*        rela;
-       uint32_t           opcode;
 
-       opcode = (0x31 << 26);
-       inst   = risc_make_inst(c, opcode);
+       inst = __naja_inst_BL(c, 0);
 
        RISC_INST_ADD_CHECK(c->instructions, inst);
        RISC_RELA_ADD_CHECK(f->text_relas,   rela, c, NULL, pf);
@@ -1154,216 +604,6 @@ int naja_inst_BL(scf_3ac_code_t* c, scf_function_t* f, scf_function_t* pf)
        return 0;
 }
 
-scf_instruction_t* naja_inst_BLR(scf_3ac_code_t* c, scf_register_t* r)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x33 << 26) | (r->id << 21);
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_SETZ(scf_3ac_code_t* c, scf_register_t* rd)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-       uint32_t           cc = 1;
-
-       opcode = (0x34 << 26) | (rd->id << 21);
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-scf_instruction_t* naja_inst_SETNZ(scf_3ac_code_t* c, scf_register_t* rd)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-       uint32_t           cc = 0;
-
-       opcode = (0x34 << 26) | (rd->id << 21) | (1 << 1);
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-scf_instruction_t* naja_inst_SETGT(scf_3ac_code_t* c, scf_register_t* rd)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x34 << 26) | (rd->id << 21) | (3 << 1);
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-scf_instruction_t* naja_inst_SETGE(scf_3ac_code_t* c, scf_register_t* rd)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x34 << 26) | (rd->id << 21) | (2 << 1);
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-scf_instruction_t* naja_inst_SETLT(scf_3ac_code_t* c, scf_register_t* rd)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x34 << 26) | (rd->id << 21) | (5 << 1);
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-scf_instruction_t* naja_inst_SETLE(scf_3ac_code_t* c, scf_register_t* rd)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x34 << 26) | (rd->id << 21) | (4 << 1);
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_JMP(scf_3ac_code_t* c)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = 0x30 << 26;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_JZ(scf_3ac_code_t* c)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x32 << 26) | 1;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_JNZ(scf_3ac_code_t* c)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x32 << 26) | (1 << 1) | 1;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_JGT(scf_3ac_code_t* c)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x32 << 26) | (3 << 1) | 1;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_JGE(scf_3ac_code_t* c)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x32 << 26) | (2 << 1) | 1;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_JLT(scf_3ac_code_t* c)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x32 << 26) | (5 << 1) | 1;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_JLE(scf_3ac_code_t* c)
-{
-       scf_instruction_t* inst;
-       uint32_t           opcode;
-
-       opcode = (0x32 << 26) | (4 << 1) | 1;
-       inst   = risc_make_inst(c, opcode);
-
-       return inst;
-}
-
-scf_instruction_t* naja_inst_JA(scf_3ac_code_t* c)
-{
-       return NULL;
-}
-scf_instruction_t* naja_inst_JB(scf_3ac_code_t* c)
-{
-       return NULL;
-}
-scf_instruction_t* naja_inst_JAE(scf_3ac_code_t* c)
-{
-       return NULL;
-}
-scf_instruction_t* naja_inst_JBE(scf_3ac_code_t* c)
-{
-       return NULL;
-}
-
-void naja_set_jmp_offset(scf_instruction_t* inst, int32_t bytes)
-{
-       uint32_t opcode;
-
-       opcode  = inst->code[0];
-       opcode |= inst->code[1] <<  8;
-       opcode |= inst->code[2] << 16;
-       opcode |= inst->code[3] << 24;
-
-       if (0x32 == (opcode >> 26) && 1 == (opcode & 1)) {
-
-               if (bytes  >= 0 && bytes < (0x1 << 20)) {
-                       bytes >>= 2;
-                       bytes <<= 5;
-
-               } else if (bytes < 0 && bytes > -(0x1 << 20)) {
-
-                       bytes >>= 2;
-                       bytes  &= 0x1fffff;
-                       bytes <<= 5;
-               } else
-                       assert(0);
-
-               inst->code[0] |= 0xff &  bytes;
-               inst->code[1] |= 0xff & (bytes >>  8);
-               inst->code[2] |= 0xff & (bytes >> 16);
-               inst->code[3] |= 0x3  & (bytes >> 24);
-
-       } else {
-               assert(0x30 == (opcode >> 26));
-
-               bytes >>= 2;
-
-               assert(bytes < (0x1 << 26) && bytes > -(0x1 << 26));
-
-               inst->code[0] |= 0xff &  bytes;
-               inst->code[1] |= 0xff & (bytes >>  8);
-               inst->code[2] |= 0xff & (bytes >> 16);
-               inst->code[3] |= 0x3  & (bytes >> 24);
-       }
-}
-
 int naja_cmp_update(scf_3ac_code_t* c, scf_function_t* f, scf_instruction_t* cmp)
 {
        scf_instruction_t* inst;
diff --git a/native/risc/scf_naja_inst.c b/native/risc/scf_naja_inst.c
new file mode 100644 (file)
index 0000000..f733572
--- /dev/null
@@ -0,0 +1,911 @@
+#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;
+}
+
+scf_instruction_t* __naja_inst_ADRP(scf_3ac_code_t* c, scf_register_t* rd)
+{
+       scf_instruction_t*  inst;
+       uint32_t            opcode;
+
+       opcode = (0x35 << 26) | (rd->id << 21);
+
+       inst = risc_make_inst(c, opcode);
+       if (inst) {
+               inst->OpCode   = (scf_OpCode_t*)risc_find_OpCode(SCF_RISC_ADRP, 8,8, SCF_RISC_E2G);
+               inst->dst.base = rd;
+               inst->src.flag = 1;
+       }
+
+       return inst;
+}
+
+scf_instruction_t* __naja_inst_SIB2G(scf_3ac_code_t* c, 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;
+
+       assert(0 == sib->disp);
+
+       if (!rb || !ri)
+               return NULL;
+
+       int scale  = sib->scale;
+       int size   = sib->size;
+
+       uint32_t opcode;
+       uint32_t SIZE = 0;
+
+       if (1 == size)
+               SIZE = 0;
+
+       else if (2 == size)
+               SIZE = 1;
+
+       else if (4 == size)
+               SIZE = 2;
+
+       else if (8 == size)
+               SIZE = 3;
+       else
+               return NULL;
+
+       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);
+       return inst;
+}
+
+scf_instruction_t* __naja_inst_G2SIB(scf_3ac_code_t* c, 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;
+
+       assert(0 == sib->disp);
+
+       if (!rb || !ri)
+               return NULL;
+
+       int scale  = sib->scale;
+       int size   = sib->size;
+
+       uint32_t opcode;
+       uint32_t SIZE = 0;
+
+       if (1 == size)
+               SIZE = 0;
+
+       else if (2 == size)
+               SIZE = 1;
+
+       else if (4 == size)
+               SIZE = 2;
+
+       else if (8 == size)
+               SIZE = 3;
+       else
+               return NULL;
+
+       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);
+       return inst;
+}
+
+scf_instruction_t* naja_inst_PUSH(scf_3ac_code_t* c, scf_register_t* r)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode  = (0x9 << 26) | (r->id << 21) | (3 << 18) | 0xe;
+       opcode |= RISC_COLOR_TYPE(r->color) << 17;
+
+       inst = risc_make_inst(c, opcode);
+       if (inst) {
+               inst->OpCode   = (scf_OpCode_t*)risc_find_OpCode(SCF_RISC_PUSH, 8,8, SCF_RISC_G);
+               inst->src.base = r;
+       }
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_POP(scf_3ac_code_t* c, scf_register_t* r)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode  = (0x8 << 26) | (r->id << 21) | (3 << 18) | 0xe;
+       opcode |= RISC_COLOR_TYPE(r->color) << 17;
+
+       inst = risc_make_inst(c, opcode);
+       if (inst) {
+               inst->OpCode   = (scf_OpCode_t*)risc_find_OpCode(SCF_RISC_POP, 8,8, SCF_RISC_G);
+               inst->dst.base = r;
+       }
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_RET(scf_3ac_code_t* c)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = 0x36 << 26;
+
+       inst = risc_make_inst(c, opcode);
+       if (inst)
+               inst->OpCode = (scf_OpCode_t*)risc_find_OpCode(SCF_RISC_RET, 8,8, SCF_RISC_G);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_MOV_SP(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0xc << 26) | (rd->id << 21) | (3 << 18) | (0xf << 4) | rs->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_MOV_G(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (0xf << 4) | rs->id;
+
+       inst = risc_make_inst(c, opcode);
+       if (inst) {
+               inst->OpCode   = (scf_OpCode_t*)risc_find_OpCode(SCF_RISC_MOV, 8,8, SCF_RISC_G2E);
+               inst->dst.base = rd;
+               inst->src.base = rs;
+       }
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_MOV_IMM(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       if (imm > 0xffff) {
+               scf_loge("NOT support too big imm: %#lx\n", imm);
+               return NULL;
+       }
+
+       opcode = (0xe << 26) | (rd->id << 21) | (0x2 << 16) | (imm & 0xffff);
+
+       inst = risc_make_inst(c, opcode);
+       if (inst) {
+               inst->OpCode   = (scf_OpCode_t*)risc_find_OpCode(SCF_RISC_MOV, 2,2, SCF_RISC_I2G);
+               inst->dst.base = rd;
+               inst->src.imm  = imm;
+               inst->src.imm_size = 2;
+       }
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_MVN(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0xe << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (1 << 16) | rs->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_FMOV_G(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x1c << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | rs->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_MOVSX(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs, int size)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+       uint32_t           SH;
+
+       if (1 == size)
+               SH = 0;
+       else if (2 == size)
+               SH = 1;
+       else if (4 == size)
+               SH = 2;
+       else
+               return NULL;
+
+       opcode = (0xd << 26) | (rd->id << 21) | (SH << 18) | (1 << 17) | rs->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_MOVZX(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs, int size)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+       uint32_t           SH;
+
+       if (1 == size)
+               SH = 0;
+       else if (2 == size)
+               SH = 1;
+       else if (4 == size)
+               SH = 2;
+       else
+               return NULL;
+
+       opcode = (0xd << 26) | (rd->id << 21) | (SH << 18) | rs->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_CVTSS2SD(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+       uint32_t           S;
+
+       opcode = (0x1d << 26) | (rd->id << 21) | (3 << 18) | (1 << 12) | (1 << 6) | (2 << 4) | rs->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_CVTSD2SS(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x1d << 26) | (rd->id << 21) | (2 << 18) | (1 << 12) | (1 << 6) | (3 << 4) | rs->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_CVTF2SI(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+       uint32_t           SH;
+
+       if (4 == rd->bytes)
+               SH = 2;
+       else
+               SH = 3;
+
+       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;
+}
+
+scf_instruction_t* naja_inst_CVTF2UI(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+       uint32_t           SH;
+
+       if (4 == rd->bytes)
+               SH = 2;
+       else
+               SH = 3;
+
+       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;
+}
+
+scf_instruction_t* naja_inst_CVTSI2F(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+       uint32_t           SH;
+
+       if (4 == rd->bytes)
+               SH = 2;
+       else
+               SH = 3;
+
+       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;
+}
+
+scf_instruction_t* naja_inst_CVTUI2F(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+       uint32_t           SH;
+
+       if (4 == rd->bytes)
+               SH = 2;
+       else
+               SH = 3;
+
+       opcode = (0x1d << 26) | (rd->id << 21) | (SH << 18) | (1 << 12) | (2 << 6) | (naja_shift(rs->bytes) << 4) | rs->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_SUB_IMM(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_register_t* rs, uint64_t imm)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       if (imm > 0xfff) {
+               scf_loge("NOT support too big imm: %#lx\n", imm);
+               return NULL;
+       }
+
+       opcode = (1 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (3 << 16) | (imm << 4) | rs->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_CMP_IMM(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, uint64_t imm)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       if (imm > 0xfff) {
+               scf_loge("NOT support too big imm: %#lx\n", imm);
+               return NULL;
+       }
+
+       opcode = (1 << 26) | (0xf << 21) | (naja_shift(rs->bytes) << 18) | (3 << 16) | (imm << 4) | rs->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_ADD_IMM(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_register_t* rs, uint64_t imm)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       if (imm > 0xfff) {
+               scf_loge("NOT support too big imm: %#lx\n", imm);
+               return NULL;
+       }
+
+       opcode = (0 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (3 << 16) | (imm << 4) | rs->id;
+
+       inst = risc_make_inst(c, opcode);
+       if (inst) {
+               inst->OpCode   = (scf_OpCode_t*)risc_find_OpCode(SCF_RISC_ADD, 8,8, SCF_RISC_E2G);
+               inst->dst.base = rd;
+               inst->src.base = rs;
+
+               inst->srcs[0].imm = imm;
+               inst->srcs[0].imm_size = 2;
+       }
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_ADD_G(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
+
+       inst = risc_make_inst(c, opcode);
+       if (inst) {
+               inst->OpCode    = (scf_OpCode_t*)risc_find_OpCode(SCF_RISC_ADD, 8,8, SCF_RISC_E2G);
+               inst->dst.base  = rd;
+               inst->src.base  = rs0;
+
+               inst->srcs[0].base = rs1;
+       }
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_SHL(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode  = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_SHR(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode  = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (1 << 16) | (rs1->id << 4) | rs0->id;
+       inst    = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_ASR(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode  = (0xc << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (2 << 16) | (rs1->id << 4) | rs0->id;
+       inst    = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_AND_G(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x5 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_OR_G(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x7 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_SUB_G(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (1 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_CMP_G(scf_3ac_code_t* c, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (1 << 26) | (0xf << 21) | (naja_shift(rs0->bytes) << 18) | (rs1->id << 4) | rs0->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_FCMP(scf_3ac_code_t* c, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x11 << 26) | (0xf << 21) | (naja_shift(rs0->bytes) << 18) | (1 << 16) | (rs1->id << 4) | rs0->id;
+       inst    = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_NEG(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0xe << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | rs->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_TEQ(scf_3ac_code_t* c, scf_register_t* rs)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x5 << 26) | (0xf << 21) | (naja_shift(rs->bytes) << 18) | (rs->id << 4) | rs->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_FADD(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x10 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
+       inst    = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_FSUB(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x11 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
+       inst    = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_MUL(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (2 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (0xf << 12) | (rs1->id << 4) | rs0->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_FMUL(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x12 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (0xf << 12) | (rs1->id << 4) | rs0->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_FDIV(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x13 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
+       inst    = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_DIV(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (3 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (rs1->id << 4) | rs0->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_SDIV(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rs0, scf_register_t* rs1)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (3 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (1 << 17) | (rs1->id << 4) | rs0->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_MSUB(scf_3ac_code_t* c, scf_register_t* rd, scf_register_t* rm, scf_register_t* rn, scf_register_t* ra)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (2 << 26) | (rd->id << 21) | (naja_shift(rd->bytes) << 18) | (1 << 16) | (ra->id << 12) | (rm->id << 4) | rn->id;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_BR(scf_3ac_code_t* c, scf_register_t* r)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x32 << 26) | (r->id << 21);
+
+       inst = risc_make_inst(c, opcode);
+       if (inst) {
+               inst->OpCode   = (scf_OpCode_t*)risc_find_OpCode(SCF_RISC_JMP, 8,8, SCF_RISC_E);
+               inst->dst.base = r;
+       }
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_BLR(scf_3ac_code_t* c, scf_register_t* r)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x33 << 26) | (r->id << 21);
+
+       inst = risc_make_inst(c, opcode);
+       if (inst) {
+               inst->OpCode   = (scf_OpCode_t*)risc_find_OpCode(SCF_RISC_CALL, 8,8, SCF_RISC_E);
+               inst->dst.base = r;
+       }
+
+       return inst;
+}
+
+scf_instruction_t* __naja_inst_BL(scf_3ac_code_t* c, uint64_t imm)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       if (imm > 0x3ffffff) {
+               scf_loge("NOT support too big imm: %#lx\n", imm);
+               return NULL;
+       }
+
+       opcode = (0x31 << 26) | imm;
+
+       inst = risc_make_inst(c, opcode);
+       if (inst) {
+               inst->OpCode  = (scf_OpCode_t*)risc_find_OpCode(SCF_RISC_CALL, 4,4, SCF_RISC_I);
+               inst->dst.imm = imm;
+               inst->dst.imm_size = 4;
+       }
+
+       return inst;
+}
+
+scf_instruction_t* __naja_inst_JMP(scf_3ac_code_t* c, uint64_t imm)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       if (imm > 0x3ffffff) {
+               scf_loge("NOT support too big imm: %#lx\n", imm);
+               return NULL;
+       }
+
+       opcode = 0x30 << 26 | imm;
+
+       inst = risc_make_inst(c, opcode);
+       if (inst) {
+               inst->OpCode  = (scf_OpCode_t*)risc_find_OpCode(SCF_RISC_JMP, 4,4, SCF_RISC_I);
+               inst->dst.imm = imm;
+               inst->dst.imm_size = 4;
+       }
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_SETZ(scf_3ac_code_t* c, scf_register_t* rd)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+       uint32_t           cc = 1;
+
+       opcode = (0x34 << 26) | (rd->id << 21);
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+scf_instruction_t* naja_inst_SETNZ(scf_3ac_code_t* c, scf_register_t* rd)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+       uint32_t           cc = 0;
+
+       opcode = (0x34 << 26) | (rd->id << 21) | (1 << 1);
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+scf_instruction_t* naja_inst_SETGT(scf_3ac_code_t* c, scf_register_t* rd)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x34 << 26) | (rd->id << 21) | (3 << 1);
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+scf_instruction_t* naja_inst_SETGE(scf_3ac_code_t* c, scf_register_t* rd)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x34 << 26) | (rd->id << 21) | (2 << 1);
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+scf_instruction_t* naja_inst_SETLT(scf_3ac_code_t* c, scf_register_t* rd)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x34 << 26) | (rd->id << 21) | (5 << 1);
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+scf_instruction_t* naja_inst_SETLE(scf_3ac_code_t* c, scf_register_t* rd)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x34 << 26) | (rd->id << 21) | (4 << 1);
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_JMP(scf_3ac_code_t* c)
+{
+       return __naja_inst_JMP(c, 0);
+}
+
+scf_instruction_t* naja_inst_JZ(scf_3ac_code_t* c)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x32 << 26) | 1;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_JNZ(scf_3ac_code_t* c)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x32 << 26) | (1 << 1) | 1;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_JGT(scf_3ac_code_t* c)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x32 << 26) | (3 << 1) | 1;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_JGE(scf_3ac_code_t* c)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x32 << 26) | (2 << 1) | 1;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_JLT(scf_3ac_code_t* c)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x32 << 26) | (5 << 1) | 1;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_JLE(scf_3ac_code_t* c)
+{
+       scf_instruction_t* inst;
+       uint32_t           opcode;
+
+       opcode = (0x32 << 26) | (4 << 1) | 1;
+       inst   = risc_make_inst(c, opcode);
+
+       return inst;
+}
+
+scf_instruction_t* naja_inst_JA(scf_3ac_code_t* c)
+{
+       return NULL;
+}
+scf_instruction_t* naja_inst_JB(scf_3ac_code_t* c)
+{
+       return NULL;
+}
+scf_instruction_t* naja_inst_JAE(scf_3ac_code_t* c)
+{
+       return NULL;
+}
+scf_instruction_t* naja_inst_JBE(scf_3ac_code_t* c)
+{
+       return NULL;
+}
+
+void naja_set_jmp_offset(scf_instruction_t* inst, int32_t bytes)
+{
+       uint32_t opcode;
+
+       opcode  = inst->code[0];
+       opcode |= inst->code[1] <<  8;
+       opcode |= inst->code[2] << 16;
+       opcode |= inst->code[3] << 24;
+
+       if (0x32 == (opcode >> 26) && 1 == (opcode & 1)) {
+
+               if (bytes  >= 0 && bytes < (0x1 << 20)) {
+                       bytes >>= 2;
+                       bytes <<= 5;
+
+               } else if (bytes < 0 && bytes > -(0x1 << 20)) {
+
+                       bytes >>= 2;
+                       bytes  &= 0x1fffff;
+                       bytes <<= 5;
+               } else
+                       assert(0);
+
+               opcode &= ~0x1ffffe0;
+               opcode |= bytes;
+
+               inst->code[0] = 0xff &  opcode;
+               inst->code[1] = 0xff & (opcode >>  8);
+               inst->code[2] = 0xff & (opcode >> 16);
+               inst->code[3] = 0xff & (opcode >> 24);
+
+       } else if (0x30 == (opcode >> 26)
+                       || 0x31 == (opcode >> 26)) {
+
+               bytes >>= 2;
+
+               assert(bytes < (0x1 << 26) && bytes > -(0x1 << 26));
+
+               bytes  &=  0x3ffffff;
+               opcode &= ~0x3ffffff;
+               opcode |= bytes;
+
+               inst->code[0] = 0xff &  opcode;
+               inst->code[1] = 0xff & (opcode >>  8);
+               inst->code[2] = 0xff & (opcode >> 16);
+               inst->code[3] = 0xff & (opcode >> 24);
+       }
+}
diff --git a/native/risc/scf_naja_reg.c b/native/risc/scf_naja_reg.c
new file mode 100644 (file)
index 0000000..cfa2532
--- /dev/null
@@ -0,0 +1,285 @@
+#include"scf_risc.h"
+
+#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},
+};
+
+static uint32_t naja_abi_regs[] =
+{
+       SCF_RISC_REG_X0,
+       SCF_RISC_REG_X1,
+       SCF_RISC_REG_X2,
+       SCF_RISC_REG_X3,
+       SCF_RISC_REG_X4,
+       SCF_RISC_REG_X5,
+};
+
+static uint32_t naja_abi_float_regs[] =
+{
+       SCF_RISC_REG_D0,
+       SCF_RISC_REG_D1,
+       SCF_RISC_REG_D2,
+       SCF_RISC_REG_D3,
+       SCF_RISC_REG_D4,
+       SCF_RISC_REG_D5,
+       SCF_RISC_REG_D6,
+       SCF_RISC_REG_D7,
+};
+
+static uint32_t naja_abi_ret_regs[] =
+{
+       SCF_RISC_REG_X0,
+       SCF_RISC_REG_X1,
+       SCF_RISC_REG_X2,
+       SCF_RISC_REG_X3,
+};
+
+static uint32_t naja_abi_caller_saves[] =
+{
+       SCF_RISC_REG_X0,
+       SCF_RISC_REG_X1,
+       SCF_RISC_REG_X2,
+       SCF_RISC_REG_X3,
+       SCF_RISC_REG_X4,
+       SCF_RISC_REG_X5,
+};
+
+static uint32_t naja_abi_callee_saves[] =
+{
+       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)
+{
+       intptr_t id0 = c0 >> 16;
+       intptr_t id1 = c1 >> 16;
+
+       return id0 == id1 && (c0 & c1 & 0xffff);
+}
+
+static int naja_variable_size(scf_variable_t* v)
+{
+       if (v->nb_dimentions > 0)
+               return 8;
+
+       if (v->type >= SCF_STRUCT && 0 == v->nb_pointers)
+               return 8;
+
+       return v->size;
+}
+
+scf_register_t* naja_find_register(const char* name)
+{
+       int i;
+       for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) {
+
+               scf_register_t* r = &(naja_registers[i]);
+
+               if (!strcmp(r->name, name))
+                       return r;
+       }
+       return NULL;
+}
+
+scf_register_t* naja_find_register_type_id_bytes(uint32_t type, uint32_t id, int bytes)
+{
+       int i;
+       for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) {
+
+               scf_register_t* r = &(naja_registers[i]);
+
+               if (RISC_COLOR_TYPE(r->color) == type && r->id == id && r->bytes == bytes)
+                       return r;
+       }
+       return NULL;
+}
+
+scf_register_t* naja_find_register_color(intptr_t color)
+{
+       int i;
+       for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) {
+
+               scf_register_t* r = &(naja_registers[i]);
+
+               if (r->color == color)
+                       return r;
+       }
+       return NULL;
+}
+
+scf_register_t* naja_find_register_color_bytes(intptr_t color, int bytes)
+{
+       int i;
+       for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) {
+
+               scf_register_t* r = &(naja_registers[i]);
+
+               if (naja_color_conflict(r->color, color) && r->bytes == bytes)
+                       return r;
+       }
+       return NULL;
+}
index d0b71d8b21bb0bbfb70f3b28c6b5a0b48b72c18f..8b5850bf14208f189f43ca92cbc67f9f42262548 100644 (file)
@@ -631,10 +631,11 @@ static int _risc_make_insts_for_list(scf_native_t* ctx, scf_basic_block_t* bb, i
 
 static void _risc_set_offset_for_jmps(scf_native_t* ctx, scf_function_t* f)
 {
+       scf_3ac_code_t* c;
        int i;
 
        for (i = 0; i < f->jmps->size; i++) {
-               scf_3ac_code_t*    c      = f->jmps->data[i];
+               c  =        f->jmps->data[i];
 
                assert(c->instructions && 1 == c->instructions->size);
 
@@ -651,14 +652,12 @@ static void _risc_set_offset_for_jmps(scf_native_t* ctx, scf_function_t* f)
                        for (l = &cur_bb->list; l != &dst_bb->list; l = scf_list_next(l)) {
 
                                bb     = scf_list_data(l, scf_basic_block_t, list);
-
                                bytes += bb->code_bytes;
                        }
                } else {
                        for (l = &dst_bb->list; l != &cur_bb->list; l = scf_list_next(l)) {
 
                                bb     = scf_list_data(l, scf_basic_block_t, list);
-
                                bytes -= bb->code_bytes;
                        }
                }
index 40930d26f1b34109d94187bf0a2f512c8f23ecf7..41847cbd43ec7ea9ec30aa5ab853c4edc4639bd7 100644 (file)
@@ -8,40 +8,6 @@
 #include"scf_graph.h"
 #include"scf_elf.h"
 
-#define RISC_INST_ADD_CHECK(vec, inst) \
-                       do { \
-                               if (!(inst)) { \
-                                       scf_loge("\n"); \
-                                       return -ENOMEM; \
-                               } \
-                               int ret = scf_vector_add((vec), (inst)); \
-                               if (ret < 0) { \
-                                       scf_loge("\n"); \
-                                       free(inst); \
-                                       return ret; \
-                               } \
-                       } while (0)
-
-#define RISC_RELA_ADD_CHECK(vec, rela, c, v, f) \
-       do { \
-               rela = calloc(1, sizeof(scf_rela_t)); \
-               if (!rela) \
-                       return -ENOMEM; \
-               \
-               (rela)->code = (c); \
-               (rela)->var  = (v); \
-               (rela)->func = (f); \
-               (rela)->inst = (c)->instructions->data[(c)->instructions->size - 1]; \
-               (rela)->addend = 0; \
-               \
-               int ret = scf_vector_add((vec), (rela)); \
-               if (ret < 0) { \
-                       free(rela); \
-                       rela = NULL; \
-                       return ret; \
-               } \
-       } while (0)
-
 #define RISC_PEEPHOLE_DEL 1
 #define RISC_PEEPHOLE_OK  0
 
@@ -92,7 +58,6 @@ int  risc_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_functi
 void risc_init_bb_colors (scf_basic_block_t* bb, scf_function_t* f);
 
 
-scf_instruction_t* risc_make_inst         (scf_3ac_code_t* c, uint32_t opcode);
 scf_instruction_t* risc_make_inst_BL      (scf_3ac_code_t* c);
 scf_instruction_t* risc_make_inst_BLR     (scf_3ac_code_t* c, scf_register_t* r);
 scf_instruction_t* risc_make_inst_PUSH    (scf_3ac_code_t* c, scf_register_t* r);
@@ -172,4 +137,3 @@ int risc_make_inst_ADRSIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t
 int risc_rcg_make(scf_3ac_code_t* c, scf_graph_t* g, scf_dag_node_t* dn, scf_register_t* reg);
 
 #endif
-
index 2d64b8d84369f50e49e4954ce622b68e1cc1c92f..c0d0143a3b965db7b34c5abe94ac2c3bf3a406d5 100644 (file)
@@ -5752,21 +5752,3 @@ risc_inst_handler_pt  scf_risc_find_inst_handler(const int op_type)
 
        return risc_inst_handlers[op_type];
 }
-
-scf_instruction_t* risc_make_inst(scf_3ac_code_t* c, uint32_t opcode)
-{
-       scf_instruction_t* inst;
-
-       inst = calloc(1, sizeof(scf_instruction_t));
-       if (!inst)
-               return NULL;
-
-       inst->c       = c;
-       inst->code[0] = opcode & 0xff;
-       inst->code[1] = (opcode >>  8) & 0xff;
-       inst->code[2] = (opcode >> 16) & 0xff;
-       inst->code[3] = (opcode >> 24) & 0xff;
-       inst->len     = 4;
-
-       return inst;
-}
index b12e502a9f36be9aacb9eb1aea6aad51f3eac185..d4a91414c3177c6bbbc223da1b048de9d1aeb638 100644 (file)
@@ -1,6 +1,7 @@
 #include"scf_risc.h"
 
-scf_risc_OpCode_t      risc_OpCodes[] = {
+scf_risc_OpCode_t      risc_OpCodes[] =
+{
        {SCF_RISC_PUSH, "push", 1, {0x50, 0x0, 0x0},1,  8,8, SCF_RISC_G,   0,0, 0,{0,0}},
        {SCF_RISC_POP,  "pop",  1, {0x58, 0x0, 0x0},1,  8,8, SCF_RISC_G,   0,0, 0,{0,0}},
 
@@ -59,6 +60,11 @@ scf_risc_OpCode_t    risc_OpCodes[] = {
 
        {SCF_RISC_RET,  "ret",  1, {0xc3, 0x0, 0x0},1,  8,8, SCF_RISC_G,   0,0, 0,{0,0}},
 
+       {SCF_RISC_ADD,  "addb", 2, {0x00, 0x0, 0x0},1,  1,1, SCF_RISC_G2E, 0,0, 0,{0,0}},
+       {SCF_RISC_ADD,  "addw", 2, {0x01, 0x0, 0x0},1,  2,2, SCF_RISC_G2E, 0,0, 0,{0,0}},
+       {SCF_RISC_ADD,  "addl", 2, {0x01, 0x0, 0x0},1,  4,4, SCF_RISC_G2E, 0,0, 0,{0,0}},
+       {SCF_RISC_ADD,  "addq", 2, {0x01, 0x0, 0x0},1,  8,8, SCF_RISC_G2E, 0,0, 0,{0,0}},
+
        {SCF_RISC_ADD,  "add",  2, {0x00, 0x0, 0x0},1,  1,1, SCF_RISC_G2E, 0,0, 0,{0,0}},
        {SCF_RISC_ADD,  "add",  2, {0x01, 0x0, 0x0},1,  2,2, SCF_RISC_G2E, 0,0, 0,{0,0}},
        {SCF_RISC_ADD,  "add",  2, {0x01, 0x0, 0x0},1,  4,4, SCF_RISC_G2E, 0,0, 0,{0,0}},
@@ -162,6 +168,11 @@ scf_risc_OpCode_t  risc_OpCodes[] = {
 
        {SCF_RISC_LEA,  "lea",  1, {0x8d, 0x0, 0x0},1,  8,8, SCF_RISC_E2G, 0,0, 0,{0,0}},
 
+       {SCF_RISC_MOV,  "movb", 2, {0x88, 0x0, 0x0},1,  1,1, SCF_RISC_G2E, 0,0, 0,{0,0}},
+       {SCF_RISC_MOV,  "movw", 2, {0x89, 0x0, 0x0},1,  2,2, SCF_RISC_G2E, 0,0, 0,{0,0}},
+       {SCF_RISC_MOV,  "movl", 2, {0x89, 0x0, 0x0},1,  4,4, SCF_RISC_G2E, 0,0, 0,{0,0}},
+       {SCF_RISC_MOV,  "movq", 2, {0x89, 0x0, 0x0},1,  8,8, SCF_RISC_G2E, 0,0, 0,{0,0}},
+
        {SCF_RISC_MOV,  "mov",  2, {0x88, 0x0, 0x0},1,  1,1, SCF_RISC_G2E, 0,0, 0,{0,0}},
        {SCF_RISC_MOV,  "mov",  2, {0x89, 0x0, 0x0},1,  2,2, SCF_RISC_G2E, 0,0, 0,{0,0}},
        {SCF_RISC_MOV,  "mov",  2, {0x89, 0x0, 0x0},1,  4,4, SCF_RISC_G2E, 0,0, 0,{0,0}},
@@ -310,9 +321,11 @@ scf_risc_OpCode_t  risc_OpCodes[] = {
        {SCF_RISC_JMP,  "jmp",  2, {0xeb, 0x0, 0x0},1,  1,1, SCF_RISC_I, 0,0, 0,{0,0}},
        {SCF_RISC_JMP,  "jmp",  5, {0xe9, 0x0, 0x0},1,  4,4, SCF_RISC_I, 0,0, 0,{0,0}},
        {SCF_RISC_JMP,  "jmp",  2, {0xff, 0x0, 0x0},1,  8,8, SCF_RISC_E, 4,1, 0,{0,0}},
+
+       {SCF_RISC_ADRP, "adrp", 1, {0xff, 0x0, 0x0},1,  8,8, SCF_RISC_E2G, 0,0, 0,{0,0}},
 };
 
-scf_risc_OpCode_t*   risc_find_OpCode_by_type(const int type)
+scf_risc_OpCode_t* risc_find_OpCode_by_type(const int type)
 {
        int i;
        for (i = 0; i < sizeof(risc_OpCodes) / sizeof(risc_OpCodes[0]); i++) {
@@ -324,23 +337,19 @@ scf_risc_OpCode_t*   risc_find_OpCode_by_type(const int type)
        return NULL;
 }
 
-scf_risc_OpCode_t* risc_find_OpCode(const int type, const int OpBytes, const int RegBytes, const int EG)
+scf_risc_OpCode_t* risc_find_OpCode_by_name(const char* name)
 {
        int i;
        for (i = 0; i < sizeof(risc_OpCodes) / sizeof(risc_OpCodes[0]); i++) {
 
                scf_risc_OpCode_t* OpCode = &(risc_OpCodes[i]);
-
-               if (type == OpCode->type
-                               && OpBytes == OpCode->OpBytes
-                               && RegBytes == OpCode->RegBytes
-                               && EG == OpCode->EG)
+               if (!strcmp(OpCode->name, name))
                        return OpCode;
        }
        return NULL;
 }
 
-int risc_find_OpCodes(scf_vector_t* results, const int type, const int OpBytes, const int RegBytes, const int EG)
+scf_risc_OpCode_t* risc_find_OpCode(const int type, const int OpBytes, const int RegBytes, const int EG)
 {
        int i;
        for (i = 0; i < sizeof(risc_OpCodes) / sizeof(risc_OpCodes[0]); i++) {
@@ -350,13 +359,26 @@ int risc_find_OpCodes(scf_vector_t* results, const int type, const int OpBytes,
                if (type == OpCode->type
                                && OpBytes == OpCode->OpBytes
                                && RegBytes == OpCode->RegBytes
-                               && EG == OpCode->EG) {
-
-                       int ret = scf_vector_add(results, OpCode);
-                       if (ret < 0)
-                               return ret;
-               }
+                               && EG == OpCode->EG)
+                       return OpCode;
        }
-       return 0;
+       return NULL;
 }
 
+scf_instruction_t* risc_make_inst(scf_3ac_code_t* c, uint32_t opcode)
+{
+       scf_instruction_t* inst;
+
+       inst = calloc(1, sizeof(scf_instruction_t));
+       if (!inst)
+               return NULL;
+
+       inst->c       = c;
+       inst->code[0] = opcode & 0xff;
+       inst->code[1] = (opcode >>  8) & 0xff;
+       inst->code[2] = (opcode >> 16) & 0xff;
+       inst->code[3] = (opcode >> 24) & 0xff;
+       inst->len     = 4;
+
+       return inst;
+}
index 0f7286a84532895d85acbeb6f8be0ff2d75782a8..c1f7653870b5e4d5a6fa3f4d6950a5e3be37f568 100644 (file)
@@ -27,11 +27,64 @@ typedef struct {
        uint32_t    regs[2];
 } scf_risc_OpCode_t;
 
-scf_risc_OpCode_t*   risc_find_OpCode_by_type(const int type);
+scf_risc_OpCode_t*  risc_find_OpCode_by_name(const char* name);
+scf_risc_OpCode_t*  risc_find_OpCode_by_type(const int   type);
+scf_risc_OpCode_t*  risc_find_OpCode        (const int   type, const int OpBytes, const int RegBytes, const int EG);
 
-scf_risc_OpCode_t*   risc_find_OpCode(const int type, const int OpBytes, const int RegBytes, const int EG);
+scf_instruction_t*  risc_make_inst(scf_3ac_code_t* c, uint32_t opcode);
 
-int                 risc_find_OpCodes(scf_vector_t* results, const int type, const int OpBytes, const int RegBytes, const int EG);
+#define RISC_INST_ADD_CHECK(vec, inst) \
+                       do { \
+                               if (!(inst)) { \
+                                       scf_loge("\n"); \
+                                       return -ENOMEM; \
+                               } \
+                               int ret = scf_vector_add((vec), (inst)); \
+                               if (ret < 0) { \
+                                       scf_loge("\n"); \
+                                       scf_instruction_free(inst); \
+                                       return ret; \
+                               } \
+                       } while (0)
 
-#endif
+#define RISC_RELA_ADD_CHECK(vec, rela, c, v, f) \
+       do { \
+               rela = calloc(1, sizeof(scf_rela_t)); \
+               if (!rela) \
+                       return -ENOMEM; \
+               \
+               (rela)->code = (c); \
+               (rela)->var  = (v); \
+               (rela)->func = (f); \
+               (rela)->inst = (c)->instructions->data[(c)->instructions->size - 1]; \
+               (rela)->addend = 0; \
+               \
+               int ret = scf_vector_add((vec), (rela)); \
+               if (ret < 0) { \
+                       scf_rela_free(rela); \
+                       return ret; \
+               } \
+       } while (0)
+
+#define RISC_RELA_ADD_LABEL(vec, rela, _inst, _label) \
+       do { \
+               rela = calloc(1, sizeof(scf_rela_t)); \
+               if (!rela) \
+                       return -ENOMEM; \
+               \
+               (rela)->inst  = (_inst); \
+               (rela)->name = scf_string_clone(_label); \
+               if (!(rela)->name) { \
+                       scf_loge("\n"); \
+                       scf_rela_free(rela); \
+                       return -ENOMEM; \
+               } \
+               int ret = scf_vector_add((vec), (rela)); \
+               if (ret < 0) { \
+                       scf_loge("\n"); \
+                       scf_rela_free(rela); \
+                       return ret; \
+               } \
+       } while (0)
 
+#endif
index 9b6ff13ff85c5860e0953e652d089fdeb96502f7..6a9ca314709a829f01756168b70abd82fb4bbe8e 100644 (file)
@@ -1,288 +1,5 @@
 #include"scf_risc.h"
-
-#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},
-};
-
-static uint32_t naja_abi_regs[] =
-{
-       SCF_RISC_REG_X0,
-       SCF_RISC_REG_X1,
-       SCF_RISC_REG_X2,
-       SCF_RISC_REG_X3,
-       SCF_RISC_REG_X4,
-       SCF_RISC_REG_X5,
-};
-
-static uint32_t naja_abi_float_regs[] =
-{
-       SCF_RISC_REG_D0,
-       SCF_RISC_REG_D1,
-       SCF_RISC_REG_D2,
-       SCF_RISC_REG_D3,
-       SCF_RISC_REG_D4,
-       SCF_RISC_REG_D5,
-       SCF_RISC_REG_D6,
-       SCF_RISC_REG_D7,
-};
-
-static uint32_t naja_abi_ret_regs[] =
-{
-       SCF_RISC_REG_X0,
-       SCF_RISC_REG_X1,
-       SCF_RISC_REG_X2,
-       SCF_RISC_REG_X3,
-};
-
-static uint32_t naja_abi_caller_saves[] =
-{
-       SCF_RISC_REG_X0,
-       SCF_RISC_REG_X1,
-       SCF_RISC_REG_X2,
-       SCF_RISC_REG_X3,
-       SCF_RISC_REG_X4,
-       SCF_RISC_REG_X5,
-};
-
-static uint32_t naja_abi_callee_saves[] =
-{
-       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)
-{
-       intptr_t id0 = c0 >> 16;
-       intptr_t id1 = c1 >> 16;
-
-       return id0 == id1 && (c0 & c1 & 0xffff);
-}
-
-static int naja_variable_size(scf_variable_t* v)
-{
-       if (v->nb_dimentions > 0)
-               return 8;
-
-       if (v->type >= SCF_STRUCT && 0 == v->nb_pointers)
-               return 8;
-
-       return v->size;
-}
-
-scf_register_t* naja_find_register(const char* name)
-{
-       int i;
-       for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) {
-
-               scf_register_t* r = &(naja_registers[i]);
-
-               if (!strcmp(r->name, name))
-                       return r;
-       }
-       return NULL;
-}
-
-scf_register_t* naja_find_register_type_id_bytes(uint32_t type, uint32_t id, int bytes)
-{
-       int i;
-       for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) {
-
-               scf_register_t* r = &(naja_registers[i]);
-
-               if (RISC_COLOR_TYPE(r->color) == type && r->id == id && r->bytes == bytes)
-                       return r;
-       }
-       return NULL;
-}
-
-scf_register_t* naja_find_register_color(intptr_t color)
-{
-       int i;
-       for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) {
-
-               scf_register_t* r = &(naja_registers[i]);
-
-               if (r->color == color)
-                       return r;
-       }
-       return NULL;
-}
-
-scf_register_t* naja_find_register_color_bytes(intptr_t color, int bytes)
-{
-       int i;
-       for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) {
-
-               scf_register_t* r = &(naja_registers[i]);
-
-               if (naja_color_conflict(r->color, color) && r->bytes == bytes)
-                       return r;
-       }
-       return NULL;
-}
+#include"scf_naja_reg.c"
 
 scf_vector_t* naja_register_colors()
 {
index d8209eb137ba570f72e41aa213fd43146b55f570..e92c8435dfbdec9bc92738a210ac5a7658e73029 100644 (file)
@@ -115,6 +115,8 @@ enum scf_risc_OpCode_types
 
        SCF_RISC_JMP,
 
+       SCF_RISC_ADRP,
+
        SCF_RISC_NB
 };
 
index 92519a84fa0a2c600a0ceb2ed38c18bdf5e1d668..935d899b6582ed4fd7cab8c873f15c7432240eea 100644 (file)
@@ -23,6 +23,26 @@ void scf_instruction_free(scf_instruction_t* inst)
        }
 }
 
+void scf_inst_data_print(scf_inst_data_t* id)
+{
+       if (1 == id->flag) {
+               if (id->index)
+                       printf("%d(%s, %s, %d)", id->disp, id->base->name, id->index->name, id->scale);
+
+               else if (id->base) {
+                       if (id->disp < 0)
+                               printf("-%#x(%s)", -id->disp, id->base->name);
+                       else
+                               printf("%#x(%s)", id->disp, id->base->name);
+               } else
+                       printf("%d(rip)", id->disp);
+
+       } else if (id->base)
+               printf("%s", id->base->name);
+       else if (id->imm_size > 0)
+               printf("%d", (int)id->imm);
+}
+
 void scf_instruction_print(scf_instruction_t* inst)
 {
        if (inst->label)
@@ -31,46 +51,23 @@ void scf_instruction_print(scf_instruction_t* inst)
        if (inst->OpCode)
                printf("%s ", inst->OpCode->name);
 
-       if (1 == inst->src.flag) {
-               if (inst->src.index)
-                       printf("%d(%s, %s, %d), ", inst->src.disp, inst->src.base->name,
-                                       inst->src.index->name, inst->src.scale);
-
-               else if (inst->src.base) {
-                       if (inst->src.disp < 0)
-                               printf("-%#x(%s), ", -inst->src.disp, inst->src.base->name);
-                       else
-                               printf("%#x(%s), ", inst->src.disp, inst->src.base->name);
-               } else
-                       printf("%d(rip), ", inst->dst.disp);
-
-       } else if (inst->src.base)
-               printf("%s, ", inst->src.base->name);
-
-       else if (inst->src.imm_size > 0)
-               printf("%d, ", (int)inst->src.imm);
+       scf_inst_data_print(&inst->dst);
 
-       if (1 == inst->dst.flag) {
-               if (inst->dst.index)
-                       printf("%d(%s, %s, %d)", inst->dst.disp, inst->dst.base->name,
-                                       inst->dst.index->name, inst->dst.scale);
+       if (!scf_inst_data_empty(&inst->dst) && !scf_inst_data_empty(&inst->src))
+               printf(", ");
+       scf_inst_data_print(&inst->src);
 
-               else if (inst->dst.base) {
-                       if (inst->dst.disp < 0)
-                               printf("-%#x(%s)", -inst->dst.disp, inst->dst.base->name);
-                       else
-                               printf("%#x(%s)", inst->dst.disp, inst->dst.base->name);
-               } else
-                       printf("%d(rip)", inst->dst.disp);
+       if (!scf_inst_data_empty(&inst->srcs[0]))
+               printf(", ");
+       scf_inst_data_print(&inst->srcs[0]);
 
-       } else if (inst->dst.base)
-               printf("%s", inst->dst.base->name);
+       if (!scf_inst_data_empty(&inst->srcs[1]))
+               printf(", ");
+       scf_inst_data_print(&inst->srcs[1]);
 
-       else if (inst->dst.imm_size > 0)
-               printf("%d", (int)inst->dst.imm);
-
-       int i;
-       for (i = 0; i < inst->len; i++)
+       printf(" |");
+       for (int i = 0; i < inst->len; i++)
                printf(" %#x", inst->code[i]);
+
        printf("\n");
 }
index 37c0b0ec1cb847ac0f504fb93cb6ffd0e2b61766..35c2391090ccd24343bc39cd6f8853b653a7a1a8 100644 (file)
@@ -56,8 +56,9 @@ struct scf_instruction_s
        scf_OpCode_t*       OpCode;
        scf_instruction_t*  next; // only for jcc, jmp, call
 
-       scf_inst_data_t     src;
        scf_inst_data_t     dst;
+       scf_inst_data_t     src;
+       scf_inst_data_t     srcs[2];
 
        scf_lex_word_t*     label;  // asm label
        scf_string_t*       bin;    // asm binary data, maybe in .text or .data
@@ -83,6 +84,12 @@ typedef struct {
        int                 addend;
 } scf_rela_t;
 
+
+static inline int scf_inst_data_empty(scf_inst_data_t* id)
+{
+       return !(id->flag || id->base || id->imm_size);
+}
+
 static inline int scf_inst_data_same(scf_inst_data_t* id0, scf_inst_data_t* id1)
 {
        // global var, are considered as different.
index f67b5d218ac466964fb65e2af6b30dcdfc6269d5..95092c4fde3185c99c8905e434c3cd9095b10824 100644 (file)
@@ -1,6 +1,7 @@
 #include"scf_x64.h"
 
-scf_x64_OpCode_t       x64_OpCodes[] = {
+scf_x64_OpCode_t       x64_OpCodes[] =
+{
        {SCF_X64_PUSH, "push", 1, {0x50, 0x0, 0x0},1,  8,8, SCF_X64_G,   0,0, 0,{0,0}},
        {SCF_X64_POP,  "pop",  1, {0x58, 0x0, 0x0},1,  8,8, SCF_X64_G,   0,0, 0,{0,0}},
 
index 46801e739ce6d29ec370a4b3c705e9b91f6111a7..5df5405bb9015a28610c0e2f99f4c6fe8e957ceb 100644 (file)
@@ -326,4 +326,60 @@ static inline int scf_dfa_is_var(scf_dfa_t* dfa, void* word)
        return SCF_LEX_WORD_KEY_VAR == w->type;
 }
 
+static int scf_asm_is_text(scf_dfa_t* dfa, void* word)
+{
+       scf_lex_word_t* w = word;
+
+       return SCF_LEX_WORD_ASM_TEXT == w->type;
+}
+
+static int scf_asm_is_data(scf_dfa_t* dfa, void* word)
+{
+       scf_lex_word_t* w = word;
+
+       return SCF_LEX_WORD_ASM_DATA == w->type;
+}
+
+static int scf_asm_is_global(scf_dfa_t* dfa, void* word)
+{
+       scf_lex_word_t* w = word;
+
+       return SCF_LEX_WORD_ASM_GLOBAL == w->type;
+}
+
+static int scf_asm_is_fill(scf_dfa_t* dfa, void* word)
+{
+       scf_lex_word_t* w = word;
+
+       return SCF_LEX_WORD_ASM_FILL == w->type;
+}
+
+static int scf_asm_is_type(scf_dfa_t* dfa, void* word)
+{
+       scf_lex_word_t* w = word;
+
+       return SCF_LEX_WORD_ASM_BYTE <= w->type && SCF_LEX_WORD_ASM_ASCIZ >= w->type;
+}
+
+static int scf_asm_is_number(scf_dfa_t* dfa, void* word)
+{
+       scf_lex_word_t* w = word;
+
+       return SCF_LEX_WORD_CONST_CHAR <= w->type && SCF_LEX_WORD_CONST_DOUBLE >= w->type;
+}
+
+static int scf_asm_is_str(scf_dfa_t* dfa, void* word)
+{
+       scf_lex_word_t* w = word;
+
+       return SCF_LEX_WORD_CONST_STRING == w->type;
+}
+
+static int scf_asm_is_percent(scf_dfa_t* dfa, void* word)
+{
+       scf_lex_word_t* w = word;
+
+       return SCF_LEX_WORD_MOD == w->type;
+}
+
 #endif
index 9a6dd3585d4758fb589e596c384202c258f40df6..5dcfc59027e7bc8b7a8d2ab8e63def27ef2eb116 100644 (file)
@@ -4,7 +4,7 @@
 #include"scf_elf.h"
 #include<dlfcn.h>
 
-#if 0
+#if 1
 #define NAJA_PRINTF   printf
 #else
 #define NAJA_PRINTF
@@ -40,6 +40,9 @@ struct  scf_vm_s
        void*                     priv;
 };
 
+#define SCF_ELF_ADDR(_vm, _addr)  ((_addr) - (uint64_t)(_vm)->text->data + (_vm)->text->addr)
+#define SCF_VM_ADDR(_vm, _addr)   ((_addr) + (uint64_t)(_vm)->text->data - (_vm)->text->addr)
+
 struct scf_vm_ops_s
 {
        const char* name;
@@ -89,8 +92,8 @@ int scf_vm_clear(scf_vm_t*   vm);
 
 int scf_vm_run  (scf_vm_t*   vm, const char* path, const char* sys);
 
-int naja_vm_open(scf_vm_t* vm);
+int naja_vm_open (scf_vm_t* vm);
 int naja_vm_close(scf_vm_t* vm);
-int naja_vm_init(scf_vm_t* vm, const char* path, const char* sys);
+int naja_vm_init (scf_vm_t* vm, const char* path, const char* sys);
 
 #endif
index a840da0e258f905c1c40064c875ce7e5b6212fee..12468b466d8be36fac067d08ca031bd1c430dbba 100644 (file)
@@ -189,20 +189,24 @@ int naja_vm_init(scf_vm_t* vm, const char* path, const char* sys)
                ph =        vm->phdrs->data[i];
 
                if (PT_LOAD ==  ph->ph.p_type) {
+                       ph->addr =  ph->ph.p_vaddr & ~(ph->ph.p_align - 1);
+                       ph->len  = (ph->ph.p_vaddr +   ph->ph.p_memsz) - ph->addr;
 
-                       ph->addr = (ph->ph.p_vaddr + ph->ph.p_memsz) & ~(ph->ph.p_align - 1);
-                       ph->len  = (ph->ph.p_vaddr + ph->ph.p_memsz) - ph->addr;
+                       long offset = ph->ph.p_offset - (ph->ph.p_vaddr - ph->addr);
+                       assert(offset >= 0);
 
-                       ph->data = calloc(1, ph->len);
-                       if (!ph->data)
-                               return -ENOMEM;
+                       if (ph->len > 0) {
+                               ph->data = calloc(1, ph->len);
+                               if (!ph->data)
+                                       return -ENOMEM;
 
-                       fseek(vm->elf->fp, 0, SEEK_SET);
+                               fseek(vm->elf->fp, offset, SEEK_SET);
 
-                       ret = fread(ph->data, ph->len, 1, vm->elf->fp);
-                       if (1 != ret) {
-                               scf_loge("\n");
-                               return -1;
+                               ret = fread(ph->data, ph->len, 1, vm->elf->fp);
+                               if (1 != ret) {
+                                       scf_loge("\n");
+                                       return -1;
+                               }
                        }
 
                        scf_logi("i: %d, ph->p_offset: %#lx, ph->p_filesz: %#lx\n", i, ph->ph.p_offset, ph->ph.p_filesz);
@@ -545,7 +549,7 @@ static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst)
        if (s13  & 0x1000)
                s13 |= 0xffffe000;
 
-       NAJA_PRINTF("ldr%s%c  %s, [%s, %d]\n", __naja_sign[s], __naja_size[size], __naja_reg[rd], __naja_reg[rb], s13 << size);
+       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;
@@ -2286,7 +2290,7 @@ static int __naja_jmp_disp(scf_vm_t* vm, uint32_t inst)
                simm26 |= 0xfc000000;
 
        naja->ip += simm26 << 2;
-       NAJA_PRINTF("jmp    %#lx\n", naja->ip);
+       NAJA_PRINTF("jmp      %#lx\n", naja->ip);
        return 0;
 }
 
@@ -2299,11 +2303,11 @@ static int __naja_call_disp(scf_vm_t* vm, uint32_t inst)
        if (simm26  & 0x2000000)
                simm26 |= 0xfc000000;
 
-       naja->regs[NAJA_REG_LR] = naja->ip + 4;
+       naja->regs[NAJA_REG_LR] = SCF_VM_ADDR(vm, naja->ip + 4);
 
        naja->ip += simm26 << 2;
 
-       NAJA_PRINTF("call   %#lx\n", naja->ip);
+       NAJA_PRINTF("call     %#lx\n", naja->ip);
        return 0;
 }
 
@@ -2327,22 +2331,22 @@ static int __naja_jmp_reg(scf_vm_t* vm, uint32_t inst)
                        naja->ip  += 4;
 
                if (0 == cc)
-                       NAJA_PRINTF("jz     %#lx, flags: %#lx\n", naja->ip, naja->flags);
+                       NAJA_PRINTF("jz       %#lx, flags: %#lx\n", naja->ip, naja->flags);
 
                else if (1 == cc)
-                       NAJA_PRINTF("jnz    %#lx, flags: %#lx\n", naja->ip, naja->flags);
+                       NAJA_PRINTF("jnz      %#lx, flags: %#lx\n", naja->ip, naja->flags);
 
                else if (2 == cc)
-                       NAJA_PRINTF("jge    %#lx, flags: %#lx\n", naja->ip, naja->flags);
+                       NAJA_PRINTF("jge      %#lx, flags: %#lx\n", naja->ip, naja->flags);
 
                else if (3 == cc)
-                       NAJA_PRINTF("jgt    %#lx, flags: %#lx\n", naja->ip, naja->flags);
+                       NAJA_PRINTF("jgt      %#lx, flags: %#lx\n", naja->ip, naja->flags);
 
                else if (4 == cc)
-                       NAJA_PRINTF("jle    %#lx, flags: %#lx\n", naja->ip, naja->flags);
+                       NAJA_PRINTF("jle      %#lx, flags: %#lx\n", naja->ip, naja->flags);
 
                else if (5 == cc)
-                       NAJA_PRINTF("jlt    %#lx, flags: %#lx\n", naja->ip, naja->flags);
+                       NAJA_PRINTF("jlt      %#lx, flags: %#lx\n", naja->ip, naja->flags);
                else {
                        scf_loge("\n");
                        return -EINVAL;
@@ -2353,7 +2357,7 @@ static int __naja_jmp_reg(scf_vm_t* vm, uint32_t inst)
 
                if (naja_vm_dynamic_link == (void*)naja->regs[rd]) {
 
-                       NAJA_PRINTF("\033[36mjmp    r%d, %#lx@plt\033[0m\n", rd, naja->regs[rd]);
+                       NAJA_PRINTF("\033[36mjmp      r%d, %#lx@plt\033[0m\n", rd, naja->regs[rd]);
 
                        int ret = naja_vm_dynamic_link(vm);
                        if (ret < 0) {
@@ -2363,10 +2367,15 @@ static int __naja_jmp_reg(scf_vm_t* vm, uint32_t inst)
 
                        naja->ip = naja->regs[NAJA_REG_LR];
 
+                       if (naja->ip >= (uint64_t)vm->text->data
+                        && naja->ip <  (uint64_t)vm->text->data + vm->text->len) {
+                               naja->ip =  SCF_ELF_ADDR(vm, naja->ip);
+                       }
+
                } else if (naja->regs[rd] < vm->text->addr
                                || naja->regs[rd] > vm->text->addr + vm->text->len) {
 
-                       NAJA_PRINTF("\033[36mjmp    r%d, %#lx@plt\033[0m\n", rd, naja->regs[rd]);
+                       NAJA_PRINTF("\033[36mjmp      r%d, %#lx@plt\033[0m\n", rd, naja->regs[rd]);
 
                        dyn_func_pt f = (void*)naja->regs[rd];
 
@@ -2386,10 +2395,15 @@ static int __naja_jmp_reg(scf_vm_t* vm, uint32_t inst)
                                        naja->fvec[7].d[0]);
 
                        naja->ip = naja->regs[NAJA_REG_LR];
+
+                       if (naja->ip >= (uint64_t)vm->text->data
+                        && naja->ip <  (uint64_t)vm->text->data + vm->text->len) {
+                               naja->ip =  SCF_ELF_ADDR(vm, naja->ip);
+                       }
                } else {
                        naja->ip = naja->regs[rd];
 
-                       NAJA_PRINTF("jmp    r%d, %#lx\n", rd, naja->regs[rd]);
+                       NAJA_PRINTF("jmp      r%d, %#lx\n", rd, naja->regs[rd]);
                }
        }
 
@@ -2503,7 +2517,7 @@ static int __naja_adrp(scf_vm_t* vm, uint32_t inst)
        else if (naja->regs[rd] >= 0x400000)
                naja->regs[rd]  = naja->regs[rd] - vm->text->addr + (uint64_t)vm->text->data;
 
-       NAJA_PRINTF("adrp   r%d, [rip, %d],  %#lx\n", rd, s21, naja->regs[rd]);
+       NAJA_PRINTF("adrp     r%d, [rip, %d],  %#lx\n", rd, s21, naja->regs[rd]);
 
        naja->ip += 4;
        return 0;
@@ -2530,6 +2544,11 @@ static int __naja_ret(scf_vm_t* vm, uint32_t inst)
                naja->size  = sp + STACK_INC;
        }
 
+       if (naja->ip >= (uint64_t)vm->text->data
+        && naja->ip <  (uint64_t)vm->text->data + vm->text->len) {
+               naja->ip =  SCF_ELF_ADDR(vm, naja->ip);
+       }
+
        NAJA_PRINTF("ret,   %#lx, sp: %ld, stack->size: %ld\n", naja->ip, sp, naja->size);
        return 0;
 }
index 3881645e725d8f181451264f802bcfcfe3ec3287..63c64ea9a47bd279dc4da81745274dba0d3578f3 100644 (file)
@@ -765,7 +765,7 @@ static int __naja_jmp_disp(scf_vm_t* vm, uint32_t inst)
                simm26 |= 0xfc000000;
 
        uint64_t ip = naja->ip + (simm26 << 2);
-       printf("jmp    %#lx\n", ip);
+       printf("jmp      %#lx\n", ip);
        return 0;
 }