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"
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
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
scf_asm_t* _asm = NULL;
- if (scf_asm_open(&_asm) < 0) {
+ if (scf_asm_open(&_asm, arch) < 0) {
scf_loge("\n");
return -1;
}
--- /dev/null
+.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"
#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;
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;
}
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];
}
}
+ 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];
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;
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);
#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)
.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) {
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;
}
--- /dev/null
+#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,
+};
#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;
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;
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;
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;
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;
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;
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++;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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)) {
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;
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 {
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;
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);
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;
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;
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);
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);
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,
};
--- /dev/null
+.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"
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;
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 {
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,
.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,
};
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,
.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,
};
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,
.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,
};
scf_elf_ops_t elf_ops_x64 =
{
.machine = "x64",
+ .arch = SCF_ELF_X64,
.open = elf_open,
.close = elf_close,
#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)
{
}
// 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;
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;
} 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;
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;
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;
}
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);
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;
--- /dev/null
+#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);
+ }
+}
--- /dev/null
+#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;
+}
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);
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;
}
}
#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
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);
int risc_rcg_make(scf_3ac_code_t* c, scf_graph_t* g, scf_dag_node_t* dn, scf_register_t* reg);
#endif
-
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;
-}
#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}},
{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}},
{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}},
{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++) {
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++) {
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;
+}
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
#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()
{
SCF_RISC_JMP,
+ SCF_RISC_ADRP,
+
SCF_RISC_NB
};
}
}
+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)
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");
}
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
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.
#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}},
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
#include"scf_elf.h"
#include<dlfcn.h>
-#if 0
+#if 1
#define NAJA_PRINTF printf
#else
#define NAJA_PRINTF
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;
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
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);
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;
simm26 |= 0xfc000000;
naja->ip += simm26 << 2;
- NAJA_PRINTF("jmp %#lx\n", naja->ip);
+ NAJA_PRINTF("jmp %#lx\n", naja->ip);
return 0;
}
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;
}
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;
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) {
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];
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]);
}
}
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;
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;
}
simm26 |= 0xfc000000;
uint64_t ip = naja->ip + (simm26 << 2);
- printf("jmp %#lx\n", ip);
+ printf("jmp %#lx\n", ip);
return 0;
}