From 36be882f71bea281d257fb628b3f12633ec40d7d Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Wed, 21 Jan 2026 21:50:59 +0800 Subject: [PATCH] asm: support simple asm code for x64 & naja --- asm/1.s | 11 +- asm/Makefile | 4 +- asm/main.c | 2 +- asm/naja.s | 15 + asm/scf_asm.c | 31 +- asm/scf_asm.h | 9 +- asm/scf_dfa_asm.c | 48 +- asm/scf_dfa_naja.c | 1053 +++++++++++++++++++++++++ asm/{scf_dfa_inst.c => scf_dfa_x64.c} | 265 +++---- asm/shellcode.s | 27 + elf/scf_elf.h | 39 +- elf/scf_elf_arm32.c | 11 +- elf/scf_elf_arm64.c | 11 +- elf/scf_elf_naja.c | 11 +- elf/scf_elf_x64.c | 1 + native/risc/scf_naja.c | 776 +----------------- native/risc/scf_naja_inst.c | 911 +++++++++++++++++++++ native/risc/scf_naja_reg.c | 285 +++++++ native/risc/scf_risc.c | 5 +- native/risc/scf_risc.h | 36 - native/risc/scf_risc_inst.c | 18 - native/risc/scf_risc_opcode.c | 54 +- native/risc/scf_risc_opcode.h | 61 +- native/risc/scf_risc_reg_naja.c | 285 +------ native/risc/scf_risc_util.h | 2 + native/scf_instruction.c | 69 +- native/scf_instruction.h | 9 +- native/x64/scf_x64_opcode.c | 3 +- parse/scf_dfa_util.h | 56 ++ vm/scf_vm.h | 9 +- vm/scf_vm_naja.c | 67 +- vm/scf_vm_naja_asm.c | 2 +- 32 files changed, 2772 insertions(+), 1414 deletions(-) create mode 100644 asm/naja.s create mode 100644 asm/scf_dfa_naja.c rename asm/{scf_dfa_inst.c => scf_dfa_x64.c} (77%) create mode 100644 asm/shellcode.s create mode 100644 native/risc/scf_naja_inst.c create mode 100644 native/risc/scf_naja_reg.c diff --git a/asm/1.s b/asm/1.s index ab14439..5f5edb8 100644 --- 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" diff --git a/asm/Makefile b/asm/Makefile index 4610bf5..c6849f7 100644 --- a/asm/Makefile +++ b/asm/Makefile @@ -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 diff --git a/asm/main.c b/asm/main.c index bf01a06..7036c12 100644 --- a/asm/main.c +++ b/asm/main.c @@ -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 index 0000000..2aed373 --- /dev/null +++ b/asm/naja.s @@ -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" diff --git a/asm/scf_asm.c b/asm/scf_asm.c index 2cc9756..46046bc 100644 --- a/asm/scf_asm.c +++ b/asm/scf_asm.c @@ -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]; diff --git a/asm/scf_asm.h b/asm/scf_asm.h index dffcf9a..9cfeca1 100644 --- a/asm/scf_asm.h +++ b/asm/scf_asm.h @@ -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); diff --git a/asm/scf_dfa_asm.c b/asm/scf_dfa_asm.c index 5519325..37e0a54 100644 --- a/asm/scf_dfa_asm.c +++ b/asm/scf_dfa_asm.c @@ -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 index 0000000..3bb2633 --- /dev/null +++ b/asm/scf_dfa_naja.c @@ -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, +}; diff --git a/asm/scf_dfa_inst.c b/asm/scf_dfa_x64.c similarity index 77% rename from asm/scf_dfa_inst.c rename to asm/scf_dfa_x64.c index 509ab66..b60eeb9 100644 --- a/asm/scf_dfa_inst.c +++ b/asm/scf_dfa_x64.c @@ -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 index 0000000..a54c623 --- /dev/null +++ b/asm/shellcode.s @@ -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" diff --git a/elf/scf_elf.h b/elf/scf_elf.h index b3599aa..0a40786 100644 --- a/elf/scf_elf.h +++ b/elf/scf_elf.h @@ -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 { diff --git a/elf/scf_elf_arm32.c b/elf/scf_elf_arm32.c index 6c85c87..6e66b0f 100644 --- a/elf/scf_elf_arm32.c +++ b/elf/scf_elf_arm32.c @@ -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, }; diff --git a/elf/scf_elf_arm64.c b/elf/scf_elf_arm64.c index 318ee2e..3cfe50e 100644 --- a/elf/scf_elf_arm64.c +++ b/elf/scf_elf_arm64.c @@ -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, }; diff --git a/elf/scf_elf_naja.c b/elf/scf_elf_naja.c index d399243..513910a 100644 --- a/elf/scf_elf_naja.c +++ b/elf/scf_elf_naja.c @@ -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, }; diff --git a/elf/scf_elf_x64.c b/elf/scf_elf_x64.c index 4d28fac..147d1e0 100644 --- a/elf/scf_elf_x64.c +++ b/elf/scf_elf_x64.c @@ -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, diff --git a/native/risc/scf_naja.c b/native/risc/scf_naja.c index ef56dff..3dd88ab 100644 --- a/native/risc/scf_naja.c +++ b/native/risc/scf_naja.c @@ -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 index 0000000..f733572 --- /dev/null +++ b/native/risc/scf_naja_inst.c @@ -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 index 0000000..cfa2532 --- /dev/null +++ b/native/risc/scf_naja_reg.c @@ -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; +} diff --git a/native/risc/scf_risc.c b/native/risc/scf_risc.c index d0b71d8..8b5850b 100644 --- a/native/risc/scf_risc.c +++ b/native/risc/scf_risc.c @@ -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; } } diff --git a/native/risc/scf_risc.h b/native/risc/scf_risc.h index 40930d2..41847cb 100644 --- a/native/risc/scf_risc.h +++ b/native/risc/scf_risc.h @@ -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 - diff --git a/native/risc/scf_risc_inst.c b/native/risc/scf_risc_inst.c index 2d64b8d..c0d0143 100644 --- a/native/risc/scf_risc_inst.c +++ b/native/risc/scf_risc_inst.c @@ -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; -} diff --git a/native/risc/scf_risc_opcode.c b/native/risc/scf_risc_opcode.c index b12e502..d4a9141 100644 --- a/native/risc/scf_risc_opcode.c +++ b/native/risc/scf_risc_opcode.c @@ -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; +} diff --git a/native/risc/scf_risc_opcode.h b/native/risc/scf_risc_opcode.h index 0f7286a..c1f7653 100644 --- a/native/risc/scf_risc_opcode.h +++ b/native/risc/scf_risc_opcode.h @@ -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 diff --git a/native/risc/scf_risc_reg_naja.c b/native/risc/scf_risc_reg_naja.c index 9b6ff13..6a9ca31 100644 --- a/native/risc/scf_risc_reg_naja.c +++ b/native/risc/scf_risc_reg_naja.c @@ -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() { diff --git a/native/risc/scf_risc_util.h b/native/risc/scf_risc_util.h index d8209eb..e92c843 100644 --- a/native/risc/scf_risc_util.h +++ b/native/risc/scf_risc_util.h @@ -115,6 +115,8 @@ enum scf_risc_OpCode_types SCF_RISC_JMP, + SCF_RISC_ADRP, + SCF_RISC_NB }; diff --git a/native/scf_instruction.c b/native/scf_instruction.c index 92519a8..935d899 100644 --- a/native/scf_instruction.c +++ b/native/scf_instruction.c @@ -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"); } diff --git a/native/scf_instruction.h b/native/scf_instruction.h index 37c0b0e..35c2391 100644 --- a/native/scf_instruction.h +++ b/native/scf_instruction.h @@ -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. diff --git a/native/x64/scf_x64_opcode.c b/native/x64/scf_x64_opcode.c index f67b5d2..95092c4 100644 --- a/native/x64/scf_x64_opcode.c +++ b/native/x64/scf_x64_opcode.c @@ -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}}, diff --git a/parse/scf_dfa_util.h b/parse/scf_dfa_util.h index 46801e7..5df5405 100644 --- a/parse/scf_dfa_util.h +++ b/parse/scf_dfa_util.h @@ -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 diff --git a/vm/scf_vm.h b/vm/scf_vm.h index 9a6dd35..5dcfc59 100644 --- a/vm/scf_vm.h +++ b/vm/scf_vm.h @@ -4,7 +4,7 @@ #include"scf_elf.h" #include -#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 diff --git a/vm/scf_vm_naja.c b/vm/scf_vm_naja.c index a840da0..12468b4 100644 --- a/vm/scf_vm_naja.c +++ b/vm/scf_vm_naja.c @@ -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; } diff --git a/vm/scf_vm_naja_asm.c b/vm/scf_vm_naja_asm.c index 3881645..63c64ea 100644 --- a/vm/scf_vm_naja_asm.c +++ b/vm/scf_vm_naja_asm.c @@ -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; } -- 2.25.1