From 8ed9438d829fc33e4134a15c908760feccbc27c3 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Mon, 17 Feb 2025 23:43:28 +0800 Subject: [PATCH] support variable length array, VLA --- core/scf_3ac.c | 43 +- core/scf_ast.c | 2 +- core/scf_basic_block.c | 19 + core/scf_basic_block.h | 5 + core/scf_core_types.h | 4 + core/scf_expr.h | 12 +- core/scf_function.h | 5 +- core/scf_operator.c | 3 + core/scf_operator_dag.c | 7 + core/scf_operator_handler_3ac.c | 11 + core/scf_optimizer.c | 2 + core/scf_optimizer_auto_gc_find.c | 2 +- core/scf_optimizer_vla.c | 190 ++++ core/scf_variable.c | 24 +- core/scf_variable.h | 16 +- docs/Naja_float.txt | 106 ++- docs/Naja_int.txt | 281 +++--- elf/scf_elf_arm64_so.c | 1 - elf/scf_elf_naja.c | 4 +- elf/scf_elf_naja_so.c | 31 +- examples/vla_0.c | 15 + examples/vla_1.c | 11 + native/eda/scf_eda.c | 4 +- native/eda/scf_eda.h | 7 +- native/eda/scf_eda_inst.c | 118 +-- native/eda/scf_eda_pack.c | 50 +- native/eda/scf_eda_pack.h | 21 +- native/risc/scf_naja.c | 241 ++--- native/risc/scf_risc.c | 6 +- native/risc/scf_risc_reg_arm64.c | 50 - native/risc/scf_risc_reg_naja.c | 1154 ++++++++++++++++++++++ native/x64/scf_x64.c | 13 + native/x64/scf_x64_inst.c | 159 +++- native/x64/scf_x64_rcg.c | 21 + native/x64/scf_x64_reg.c | 2 +- parse/Makefile | 2 + parse/main.c | 4 +- parse/scf_dfa.c | 3 +- parse/scf_dfa_class.c | 6 +- parse/scf_dfa_enum.c | 10 + parse/scf_dfa_union.c | 8 +- parse/scf_dfa_var.c | 334 ++++++- parse/scf_operator_handler_const.c | 9 + parse/scf_operator_handler_expr.c | 11 +- parse/scf_operator_handler_semantic.c | 39 +- parse/scf_parse.c | 4 +- parse/scf_struct_array.c | 28 +- vm/Makefile | 2 +- vm/main.c | 35 + vm/scf_vm.h | 29 +- vm/scf_vm_naja.c | 1261 +++++++++++++------------ vm/scf_vm_naja_asm.c | 871 +++++++++-------- 52 files changed, 3696 insertions(+), 1600 deletions(-) create mode 100644 core/scf_optimizer_vla.c create mode 100644 examples/vla_0.c create mode 100644 examples/vla_1.c create mode 100644 native/risc/scf_risc_reg_naja.c create mode 100644 vm/main.c diff --git a/core/scf_3ac.c b/core/scf_3ac.c index ba65074..2f3dce7 100644 --- a/core/scf_3ac.c +++ b/core/scf_3ac.c @@ -60,6 +60,9 @@ static scf_3ac_operator_t _3ac_operators[] = { {SCF_OP_VA_ARG, "va_arg"}, {SCF_OP_VA_END, "va_end"}, + {SCF_OP_VLA_ALLOC, "vla_alloc"}, + {SCF_OP_VLA_FREE, "vla_free"}, + {SCF_OP_RETURN, "return"}, {SCF_OP_GOTO, "jmp"}, @@ -707,6 +710,34 @@ int scf_3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag) if (ret < 0) return ret; } + + } else if (SCF_OP_VLA_ALLOC == c->op->type) { + + dst = c->dsts->data[0]; + ret = scf_dag_get_node(dag, dst->node, &dst->dag_node); + if (ret < 0) + return ret; + + scf_dag_node_t* alloc = scf_dag_node_alloc(c->op->type, NULL, NULL); + if (!alloc) + return -ENOMEM; + scf_list_add_tail(dag, &alloc->list); + + ret = scf_dag_node_add_child(alloc, dst->dag_node); + if (ret < 0) + return ret; + + for (i = 0; i < c->srcs->size; i++) { + src = c->srcs->data[i]; + + ret = scf_dag_get_node(dag, src->node, &src->dag_node); + if (ret < 0) + return ret; + + ret = scf_dag_node_add_child(alloc, src->dag_node); + if (ret < 0) + return ret; + } } else if (SCF_OP_3AC_CMP == c->op->type || SCF_OP_3AC_TEQ == c->op->type) { @@ -801,9 +832,9 @@ int scf_3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag) } else if (SCF_OP_RETURN == c->op->type) { if (c->srcs) { - scf_dag_node_t* dn_return = scf_dag_node_alloc(c->op->type, NULL, NULL); + scf_dag_node_t* dn = scf_dag_node_alloc(c->op->type, NULL, NULL); - scf_list_add_tail(dag, &dn_return->list); + scf_list_add_tail(dag, &dn->list); for (i = 0; i < c->srcs->size; i++) { src = c->srcs->data[i]; @@ -812,7 +843,7 @@ int scf_3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag) if (ret < 0) return ret; - ret = scf_dag_node_add_child(dn_return, src->dag_node); + ret = scf_dag_node_add_child(dn, src->dag_node); if (ret < 0) return ret; } @@ -1548,7 +1579,11 @@ static int _3ac_split_basic_blocks(scf_list_t* h, scf_function_t* f) else if (SCF_OP_RETURN == c->op->type) bb->ret_flag = 1; - else if (SCF_OP_VA_START == c->op->type + else if (SCF_OP_VLA_ALLOC == c->op->type) { + bb->vla_flag = 1; + f ->vla_flag = 1; + + } else if (SCF_OP_VA_START == c->op->type || SCF_OP_VA_ARG == c->op->type || SCF_OP_VA_END == c->op->type) bb->varg_flag = 1; diff --git a/core/scf_ast.c b/core/scf_ast.c index 843fb10..a85bc7f 100644 --- a/core/scf_ast.c +++ b/core/scf_ast.c @@ -92,7 +92,7 @@ scf_string_t* scf_variable_type_name(scf_ast_t* ast, scf_variable_t* v) for (i = 0; i < v->nb_dimentions; i++) { char str[256]; - snprintf(str, sizeof(str) - 1, "[%d]", v->dimentions[i]); + snprintf(str, sizeof(str) - 1, "[%d]", v->dimentions[i].num); scf_string_cat_cstr(s, str); } diff --git a/core/scf_basic_block.c b/core/scf_basic_block.c index bdf13ce..b38a2dd 100644 --- a/core/scf_basic_block.c +++ b/core/scf_basic_block.c @@ -1403,3 +1403,22 @@ void scf_basic_block_add_code(scf_basic_block_t* bb, scf_list_t* h) c->basic_block = bb; } } + +scf_bb_group_t* scf_basic_block_find_min_loop(scf_basic_block_t* bb, scf_vector_t* loops) +{ + scf_bb_group_t* loop; + int i; + + for (i = 0; i < loops->size; i++) { + loop = loops->data[i]; + + if (scf_vector_find(loop->body, bb)) { + + if (!loop->loop_childs || loop->loop_childs->size <= 0) + return loop; + + return scf_basic_block_find_min_loop(bb, loop->loop_childs); + } + } + return NULL; +} diff --git a/core/scf_basic_block.h b/core/scf_basic_block.h index eec1060..d0aab43 100644 --- a/core/scf_basic_block.h +++ b/core/scf_basic_block.h @@ -85,6 +85,7 @@ struct scf_basic_block_s uint32_t jmp_flag :1; uint32_t jcc_flag :1; uint32_t ret_flag :1; + uint32_t vla_flag :1; uint32_t end_flag :1; uint32_t varg_flag :1; uint32_t jmp_dst_flag:1; @@ -100,6 +101,8 @@ struct scf_basic_block_s uint32_t group_flag :1; uint32_t visit_flag :1; uint32_t native_flag :1; + + scf_basic_block_t* vla_free; }; typedef int (*scf_basic_block_bfs_pt)(scf_basic_block_t* bb, void* data, scf_vector_t* queue); @@ -137,6 +140,8 @@ int scf_basic_block_inited_by3ac(scf_basic_block_t* bb); void scf_basic_block_mov_code(scf_basic_block_t* to, scf_list_t* start, scf_basic_block_t* from); void scf_basic_block_add_code(scf_basic_block_t* bb, scf_list_t* h); +scf_bb_group_t* scf_basic_block_find_min_loop(scf_basic_block_t* bb, scf_vector_t* loops); + static inline void scf_basic_block_visit_flag(scf_list_t* h, int visit_flag) { scf_basic_block_t* bb; diff --git a/core/scf_core_types.h b/core/scf_core_types.h index a3e8468..6d844ca 100644 --- a/core/scf_core_types.h +++ b/core/scf_core_types.h @@ -10,6 +10,7 @@ typedef struct scf_index_s scf_index_t; typedef struct scf_label_s scf_label_t; typedef struct scf_node_s scf_node_t; +typedef struct scf_node_s scf_expr_t; typedef struct scf_operator_s scf_operator_t; typedef struct scf_block_s scf_block_t; @@ -94,6 +95,9 @@ enum scf_core_types SCF_OP_POINTER, // -> struct member SCF_OP_DOT, // . dot + SCF_OP_VLA_ALLOC, // variable length array, VLA + SCF_OP_VLA_FREE, + SCF_OP_VAR_ARGS, // ... variable args SCF_OP_VA_START, diff --git a/core/scf_expr.h b/core/scf_expr.h index de8ca60..2d15797 100644 --- a/core/scf_expr.h +++ b/core/scf_expr.h @@ -3,13 +3,11 @@ #include"scf_node.h" -typedef scf_node_t scf_expr_t; // expr is a node +scf_expr_t* scf_expr_alloc(); +scf_expr_t* scf_expr_clone(scf_expr_t* e); +void scf_expr_free (scf_expr_t* e); -scf_expr_t* scf_expr_alloc(); -scf_expr_t* scf_expr_clone(scf_expr_t* e); -void scf_expr_free (scf_expr_t* e); - -int scf_expr_add_node(scf_expr_t* e, scf_node_t* node); -void scf_expr_simplify(scf_expr_t** pe); +int scf_expr_add_node(scf_expr_t* e, scf_node_t* node); +void scf_expr_simplify(scf_expr_t** pe); #endif diff --git a/core/scf_function.h b/core/scf_function.h index d6d987c..87e02da 100644 --- a/core/scf_function.h +++ b/core/scf_function.h @@ -59,8 +59,9 @@ struct scf_function_s { uint32_t inline_flag:1; uint32_t member_flag:1; - uint32_t vargs_flag :1; - uint32_t void_flag :1; + uint32_t vargs_flag:1; + uint32_t void_flag :1; + uint32_t vla_flag :1; }; scf_function_t* scf_function_alloc(scf_lex_word_t* w); diff --git a/core/scf_operator.c b/core/scf_operator.c index 8d870b0..ab12ac9 100644 --- a/core/scf_operator.c +++ b/core/scf_operator.c @@ -80,6 +80,9 @@ static scf_operator_t base_operators[] = {"switch", NULL, SCF_OP_SWITCH, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, {"case", NULL, SCF_OP_CASE, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, {"default", NULL, SCF_OP_DEFAULT, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + + {"vla_alloc", NULL, SCF_OP_VLA_ALLOC, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + {"vla_free", NULL, SCF_OP_VLA_FREE, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, }; scf_operator_t* scf_find_base_operator(const char* name, const int nb_operands) diff --git a/core/scf_operator_dag.c b/core/scf_operator_dag.c index fbe81cc..462e0ab 100644 --- a/core/scf_operator_dag.c +++ b/core/scf_operator_dag.c @@ -352,6 +352,12 @@ static int _scf_dag_op_return(scf_list_t* h, scf_dag_node_t* parent, scf_dag_nod return _scf_3ac_code_N(h, SCF_OP_RETURN, NULL, nodes, nb_nodes); } +static int _scf_dag_op_vla_alloc(scf_list_t* h, scf_dag_node_t* parent, scf_dag_node_t** nodes, int nb_nodes) +{ + assert(4 == nb_nodes); + return _scf_3ac_code_N(h, SCF_OP_VLA_ALLOC, nodes[0], nodes + 1, 3); +} + static int _scf_dag_op_cmp(scf_list_t* h, scf_dag_node_t* parent, scf_dag_node_t** nodes, int nb_nodes) { assert(2 == nb_nodes); @@ -421,6 +427,7 @@ scf_dag_operator_t dag_operators[] = {SCF_OP_GT, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_gt}, {SCF_OP_LT, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_lt}, + {SCF_OP_VLA_ALLOC, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_vla_alloc}, {SCF_OP_RETURN, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_return}, {SCF_OP_3AC_CMP, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_cmp}, {SCF_OP_3AC_TEQ, SCF_OP_ASSOCIATIVITY_LEFT, _scf_dag_op_teq}, diff --git a/core/scf_operator_handler_3ac.c b/core/scf_operator_handler_3ac.c index cbaf8fe..767ba28 100644 --- a/core/scf_operator_handler_3ac.c +++ b/core/scf_operator_handler_3ac.c @@ -1065,6 +1065,15 @@ static int _scf_op_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* return 0; } +static int _scf_op_vla_alloc(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + assert(4 == nb_nodes); + + scf_handler_data_t* d = data; + + return _scf_3ac_code_N(d->_3ac_list_head, SCF_OP_VLA_ALLOC, nodes[0], nodes + 1, 3); +} + static int _scf_op_default(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { return 0; @@ -2454,6 +2463,8 @@ scf_operator_handler_pt __operator_handlers[SCF_N_3AC_OPS] = [SCF_OP_SWITCH ] = _scf_op_switch, [SCF_OP_CASE ] = _scf_op_case, [SCF_OP_DEFAULT] = _scf_op_default, + + [SCF_OP_VLA_ALLOC] = _scf_op_vla_alloc, }; scf_operator_handler_pt scf_find_3ac_operator_handler(const int type) diff --git a/core/scf_optimizer.c b/core/scf_optimizer.c index 15dee64..faf4f20 100644 --- a/core/scf_optimizer.c +++ b/core/scf_optimizer.c @@ -23,6 +23,7 @@ extern scf_optimizer_t scf_optimizer_basic_block; extern scf_optimizer_t scf_optimizer_const_teq; extern scf_optimizer_t scf_optimizer_loop; +extern scf_optimizer_t scf_optimizer_vla; extern scf_optimizer_t scf_optimizer_group; extern scf_optimizer_t scf_optimizer_generate_loads_saves; @@ -52,6 +53,7 @@ static scf_optimizer_t* scf_optimizers[] = &scf_optimizer_dominators, &scf_optimizer_loop, + &scf_optimizer_vla, &scf_optimizer_group, &scf_optimizer_generate_loads_saves, diff --git a/core/scf_optimizer_auto_gc_find.c b/core/scf_optimizer_auto_gc_find.c index 6e0bf9b..c006e31 100644 --- a/core/scf_optimizer_auto_gc_find.c +++ b/core/scf_optimizer_auto_gc_find.c @@ -414,7 +414,7 @@ int __auto_gc_ds_for_assign(scf_dn_status_t** ds, scf_dag_node_t** dn, scf_3ac_c base = c->srcs->data[0]; v = _scf_operand_get(base->node->parent); - if (!scf_variable_may_malloced(v)) + if (!v || !scf_variable_may_malloced(v)) return 0; index = c->srcs->data[1]; diff --git a/core/scf_optimizer_vla.c b/core/scf_optimizer_vla.c new file mode 100644 index 0000000..3503d4c --- /dev/null +++ b/core/scf_optimizer_vla.c @@ -0,0 +1,190 @@ +#include"scf_optimizer.h" + +static int __bb_add_vla_free(scf_basic_block_t* back, scf_function_t* f) +{ + scf_basic_block_t* jcc = scf_list_data(scf_list_next(&back->list), scf_basic_block_t, list); + scf_basic_block_t* next = scf_list_data(scf_list_next(&jcc ->list), scf_basic_block_t, list); + scf_basic_block_t* free; + scf_basic_block_t* jmp; + scf_3ac_operand_t* dst; + scf_3ac_code_t* c; + scf_3ac_code_t* c2; + scf_list_t* l; + + assert(jcc->jmp_flag); + + free = scf_basic_block_alloc(); + if (!free) + return -ENOMEM; + scf_list_add_front(&jcc->list, &free->list); + + jmp = scf_basic_block_alloc(); + if (!jmp) + return -ENOMEM; + scf_list_add_front(&free->list, &jmp->list); + + l = scf_list_head(&jcc->code_list_head); + c = scf_list_data(l, scf_3ac_code_t, list); + + c2 = scf_3ac_code_clone(c); + if (!c2) + return -ENOMEM; + scf_list_add_tail(&jmp->code_list_head, &c2->list); + + c2->op = scf_3ac_find_operator(SCF_OP_GOTO); + c2->basic_block = jmp; + + int ret = scf_vector_add(f->jmps, c2); + if (ret < 0) + return ret; + + switch (c->op->type) { + case SCF_OP_3AC_JZ: + c->op = scf_3ac_find_operator(SCF_OP_3AC_JNZ); + break; + case SCF_OP_3AC_JNZ: + c->op = scf_3ac_find_operator(SCF_OP_3AC_JZ); + break; + + case SCF_OP_3AC_JGE: + c->op = scf_3ac_find_operator(SCF_OP_3AC_JLT); + break; + case SCF_OP_3AC_JLT: + c->op = scf_3ac_find_operator(SCF_OP_3AC_JGE); + break; + + case SCF_OP_3AC_JGT: + c->op = scf_3ac_find_operator(SCF_OP_3AC_JLE); + break; + case SCF_OP_3AC_JLE: + c->op = scf_3ac_find_operator(SCF_OP_3AC_JGT); + break; + + case SCF_OP_3AC_JA: + c->op = scf_3ac_find_operator(SCF_OP_3AC_JBE); + break; + case SCF_OP_3AC_JBE: + c->op = scf_3ac_find_operator(SCF_OP_3AC_JA); + break; + + case SCF_OP_3AC_JB: + c->op = scf_3ac_find_operator(SCF_OP_3AC_JAE); + break; + case SCF_OP_3AC_JAE: + c->op = scf_3ac_find_operator(SCF_OP_3AC_JB); + break; + default: + break; + }; + dst = c->dsts->data[0]; + dst->bb = next; + + back->vla_free = free; + return 0; +} + +static int __loop_add_vla_free(scf_bb_group_t* loop, scf_function_t* f) +{ + scf_basic_block_t* bb; + scf_basic_block_t* back; + scf_basic_block_t* jcc; + scf_3ac_operand_t* dst; + scf_3ac_code_t* c; + scf_3ac_code_t* c2; + scf_list_t* l; + + int i; + int j; + int k; + + for (i = 0; i < loop->body->size; i++) { + bb = loop->body->data[i]; + + if (!bb->vla_flag) + continue; + + for (j = i; j < loop->body->size; j++) { + back = loop->body->data[j]; + + if (!back->back_flag) + continue; + + jcc = scf_list_data(scf_list_next(&back->list), scf_basic_block_t, list); + + l = scf_list_head(&jcc->code_list_head); + c = scf_list_data(l, scf_3ac_code_t, list); + dst = c->dsts->data[0]; + + for (k = j; k > i; k--) { + if (dst->bb == loop->body->data[k]) + break; + } + if (k > i) + continue; + + if (!back->vla_free) { + int ret = __bb_add_vla_free(back, f); + if (ret < 0) + return ret; + + ret = scf_vector_add(loop->body, back->vla_free); + if (ret < 0) + return ret; + + for (k = loop->body->size - 2; k > j; k--) + loop->body->data[k + 1] = loop->body->data[k]; + loop->body->data[k + 1] = back->vla_free; + + back->vla_free->loop_flag = 1; + } + + for (l = scf_list_head(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); l = scf_list_next(l)) { + c = scf_list_data(l, scf_3ac_code_t, list); + + if (SCF_OP_VLA_ALLOC != c->op->type) + continue; + + c2 = scf_3ac_code_clone(c); + if (!c2) + return -ENOMEM; + scf_list_add_front(&back->vla_free->code_list_head, &c2->list); + + c2->op = scf_3ac_find_operator(SCF_OP_VLA_FREE); + c2->basic_block = back->vla_free; + } + } + } + + return 0; +} + +static int _optimize_vla(scf_ast_t* ast, scf_function_t* f, scf_vector_t* functions) +{ + if (!f) + return -EINVAL; + + if (!f->vla_flag || f->bb_loops->size <= 0) + return 0; + + scf_bb_group_t* loop; + int i; + + for (i = 0; i < f->bb_loops->size; i++) { + loop = f->bb_loops->data[i]; + + int ret = __loop_add_vla_free(loop, f); + if (ret < 0) + return ret; + } + + return 0; +} + +scf_optimizer_t scf_optimizer_vla = +{ + .name = "vla", + + .optimize = _optimize_vla, + + .flags = SCF_OPTIMIZER_LOCAL, +}; diff --git a/core/scf_variable.c b/core/scf_variable.c index daeab44..bf260a7 100644 --- a/core/scf_variable.c +++ b/core/scf_variable.c @@ -54,7 +54,7 @@ int scf_member_offset(scf_member_t* m) int capacity = 1; for (j = dim; j < base->nb_dimentions; j++) - capacity *= base->dimentions[j]; + capacity *= base->dimentions[j].num; capacity *= base->size; offset += capacity * idx->index; @@ -295,15 +295,17 @@ void scf_variable_free(scf_variable_t* v) } } -void scf_variable_add_array_dimention(scf_variable_t* v, int dimention_size) +void scf_variable_add_array_dimention(scf_variable_t* array, int num, scf_expr_t* vla) { - assert(v); + assert(array); - void* p = realloc(v->dimentions, sizeof(int) * (v->nb_dimentions + 1)); + void* p = realloc(array->dimentions, sizeof(scf_dimention_t) * (array->nb_dimentions + 1)); assert(p); - v->dimentions = p; - v->dimentions[v->nb_dimentions++] = dimention_size; + array->dimentions = p; + array->dimentions[array->nb_dimentions].num = num; + array->dimentions[array->nb_dimentions].vla = vla; + array->nb_dimentions++; } void scf_variable_get_array_member(scf_variable_t* array, int index, scf_variable_t* member) @@ -363,7 +365,7 @@ int scf_variable_same_type(scf_variable_t* v0, scf_variable_t* v1) int i; for (i = 0; i < v0->nb_dimentions; i++) { - if (v0->dimentions[i] != v1->dimentions[i]) + if (v0->dimentions[i].num != v1->dimentions[i].num) return 0; } @@ -461,16 +463,20 @@ int scf_variable_size(scf_variable_t* v) assert(v->nb_dimentions > 0); + if (v->vla_flag) + return sizeof(void*); + int capacity = 1; int j; for (j = 0; j < v->nb_dimentions; j++) { - if (v->dimentions[j] < 0) { + + if (v->dimentions[j].num < 0) { scf_loge("\n"); return -EINVAL; } - capacity *= v->dimentions[j]; + capacity *= v->dimentions[j].num; } v->capacity = capacity; diff --git a/core/scf_variable.h b/core/scf_variable.h index 7d0360d..471fd56 100644 --- a/core/scf_variable.h +++ b/core/scf_variable.h @@ -4,6 +4,11 @@ #include"scf_core_types.h" #include"scf_lex_word.h" +typedef struct { + scf_expr_t* vla; // variable length array + int num; // const length array +} scf_dimention_t; + struct scf_variable_s { int refs; // reference count @@ -14,7 +19,7 @@ struct scf_variable_s { int nb_pointers; // Multiple pointer count scf_function_t* func_ptr; - int* dimentions; // var array every dimention size + scf_dimention_t* dimentions; // number of every dimention int nb_dimentions; // total dimentions int dim_index; int capacity; @@ -53,12 +58,9 @@ struct scf_variable_s { uint32_t global_flag :1; uint32_t member_flag :1; + uint32_t vla_flag :1; uint32_t arg_flag :1; uint32_t auto_gc_flag:1; - - uint32_t array_flag :1; - uint32_t input_flag :1; - uint32_t output_flag :1; }; struct scf_index_s @@ -86,7 +88,7 @@ void scf_variable_free(scf_variable_t* var); void scf_variable_print(scf_variable_t* var); -void scf_variable_add_array_dimention(scf_variable_t* var, int dimention_size); +void scf_variable_add_array_dimention(scf_variable_t* array, int num, scf_expr_t* vla); void scf_variable_set_array_member(scf_variable_t* array, int index, scf_variable_t* member); void scf_variable_get_array_member(scf_variable_t* array, int index, scf_variable_t* member); @@ -109,7 +111,7 @@ static inline int scf_variable_const(scf_variable_t* v) return v->const_literal_flag; if (v->nb_pointers + v->nb_dimentions > 0) - return v->const_literal_flag; + return v->const_literal_flag && !v->vla_flag; return v->const_flag && 0 == v->nb_pointers && 0 == v->nb_dimentions; } diff --git a/docs/Naja_float.txt b/docs/Naja_float.txt index 0d92c36..f5e3452 100644 --- a/docs/Naja_float.txt +++ b/docs/Naja_float.txt @@ -4,7 +4,7 @@ 16, fadd, +, +=, opcode = 16 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 0 0 0 0|<--- rd ---->|0 | 0 0| 0 0 0 0 0 0 0 0|<--- rs1 ---->|<--- rs0 ---->| +| 0 1 0 0 0 0|<--- rd ---->|0 0| 0 0 0 0 0 0 0 0 0|<--- rs1 ---->|<--- rs0 ---->| rd = rs0 + rs1; @@ -12,16 +12,23 @@ rd = rs0 + rs1; 17, fsub, -, -=, opcode = 17 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 0 0 0 1|<--- rd ---->|0 | 0 0| 0 0 0 0 0 0 0 0|<--- rs1 ---->|<--- rs0 ---->| +| 0 1 0 0 0 1|<--- rd ---->|0 0| 0 0 0 0 0 0 0 0 0|<--- rs1 ---->|<--- rs0 ---->| rd = rs0 - rs1; ------------------------------------------------------------------------------------------------ +fcmp, >, >=, <, <=, ==, !=, opcode = 17 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 0 0 0 1| 1 1 1 1 1|0 0| 0 0 0 0 0 0 0 0 0|<--- rs1 ---->|<--- rs0 ---->| + +flags = rs0 - rs1; +------------------------------------------------------------------------------------------------ 18, fmul, *, *=, opcode = 18 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 0 0 1 0|<--- rd ---->| s| opt | 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| +| 0 1 0 0 1 0|<--- rd ---->| opt | s| 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| s = 1, signed mul. @@ -34,7 +41,7 @@ rd = rs0 * rs1; // opt = 2 19, fdiv, *, *=, opcode = 19 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 0 0 1 1|<--- rd ---->| s| opt | 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| +| 0 1 0 0 1 1|<--- rd ---->| opt | s| 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| s = 1, signed div. @@ -47,76 +54,91 @@ rd = rs0 / rs1; // opt = 2 20, fldr, b[i] opcode = 20 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 0 1 0 0|<--- rd ---->| A| ext |<--------- simm12 ---------------->|<---- rb ---->| - -rd = *(double*)(rb + ((int64_t)simm12 << 3)); // ext = 3, -rd = *(float *)(rb + ((int64_t)simm12 << 2)); // ext = 6, SS2SD +| 0 1 0 1 0 0|<--- rd ---->| SH | 1|<------------ simm13 ---------------->|<---- rb ---->| -rb += simm12 << sh, if A = 1 +rd = *(double*)(rb + ((int64_t)simm13 << 3)); // SH = 3, +rd = *(float *)(rb + ((int64_t)simm13 << 2)); // SH = 2, SS2SD ------------------------------------------------------------------------------------------------ -21, fstr, b[i] opcode = 21 +21, fpop, b[i] opcode = 21 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 0 1 0 1|<--- rd ---->| A| ext |<--------- simm12 ---------------->|<---- rb ---->| +| 0 1 0 1 0 1|<--- rd ----->| SH | 1| 0 0 0 0 0 0 0 0 0 0 0 0 0|<---- rb ---->| -*(double*)(rb + ((int64_t)simm15 << 3) = rd; // ext = 3, -*(float *)(rb + ((int64_t)simm15 << 2) = rd; // ext = 6, SD2SS +rd = *(double*)rb; // SH = 3, +rd = *(float *)rb; // SH = 2, SS2SD -rb += simm12 << sh, if A = 1 +rb += 1 << SH ------------------------------------------------------------------------------------------------ - -25, fcmp, >, >=, <, <=, ==, !=, opcode = 25 +22, fstr, b[i] opcode = 22 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 1 0 0 1| 0 0 0 0 0|0 0 0| 0 0 0 0 0 0 0 0|<--- rs1 ---->|<--- rs0 ---->| +| 0 1 0 1 1 0|<--- rs ----->| SH | 1|<----------- simm13 ----------------->|<---- rb ---->| -flags = rs0 - rs1; +*(double*)(rb + ((int64_t)simm13 << 3) = rs; // SH = 3, +*(float *)(rb + ((int64_t)simm13 << 2) = rs; // SH = 2, SD2SS ------------------------------------------------------------------------------------------------ - -28, fldr, b[i << s] opcode = 28 +23, fpush, b[i] opcode = 23 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 1 1 0 0|<--- rd ---->|PA| ext |<-------- uimm7 -->|<---- ri ---->|<---- rb ---->| +| 0 1 0 1 1 1|<---- rs ---->| SH | 1| 0 0 0 0 0 0 0 0 0 0 0 0 0|<---- rb ---->| -rd = *(double*)(rb + (ri << uimm8)); // ext = 3, -rd = *(float* )(rb + (ri << uimm8)); // ext = 6, SS2SD +*(double*)rb = rs; // SH = 3, +*(float *)rb = rs; // SH = 2, SD2SS -rb += ri << uimm7, if PA = 1 +rb -= 1 << SH ------------------------------------------------------------------------------------------------ -29, fstr, b[i << s] opcode = 29 +29, fldr, b[i << s] opcode = 29 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 1 1 0 1|<--- rd ---->|PA| ext |<-------- uimm7 -->|<---- ri ---->|<---- rb ---->| +| 0 1 1 1 0 1|<--- rd ----->| SH | 1|<-------- uimm8 ------>|<---- ri ---->|<---- rb ---->| -rd = *(double*)(rb + (ri << uimm8)); // ext = 3 -rd = *(float *)(rb + (ri << uimm8)); // ext = 6, SD2SS +rd = *(double*)(rb + (ri << uimm8)); // SH = 3, +rd = *(float* )(rb + (ri << uimm8)); // SH = 2, SS2SD +------------------------------------------------------------------------------------------------ -rb += ri << uimm7, if PA = 1 +30, fstr, b[i << s] opcode = 30 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 1 1 1 0|<---- rs ---->| SH | 1|<-------- uimm8 ------>|<---- ri ---->|<---- rb ---->| + +*(double*)(rb + (ri << uimm8)) = rs; // SH = 3 +*(float *)(rb + (ri << uimm8)) = rs; // SH = 2, SD2SS ------------------------------------------------------------------------------------------------ 31, fmov, =, ~, -, opcode = 31 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 1 1 1 1|<--- rd ---->| 0| opt | 0 0 0 0 0 0 0 0 0 0 0|<---- rs ---->| +| 0 1 1 1 1 1|<--- rd ---->| SH | s| 0 0| 0 0 0 0 0 0 0 0 0 0 0|<---- rs ---->| + +rd = (double)rs; // SH = 2, s = 0, SS2SD, +rd = (float )rs; // SH = 3, s = 0, SD2SS, -rd = rs; // opt = 0 -rd = rs; // opt = 1 SS2SD, -rd = rs; // opt = 2 SD2SS, -rd = -rs; // opt = 3 NEG, +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 1 1 1 1|<--- rd ---->| SH | s| 0 1| 0 0 0 0 0 0 0 0 0 0 0|<---- rs ---->| -rd = rs; // opt = 4 CVTSS2SI, -rd = rs; // opt = 5 CVTSD2SI, -rd = rs; // opt = 6 CVTSS2UI, -rd = rs; // opt = 7 CVTSD2UI, +rd = (int32_t )rs; // SH = 2, s = 1, CVTSS2SI, +rd = (int64_t )rs; // SH = 3, s = 1, CVTSD2SI, +rd = (uint32_t)rs; // SH = 2, s = 0, CVTSS2UI, +rd = (uint64_t)rs; // SH = 3, s = 0, CVTSD2UI, -rd = rs; // opt = c CVTSI2SS, -rd = rs; // opt = d CVTSI2SD, -rd = rs; // opt = e CVTUI2SS, -rd = rs; // opt = f CVTUI2SD, ------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 1 1 1 1|<--- rd ---->| SH | s| 1 0| 0 0 0 0 0 0 0 0 0 0 0|<---- rs ---->| +rd = (float )(int32_t )rs; // SH = 2, s = 1, CVTSI2SS, +rd = (double)(int32_t )rs; // SH = 3, s = 1, CVTSI2SD, +rd = (float )(uint32_t)rs; // SH = 2, s = 0, CVTUI2SS, +rd = (double)(uint32_t)rs; // SH = 3, s = 0, CVTUI2SD, +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 1 1 1 1|<--- rd ---->| SH | s| 1 1| 0 0 0 0 0 0 0 0 0 0 0|<---- rs ---->| + +rd = rs; // SH = 2 or 3, s = 0, +rd = -rs; // SH = 2 or 3, s = 1, NEG, +------------------------------------------------------------------------------------------------ diff --git a/docs/Naja_int.txt b/docs/Naja_int.txt index caf43fd..fc63fa0 100644 --- a/docs/Naja_int.txt +++ b/docs/Naja_int.txt @@ -4,38 +4,53 @@ 0, add, +, +=, opcode = 0 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 0 0 0|<--- rd ---->|0 | sh |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->| +| 0 0 0 0 0 0|<---- rd ---->| SH |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->| -rd = rs0 + (rs1 << IMM); // SH = 0, LSL -rd = rs0 + (rs1 >> IMM); // SH = 1, LSR -rd = rs0 + (rs1 >> IMM); // SH = 2, ASR +rd = rs0 + (rs1 << uimm9); // SH = 0, LSL +rd = rs0 + (rs1 >> uimm9); // SH = 1, LSR +rd = rs0 + (rs1 >> uimm9); // SH = 2, ASR ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 0 0 0|<--- rd ---->|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->| +| 0 0 0 0 0 0|<---- rd ---->| 1 1|<----------------- uimm14 -------------->|<--- rs0 ---->| -rd = rs0 + (uint64_t)uimm15; +rd = rs0 + (uint64_t)uimm14; // SH = 3, IMM ------------------------------------------------------------------------------------------------ 1, sub, -, -=, opcode = 1 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 0 0 1|<--- rd ---->|0 | sh |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->| +| 0 0 0 0 0 1|<---- rd ---->| SH |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->| -rd = rs0 - (rs1 << IMM); // SH = 0, LSL -rd = rs0 - (rs1 >> IMM); // SH = 1, LSR -rd = rs0 - (rs1 >> IMM); // SH = 2, ASR +rd = rs0 - (rs1 << uimm9); // SH = 0, LSL +rd = rs0 - (rs1 >> uimm9); // SH = 1, LSR +rd = rs0 - (rs1 >> uimm9); // SH = 2, ASR ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 0 0 1|<--- rd ---->|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->| +| 0 0 0 0 0 1|<---- rd ---->| 1 1|<----------------- uimm14 -------------->|<--- rs0 ---->| -rd = rs0 - (uint64_t)uimm15; +rd = rs0 - (uint64_t)uimm14; // SH = 3, IMM ------------------------------------------------------------------------------------------------ +cmp, >, >=, <, <=, ==, !=, opcode = 1 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 0 0 0 1| 1 1 1 1 1| SH |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->| + +flags = rs0 - (rs1 << uimm9); // SH = 0, LSL, rd = 31 +flags = rs0 - (rs1 >> uimm9); // SH = 1, LSR, rd = 31 +flags = rs0 - (rs1 >> uimm9); // SH = 2, ASR, rd = 31 + +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 0 0 0 1| 1 1 1 1 1| 1 1|<----------------- uimm14 -------------->|<--- rs0 ---->| + +flags = rs0 - (uint64_t)uimm14; // SH = 3, IMM, rd = 31 +------------------------------------------------------------------------------------------------ 2, mul, *, *=, opcode = 2 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 0 1 0|<--- rd ---->| s| opt | 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| +| 0 0 0 0 1 0|<---- rd ---->| opt | s| 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| s = 0, unsigned mul. s = 1, signed mul. @@ -48,7 +63,7 @@ rd = rs0 * rs1; // opt = 2 3, div, *, *=, opcode = 3 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 0 1 1|<--- rd ---->| s| opt | 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| +| 0 0 0 0 1 1|<--- rd ----->| opt | s| 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| s = 0, unsigned div. s = 1, signed div. @@ -58,106 +73,128 @@ rd = rs2 - rs0 / rs1; // opt = 1 rd = rs0 / rs1; // opt = 2 ------------------------------------------------------------------------------------------------ - 4, ldr, b[i] opcode = 4 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 1 0 0|<--- rd ---->| A| ext |<-------- simm12 ----------------->|<---- rb ---->| +| 0 0 0 1 0 0|<--- rd ----->| SH | s|<----------- simm13 ----------------->|<---- rb ---->| -rd = *(uint8_t* )(rs0 + (int64_t)simm12); // ext = 0, zbq -rd = *(uint16_t*)(rs0 + ((int64_t)simm12 << 1)); // ext = 1, zwq -rd = *(uint32_t*)(rs0 + ((int64_t)simm12 << 2)); // ext = 2, zlq +rd = *(uint8_t* )(rb + (int64_t)simm13); // SH = 0, s = 0, zbq +rd = *(uint16_t*)(rb + ((int64_t)simm13 << 1)); // SH = 1, s = 0, zwq +rd = *(uint32_t*)(rb + ((int64_t)simm13 << 2)); // SH = 2, s = 0, zlq -rd = *(uint64_t*)(rs0 + ((int64_t)simm12 << 3)); // ext = 3, +rd = *(uint64_t*)(rb + ((int64_t)simm13 << 3)); // SH = 3, s = 0, keep -rd = *( int8_t* )(rs0 + (int64_t)simm12); // ext = 4, sbq -rd = *( int16_t*)(rs0 + ((int64_t)simm12 << 1)); // ext = 5, swq -rd = *( int32_t*)(rs0 + ((int64_t)simm12 << 2)); // ext = 6, slq - -rb += simm12 << SH, if A = 1 +rd = *( int8_t* )(rb + (int64_t)simm13); // SH = 0, s = 1, sbq +rd = *( int16_t*)(rb + ((int64_t)simm13 << 1)); // SH = 1, s = 1, swq +rd = *( int32_t*)(rb + ((int64_t)simm13 << 2)); // SH = 2, s = 1, slq ------------------------------------------------------------------------------------------------ -5, str, b[i] opcode = 5 +5, pop, b[i] opcode = 5 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 1 0 1|<--- rd ---->| A| ext |--------- simm12 ----------------->|<---- rb ---->| +| 0 0 0 1 0 1|<--- rd ----->| SH | s| 0 0 0 0 0 0 0 0 0 0 0 0 0|<---- rb ---->| -*(uint8_t* )(rs0 + (int64_t)simm12) = rd; // ext = 0, zbq -*(uint16_t*)(rs0 + ((int64_t)simm12 << 1)) = rd; // ext = 1, zwq -*(uint32_t*)(rs0 + ((int64_t)simm12 << 2)) = rd; // ext = 2, zlq -*(uint64_t*)(rs0 + ((int64_t)simm12 << 3)) = rd; // ext = 3 +rd = *(uint8_t* )rb; // SH = 0, s = 0, zbq +rd = *(uint16_t*)rb; // SH = 1, s = 0, zwq +rd = *(uint32_t*)rb; // SH = 2, s = 0, zlq -rb += simm12 << SH, if A = 1 ------------------------------------------------------------------------------------------------- +rd = *(uint64_t*)rb; // SH = 3, s = 0, keep +rd = *( int8_t* )rb; // SH = 0, s = 1, sbq +rd = *( int16_t*)rb; // SH = 1, s = 1, swq +rd = *( int32_t*)rb; // SH = 2, s = 1, slq -6, and, &, &=, opcode = 6 +rb += 1 << SH ------------------------------------------------------------------------------------------------ -|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 1 1 0|<--- rd ---->|0 | sh |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->| -rd = rs0 & (rs1 << IMM); // SH = 0, LSL -rd = rs0 & (rs1 >> IMM); // SH = 1, LSR -rd = rs0 & (rs1 >> IMM); // SH = 2, ASR +6, str, b[i] opcode = 6 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 1 1 0|<--- rd ---->|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->| +| 0 0 0 1 1 0|<--- rs ----->| SH | 0|<----------- simm13 ----------------->|<---- rb ---->| -rd = rs0 & (uint64_t)uimm15; +*(uint8_t* )(rb + (int64_t)simm13) = rs; // SH = 0, zbq +*(uint16_t*)(rb + ((int64_t)simm13 << 1)) = rs; // SH = 1, zwq +*(uint32_t*)(rb + ((int64_t)simm13 << 2)) = rs; // SH = 2, zlq +*(uint64_t*)(rb + ((int64_t)simm13 << 3)) = rs; // SH = 3, keep ------------------------------------------------------------------------------------------------ -7, or, |, |=, opcode = 7 +7, push, b[i] opcode = 7 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 1 1 1|<--- rd ---->|0 | sh |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->| +| 0 0 0 1 1 1|<---- rs ---->| SH | s| 0 0 0 0 0 0 0 0 0 0 0 0 0|<---- rb ---->| -rd = rs0 | (rs1 << uimm8); // SH = 0, LSL -rd = rs0 | (rs1 >> uimm8); // SH = 1, LSR -rd = rs0 | (rs1 >> uimm8); // SH = 2, ASR +*(uint8_t* )rb = rs; // SH = 0, s = 0, zbq +*(uint16_t*)rb = rs; // SH = 1, s = 0, zwq +*(uint32_t*)rb = rs; // SH = 2, s = 0, zlq +*(uint64_t*)rb = rs; // SH = 3, s = 0, keep + +rb -= 1 << SH +------------------------------------------------------------------------------------------------ + +8, and, &, &=, opcode = 8 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 0 0 0|<---- rd ---->| SH |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->| +rd = rs0 & (rs1 << uimm9); // SH = 0, LSL +rd = rs0 & (rs1 >> uimm9); // SH = 1, LSR +rd = rs0 & (rs1 >> uimm9); // SH = 2, ASR ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 0 1 1 1|<--- rd ---->|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->| +| 0 0 1 0 0 0|<---- rd ---->| 1 1|<---------------- uimm14 --------------->|<--- rs0 ---->| -rd = rs0 | (uint64_t)uimm15; +rd = rs0 & (uint64_t)uimm14; // SH = 3, IMM ------------------------------------------------------------------------------------------------ -8, jmp, disp opcode = 8 +teq, !, opcode = 8 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 0 0 0|<-------------------------------- simm26:00 -------------------------------->| +| 0 0 1 0 0 0| 1 1 1 1 1| SH |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->| + +ZF = rs0 & (rs1 << uimm9); // SH = 0, LSL +ZF = rs0 & (rs1 >> uimm9); // SH = 1, LSR +ZF = rs0 & (rs1 >> uimm9); // SH = 2, ASR -jmp disp; // -128M ~ 128M ------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 0 0 0| 1 1 1 1 1| 1 1|<---------------- uimm14 --------------->|<--- rs0 ---->| +ZF = rs0 & (uint64_t)uimm14; // SH = 3, IMM +------------------------------------------------------------------------------------------------ -9, cmp, >, >=, <, <=, ==, !=, opcode = 9 +9, or, |, |=, opcode = 9 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 0 0 1| 0 0 0 0 0|0 | sh |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->| +| 0 0 1 0 0 1|<---- rd ---->| SH |<---------- uimm9 ------->|<--- rs1 ---->|<--- rs0 ---->| -flags = rs0 - (rs1 << IMM); // SH = 0, LSL -flags = rs0 - (rs1 >> IMM); // SH = 1, LSR -flags = rs0 - (rs1 >> IMM); // SH = 2, ASR +rd = rs0 | (rs1 << uimm8); // SH = 0, LSL +rd = rs0 | (rs1 >> uimm8); // SH = 1, LSR +rd = rs0 | (rs1 >> uimm8); // SH = 2, ASR ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 0 0 1| 0 0 0 0 0|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->| +| 0 0 0 1 1 1|<---- rd ---->| 1 1|<---------------- uimm14 --------------->|<--- rs0 ---->| -flags = rs0 - (uint64_t)uimm15; +rd = rs0 | (uint64_t)uimm14; // SH = 3, IMM ------------------------------------------------------------------------------------------------ +10, jmp, disp opcode = 10 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 0 1 0|<-------------------------------- simm26:00 -------------------------------->| + +jmp disp; // -128M ~ 128M +------------------------------------------------------------------------------------------------ -10, jmp, reg, opcode = 10 +11, jmp, reg, opcode = 11 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 0 1 0|<--- rd ---->| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| +| 0 0 1 0 1 1|<---- rd ---->| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| jmp *rd; ------------------------------------------------------------------------------------------------ - |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 0 1 0|<----------------------------- simm21:00 -------------------->|<--- cc -->| 1| +| 0 0 1 0 1 1|<----------------------------- simm21:00 -------------------->|<--- cc -->| 1| jcc simm21:00; // -4M ~ +4M cc = 0, z, @@ -168,11 +205,10 @@ cc = 4, le, cc = 5, lt, ------------------------------------------------------------------------------------------------ - -11, setcc, &&,||, opcode = 11 +12, setcc, &&,||, opcode = 12 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 0 1 1|<--- rd ---->| cc | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| +| 0 0 1 1 0 0|<---- rd ---->| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| 0|<--- cc -->| 0| cc = 0, z, cc = 1, nz, @@ -182,116 +218,94 @@ cc = 4, le, cc = 5, lt, ------------------------------------------------------------------------------------------------ - -12, ldr, b[i << s] opcode = 12 +13, ldr, b[i << s] opcode = 13 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 0 0|<--- rd ---->|0 | ext |<------ uimm7 ----->|<---- ri ---->|<---- rb ---->| +| 0 0 1 1 0 1|<--- rd ----->| SH | s|<-------- uimm8 ------>|<---- ri ---->|<---- rb ---->| -rd = *(uint8_t* )(rb + (ri << uimm7)); // ext = 0, zbq -rd = *(uint16_t*)(rb + (ri << uimm7)); // ext = 1, zwq -rd = *(uint32_t*)(rb + (ri << uimm7)); // ext = 2, zlq +rd = *(uint8_t* )(rb + (ri << uimm8)); // SH = 0, s = 0, zbq +rd = *(uint16_t*)(rb + (ri << uimm8)); // SH = 1, s = 0, zwq +rd = *(uint32_t*)(rb + (ri << uimm8)); // SH = 2, s = 0, zlq -rd = *(uint64_t*)(rb + (ri << uimm7)); // ext = 3, +rd = *(uint64_t*)(rb + (ri << uimm8)); // SH = 3, s = 0, keep -rd = *( int8_t* )(rb + (ri << uimm7)); // ext = 4, sbq -rd = *( int16_t*)(rb + (ri << uimm7)); // ext = 5, swq -rd = *( int32_t*)(rb + (ri << uimm7)); // ext = 6, slq +rd = *( int8_t* )(rb + (ri << uimm8)); // SH = 0, s = 1, sbq +rd = *( int16_t*)(rb + (ri << uimm8)); // SH = 1, s = 1, swq +rd = *( int32_t*)(rb + (ri << uimm8)); // SH = 2, s = 1, slq ------------------------------------------------------------------------------------------------ -13, str, b[i << s] opcode = 13 +14, str, b[i << s] opcode = 14 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 0 1|<--- rd ---->|0 | ext |<-------- uimm7 -->|<---- ri ---->|<---- rb ---->| - -rd = *(uint8_t* )(rb + (ri << uimm7)); // ext = 0, zbq -rd = *(uint16_t*)(rb + (ri << uimm7)); // ext = 1, zwq -rd = *(uint32_t*)(rb + (ri << uimm7)); // ext = 2, zlq +| 0 0 1 1 1 0|<---- rs ---->| SH | s|<-------- uimm8 ------>|<---- ri ---->|<---- rb ---->| -rd = *(uint64_t*)(rb + (ri << uimm7)); // ext = 3, - -rd = *( int8_t* )(rb + (ri << uimm7)); // ext = 4, sbq -rd = *( int16_t*)(rb + (ri << uimm7)); // ext = 5, swq -rd = *( int32_t*)(rb + (ri << uimm7)); // ext = 6, slq +*(uint8_t* )(rb + (ri << uimm8)) = rs; // SH = 0, s = 0, zbq +*(uint16_t*)(rb + (ri << uimm8)) = rs; // SH = 1, s = 0, zwq +*(uint32_t*)(rb + (ri << uimm8)) = rs; // SH = 2, s = 0, zlq +*(uint64_t*)(rb + (ri << uimm8)) = rs; // SH = 3, s = 0, keep ------------------------------------------------------------------------------------------------ -14, teq, !, opcode = 14 +15, mov, =, ~, -, opcode = 15 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 1 0| 0 0 0 0 0|0 | sh |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->| +| 0 0 1 1 1 1|<--- rd ---->| SH | 0| 0 0| 0 0 0 0 0 0|<--- rs1 ---->|<---- rs0---->| -ZF = rs0 & (rs1 << IMM); // SH = 0, LSL -ZF = rs0 & (rs1 >> IMM); // SH = 1, LSR -ZF = rs0 & (rs1 >> IMM); // SH = 2, ASR +rd = rs << rs1; // SH = 0 LSL, +rd = rs >> rs1; // SH = 1 LSR, +rd = rs >> rs1; // SH = 2 ASR, ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 1 0| 0 0 0 0 0|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->| - -ZF = rs0 & (uint64_t)uimm15; ------------------------------------------------------------------------------------------------- +| 0 0 1 1 1 1|<--- rd ---->| SH | 0| 0 1|<------------- uimm11 --------->|<---- rs ---->| +rd = rs; // SH = 0 LSL, uimm11 = 0 +rd = rs << uimm11; // SH = 0 LSL, +rd = rs >> uimm11; // SH = 1 LSR, +rd = rs >> uimm11; // SH = 2 ASR, -15, mov, =, ~, -, opcode = 15 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 1 1|<--- rd ---->|0 | 0| opt |<------------- uimm11 --------->|<---- rs ---->| - -rd = rs; // opt = 0 LSL, uimm11 = 0 -rd = rs << uimm11; // opt = 0 LSL, -rd = rs >> uimm11; // opt = 1 LSR, -rd = rs >> uimm11; // opt = 2 ASR, -rd = ~rs; // opt = 3 NOT, -rd = -rs; // opt = 4 NEG, +| 0 0 1 1 1 1|<--- rd ---->| SH | s| 1 0| 0 0 0 0 0 0 0 0 0 0 0|<---- rs ---->| ------------------------------------------------------------------------------------------------- -|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 1 1|<--- rd ---->|0 | 1| opt | 0 0 0 0 0 0|<--- rs1 ---->|<---- rs0---->| +rd = uint8_t(rs); // SH = 0, s = 0, zbq, +rd = uint16_t(rs); // SH = 1, s = 0, zwq, +rd = uint32_t(rs); // SH = 2, s = 0, zlq -rd = rs << rs1; // opt = 0 LSL, -rd = rs >> rs1; // opt = 1 LSR, -rd = rs >> rs1; // opt = 2 ASR, +rd = int8_t(rs); // SH = 0, s = 1, sbq, +rd = int16_t(rs); // SH = 1, s = 1, swq +rd = int32_t(rs); // SH = 2, s = 1, slq +rd = ~rs; // SH = 3, s = 0, NOT, +rd = -rs; // SH = 3, s = 1, NEG, ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 1 1|<--- rd ---->|0 | x| opt |<------------- uimm11 --------->|<---- rs ---->| +| 0 0 1 1 1 1|<--- rd ---->| SH | 0| 1 1|<------------------ uimm16 ------------------->| -rd = uint8_t(rs); // x = 0, zbq, opt = 5, -rd = int8_t(rs); // x = 1, sbq, opt = 5, -rd = uint16_t(rs); // x = 0, zwq, opt = 6, -rd = int16_t(rs); // x = 1, swq, opt = 6, -rd = uint32_t(rs); // x = 0, zlq, opt = 7, -rd = int32_t(rs); // x = 1, slq, opt = 7, +rd = uint64_t(imm16); // SH = 0, IMM +rd = uint64_t(imm16) << 16; // SH = 1, IMM +rd = uint64_t(imm16) << 32; // SH = 2, IMM +rd = uint64_t(imm16) << 48; // SH = 3, IMM ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 0 1 1 1 1|<--- rd ---->|1 | x| opt |<------------------ imm16 ------------------->| - -rd = uint64_t(imm16); // opt = 0 -rd = uint64_t(imm16) << 16; // opt = 1 -rd = uint64_t(imm16) << 32; // opt = 2 -rd = uint64_t(imm16) << 48; // opt = 3 +| 0 0 1 1 1 1|<--- rd ---->| 0 0| 1| 1 1|<------------------ uimm16 ------------------->| -rd = uint64_t(imm16); // opt = 7, NOT - -rd = uint64_t(imm16); // x = 0, zwq -rd = int64_t(imm16); // x = 1, swq +rd = uint64_t(imm16); // NOT ------------------------------------------------------------------------------------------------ - -24, call, disp opcode = 24 +26, call, disp opcode = 26 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 1 0 0 0|<-------------------------------- simm26:00 -------------------------------->| +| 0 1 1 0 1 0|<-------------------------------- simm26:00 -------------------------------->| call disp; // -128M ~ 128M ------------------------------------------------------------------------------------------------ -26, call, reg, opcode = 26 +27, call, reg, opcode = 27 ------------------------------------------------------------------------------------------------ |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| -| 0 1 1 0 1 0|<--- rd ---->| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| +| 0 1 1 0 1 1|<---- rd ---->| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| call *rd; ------------------------------------------------------------------------------------------------ @@ -301,7 +315,7 @@ call *rd; |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| | 1 0 1 0 1 0|<--- rd ---->|<-------------------- simm21 ---------------------------->| -rd = RIP + ((int64_t)simm21 << 15); // load address' high 21 bits relative to current RIP, -32G:+32G +rd = RIP + ((int64_t)simm21 << 14); // load address' high 21 bits relative to current RIP, -16G:+16G ------------------------------------------------------------------------------------------------ 56, ret, opcode = 56 @@ -311,4 +325,3 @@ rd = RIP + ((int64_t)simm21 << 15); // load address' high 21 bits relative to cu ret ------------------------------------------------------------------------------------------------ - diff --git a/elf/scf_elf_arm64_so.c b/elf/scf_elf_arm64_so.c index 60d8883..803fbc9 100644 --- a/elf/scf_elf_arm64_so.c +++ b/elf/scf_elf_arm64_so.c @@ -881,4 +881,3 @@ int __arm64_elf_write_dynamic(scf_elf_context_t* elf, uint64_t rw_base, uint64_t fwrite(&ph_dynamic, sizeof(Elf64_Phdr), 1, elf->fp); return 0; } - diff --git a/elf/scf_elf_naja.c b/elf/scf_elf_naja.c index c911a65..0550fc3 100644 --- a/elf/scf_elf_naja.c +++ b/elf/scf_elf_naja.c @@ -60,7 +60,7 @@ static int _naja_elf_link_cs(elf_native_t* naja, elf_section_t* s, elf_section_t case R_AARCH64_ADR_PREL_PG_HI21: - offset >>= 15; + offset >>= 14; offset &= 0x1fffff; *(uint32_t*)(s->data + rela->r_offset) |= offset; @@ -68,7 +68,7 @@ static int _naja_elf_link_cs(elf_native_t* naja, elf_section_t* s, elf_section_t case R_AARCH64_ADD_ABS_LO12_NC: - *(uint32_t*)(s->data + rela->r_offset) |= (sym->sym.st_value & 0x7fff) << 5; + *(uint32_t*)(s->data + rela->r_offset) |= (sym->sym.st_value & 0x3fff) << 5; break; default: diff --git a/elf/scf_elf_naja_so.c b/elf/scf_elf_naja_so.c index 486dbb7..04d800c 100644 --- a/elf/scf_elf_naja_so.c +++ b/elf/scf_elf_naja_so.c @@ -2,23 +2,23 @@ #include"scf_elf_link.h" static uint32_t naja_plt_lazy[8] = { - // str x16, x30, [sp, #-16]! - (5 << 26) | (16 << 21) | (1 << 20) | (3 << 17) | (((-1) & 0xfff) << 5) | 0x1f, - (5 << 26) | (30 << 21) | (1 << 20) | (3 << 17) | (((-1) & 0xfff) << 5) | 0x1f, + // str x16, lr, [sp, #-16]! + (7 << 26) | (16 << 21) | (3 << 19) | 0x1e, + (7 << 26) | (29 << 21) | (3 << 19) | 0x1e, (0x2a << 26) | (16 << 21), // adrp x16, 0 - (0 << 26) | (16 << 21) | (1 << 20) | 16, // add x16, x16, #0 + (0 << 26) | (16 << 21) | (3 << 19) | 16, // add x16, x16, #0 - (4 << 26) | (17 << 21) | (3 << 17) | 16, // ldr x17, [x16, #0] - (0xa << 26) | (17 << 21), // jmp *x17 - (0xf << 26), // nop, mov r0, r0 - (0xf << 26), // nop, mov r0, r0 + (4 << 26) | (17 << 21) | (3 << 19) | 16, // ldr x17, [x16, #0] + (0xb << 26) | (17 << 21), // jmp *x17 + (0xf << 26) | (1 << 16), // nop, mov r0, r0 + (0xf << 26) | (1 << 16), // nop, mov r0, r0 }; static uint32_t naja_plt[4] = { (0x2a << 26) | (16 << 21), // adrp x16, 0 - (0 << 26) | (16 << 21) | (1 << 20) | 16, // add x16, x16, #0 - (4 << 26) | (17 << 21) | (3 << 17) | 16, // ldr x17, [x16, #0] - (0xa << 26) | (17 << 21), // jmp *x17 + (0 << 26) | (16 << 21) | (3 << 19) | 16, // add x16, x16, #0 + (4 << 26) | (17 << 21) | (3 << 19) | 16, // ldr x17, [x16, #0] + (0xb << 26) | (17 << 21), // jmp *x17 }; @@ -693,8 +693,8 @@ int __naja_elf_post_dyn(elf_native_t* naja, uint64_t rx_base, uint64_t rw_base, scf_logi("got_addr: %#lx, plt_addr: %#lx, offset: %d, %#x\n", got_addr, plt_addr, offset, offset); - plt[2] |= (offset >> 15) & 0x1fffff; - plt[3] |= (got_addr & 0x7fff) << 5; + plt[2] |= (offset >> 14) & 0x1fffff; + plt[3] |= (got_addr & 0x3fff) << 5; got_addr += 8; plt_addr += sizeof(naja_plt_lazy); @@ -712,8 +712,8 @@ int __naja_elf_post_dyn(elf_native_t* naja, uint64_t rx_base, uint64_t rw_base, scf_logi("i: %d, got_addr: %#lx, plt_addr: %#lx, offset: %d, %#x\n", i, got_addr, plt_addr, offset, offset); - plt[0] |= (offset >> 15) & 0x1fffff; - plt[1] |= (got_addr & 0x7fff) << 5; + plt[0] |= (offset >> 14) & 0x1fffff; + plt[1] |= (got_addr & 0x3fff) << 5; plt += sizeof(naja_plt) / sizeof(naja_plt[0]); plt_addr += sizeof(naja_plt); @@ -879,4 +879,3 @@ int __naja_elf_write_dynamic(scf_elf_context_t* elf, uint64_t rw_base, uint64_t fwrite(&ph_dynamic, sizeof(Elf64_Phdr), 1, elf->fp); return 0; } - diff --git a/examples/vla_0.c b/examples/vla_0.c new file mode 100644 index 0000000..1647712 --- /dev/null +++ b/examples/vla_0.c @@ -0,0 +1,15 @@ +int printf(const char* fmt, ...); + +int main(int argc, char* argv[]) +{ + int i; + for (i = 1; i < 4; i++) { + char a[i]; + + a[0] = '1'; + + printf("i: %d, a[0]: %c, %lg\n", i, a[0], 3.14); + } + + return 0; +} diff --git a/examples/vla_1.c b/examples/vla_1.c new file mode 100644 index 0000000..f25a38b --- /dev/null +++ b/examples/vla_1.c @@ -0,0 +1,11 @@ +int printf(const char* fmt, ...); + +int main(int argc, char* argv[]) +{ + char a[argc - 1]; + + a[0] = '1'; + + printf("a[0]: %c, %lg\n", a[0], 3.14); + return 0; +} diff --git a/native/eda/scf_eda.c b/native/eda/scf_eda.c index c9aedb1..4544932 100644 --- a/native/eda/scf_eda.c +++ b/native/eda/scf_eda.c @@ -43,13 +43,13 @@ static int _eda_make_insts_for_list(scf_native_t* ctx, scf_list_t* h, int bb_off scf_3ac_code_t* c = scf_list_data(l, scf_3ac_code_t, list); - eda_inst_handler_t* h = scf_eda_find_inst_handler(c->op->type); + eda_inst_handler_pt h = scf_eda_find_inst_handler(c->op->type); if (!h) { scf_loge("3ac operator '%s' not supported\n", c->op->name); return -EINVAL; } - ret = h->func(ctx, c); + ret = h(ctx, c); if (ret < 0) { scf_3ac_code_print(c, NULL); scf_loge("3ac op '%s' make inst failed\n", c->op->name); diff --git a/native/eda/scf_eda.h b/native/eda/scf_eda.h index cc84d93..8db4723 100644 --- a/native/eda/scf_eda.h +++ b/native/eda/scf_eda.h @@ -10,12 +10,9 @@ typedef struct { } scf_eda_context_t; -typedef struct { - int type; - int (*func)(scf_native_t* ctx, scf_3ac_code_t* c); -} eda_inst_handler_t; +typedef int (*eda_inst_handler_pt)(scf_native_t* ctx, scf_3ac_code_t* c); -eda_inst_handler_t* scf_eda_find_inst_handler(const int op_type); +eda_inst_handler_pt scf_eda_find_inst_handler(const int op_type); int scf_eda_open (scf_native_t* ctx, const char* arch); int scf_eda_close (scf_native_t* ctx); diff --git a/native/eda/scf_eda_inst.c b/native/eda/scf_eda_inst.c index 7292521..c56cf6a 100644 --- a/native/eda/scf_eda_inst.c +++ b/native/eda/scf_eda_inst.c @@ -223,9 +223,14 @@ static int __eda_bit_or(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin } /* - x + y = ~(x & y) & (x | y) - x + y = (x NAND y) & (x | y) - x + y = ~(~(x NAND y) | ~(x | y)) + x + y = ~(x & y) & ( x | y) + x + y = (x NAND y) & ~(~x & ~y) + x + y = (x NAND y) & (~x NAND ~y) + x + y = ~((x NAND y) NAND (~x NAND ~y)) + + x + y = ~(x & y) & (x | y) + x + y = (x NAND y) & (x | y) + x + y = ~(~(x NAND y) | ~(x | y)) x + y = ~(x NAND y) NOR (x NOR y)) cf = ~(x NAND y) */ @@ -1296,80 +1301,75 @@ static int _eda_inst_or_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) return 0; } -static eda_inst_handler_t eda_inst_handlers[] = +static eda_inst_handler_pt eda_inst_handlers[] = { - {SCF_OP_ARRAY_INDEX, _eda_inst_array_index_handler}, + [SCF_OP_ARRAY_INDEX] = _eda_inst_array_index_handler, - {SCF_OP_TYPE_CAST, _eda_inst_cast_handler}, - {SCF_OP_LOGIC_NOT, _eda_inst_logic_not_handler}, - {SCF_OP_BIT_NOT, _eda_inst_bit_not_handler}, + [SCF_OP_TYPE_CAST] = _eda_inst_cast_handler, + [SCF_OP_LOGIC_NOT] = _eda_inst_logic_not_handler, + [SCF_OP_BIT_NOT] = _eda_inst_bit_not_handler, - {SCF_OP_INC, _eda_inst_inc_handler}, - {SCF_OP_DEC, _eda_inst_dec_handler}, + [SCF_OP_INC] = _eda_inst_inc_handler, + [SCF_OP_DEC] = _eda_inst_dec_handler, - {SCF_OP_BIT_AND, _eda_inst_bit_and_handler}, - {SCF_OP_BIT_OR, _eda_inst_bit_or_handler}, + [SCF_OP_BIT_AND] = _eda_inst_bit_and_handler, + [SCF_OP_BIT_OR] = _eda_inst_bit_or_handler, - {SCF_OP_ADD, _eda_inst_add_handler}, - {SCF_OP_SUB, _eda_inst_sub_handler}, - {SCF_OP_MUL, _eda_inst_mul_handler}, - {SCF_OP_DIV, _eda_inst_div_handler}, + [SCF_OP_ADD] = _eda_inst_add_handler, + [SCF_OP_SUB] = _eda_inst_sub_handler, + [SCF_OP_MUL] = _eda_inst_mul_handler, + [SCF_OP_DIV] = _eda_inst_div_handler, - {SCF_OP_3AC_TEQ, _eda_inst_teq_handler}, - {SCF_OP_3AC_CMP, _eda_inst_cmp_handler}, + [SCF_OP_3AC_TEQ] = _eda_inst_teq_handler, + [SCF_OP_3AC_CMP] = _eda_inst_cmp_handler, - {SCF_OP_3AC_SETZ, _eda_inst_setz_handler}, - {SCF_OP_3AC_SETNZ, _eda_inst_setnz_handler}, - {SCF_OP_3AC_SETGT, _eda_inst_setgt_handler}, - {SCF_OP_3AC_SETGE, _eda_inst_setge_handler}, - {SCF_OP_3AC_SETLT, _eda_inst_setlt_handler}, - {SCF_OP_3AC_SETLE, _eda_inst_setle_handler}, + [SCF_OP_3AC_SETZ] = _eda_inst_setz_handler, + [SCF_OP_3AC_SETNZ] = _eda_inst_setnz_handler, + [SCF_OP_3AC_SETGT] = _eda_inst_setgt_handler, + [SCF_OP_3AC_SETGE] = _eda_inst_setge_handler, + [SCF_OP_3AC_SETLT] = _eda_inst_setlt_handler, + [SCF_OP_3AC_SETLE] = _eda_inst_setle_handler, - {SCF_OP_EQ, _eda_inst_eq_handler}, - {SCF_OP_NE, _eda_inst_ne_handler}, - {SCF_OP_GT, _eda_inst_gt_handler}, - {SCF_OP_GE, _eda_inst_ge_handler}, - {SCF_OP_LT, _eda_inst_lt_handler}, - {SCF_OP_LE, _eda_inst_le_handler}, + [SCF_OP_EQ] = _eda_inst_eq_handler, + [SCF_OP_NE] = _eda_inst_ne_handler, + [SCF_OP_GT] = _eda_inst_gt_handler, + [SCF_OP_GE] = _eda_inst_ge_handler, + [SCF_OP_LT] = _eda_inst_lt_handler, + [SCF_OP_LE] = _eda_inst_le_handler, - {SCF_OP_ASSIGN, _eda_inst_assign_handler}, + [SCF_OP_ASSIGN] = _eda_inst_assign_handler, - {SCF_OP_AND_ASSIGN, _eda_inst_and_assign_handler}, - {SCF_OP_OR_ASSIGN, _eda_inst_or_assign_handler}, + [SCF_OP_AND_ASSIGN] = _eda_inst_and_assign_handler, + [SCF_OP_OR_ASSIGN] = _eda_inst_or_assign_handler, - {SCF_OP_RETURN, _eda_inst_return_handler}, - {SCF_OP_GOTO, _eda_inst_goto_handler}, + [SCF_OP_RETURN] = _eda_inst_return_handler, + [SCF_OP_GOTO] = _eda_inst_goto_handler, - {SCF_OP_3AC_JZ, _eda_inst_jz_handler}, - {SCF_OP_3AC_JNZ, _eda_inst_jnz_handler}, - {SCF_OP_3AC_JGT, _eda_inst_jgt_handler}, - {SCF_OP_3AC_JGE, _eda_inst_jge_handler}, - {SCF_OP_3AC_JLT, _eda_inst_jlt_handler}, - {SCF_OP_3AC_JLE, _eda_inst_jle_handler}, + [SCF_OP_3AC_JZ] = _eda_inst_jz_handler, + [SCF_OP_3AC_JNZ] = _eda_inst_jnz_handler, + [SCF_OP_3AC_JGT] = _eda_inst_jgt_handler, + [SCF_OP_3AC_JGE] = _eda_inst_jge_handler, + [SCF_OP_3AC_JLT] = _eda_inst_jlt_handler, + [SCF_OP_3AC_JLE] = _eda_inst_jle_handler, - {SCF_OP_3AC_NOP, _eda_inst_nop_handler}, - {SCF_OP_3AC_END, _eda_inst_end_handler}, + [SCF_OP_3AC_NOP] = _eda_inst_nop_handler, + [SCF_OP_3AC_END] = _eda_inst_end_handler, - {SCF_OP_3AC_SAVE, _eda_inst_save_handler}, - {SCF_OP_3AC_LOAD, _eda_inst_load_handler}, + [SCF_OP_3AC_SAVE] = _eda_inst_save_handler, + [SCF_OP_3AC_LOAD] = _eda_inst_load_handler, - {SCF_OP_3AC_RESAVE, _eda_inst_save_handler}, - {SCF_OP_3AC_RELOAD, _eda_inst_reload_handler}, + [SCF_OP_3AC_RESAVE] = _eda_inst_save_handler, + [SCF_OP_3AC_RELOAD] = _eda_inst_reload_handler, - {SCF_OP_3AC_ASSIGN_ARRAY_INDEX, _eda_inst_assign_array_index_handler}, - {SCF_OP_3AC_AND_ASSIGN_ARRAY_INDEX, _eda_inst_and_assign_array_index_handler}, - {SCF_OP_3AC_OR_ASSIGN_ARRAY_INDEX, _eda_inst_or_assign_array_index_handler}, + [SCF_OP_3AC_ASSIGN_ARRAY_INDEX] = _eda_inst_assign_array_index_handler, + [SCF_OP_3AC_AND_ASSIGN_ARRAY_INDEX] = _eda_inst_and_assign_array_index_handler, + [SCF_OP_3AC_OR_ASSIGN_ARRAY_INDEX] = _eda_inst_or_assign_array_index_handler, }; -eda_inst_handler_t* scf_eda_find_inst_handler(const int op_type) +eda_inst_handler_pt scf_eda_find_inst_handler(const int op_type) { - int i; - for (i = 0; i < sizeof(eda_inst_handlers) / sizeof(eda_inst_handlers[0]); i++) { - - eda_inst_handler_t* h = &(eda_inst_handlers[i]); + if (op_type < 0 || op_type >= SCF_N_3AC_OPS) + return NULL; - if (op_type == h->type) - return h; - } - return NULL; + return eda_inst_handlers[op_type]; } diff --git a/native/eda/scf_eda_pack.c b/native/eda/scf_eda_pack.c index 0538826..0489d2d 100644 --- a/native/eda/scf_eda_pack.c +++ b/native/eda/scf_eda_pack.c @@ -157,33 +157,33 @@ static ScfEops __not_ops = static ScfEdata component_datas[] = { - {SCF_EDA_None, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL}, - {SCF_EDA_Battery, 0, SCF_EDA_Battery_POS, 0, 0, 1e-9, 1e9, 0, 0, NULL, NULL}, + {SCF_EDA_None, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL}, + {SCF_EDA_Battery, 0, SCF_EDA_Battery_POS, 0, 0, 1e-9, 1e9, 0, 0, NULL, NULL, NULL}, - {SCF_EDA_Resistor, 0, 0, 0, 0, 1e4, 0, 0, 0, NULL, NULL}, - {SCF_EDA_Capacitor, 0, 0, 0, 0, 10, 0.1, 0, 0, NULL, NULL}, - {SCF_EDA_Inductor, 0, 0, 0, 0, 10, 0, 1e3, 0, NULL, NULL}, + {SCF_EDA_Resistor, 0, 0, 0, 0, 1e4, 0, 0, 0, NULL, NULL, NULL}, + {SCF_EDA_Capacitor, 0, 0, 0, 0, 10, 0.1, 0, 0, NULL, NULL, NULL}, + {SCF_EDA_Inductor, 0, 0, 0, 0, 10, 0, 1e3, 0, NULL, NULL, NULL}, - {SCF_EDA_Diode, 0, 0, 0, 0, 0, 0, 0, 0, &__diode_ops, NULL}, - {SCF_EDA_NPN, 0, 0, 0, 0, 0, 0, 0, 0, &__npn_ops, NULL}, - {SCF_EDA_PNP, 0, 0, 0, 0, 0, 0, 0, 0, &__pnp_ops, NULL}, + {SCF_EDA_Diode, 0, 0, 0, 0, 0, 0, 0, 0, &__diode_ops, NULL, NULL}, + {SCF_EDA_NPN, 0, 0, 0, 0, 0, 0, 0, 0, &__npn_ops, NULL, "./cpk/9013.txt"}, + {SCF_EDA_PNP, 0, 0, 0, 0, 0, 0, 0, 0, &__pnp_ops, NULL, NULL}, - {SCF_EDA_NAND, 0, 0, 0, 0, 0, 0, 0, 0, &__nand_ops, "./cpk/nand.cpk"}, - {SCF_EDA_NOR, 0, 0, 0, 0, 0, 0, 0, 0, &__nor_ops, "./cpk/nor.cpk"}, - {SCF_EDA_NOT, 0, 0, 0, 0, 0, 0, 0, 0, &__not_ops, "./cpk/not.cpk"}, + {SCF_EDA_NAND, 0, 0, 0, 0, 0, 0, 0, 0, &__nand_ops, "./cpk/nand.cpk", NULL}, + {SCF_EDA_NOR, 0, 0, 0, 0, 0, 0, 0, 0, &__nor_ops, "./cpk/nor.cpk", NULL}, + {SCF_EDA_NOT, 0, 0, 0, 0, 0, 0, 0, 0, &__not_ops, "./cpk/not.cpk", NULL}, }; static ScfEdata pin_datas[] = { - {SCF_EDA_None, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL}, + {SCF_EDA_None, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL}, - {SCF_EDA_Diode, 0, SCF_EDA_Diode_NEG, 0, 0, 750, 0, 0, 0, NULL, NULL}, + {SCF_EDA_Diode, 0, SCF_EDA_Diode_NEG, 0, 0, 750, 0, 0, 0, NULL, NULL, NULL}, - {SCF_EDA_NPN, 0, SCF_EDA_NPN_B, 0, 0, 750, 0, 0, 0, NULL, NULL}, - {SCF_EDA_NPN, 0, SCF_EDA_NPN_C, 0, 0, 3, 0, 0, 250, NULL, NULL}, + {SCF_EDA_NPN, 0, SCF_EDA_NPN_B, 0, 0, 750, 0, 0, 0, NULL, NULL, NULL}, + {SCF_EDA_NPN, 0, SCF_EDA_NPN_C, 0, 0, 3, 0, 0, 250, NULL, NULL, NULL}, - {SCF_EDA_PNP, 0, SCF_EDA_PNP_B, 0, 0, 750, 0, 0, 0, NULL, NULL}, - {SCF_EDA_PNP, 0, SCF_EDA_PNP_C, 0, 0, 3, 0, 0, 250, NULL, NULL}, + {SCF_EDA_PNP, 0, SCF_EDA_PNP_B, 0, 0, 750, 0, 0, 0, NULL, NULL, NULL}, + {SCF_EDA_PNP, 0, SCF_EDA_PNP_C, 0, 0, 3, 0, 0, 250, NULL, NULL, NULL}, }; static ScfEdata* _pin_find_data(const uint64_t type, const uint64_t model, const uint64_t pid) @@ -524,7 +524,7 @@ ScfEcomponent* scf_ecomponent__alloc(uint64_t type) pin->id = i; pin->ic_lid = -1; - scf_loge("pin %p, id: %ld, ic_lid: %ld\n", pin, pin->id, pin->ic_lid); + scf_logd("pin %p, id: %ld, ic_lid: %ld\n", pin, pin->id, pin->ic_lid); if (scf_ecomponent__add_pin(c, pin) < 0) { ScfEcomponent_free(c); @@ -546,6 +546,20 @@ ScfEcomponent* scf_ecomponent__alloc(uint64_t type) return c; } +int scf_ecomponent__add_curve(ScfEcomponent* c, ScfEcurve* curve) +{ + if (!c || !curve) + return -EINVAL; + + void* p = realloc(c->curves, sizeof(ScfEcurve*) * (c->n_curves + 1)); + if (!p) + return -ENOMEM; + + c->curves = p; + c->curves[c->n_curves++] = curve; + return 0; +} + int scf_ecomponent__add_pin(ScfEcomponent* c, ScfEpin* pin) { if (!c || !pin) diff --git a/native/eda/scf_eda_pack.h b/native/eda/scf_eda_pack.h index f76525e..f3813b8 100644 --- a/native/eda/scf_eda_pack.h +++ b/native/eda/scf_eda_pack.h @@ -125,6 +125,7 @@ typedef struct { void* ops; char* cpk; + char* va_curve; } ScfEdata; typedef struct { @@ -141,6 +142,18 @@ SCF_PACK_INFO_VAR(ScfLine, x1), SCF_PACK_INFO_VAR(ScfLine, y1), SCF_PACK_END(ScfLine) +typedef struct { + SCF_PACK_DEF_VAR(double, v); + SCF_PACK_DEF_VAR(double, a); + SCF_PACK_DEF_VAR(double, hfe); +} ScfEcurve; + +SCF_PACK_TYPE(ScfEcurve) +SCF_PACK_INFO_VAR(ScfEcurve, v), +SCF_PACK_INFO_VAR(ScfEcurve, a), +SCF_PACK_INFO_VAR(ScfEcurve, hfe), +SCF_PACK_END(ScfEcurve) + typedef struct scf_eops_s ScfEops; typedef struct scf_epin_s ScfEpin; typedef struct scf_ecomponent_s ScfEcomponent; @@ -280,6 +293,8 @@ struct scf_ecomponent_s SCF_PACK_DEF_VAR(uint64_t, model); SCF_PACK_DEF_OBJS(ScfEpin, pins); + SCF_PACK_DEF_OBJS(ScfEcurve, curves); + SCF_PACK_DEF_OBJ(ScfEfunction, pf); SCF_PACK_DEF_OBJ(ScfEfunction, f); SCF_PACK_DEF_OBJ(ScfEops, ops); @@ -309,7 +324,8 @@ SCF_PACK_TYPE(ScfEcomponent) SCF_PACK_INFO_VAR(ScfEcomponent, id), SCF_PACK_INFO_VAR(ScfEcomponent, type), SCF_PACK_INFO_VAR(ScfEcomponent, model), -SCF_PACK_INFO_OBJS(ScfEcomponent, pins, ScfEpin), +SCF_PACK_INFO_OBJS(ScfEcomponent, pins, ScfEpin), +SCF_PACK_INFO_OBJS(ScfEcomponent, curves, ScfEcurve), SCF_PACK_INFO_VAR(ScfEcomponent, v), SCF_PACK_INFO_VAR(ScfEcomponent, a), @@ -380,9 +396,10 @@ ScfEpin* scf_epin__alloc(); int scf_epin__add_component(ScfEpin* pin, uint64_t cid, uint64_t pid); int scf_epin__del_component(ScfEpin* pin, uint64_t cid, uint64_t pid); -ScfEcomponent* scf_ecomponent__alloc (uint64_t type); +ScfEcomponent* scf_ecomponent__alloc(uint64_t type); int scf_ecomponent__add_pin(ScfEcomponent* c, ScfEpin* pin); int scf_ecomponent__del_pin(ScfEcomponent* c, ScfEpin* pin); +int scf_ecomponent__add_curve(ScfEcomponent* c, ScfEcurve* curve); ScfEdata* scf_ecomponent__find_data(const uint64_t type, const uint64_t model); ScfEfunction* scf_efunction__alloc (const char* name); diff --git a/native/risc/scf_naja.c b/native/risc/scf_naja.c index 37cf9d0..791519a 100644 --- a/native/risc/scf_naja.c +++ b/native/risc/scf_naja.c @@ -9,14 +9,14 @@ int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes if (0 == (invert >> 32)) { - // movn rd, invert[15:0] - opcode = (0xf << 26) | (rd->id << 21) | (0x1 << 20) | (0x7 << 16) | (invert & 0xffff); + // mvn rd, invert[15:0] + opcode = (0xf << 26) | (rd->id << 21) | (1 << 18) | (0x3 << 16) | (invert & 0xffff); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); if (invert >> 16) { // movk rd, imm[31:16] - opcode = (0xf << 26) | (rd->id << 21) | (0x1 << 20) | (0x1 << 16)| ((imm >> 16) & 0xffff); + opcode = (0xf << 26) | (rd->id << 21) | (1 << 19) | (0x3 << 16)| ((imm >> 16) & 0xffff); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); } @@ -25,7 +25,7 @@ int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes } // mov rd, imm[15:0] - opcode = (0xf << 26) | (rd->id << 21) | (0x1 << 20) | (imm & 0xffff); + opcode = (0xf << 26) | (rd->id << 21) | (0x3 << 16) | (imm & 0xffff); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); @@ -33,7 +33,7 @@ int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes if (imm & 0xffff) { // movk rd, imm[31:16] - opcode = (0xf << 26) | (rd->id << 21) | (0x1 << 20) | (0x1 << 16) | (imm & 0xffff); + opcode = (0xf << 26) | (rd->id << 21) | (1 << 19) | (0x3 << 16) | (imm & 0xffff); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); } @@ -42,7 +42,7 @@ int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes if (imm & 0xffff) { // movk rd, imm[47:32] - opcode = (0xf << 26) | (rd->id << 21) | (0x1 << 20) | (0x2 << 16) | (imm & 0xffff); + opcode = (0xf << 26) | (rd->id << 21) | (2 << 19) | (0x3 << 16) | (imm & 0xffff); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); } @@ -51,7 +51,7 @@ int naja_inst_I2G(scf_3ac_code_t* c, scf_register_t* rd, uint64_t imm, int bytes if (imm & 0xffff) { // movk rd, imm[63:48] - opcode = (0xf << 26) | (rd->id << 21) | (0x1 << 20) | (0x3 << 16) | (imm & 0xffff); + opcode = (0xf << 26) | (rd->id << 21) | (3 << 19) | (0x3 << 16) | (imm & 0xffff); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); } @@ -76,13 +76,13 @@ int naja_inst_ADR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, sc offset = vs->bp_offset; - if (offset >= 0 && offset <= 0x7fff) + if (offset >= 0 && offset <= 0x3fff) - opcode = (0 << 26) | (rd->id << 21) | (0x1 << 20) | (offset << 5) | fp->id; + opcode = (0 << 26) | (rd->id << 21) | (0x3 << 19) | (offset << 5) | fp->id; - else if (offset < 0 && -offset <= 0x7fff) + else if (offset < 0 && -offset <= 0x3fff) - opcode = (1 << 26) | (rd->id << 21) | (0x1 << 20) | ((-offset) << 5) | fp->id; + opcode = (1 << 26) | (rd->id << 21) | (0x3 << 19) | ((-offset) << 5) | fp->id; else { int ret = naja_inst_I2G(c, rd, offset, 8); @@ -104,7 +104,7 @@ int naja_inst_ADR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, sc RISC_RELA_ADD_CHECK(f->data_relas, rela, c, vs, NULL); rela->type = R_AARCH64_ADR_PREL_PG_HI21; - opcode = (0 << 26) | (rd->id << 21) | (0x1 << 20) | rd->id; + opcode = (0 << 26) | (rd->id << 21) | (0x3 << 19) | rd->id; inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); RISC_RELA_ADD_CHECK(f->data_relas, rela, c, vs, NULL); @@ -193,8 +193,8 @@ int naja_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_ return -EINVAL; - if (offset >= -0x7ff && offset <= 0x7ff) - opcode = (0x4 << 26) | ((offset & 0xfff) << 5) | rb->id; + if (offset >= -0xfff && offset <= 0xfff) + opcode = (0x4 << 26) | ((offset & 0x1fff) << 5) | rb->id; else { int ret = risc_select_free_reg(&ri, c, f, 0); if (ret < 0) { @@ -206,18 +206,18 @@ int naja_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_ if (ret < 0) return ret; - opcode = (0xc << 26) | (SIZE << 10) | (ri->id << 5) | rb->id; + opcode = (0xd << 26) | (SIZE << 10) | (ri->id << 5) | rb->id; } if (rd->bytes > size && scf_variable_signed(vs)) - opcode |= 0x1 << 19; + opcode |= 0x1 << 18; else if (scf_variable_float(vs) && 4 == size) - opcode |= 0x1 << 19; + opcode |= 0x1 << 18; scf_loge("SIZE: %d, size: %d\n", SIZE, size); - opcode |= (rd->id << 21) | SIZE << 17; + opcode |= (rd->id << 21) | SIZE << 19; opcode |= RISC_COLOR_TYPE(rd->color) << 30; inst = risc_make_inst(c, opcode); @@ -307,8 +307,8 @@ int naja_inst_G2M(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_ scf_loge("offset: %ld, SIZE: %d\n", offset, SIZE); - if (offset >= -0x7ff && offset <= 0x7ff) - opcode = (0x5 << 26) | ((offset & 0xfff) << 5) | rb->id; + if (offset >= -0xfff && offset <= 0xfff) + opcode = (0x6 << 26) | ((offset & 0x1fff) << 5) | rb->id; else { int ret = risc_select_free_reg(&ri, c, f, 0); if (ret < 0) { @@ -320,14 +320,14 @@ int naja_inst_G2M(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_ if (ret < 0) return ret; - opcode = (0xd << 26) | (SIZE << 10) | (ri->id << 5) | rb->id; + opcode = (0xe << 26) | (SIZE << 10) | (ri->id << 5) | rb->id; } - opcode |= (rs->id << 21) | SIZE << 17; + opcode |= (rs->id << 21) | SIZE << 19; opcode |= RISC_COLOR_TYPE(rs->color) << 30; if (scf_variable_float(vs) && 4 == size) - opcode |= (1 << 19); + opcode |= (1 << 18); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); @@ -357,7 +357,7 @@ int naja_inst_ISTR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, s RISC_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL); rela->type = R_AARCH64_ADR_PREL_PG_HI21; - opcode = (0 << 26) | (rd->id << 21) | (0x1 << 20) | rd->id; + opcode = (0 << 26) | (rd->id << 21) | (0x3 << 19) | rd->id; inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); RISC_RELA_ADD_CHECK(f->data_relas, rela, c, v, NULL); @@ -412,8 +412,8 @@ int naja_inst_G2P(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_ } else return -EINVAL; - if (offset >= -0x7ff && offset <= 0x7ff) - opcode = (0x5 << 26) | ((offset & 0xfff) << 5) | rb->id; + if (offset >= -0xfff && offset <= 0xfff) + opcode = (0x6 << 26) | ((offset & 0x1fff) << 5) | rb->id; else { int ret = risc_select_free_reg(&ri, c, f, 0); if (ret < 0) { @@ -425,10 +425,10 @@ int naja_inst_G2P(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_ if (ret < 0) return ret; - opcode = (0xd << 26) | (SIZE << 10) | (ri->id << 5) | rb->id; + opcode = (0xe << 26) | (SIZE << 10) | (ri->id << 5) | rb->id; } - opcode |= (rs->id << 21) | SIZE << 17; + opcode |= (rs->id << 21) | SIZE << 19; opcode |= RISC_COLOR_TYPE(rs->color) << 30; inst = risc_make_inst(c, opcode); @@ -483,8 +483,8 @@ int naja_inst_P2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_ } else return -EINVAL; - if (offset >= -0x7ff && offset <= 0x7ff) - opcode = (0x4 << 26) | ((offset & 0xfff) << 5) | rb->id; + if (offset >= -0xfff && offset <= 0xfff) + opcode = (0x4 << 26) | ((offset & 0x1fff) << 5) | rb->id; else { int ret = risc_select_free_reg(&ri, c, f, 0); if (ret < 0) { @@ -496,10 +496,10 @@ int naja_inst_P2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_ if (ret < 0) return ret; - opcode = (0xc << 26) | (SIZE << 10) | (ri->id << 5) | rb->id; + opcode = (0xd << 26) | (SIZE << 10) | (ri->id << 5) | rb->id; } - opcode |= (rd->id << 21) | SIZE << 17; + opcode |= (rd->id << 21) | SIZE << 19; opcode |= RISC_COLOR_TYPE(rd->color) << 30; inst = risc_make_inst(c, opcode); @@ -514,11 +514,11 @@ int naja_inst_ADRP2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, s uint32_t opcode = 0; - if (offset >= 0 && offset <= 0x7fff) - opcode = (0 << 26) | (rd->id << 21) | (1 << 20) | (offset << 5) | rb->id; + if (offset >= 0 && offset <= 0x3fff) + opcode = (0 << 26) | (rd->id << 21) | (3 << 19) | (offset << 5) | rb->id; - else if (offset < 0 && offset >= -0x7fff) - opcode = (1 << 26) | (rd->id << 21) | (1 << 20) | ((-offset) << 5) | rb->id; + else if (offset < 0 && offset >= -0x3fff) + opcode = (1 << 26) | (rd->id << 21) | (3 << 19) | ((-offset) << 5) | rb->id; else { int ret = risc_select_free_reg(&r, c, f, 0); @@ -602,8 +602,8 @@ int naja_inst_SIB2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, sc else return -EINVAL; - opcode = (0xc << 26) | (rd->id << 21) | (SIZE << 10) | (ri->id << 5) | rb->id; - opcode |= SIZE << 17; + opcode = (0xd << 26) | (rd->id << 21) | (SIZE << 10) | (ri->id << 5) | rb->id; + opcode |= SIZE << 19; opcode |= RISC_COLOR_TYPE(rd->color) << 30; inst = risc_make_inst(c, opcode); @@ -643,8 +643,8 @@ int naja_inst_G2SIB(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, sc else return -EINVAL; - opcode = (0xd << 26) | (rs->id << 21) | (SIZE << 10) | (ri->id << 5) | rb->id; - opcode |= SIZE << 17; + opcode = (0xe << 26) | (rs->id << 21) | (SIZE << 10) | (ri->id << 5) | rb->id; + opcode |= SIZE << 19; opcode |= RISC_COLOR_TYPE(rs->color) << 26; inst = risc_make_inst(c, opcode); @@ -663,7 +663,7 @@ scf_instruction_t* naja_inst_PUSH(scf_3ac_code_t* c, scf_register_t* r) scf_instruction_t* inst; uint32_t opcode; - opcode = (0x5 << 26) | (r->id << 21) | (1 << 20) | (3 << 17) | ((0xfff & -1) << 5) | 0x1f; + opcode = (0x7 << 26) | (r->id << 21) | (3 << 19) | 0x1e; inst = risc_make_inst(c, opcode); return inst; @@ -674,7 +674,7 @@ scf_instruction_t* naja_inst_POP(scf_3ac_code_t* c, scf_register_t* r) scf_instruction_t* inst; uint32_t opcode; - opcode = (0x4 << 26) | (r->id << 21) | (1 << 20) | (3 << 17) | (1 << 5) | 0x1f; + opcode = (0x5 << 26) | (r->id << 21) | (3 << 19) | 0x1e; inst = risc_make_inst(c, opcode); return inst; @@ -696,7 +696,7 @@ scf_instruction_t* naja_inst_MOV_SP(scf_3ac_code_t* c, scf_register_t* rd, scf_r scf_instruction_t* inst; uint32_t opcode; - opcode = (0xf << 26) | (rd->id << 21) | rs->id; + opcode = (0xf << 26) | (rd->id << 21) | (0x1 << 16) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -707,7 +707,7 @@ scf_instruction_t* naja_inst_MOV_G(scf_3ac_code_t* c, scf_register_t* rd, scf_re scf_instruction_t* inst; uint32_t opcode; - opcode = (0xf << 26) | (rd->id << 21) | rs->id; + opcode = (0xf << 26) | (rd->id << 21) | (0x1 << 16) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -718,7 +718,7 @@ scf_instruction_t* naja_inst_MVN(scf_3ac_code_t* c, scf_register_t* rd, scf_regi scf_instruction_t* inst; uint32_t opcode; - opcode = (0xf << 26) | (rd->id << 21) | (3 << 16) | rs->id; + opcode = (0xf << 26) | (rd->id << 21) | (0x3 << 19) | (0x2 << 16) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -729,7 +729,7 @@ scf_instruction_t* naja_inst_FMOV_G(scf_3ac_code_t* c, scf_register_t* rd, scf_r scf_instruction_t* inst; uint32_t opcode; - opcode = (0x1f << 26) | (rd->id << 21) | rs->id; + opcode = (0x1f << 26) | (rd->id << 21) | (0x3 << 19) | (0x3 << 16) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -739,18 +739,18 @@ scf_instruction_t* naja_inst_MOVSX(scf_3ac_code_t* c, scf_register_t* rd, scf_re { scf_instruction_t* inst; uint32_t opcode; - uint32_t S; + uint32_t SH; if (1 == size) - S = 5; + SH = 0; else if (2 == size) - S = 6; + SH = 1; else if (4 == size) - S = 7; + SH = 2; else return NULL; - opcode = (0xf << 26) | (rd->id << 21) | (1 << 19) | (S << 16)| rs->id; + opcode = (0xf << 26) | (rd->id << 21) | (SH << 19) | (1 << 18) | (0x2 << 16) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -760,18 +760,18 @@ scf_instruction_t* naja_inst_MOVZX(scf_3ac_code_t* c, scf_register_t* rd, scf_re { scf_instruction_t* inst; uint32_t opcode; - uint32_t S; + uint32_t SH; if (1 == size) - S = 5; + SH = 0; else if (2 == size) - S = 6; + SH = 1; else if (4 == size) - S = 7; + SH = 2; else return NULL; - opcode = (0xf << 26) | (rd->id << 21) | (S << 16)| rs->id; + opcode = (0xf << 26) | (rd->id << 21) | (SH << 19) | (0x2 << 16)| rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -783,7 +783,7 @@ scf_instruction_t* naja_inst_CVTSS2SD(scf_3ac_code_t* c, scf_register_t* rd, scf uint32_t opcode; uint32_t S; - opcode = (0x1f << 26) | (rd->id << 21) | (1 << 16) | rs->id; + opcode = (0x1f << 26) | (rd->id << 21) | (2 << 19) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -794,7 +794,7 @@ scf_instruction_t* naja_inst_CVTSD2SS(scf_3ac_code_t* c, scf_register_t* rd, scf scf_instruction_t* inst; uint32_t opcode; - opcode = (0x1f << 26) | (rd->id << 21) | (2 << 16) | rs->id; + opcode = (0x1f << 26) | (rd->id << 21) | (3 << 19) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -804,14 +804,14 @@ scf_instruction_t* naja_inst_CVTF2SI(scf_3ac_code_t* c, scf_register_t* rd, scf_ { scf_instruction_t* inst; uint32_t opcode; - uint32_t S; + uint32_t SH; if (4 == rd->bytes) - S = 0x4; + SH = 2; else - S = 0x5; + SH = 3; - opcode = (0x1f << 26) | (rd->id << 21) | (S << 16) | rs->id; + opcode = (0x1f << 26) | (rd->id << 21) | (SH << 19) | (1 << 18) | (0x1 << 16) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -821,14 +821,14 @@ scf_instruction_t* naja_inst_CVTF2UI(scf_3ac_code_t* c, scf_register_t* rd, scf_ { scf_instruction_t* inst; uint32_t opcode; - uint32_t S; + uint32_t SH; if (4 == rd->bytes) - S = 0x6; + SH = 2; else - S = 0x7; + SH = 3; - opcode = (0x1f << 26) | (rd->id << 21) | (S << 16) | rs->id; + opcode = (0x1f << 26) | (rd->id << 21) | (SH << 19) | (0x1 << 16) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -838,14 +838,14 @@ scf_instruction_t* naja_inst_CVTSI2F(scf_3ac_code_t* c, scf_register_t* rd, scf_ { scf_instruction_t* inst; uint32_t opcode; - uint32_t S; + uint32_t SH; if (4 == rd->bytes) - S = 0xc; + SH = 2; else - S = 0xd; + SH = 3; - opcode = (0x1f << 26) | (rd->id << 21) | (S << 16) | rs->id; + opcode = (0x1f << 26) | (rd->id << 21) | (SH << 19) | (1 << 18) | (0x2 << 16) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -855,14 +855,14 @@ scf_instruction_t* naja_inst_CVTUI2F(scf_3ac_code_t* c, scf_register_t* rd, scf_ { scf_instruction_t* inst; uint32_t opcode; - uint32_t S; + uint32_t SH; if (4 == rd->bytes) - S = 0xe; + SH = 2; else - S = 0xf; + SH = 3; - opcode = (0x1f << 26) | (rd->id << 21) | (S << 16) | rs->id; + opcode = (0x1f << 26) | (rd->id << 21) | (SH << 19) | (0x2 << 16) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -873,12 +873,12 @@ scf_instruction_t* naja_inst_SUB_IMM(scf_3ac_code_t* c, scf_function_t* f, scf_r scf_instruction_t* inst; uint32_t opcode; - if (imm > 0x7fff) { + if (imm > 0x3fff) { scf_loge("NOT support too big imm: %#lx\n", imm); return NULL; } - opcode = (1 << 26) | (rd->id << 21) | (1 << 20) | (imm << 5) | rs->id; + opcode = (1 << 26) | (rd->id << 21) | (3 << 19) | (imm << 5) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -889,12 +889,12 @@ scf_instruction_t* naja_inst_CMP_IMM(scf_3ac_code_t* c, scf_function_t* f, scf_r scf_instruction_t* inst; uint32_t opcode; - if (imm > 0x7fff) { + if (imm > 0x3fff) { scf_loge("NOT support too big imm: %#lx\n", imm); return NULL; } - opcode = (9 << 26) | (1 << 20) | (imm << 5) | rs->id; + opcode = (1 << 26) | (0x1f << 21) | (3 << 19) | (imm << 5) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -905,12 +905,12 @@ scf_instruction_t* naja_inst_ADD_IMM(scf_3ac_code_t* c, scf_function_t* f, scf_r scf_instruction_t* inst; uint32_t opcode; - if (imm > 0x7fff) { + if (imm > 0x3fff) { scf_loge("NOT support too big imm: %#lx\n", imm); return NULL; } - opcode = (0 << 26) | (rd->id << 21) | (1 << 20) | (imm << 5) | rs->id; + opcode = (0 << 26) | (rd->id << 21) | (3 << 19) | (imm << 5) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -932,7 +932,7 @@ scf_instruction_t* naja_inst_SHL(scf_3ac_code_t* c, scf_register_t* rd, scf_regi scf_instruction_t* inst; uint32_t opcode; - opcode = (0xf << 26) | (rd->id << 21) | (1 << 19) | (rs1->id << 5) | rs0->id; + opcode = (0xf << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -943,7 +943,7 @@ scf_instruction_t* naja_inst_SHR(scf_3ac_code_t* c, scf_register_t* rd, scf_regi scf_instruction_t* inst; uint32_t opcode; - opcode = (0xf << 26) | (rd->id << 21) | (1 << 19) | (1 << 16) | (rs1->id << 5) | rs0->id; + opcode = (0xf << 26) | (rd->id << 21) | (1 << 19) | (rs1->id << 5) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -954,7 +954,7 @@ scf_instruction_t* naja_inst_ASR(scf_3ac_code_t* c, scf_register_t* rd, scf_regi scf_instruction_t* inst; uint32_t opcode; - opcode = (0xf << 26) | (rd->id << 21) | (1 << 19) | (2 << 16) | (rs1->id << 5) | rs0->id; + opcode = (0xf << 26) | (rd->id << 21) | (2 << 19) | (rs1->id << 5) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -965,7 +965,7 @@ scf_instruction_t* naja_inst_AND_G(scf_3ac_code_t* c, scf_register_t* rd, scf_re scf_instruction_t* inst; uint32_t opcode; - opcode = (0x6 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id; + opcode = (0x8 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -976,7 +976,7 @@ scf_instruction_t* naja_inst_OR_G(scf_3ac_code_t* c, scf_register_t* rd, scf_reg scf_instruction_t* inst; uint32_t opcode; - opcode = (0x7 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id; + opcode = (0x9 << 26) | (rd->id << 21) | (rs1->id << 5) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -998,7 +998,7 @@ scf_instruction_t* naja_inst_CMP_G(scf_3ac_code_t* c, scf_register_t* rs0, scf_r scf_instruction_t* inst; uint32_t opcode; - opcode = (0x9 << 26) | (rs1->id << 5) | rs0->id; + opcode = (0x1 << 26) | (0x1f << 21) | (rs1->id << 5) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1009,7 +1009,7 @@ scf_instruction_t* naja_inst_FCMP(scf_3ac_code_t* c, scf_register_t* rs0, scf_re scf_instruction_t* inst; uint32_t opcode; - opcode = (0x19 << 26) | (rs1->id << 5) | rs0->id; + opcode = (0x11 << 26) | (0x1f << 21) | (rs1->id << 5) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1020,7 +1020,7 @@ scf_instruction_t* naja_inst_NEG(scf_3ac_code_t* c, scf_register_t* rd, scf_regi scf_instruction_t* inst; uint32_t opcode; - opcode = (0xf << 26) | (rd->id << 21) | (0x4 << 16) | rs->id; + opcode = (0xf << 26) | (rd->id << 21) | (0x7 << 18) | (0x2 << 16) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -1031,7 +1031,7 @@ scf_instruction_t* naja_inst_TEQ(scf_3ac_code_t* c, scf_register_t* rs) scf_instruction_t* inst; uint32_t opcode; - opcode = (0x14 << 26) | (rs->id << 5) | rs->id; + opcode = (0x8 << 26) | (0x1f << 21) | (rs->id << 5) | rs->id; inst = risc_make_inst(c, opcode); return inst; @@ -1064,7 +1064,7 @@ scf_instruction_t* naja_inst_MUL(scf_3ac_code_t* c, scf_register_t* rd, scf_regi scf_instruction_t* inst; uint32_t opcode; - opcode = (0x2 << 26) | (rd->id << 21) | (2 << 18) | (rs1->id << 5) | rs0->id; + opcode = (0x2 << 26) | (rd->id << 21) | (2 << 19) | (rs1->id << 5) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1075,7 +1075,7 @@ scf_instruction_t* naja_inst_FMUL(scf_3ac_code_t* c, scf_register_t* rd, scf_reg scf_instruction_t* inst; uint32_t opcode; - opcode = (0x12 << 26) | (rd->id << 21) | (1 << 20) | (2 << 18) | (rs1->id << 5) | rs0->id; + opcode = (0x12 << 26) | (rd->id << 21) | (2 << 19) | (1 << 18) | (rs1->id << 5) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1086,7 +1086,7 @@ scf_instruction_t* naja_inst_FDIV(scf_3ac_code_t* c, scf_register_t* rd, scf_reg scf_instruction_t* inst; uint32_t opcode; - opcode = (0x13 << 26) | (rd->id << 21) | (1 << 20) | (2 << 18) | (rs1->id << 5) | rs0->id; + opcode = (0x13 << 26) | (rd->id << 21) | (2 << 19) | (1 << 18) | (rs1->id << 5) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1097,7 +1097,7 @@ scf_instruction_t* naja_inst_DIV(scf_3ac_code_t* c, scf_register_t* rd, scf_regi scf_instruction_t* inst; uint32_t opcode; - opcode = (0x3 << 26) | (rd->id << 21) | (2 << 18) | (rs1->id << 5) | rs0->id; + opcode = (0x3 << 26) | (rd->id << 21) | (2 << 19) | (rs1->id << 5) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1108,7 +1108,7 @@ scf_instruction_t* naja_inst_SDIV(scf_3ac_code_t* c, scf_register_t* rd, scf_reg scf_instruction_t* inst; uint32_t opcode; - opcode = (0x3 << 26) | (rd->id << 21) | (1 << 20) | (2 << 18) | (rs1->id << 5) | rs0->id; + opcode = (0x3 << 26) | (rd->id << 21) | (2 << 19) | (1 << 18) | (rs1->id << 5) | rs0->id; inst = risc_make_inst(c, opcode); return inst; @@ -1119,7 +1119,7 @@ scf_instruction_t* naja_inst_MSUB(scf_3ac_code_t* c, scf_register_t* rd, scf_reg scf_instruction_t* inst; uint32_t opcode; - opcode = (0x2 << 26) | (rd->id << 21) | (1 << 20) | (1 << 18) | (ra->id << 10) | (rm->id << 5) | rn->id; + opcode = (0x2 << 26) | (rd->id << 21) | (1 << 19) | (1 << 18) | (ra->id << 10) | (rm->id << 5) | rn->id; inst = risc_make_inst(c, opcode); return inst; @@ -1131,7 +1131,7 @@ int naja_inst_BL(scf_3ac_code_t* c, scf_function_t* f, scf_function_t* pf) scf_rela_t* rela; uint32_t opcode; - opcode = (0x18 << 26); + opcode = (0x1a << 26); inst = risc_make_inst(c, opcode); RISC_INST_ADD_CHECK(c->instructions, inst); @@ -1146,7 +1146,7 @@ scf_instruction_t* naja_inst_BLR(scf_3ac_code_t* c, scf_register_t* r) scf_instruction_t* inst; uint32_t opcode; - opcode = (0x1a << 26) | (r->id << 21); + opcode = (0x1b << 26) | (r->id << 21); inst = risc_make_inst(c, opcode); return inst; @@ -1158,7 +1158,7 @@ scf_instruction_t* naja_inst_SETZ(scf_3ac_code_t* c, scf_register_t* rd) uint32_t opcode; uint32_t cc = 1; - opcode = (0xb << 26) | (rd->id << 21); + opcode = (0xc << 26) | (rd->id << 21); inst = risc_make_inst(c, opcode); return inst; @@ -1169,7 +1169,7 @@ scf_instruction_t* naja_inst_SETNZ(scf_3ac_code_t* c, scf_register_t* rd) uint32_t opcode; uint32_t cc = 0; - opcode = (0xb << 26) | (rd->id << 21) | (1 << 17); + opcode = (0xc << 26) | (rd->id << 21) | (1 << 1); inst = risc_make_inst(c, opcode); return inst; @@ -1179,7 +1179,7 @@ scf_instruction_t* naja_inst_SETGT(scf_3ac_code_t* c, scf_register_t* rd) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xb << 26) | (rd->id << 21) | (3 << 17); + opcode = (0xc << 26) | (rd->id << 21) | (3 << 1); inst = risc_make_inst(c, opcode); return inst; @@ -1189,7 +1189,7 @@ scf_instruction_t* naja_inst_SETGE(scf_3ac_code_t* c, scf_register_t* rd) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xb << 26) | (rd->id << 21) | (2 << 17); + opcode = (0xc << 26) | (rd->id << 21) | (2 << 1); inst = risc_make_inst(c, opcode); return inst; @@ -1199,7 +1199,7 @@ scf_instruction_t* naja_inst_SETLT(scf_3ac_code_t* c, scf_register_t* rd) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xb << 26) | (rd->id << 21) | (5 << 17); + opcode = (0xb << 26) | (rd->id << 21) | (5 << 1); inst = risc_make_inst(c, opcode); return inst; @@ -1209,7 +1209,7 @@ scf_instruction_t* naja_inst_SETLE(scf_3ac_code_t* c, scf_register_t* rd) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xb << 26) | (rd->id << 21) | (4 << 17); + opcode = (0xb << 26) | (rd->id << 21) | (4 << 1); inst = risc_make_inst(c, opcode); return inst; @@ -1220,7 +1220,7 @@ scf_instruction_t* naja_inst_JMP(scf_3ac_code_t* c) scf_instruction_t* inst; uint32_t opcode; - opcode = 0x8 << 26; + opcode = 0xa << 26; inst = risc_make_inst(c, opcode); return inst; @@ -1231,7 +1231,7 @@ scf_instruction_t* naja_inst_JZ(scf_3ac_code_t* c) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xa << 26) | 1; + opcode = (0xb << 26) | 1; inst = risc_make_inst(c, opcode); return inst; @@ -1242,7 +1242,7 @@ scf_instruction_t* naja_inst_JNZ(scf_3ac_code_t* c) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xa << 26) | (1 << 1) | 1; + opcode = (0xb << 26) | (1 << 1) | 1; inst = risc_make_inst(c, opcode); return inst; @@ -1253,7 +1253,7 @@ scf_instruction_t* naja_inst_JGT(scf_3ac_code_t* c) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xa << 26) | (3 << 1) | 1; + opcode = (0xb << 26) | (3 << 1) | 1; inst = risc_make_inst(c, opcode); return inst; @@ -1264,7 +1264,7 @@ scf_instruction_t* naja_inst_JGE(scf_3ac_code_t* c) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xa << 26) | (2 << 1) | 1; + opcode = (0xb << 26) | (2 << 1) | 1; inst = risc_make_inst(c, opcode); return inst; @@ -1275,7 +1275,7 @@ scf_instruction_t* naja_inst_JLT(scf_3ac_code_t* c) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xa << 26) | (5 << 1) | 1; + opcode = (0xb << 26) | (5 << 1) | 1; inst = risc_make_inst(c, opcode); return inst; @@ -1286,7 +1286,7 @@ scf_instruction_t* naja_inst_JLE(scf_3ac_code_t* c) scf_instruction_t* inst; uint32_t opcode; - opcode = (0xa << 26) | (4 << 1) | 1; + opcode = (0xb << 26) | (4 << 1) | 1; inst = risc_make_inst(c, opcode); return inst; @@ -1311,7 +1311,14 @@ scf_instruction_t* naja_inst_JBE(scf_3ac_code_t* c) void naja_set_jmp_offset(scf_instruction_t* inst, int32_t bytes) { - if (0x28 == inst->code[3] && 1 == (inst->code[0] & 1)) { + uint32_t opcode; + + opcode = inst->code[0]; + opcode |= inst->code[1] << 8; + opcode |= inst->code[2] << 16; + opcode |= inst->code[3] << 24; + + if (0xb == (opcode >> 26) && 1 == (opcode & 1)) { if (bytes >= 0 && bytes < (0x1 << 20)) { bytes >>= 2; @@ -1331,7 +1338,7 @@ void naja_set_jmp_offset(scf_instruction_t* inst, int32_t bytes) inst->code[3] |= 0x3 & (bytes >> 24); } else { - assert(0x20 == inst->code[3]); + assert(0xa == (opcode >> 26)); bytes >>= 2; @@ -1355,16 +1362,19 @@ int naja_cmp_update(scf_3ac_code_t* c, scf_function_t* f, scf_instruction_t* cmp uint32_t mov; uint32_t i0; uint32_t i1; + uint32_t SH; opcode = cmp->code[0]; opcode |= cmp->code[1] << 8; opcode |= cmp->code[2] << 16; opcode |= cmp->code[3] << 24; - switch (cmp->code[3]) { + switch (opcode >> 21) { - case 0x24: - if (cmp->code[2] & 0x10) { + case 0x3f: + SH = (opcode >> 19) & 0x3; + + if (0x3 == SH) { i0 = opcode & 0x1f; r0 = f->rops->find_register_type_id_bytes(0, i0, 8); inst = f->iops->MOV_G(c, r16, r0); // use r16 to backup r0 @@ -1490,4 +1500,3 @@ scf_inst_ops_t inst_ops_naja = .set_jmp_offset = naja_set_jmp_offset, .cmp_update = naja_cmp_update, }; - diff --git a/native/risc/scf_risc.c b/native/risc/scf_risc.c index 6d99f57..2915c98 100644 --- a/native/risc/scf_risc.c +++ b/native/risc/scf_risc.c @@ -1147,12 +1147,12 @@ int scf_risc_select_inst(scf_native_t* ctx, scf_function_t* f) return 0; } -scf_native_ops_t native_ops_risc = { - .name = "arm64", +scf_native_ops_t native_ops_risc = +{ + .name = "risc", .open = scf_risc_open, .close = scf_risc_close, .select_inst = scf_risc_select_inst, }; - diff --git a/native/risc/scf_risc_reg_arm64.c b/native/risc/scf_risc_reg_arm64.c index 2ed8758..158b409 100644 --- a/native/risc/scf_risc_reg_arm64.c +++ b/native/risc/scf_risc_reg_arm64.c @@ -1154,53 +1154,3 @@ scf_regs_ops_t regs_ops_arm64 = .push_callee_regs = arm64_push_callee_regs, .pop_callee_regs = arm64_pop_callee_regs, }; - -scf_regs_ops_t regs_ops_naja = -{ - .name = "naja", - - .abi_regs = arm64_abi_regs, - .abi_float_regs = arm64_abi_float_regs, - .abi_ret_regs = arm64_abi_ret_regs, - .abi_caller_saves = arm64_abi_caller_saves, - .abi_callee_saves = arm64_abi_callee_saves, - - .ABI_NB = sizeof(arm64_abi_regs) / sizeof(uint32_t), - .ABI_RET_NB = sizeof(arm64_abi_ret_regs) / sizeof(uint32_t), - .ABI_CALLER_SAVES_NB = sizeof(arm64_abi_caller_saves) / sizeof(uint32_t), - .ABI_CALLEE_SAVES_NB = sizeof(arm64_abi_callee_saves) / sizeof(uint32_t), - - .MAX_BYTES = 8, - - .registers_init = arm64_registers_init, - .registers_reset = arm64_registers_reset, - .registers_clear = arm64_registers_clear, - .register_colors = arm64_register_colors, - - .color_conflict = arm64_color_conflict, - - .argv_rabi = arm64_argv_rabi, - .call_rabi = arm64_call_rabi, - - .reg_used = arm64_reg_used, - .reg_cached_vars = arm64_reg_cached_vars, - - .variable_size = arm64_variable_size, - - .caller_save_regs = arm64_caller_save_regs, - .pop_regs = arm64_pop_regs, - - .find_register = arm64_find_register, - .find_register_color = arm64_find_register_color, - .find_register_color_bytes = arm64_find_register_color_bytes, - .find_register_type_id_bytes = arm64_find_register_type_id_bytes, - - .select_overflowed_reg = arm64_select_overflowed_reg, - .overflow_reg = arm64_overflow_reg, - .overflow_reg2 = arm64_overflow_reg2, - .overflow_reg3 = arm64_overflow_reg3, - - .push_callee_regs = arm64_push_callee_regs, - .pop_callee_regs = arm64_pop_callee_regs, -}; - diff --git a/native/risc/scf_risc_reg_naja.c b/native/risc/scf_risc_reg_naja.c new file mode 100644 index 0000000..bd3c8ac --- /dev/null +++ b/native/risc/scf_risc_reg_naja.c @@ -0,0 +1,1154 @@ +#include"scf_risc.h" + +#define SCF_RISC_REG_FP 28 +#define SCF_RISC_REG_LR 29 +#define SCF_RISC_REG_SP 30 +#define SCF_RISC_REG_NULL 31 + +scf_register_t naja_registers[] = { + + {0, 4, "w0", RISC_COLOR(0, 0, 0xf), NULL, 0, 0}, + {0, 8, "x0", RISC_COLOR(0, 0, 0xff), NULL, 0, 0}, + + {1, 4, "w1", RISC_COLOR(0, 1, 0xf), NULL, 0, 0}, + {1, 8, "x1", RISC_COLOR(0, 1, 0xff), NULL, 0, 0}, + + {2, 4, "w2", RISC_COLOR(0, 2, 0xf), NULL, 0, 0}, + {2, 8, "x2", RISC_COLOR(0, 2, 0xff), NULL, 0, 0}, + + {3, 4, "w3", RISC_COLOR(0, 3, 0xf), NULL, 0, 0}, + {3, 8, "x3", RISC_COLOR(0, 3, 0xff), NULL, 0, 0}, + + {4, 4, "w4", RISC_COLOR(0, 4, 0xf), NULL, 0, 0}, + {4, 8, "x4", RISC_COLOR(0, 4, 0xff), NULL, 0, 0}, + + {5, 4, "w5", RISC_COLOR(0, 5, 0xf), NULL, 0, 0}, + {5, 8, "x5", RISC_COLOR(0, 5, 0xff), NULL, 0, 0}, + + {6, 4, "w6", RISC_COLOR(0, 6, 0xf), NULL, 0, 0}, + {6, 8, "x6", RISC_COLOR(0, 6, 0xff), NULL, 0, 0}, + + {7, 4, "w7", RISC_COLOR(0, 7, 0xf), NULL, 0, 0}, + {7, 8, "x7", RISC_COLOR(0, 7, 0xff), NULL, 0, 0}, + +// not use x8 + +// {8, 4, "w8", RISC_COLOR(0, 8, 0xf), NULL, 0}, +// {8, 8, "x8", RISC_COLOR(0, 8, 0xff), NULL, 0}, + + {9, 4, "w9", RISC_COLOR(0, 9, 0xf), NULL, 0, 0}, + {9, 8, "x9", RISC_COLOR(0, 9, 0xff), NULL, 0, 0}, + + {10, 4, "w10", RISC_COLOR(0, 10, 0xf), NULL, 0, 0}, + {10, 8, "x10", RISC_COLOR(0, 10, 0xff), NULL, 0, 0}, + + {11, 4, "w11", RISC_COLOR(0, 11, 0xf), NULL, 0, 0}, + {11, 8, "x11", RISC_COLOR(0, 11, 0xff), NULL, 0, 0}, + + {12, 4, "w12", RISC_COLOR(0, 12, 0xf), NULL, 0, 0}, + {12, 8, "x12", RISC_COLOR(0, 12, 0xff), NULL, 0, 0}, + + {13, 4, "w13", RISC_COLOR(0, 13, 0xf), NULL, 0, 0}, + {13, 8, "x13", RISC_COLOR(0, 13, 0xff), NULL, 0, 0}, + + {14, 4, "w14", RISC_COLOR(0, 14, 0xf), NULL, 0, 0}, + {14, 8, "x14", RISC_COLOR(0, 14, 0xff), NULL, 0, 0}, + + {15, 4, "w15", RISC_COLOR(0, 15, 0xf), NULL, 0, 0}, + {15, 8, "x15", RISC_COLOR(0, 15, 0xff), NULL, 0, 0}, + +// not use x16, x17, x18 + + {16, 4, "w16", RISC_COLOR(0, 16, 0xf), NULL, 0, 0}, + {16, 8, "x16", RISC_COLOR(0, 16, 0xff), NULL, 0, 0}, + + {17, 4, "w17", RISC_COLOR(0, 17, 0xf), NULL, 0, 0}, + {17, 8, "x17", RISC_COLOR(0, 17, 0xff), NULL, 0, 0}, + +// {18, 4, "w18", RISC_COLOR(0, 18, 0xf), NULL, 0, 0}, +// {18, 8, "x18", RISC_COLOR(0, 18, 0xff), NULL, 0, 0}, + + {19, 4, "w19", RISC_COLOR(0, 19, 0xf), NULL, 0, 0}, + {19, 8, "x19", RISC_COLOR(0, 19, 0xff), NULL, 0, 0}, + + {20, 4, "w20", RISC_COLOR(0, 20, 0xf), NULL, 0, 0}, + {20, 8, "x20", RISC_COLOR(0, 20, 0xff), NULL, 0, 0}, + + {21, 4, "w21", RISC_COLOR(0, 21, 0xf), NULL, 0, 0}, + {21, 8, "x21", RISC_COLOR(0, 21, 0xff), NULL, 0, 0}, + + {22, 4, "w22", RISC_COLOR(0, 22, 0xf), NULL, 0, 0}, + {22, 8, "x22", RISC_COLOR(0, 22, 0xff), NULL, 0, 0}, + + {23, 4, "w23", RISC_COLOR(0, 23, 0xf), NULL, 0, 0}, + {23, 8, "x23", RISC_COLOR(0, 23, 0xff), NULL, 0, 0}, + + {24, 4, "w24", RISC_COLOR(0, 24, 0xf), NULL, 0, 0}, + {24, 8, "x24", RISC_COLOR(0, 24, 0xff), NULL, 0, 0}, + + {25, 4, "w25", RISC_COLOR(0, 25, 0xf), NULL, 0, 0}, + {25, 8, "x25", RISC_COLOR(0, 25, 0xff), NULL, 0, 0}, + + {26, 4, "w26", RISC_COLOR(0, 26, 0xf), NULL, 0, 0}, + {26, 8, "x26", RISC_COLOR(0, 26, 0xff), NULL, 0, 0}, + + {27, 4, "w27", RISC_COLOR(0, 27, 0xf), NULL, 0, 0}, + {27, 8, "x27", RISC_COLOR(0, 27, 0xff), NULL, 0, 0}, + +// fp = x28 = bp + {28, 4, "w28", RISC_COLOR(0, 28, 0xf), NULL, 0, 0}, + {28, 8, "fp", RISC_COLOR(0, 28, 0xff), NULL, 0, 0}, +// lr = x29 + {29, 4, "w29", RISC_COLOR(0, 29, 0xf), NULL, 0, 0}, + {29, 8, "lr", RISC_COLOR(0, 29, 0xff), NULL, 0, 0}, + {30, 8, "sp", RISC_COLOR(0, 30, 0xff), NULL, 0, 0}, +// {31, 8, "null", RISC_COLOR(0, 31, 0xff), NULL, 0, 0}, + + + {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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 2, "h15", RISC_COLOR(1, 15, 0x3), NULL, 0, 0}, + {15, 4, "s15", RISC_COLOR(1, 15, 0xf), NULL, 0, 0}, + {15, 8, "d15", RISC_COLOR(1, 15, 0xff), NULL, 0, 0}, + + {16, 2, "h16", RISC_COLOR(1, 16, 0x3), NULL, 0, 0}, + {16, 4, "s16", RISC_COLOR(1, 16, 0xf), NULL, 0, 0}, + {16, 8, "d16", RISC_COLOR(1, 16, 0xff), NULL, 0, 0}, + + {17, 2, "h17", RISC_COLOR(1, 17, 0x3), NULL, 0, 0}, + {17, 4, "s17", RISC_COLOR(1, 17, 0xf), NULL, 0, 0}, + {17, 8, "d17", RISC_COLOR(1, 17, 0xff), NULL, 0, 0}, + + {18, 2, "h18", RISC_COLOR(1, 18, 0x3), NULL, 0, 0}, + {18, 4, "s18", RISC_COLOR(1, 18, 0xf), NULL, 0, 0}, + {18, 8, "d18", RISC_COLOR(1, 18, 0xff), NULL, 0, 0}, + + {19, 2, "h19", RISC_COLOR(1, 19, 0x3), NULL, 0, 0}, + {19, 4, "s19", RISC_COLOR(1, 19, 0xf), NULL, 0, 0}, + {19, 8, "d19", RISC_COLOR(1, 19, 0xff), NULL, 0, 0}, + + {20, 2, "h20", RISC_COLOR(1, 20, 0x3), NULL, 0, 0}, + {20, 4, "s20", RISC_COLOR(1, 20, 0xf), NULL, 0, 0}, + {20, 8, "d20", RISC_COLOR(1, 20, 0xff), NULL, 0, 0}, + + {21, 2, "h21", RISC_COLOR(1, 21, 0x3), NULL, 0, 0}, + {21, 4, "s21", RISC_COLOR(1, 21, 0xf), NULL, 0, 0}, + {21, 8, "d21", RISC_COLOR(1, 21, 0xff), NULL, 0, 0}, + + {22, 2, "h22", RISC_COLOR(1, 22, 0x3), NULL, 0, 0}, + {22, 4, "s22", RISC_COLOR(1, 22, 0xf), NULL, 0, 0}, + {22, 8, "d22", RISC_COLOR(1, 22, 0xff), NULL, 0, 0}, + + {23, 2, "h23", RISC_COLOR(1, 23, 0x3), NULL, 0, 0}, + {23, 4, "s23", RISC_COLOR(1, 23, 0xf), NULL, 0, 0}, + {23, 8, "d23", RISC_COLOR(1, 23, 0xff), NULL, 0, 0}, + + {24, 2, "h24", RISC_COLOR(1, 24, 0x3), NULL, 0, 0}, + {24, 4, "s24", RISC_COLOR(1, 24, 0xf), NULL, 0, 0}, + {24, 8, "d24", RISC_COLOR(1, 24, 0xff), NULL, 0, 0}, + + {25, 2, "h25", RISC_COLOR(1, 25, 0x3), NULL, 0, 0}, + {25, 4, "s25", RISC_COLOR(1, 25, 0xf), NULL, 0, 0}, + {25, 8, "d25", RISC_COLOR(1, 25, 0xff), NULL, 0, 0}, + + {26, 2, "h26", RISC_COLOR(1, 26, 0x3), NULL, 0, 0}, + {26, 4, "s26", RISC_COLOR(1, 26, 0xf), NULL, 0, 0}, + {26, 8, "d26", RISC_COLOR(1, 26, 0xff), NULL, 0, 0}, + + {27, 2, "h27", RISC_COLOR(1, 27, 0x3), NULL, 0, 0}, + {27, 4, "s27", RISC_COLOR(1, 27, 0xf), NULL, 0, 0}, + {27, 8, "d27", RISC_COLOR(1, 27, 0xff), NULL, 0, 0}, + + {28, 2, "h28", RISC_COLOR(1, 28, 0x3), NULL, 0, 0}, + {28, 4, "s28", RISC_COLOR(1, 28, 0xf), NULL, 0, 0}, + {28, 8, "d28", RISC_COLOR(1, 28, 0xff), NULL, 0, 0}, + + {29, 2, "h29", RISC_COLOR(1, 29, 0x3), NULL, 0, 0}, + {29, 4, "s29", RISC_COLOR(1, 29, 0xf), NULL, 0, 0}, + {29, 8, "d29", RISC_COLOR(1, 29, 0xff), NULL, 0, 0}, + + {30, 2, "h30", RISC_COLOR(1, 30, 0x3), NULL, 0, 0}, + {30, 4, "s30", RISC_COLOR(1, 30, 0xf), NULL, 0, 0}, + {30, 8, "d30", RISC_COLOR(1, 30, 0xff), NULL, 0, 0}, + + {31, 2, "h31", RISC_COLOR(1, 31, 0x3), NULL, 0, 0}, + {31, 4, "s31", RISC_COLOR(1, 31, 0xf), NULL, 0, 0}, + {31, 8, "d31", RISC_COLOR(1, 31, 0xff), NULL, 0, 0}, +}; + +static uint32_t naja_abi_regs[] = +{ + SCF_RISC_REG_X0, + SCF_RISC_REG_X1, + SCF_RISC_REG_X2, + SCF_RISC_REG_X3, + SCF_RISC_REG_X4, + SCF_RISC_REG_X5, + SCF_RISC_REG_X6, + SCF_RISC_REG_X7, +}; + +static uint32_t naja_abi_float_regs[] = +{ + SCF_RISC_REG_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, + SCF_RISC_REG_X6, + SCF_RISC_REG_X7, + + SCF_RISC_REG_X9, + SCF_RISC_REG_X10, + SCF_RISC_REG_X11, + SCF_RISC_REG_X12, + SCF_RISC_REG_X13, + SCF_RISC_REG_X14, + SCF_RISC_REG_X15, +}; + +static uint32_t naja_abi_callee_saves[] = +{ + SCF_RISC_REG_X19, + SCF_RISC_REG_X20, + SCF_RISC_REG_X21, + SCF_RISC_REG_X22, + SCF_RISC_REG_X23, + SCF_RISC_REG_X24, + SCF_RISC_REG_X25, + SCF_RISC_REG_X26, + SCF_RISC_REG_X27, + SCF_RISC_REG_X28, + SCF_RISC_REG_X29, +}; + +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 < 4 ? 4 : 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; +} + +scf_vector_t* naja_register_colors() +{ + scf_vector_t* colors = scf_vector_alloc(); + if (!colors) + return NULL; + + int i; + for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) { + + scf_register_t* r = &(naja_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + int ret = scf_vector_add(colors, (void*)r->color); + if (ret < 0) { + scf_vector_free(colors); + return NULL; + } + } +#if 0 + srand(time(NULL)); + for (i = 0; i < colors->size; i++) { + int j = rand() % colors->size; + + void* t = colors->data[i]; + colors->data[i] = colors->data[j]; + colors->data[j] = t; + } +#endif + return colors; +} + +int naja_reg_cached_vars(scf_register_t* r) +{ + int nb_vars = 0; + int i; + + for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) { + + scf_register_t* r2 = &(naja_registers[i]); + + if (SCF_RISC_REG_SP == r2->id + || SCF_RISC_REG_FP == r2->id + || SCF_RISC_REG_LR == r2->id + || SCF_RISC_REG_X16 == r2->id + || SCF_RISC_REG_X17 == r2->id) + continue; + + if (!naja_color_conflict(r->color, r2->color)) + continue; + + nb_vars += r2->dag_nodes->size; + } + + return nb_vars; +} + +int naja_registers_init() +{ + int i; + for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) { + + scf_register_t* r = &(naja_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + assert(!r->dag_nodes); + + r->dag_nodes = scf_vector_alloc(); + if (!r->dag_nodes) + return -ENOMEM; + + r->used = 0; + } + + return 0; +} + +void naja_registers_clear() +{ + int i; + for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) { + + scf_register_t* r = &(naja_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + if (r->dag_nodes) { + scf_vector_free(r->dag_nodes); + r->dag_nodes = NULL; + } + + r->used = 0; + } +} + +static scf_register_t* risc_reg_cached_min_vars(scf_register_t** regs, int nb_regs) +{ + scf_register_t* r_min = NULL; + + int min = 0; + int i; + + for (i = 0; i < nb_regs; i++) { + scf_register_t* r = regs[i]; + + int nb_vars = naja_reg_cached_vars(r); + + if (!r_min) { + r_min = r; + min = nb_vars; + continue; + } + + if (min > nb_vars) { + r_min = r; + min = nb_vars; + } + } + + return r_min; +} + +int naja_caller_save_regs(scf_3ac_code_t* c, scf_function_t* f, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs) +{ + int i; + int j; + scf_register_t* r; + scf_register_t* r2; + scf_instruction_t* inst; + scf_register_t* sp = naja_find_register("sp"); + + uint32_t opcode; + + int ret; + int size = 0; + int k = 0; + + for (j = 0; j < nb_regs; j++) { + r2 = naja_find_register_type_id_bytes(0, regs[j], 8); + + for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) { + r = &(naja_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + if (0 == r->dag_nodes->size) + continue; + + if (naja_color_conflict(r2->color, r->color)) + break; + } + + if (i == sizeof(naja_registers) / sizeof(naja_registers[0])) + continue; + + if (stack_size > 0) { + ret = f->iops->G2P(c, f, r2, sp, size + stack_size, 8); + if (ret < 0) + return ret; + } else { + inst = f->iops->PUSH(NULL, r2); + RISC_INST_ADD_CHECK(c->instructions, inst); + } + + saved_regs[k++] = r2; + size += 8; + } + + if (size & 0xf) { + r2 = saved_regs[k - 1]; + + if (stack_size > 0) { + ret = f->iops->G2P(c, f, r2, sp, size + stack_size, 8); + if (ret < 0) + return ret; + } else { + inst = f->iops->PUSH(NULL, r2); + RISC_INST_ADD_CHECK(c->instructions, inst); + } + + saved_regs[k++] = r2; + size += 8; + } + + if (stack_size > 0) { + for (j = 0; j < k / 2; j++) { + + i = k - 1 - j; + SCF_XCHG(saved_regs[i], saved_regs[j]); + } + } + + return size; +} + +int naja_pop_regs(scf_3ac_code_t* c, scf_function_t* f, scf_register_t** regs, int nb_regs, scf_register_t** updated_regs, int nb_updated) +{ + int i; + int j; + + scf_register_t* sp = naja_find_register("sp"); + scf_register_t* r; + scf_register_t* r2; + scf_instruction_t* inst; + + for (j = nb_regs - 1; j >= 0; j--) { + r2 = regs[j]; + + for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) { + r = &(naja_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + if (0 == r->dag_nodes->size) + continue; + + if (naja_color_conflict(r2->color, r->color)) + break; + } + + if (i == sizeof(naja_registers) / sizeof(naja_registers[0])) + continue; + + for (i = 0; i < nb_updated; i++) { + + r = updated_regs[i]; + + if (naja_color_conflict(r2->color, r->color)) + break; + } + + if (i == nb_updated) { + inst = f->iops->POP(c, r2); + RISC_INST_ADD_CHECK(c->instructions, inst); + } else { + inst = f->iops->ADD_IMM(c, f, sp, sp, 8); + RISC_INST_ADD_CHECK(c->instructions, inst); + } + } + return 0; +} + +int naja_registers_reset() +{ + int i; + for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) { + + scf_register_t* r = &(naja_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + if (!r->dag_nodes) + continue; + + int j = 0; + while (j < r->dag_nodes->size) { + scf_dag_node_t* dn = r->dag_nodes->data[j]; + + if (dn->var->w) + scf_logw("drop: v_%d_%d/%s\n", dn->var->w->line, dn->var->w->pos, dn->var->w->text->data); + else + scf_logw("drop: v_%#lx\n", 0xffff & (uintptr_t)dn->var); + + int ret = scf_vector_del(r->dag_nodes, dn); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + + dn->loaded = 0; + dn->color = 0; + } + } + + return 0; +} + + +int naja_overflow_reg(scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f) +{ + int i; + + for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) { + + scf_register_t* r2 = &(naja_registers[i]); + + if (SCF_RISC_REG_SP == r2->id + || SCF_RISC_REG_FP == r2->id + || SCF_RISC_REG_LR == r2->id + || SCF_RISC_REG_X16 == r2->id + || SCF_RISC_REG_X17 == r2->id) + continue; + + if (!naja_color_conflict(r->color, r2->color)) + continue; + + int ret = risc_save_reg(r2, c, f); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + } + + r->used = 1; + return 0; +} + +int naja_overflow_reg2(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f) +{ + scf_register_t* r2; + scf_dag_node_t* dn2; + + int i; + int j; + + for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) { + + r2 = &(naja_registers[i]); + + if (SCF_RISC_REG_SP == r2->id + || SCF_RISC_REG_FP == r2->id + || SCF_RISC_REG_LR == r2->id + || SCF_RISC_REG_X16 == r2->id + || SCF_RISC_REG_X17 == r2->id) + continue; + + if (!naja_color_conflict(r->color, r2->color)) + continue; + + for (j = 0; j < r2->dag_nodes->size; ) { + dn2 = r2->dag_nodes->data[j]; + + if (dn2 == dn) { + j++; + continue; + } + + int ret = risc_save_var(dn2, c, f); + if (ret < 0) + return ret; + } + } + + r->used = 1; + return 0; +} + +int naja_overflow_reg3(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f) +{ + scf_register_t* r2; + scf_dn_status_t* ds2; + scf_dag_node_t* dn2; + + int i; + int j; + int ret; + + for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) { + + r2 = &(naja_registers[i]); + + if (SCF_RISC_REG_SP == r2->id + || SCF_RISC_REG_FP == r2->id + || SCF_RISC_REG_LR == r2->id + || SCF_RISC_REG_X16 == r2->id + || SCF_RISC_REG_X17 == r2->id) + continue; + + if (!naja_color_conflict(r->color, r2->color)) + continue; + + for (j = 0; j < r2->dag_nodes->size; ) { + dn2 = r2->dag_nodes->data[j]; + + if (dn2 == dn) { + j++; + continue; + } + + ds2 = scf_vector_find_cmp(c->active_vars, dn2, scf_dn_status_cmp); + if (!ds2) { + j++; + continue; + } + + if (!ds2->active) { + j++; + continue; + } +#if 1 + scf_variable_t* v = dn->var; + scf_variable_t* v2 = dn2->var; + if (v->w) + scf_loge("v_%d_%d/%s, bp_offset: %d\n", v->w->line, v->w->pos, v->w->text->data, v->bp_offset); + else + scf_loge("v_%#lx, bp_offset: %d\n", 0xffff & (uintptr_t)v, v->bp_offset); + + if (v2->w) + scf_loge("v2_%d_%d/%s, bp_offset: %d\n", v2->w->line, v2->w->pos, v2->w->text->data, v2->bp_offset); + else + scf_loge("v2_%#lx, bp_offset: %d\n", 0xffff & (uintptr_t)v2, v2->bp_offset); +#endif + int ret = risc_save_var(dn2, c, f); + if (ret < 0) + return ret; + } + } + + r->used = 1; + return 0; +} + +int naja_reg_used(scf_register_t* r, scf_dag_node_t* dn) +{ + scf_register_t* r2; + scf_dag_node_t* dn2; + + int i; + int j; + + for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) { + + r2 = &(naja_registers[i]); + + if (SCF_RISC_REG_SP == r2->id + || SCF_RISC_REG_FP == r2->id + || SCF_RISC_REG_LR == r2->id + || SCF_RISC_REG_X16 == r2->id + || SCF_RISC_REG_X17 == r2->id) + continue; + + if (!naja_color_conflict(r->color, r2->color)) + continue; + + for (j = 0; j < r2->dag_nodes->size; j++) { + dn2 = r2->dag_nodes->data[j]; + + if (dn2 != dn) + return 1; + } + } + return 0; +} + +scf_register_t* naja_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c, int is_float) +{ + scf_vector_t* neighbors = NULL; + scf_graph_node_t* gn = NULL; + + scf_register_t* free_regs[sizeof(naja_registers) / sizeof(naja_registers[0])]; + + int nb_free_regs = 0; + int bytes = 8; + int ret; + int i; + int j; + + assert(c->rcg); + + if (dn) { + is_float = scf_variable_float(dn->var); + bytes = naja_variable_size (dn->var); + } + + ret = risc_rcg_find_node(&gn, c->rcg, dn, NULL); + if (ret < 0) + neighbors = c->rcg->nodes; + else + neighbors = gn->neighbors; + + for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) { + + scf_register_t* r = &(naja_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + if (r->bytes < bytes || RISC_COLOR_TYPE(r->color) != is_float) + continue; + + for (j = 0; j < neighbors->size; j++) { + + scf_graph_node_t* neighbor = neighbors->data[j]; + risc_rcg_node_t* rn = neighbor->data; + + if (rn->dag_node) { + if (rn->dag_node->color <= 0) + continue; + + if (naja_color_conflict(r->color, rn->dag_node->color)) + break; + } else { + assert(rn->reg); + + if (naja_color_conflict(r->color, rn->reg->color)) + break; + } + } + + if (j == neighbors->size) + free_regs[nb_free_regs++] = r; + } + + if (nb_free_regs > 0) + return risc_reg_cached_min_vars(free_regs, nb_free_regs); + + for (i = 0; i < sizeof(naja_registers) / sizeof(naja_registers[0]); i++) { + + scf_register_t* r = &(naja_registers[i]); + + if (SCF_RISC_REG_SP == r->id + || SCF_RISC_REG_FP == r->id + || SCF_RISC_REG_LR == r->id + || SCF_RISC_REG_X16 == r->id + || SCF_RISC_REG_X17 == r->id) + continue; + + if (r->bytes < bytes || RISC_COLOR_TYPE(r->color) != is_float) + continue; + + if (c->dsts) { + scf_3ac_operand_t* dst; + + for (j = 0; j < c->dsts->size; j++) { + dst = c->dsts->data[j]; + + if (dst->dag_node && dst->dag_node->color > 0 + && naja_color_conflict(r->color, dst->dag_node->color)) + break; + } + + if (j < c->dsts->size) + continue; + } + + if (c->srcs) { + scf_3ac_operand_t* src; + + for (j = 0; j < c->srcs->size; j++) { + src = c->srcs->data[j]; + + if (src->dag_node && src->dag_node->color > 0 + && naja_color_conflict(r->color, src->dag_node->color)) + break; + } + + if (j < c->srcs->size) + continue; + } + + return r; + } + + return NULL; +} + +static void naja_argv_rabi(scf_function_t* f) +{ + scf_variable_t* v; + + f->args_int = 0; + f->args_float = 0; + + int bp_int = -8; + int bp_floats = -8 - (int)f->rops->ABI_NB * 8; + int bp_others = 16; + + int i; + for (i = 0; i < f->argv->size; i++) { + v = f->argv->data[i]; + + if (!v->arg_flag) { + v ->arg_flag = 1; + assert(f->inline_flag); + } + + int is_float = scf_variable_float(v); + int size = f->rops->variable_size (v); + + if (is_float) { + + if (f->args_float < f->rops->ABI_NB) { + + v->rabi = f->rops->find_register_type_id_bytes(is_float, f->rops->abi_float_regs[f->args_float], size); + v->bp_offset = bp_floats; + bp_floats -= 8; + f->args_float++; + continue; + } + } else if (f->args_int < f->rops->ABI_NB) { + + v->rabi = f->rops->find_register_type_id_bytes(is_float, f->rops->abi_regs[f->args_int], size); + v->bp_offset = bp_int; + bp_int -= 8; + f->args_int++; + continue; + } + + v->rabi = NULL; + v->bp_offset = bp_others; + bp_others += 8; + } +} + +void naja_call_rabi(scf_3ac_code_t* c, scf_function_t* f, int* p_nints, int* p_nfloats, int* p_ndoubles) +{ + scf_3ac_operand_t* src = NULL; + scf_dag_node_t* dn = NULL; + + int nfloats = 0; + int nints = 0; + int i; + + for (i = 1; i < c->srcs->size; i++) { + src = c->srcs->data[i]; + dn = src->dag_node; + + int is_float = scf_variable_float(dn->var); + int size = f->rops->variable_size (dn->var); + + if (is_float) { + if (nfloats < f->rops->ABI_NB) + dn->rabi2 = f->rops->find_register_type_id_bytes(is_float, f->rops->abi_float_regs[nfloats++], size); + else + dn->rabi2 = NULL; + } else { + if (nints < f->rops->ABI_NB) + dn->rabi2 = f->rops->find_register_type_id_bytes(is_float, f->rops->abi_regs[nints++], size); + else + dn->rabi2 = NULL; + } + + src->rabi = dn->rabi2; + } + + if (p_nints) + *p_nints = nints; + + if (p_nfloats) + *p_nfloats = nfloats; +} + +int naja_push_callee_regs(scf_3ac_code_t* c, scf_function_t* f) +{ + scf_instruction_t* inst; + scf_register_t* r; + + int i; + for (i = 0; i < f->rops->ABI_CALLEE_SAVES_NB; i++) { + + r = f->rops->find_register_type_id_bytes(0, f->rops->abi_callee_saves[i], 8); + + if (!r->used) { + r = f->rops->find_register_type_id_bytes(0, f->rops->abi_callee_saves[i], 4); + + if (!r->used) + continue; + } + + inst = f->iops->PUSH(NULL, r); + RISC_INST_ADD_CHECK(f->init_code->instructions, inst); + + f->init_code_bytes += inst->len; + } + + return 0; +} + +int naja_pop_callee_regs(scf_3ac_code_t* c, scf_function_t* f) +{ + scf_instruction_t* inst; + scf_register_t* r; + + int i; + for (i = f->rops->ABI_CALLEE_SAVES_NB - 1; i >= 0; i--) { + + r = f->rops->find_register_type_id_bytes(0, f->rops->abi_callee_saves[i], 8); + + if (!r->used) { + r = f->rops->find_register_type_id_bytes(0, f->rops->abi_callee_saves[i], 4); + + if (!r->used) + continue; + } + + inst = f->iops->POP(c, r); + RISC_INST_ADD_CHECK(c->instructions, inst); + } + + return 0; +} + +#define RISC_ABI_NB (sizeof(naja_abi_regs) / sizeof(naja_abi_regs[0])) +#define RISC_ABI_RET_NB (sizeof(risc_abi_ret_regs) / sizeof(risc_abi_ret_regs[0])) +#define RISC_ABI_CALLER_SAVES_NB (sizeof(risc_abi_caller_saves) / sizeof(risc_abi_caller_saves[0])) +#define RISC_ABI_CALLEE_SAVES_NB (sizeof(risc_abi_callee_saves) / sizeof(risc_abi_callee_saves[0])) + +scf_regs_ops_t regs_ops_naja = +{ + .name = "naja", + + .abi_regs = naja_abi_regs, + .abi_float_regs = naja_abi_float_regs, + .abi_ret_regs = naja_abi_ret_regs, + .abi_caller_saves = naja_abi_caller_saves, + .abi_callee_saves = naja_abi_callee_saves, + + .ABI_NB = sizeof(naja_abi_regs) / sizeof(uint32_t), + .ABI_RET_NB = sizeof(naja_abi_ret_regs) / sizeof(uint32_t), + .ABI_CALLER_SAVES_NB = sizeof(naja_abi_caller_saves) / sizeof(uint32_t), + .ABI_CALLEE_SAVES_NB = sizeof(naja_abi_callee_saves) / sizeof(uint32_t), + + .MAX_BYTES = 8, + + .registers_init = naja_registers_init, + .registers_reset = naja_registers_reset, + .registers_clear = naja_registers_clear, + .register_colors = naja_register_colors, + + .color_conflict = naja_color_conflict, + + .argv_rabi = naja_argv_rabi, + .call_rabi = naja_call_rabi, + + .reg_used = naja_reg_used, + .reg_cached_vars = naja_reg_cached_vars, + + .variable_size = naja_variable_size, + + .caller_save_regs = naja_caller_save_regs, + .pop_regs = naja_pop_regs, + + .find_register = naja_find_register, + .find_register_color = naja_find_register_color, + .find_register_color_bytes = naja_find_register_color_bytes, + .find_register_type_id_bytes = naja_find_register_type_id_bytes, + + .select_overflowed_reg = naja_select_overflowed_reg, + .overflow_reg = naja_overflow_reg, + .overflow_reg2 = naja_overflow_reg2, + .overflow_reg3 = naja_overflow_reg3, + + .push_callee_regs = naja_push_callee_regs, + .pop_callee_regs = naja_pop_callee_regs, +}; diff --git a/native/x64/scf_x64.c b/native/x64/scf_x64.c index 5ebd062..1278ca6 100644 --- a/native/x64/scf_x64.c +++ b/native/x64/scf_x64.c @@ -261,6 +261,13 @@ static int _x64_function_finish(scf_function_t* f) if (err < 0) return err; } else { + if (f->vla_flag) { + inst = x64_make_inst_G2E(mov, rsp, rbp); + X64_INST_ADD_CHECK(end->instructions, inst); + end->inst_bytes += inst->len; + bb ->code_bytes += inst->len; + } + inst = x64_make_inst_G(pop, rbp); X64_INST_ADD_CHECK(end->instructions, inst); end->inst_bytes += inst->len; @@ -269,6 +276,12 @@ static int _x64_function_finish(scf_function_t* f) inst = x64_make_inst_G(push, rbp); X64_INST_ADD_CHECK(f->init_code->instructions, inst); f->init_code_bytes = inst->len; + + if (f->vla_flag) { + inst = x64_make_inst_G2E(mov, rbp, rsp); + X64_INST_ADD_CHECK(f->init_code->instructions, inst); + f->init_code_bytes += inst->len; + } } err = x64_push_callee_regs(f->init_code, f); diff --git a/native/x64/scf_x64_inst.c b/native/x64/scf_x64_inst.c index 392cf08..3283407 100644 --- a/native/x64/scf_x64_inst.c +++ b/native/x64/scf_x64_inst.c @@ -944,7 +944,6 @@ static int _x64_inst_assign_array_index(scf_native_t* ctx, scf_3ac_code_t* c, in OpCode = x64_find_OpCode(SCF_X64_LEA, 8, 8, SCF_X64_E2G); } else { if (is_float) { - OpCode_type = x64_float_OpCode_type(OpCode_type, vs->type); if (0 == src->dag_node->color) { @@ -1439,6 +1438,161 @@ static int _x64_inst_mod_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) return _div_mod_assign(ctx, c, 1); } +static int _x64_inst_vla_alloc_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; + + if (!c->srcs || c->srcs->size != 3) + return -EINVAL; + + scf_x64_context_t* x64 = ctx->priv; + scf_function_t* f = x64->f; + + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_3ac_operand_t* src = c->srcs->data[0]; + scf_3ac_operand_t* logf = c->srcs->data[1]; + scf_3ac_operand_t* msg = c->srcs->data[2]; + + if (!dst || !dst->dag_node) + return -EINVAL; + + if (!src || !src->dag_node) + return -EINVAL; + + if (!logf || !logf->dag_node) + return -EINVAL; + + if (!msg || !msg->dag_node) + return -EINVAL; + + scf_instruction_t* inst = NULL; + scf_instruction_t* jcc = NULL; + scf_register_t* rs = NULL; + scf_register_t* rd = NULL; + scf_register_t* rsp = x64_find_register("rsp"); + scf_register_t* rdi = x64_find_register("rdi"); + scf_register_t* rsi = x64_find_register("rsi"); + scf_register_t* rax = x64_find_register("rax"); + + scf_x64_OpCode_t* cmp = x64_find_OpCode(SCF_X64_CMP, 1, 4, SCF_X64_I2E); + scf_x64_OpCode_t* jg = x64_find_OpCode(SCF_X64_JG , 1, 1, SCF_X64_I); + scf_x64_OpCode_t* lea = x64_find_OpCode(SCF_X64_LEA, 8, 8, SCF_X64_E2G); + scf_x64_OpCode_t* call = x64_find_OpCode(SCF_X64_CALL,4, 4, SCF_X64_I); + scf_x64_OpCode_t* sub = x64_find_OpCode(SCF_X64_SUB, 8, 8, SCF_X64_E2G); + scf_x64_OpCode_t* add = x64_find_OpCode(SCF_X64_ADD, 4, 8, SCF_X64_I2E); + scf_x64_OpCode_t* and = x64_find_OpCode(SCF_X64_AND, 4, 8, SCF_X64_I2E); + scf_x64_OpCode_t* mov = x64_find_OpCode(SCF_X64_MOV, 8, 8, SCF_X64_G2E); + scf_x64_OpCode_t* xor = x64_find_OpCode(SCF_X64_XOR, 8, 8, SCF_X64_G2E); + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); + X64_SELECT_REG_CHECK(&rd, dst->dag_node, c, f, 0); + + // if src > 0 + uint32_t imm = 0; + inst = x64_make_inst_I2E(cmp, rs, (uint8_t*)&imm, 1); + X64_INST_ADD_CHECK(c->instructions, inst); + + jcc = x64_make_inst_I(jg, (uint8_t*)&imm, 1); + X64_INST_ADD_CHECK(c->instructions, jcc); + + // process error when src <= 0 + scf_rela_t* rela = NULL; + int i = c->instructions->size; + + inst = x64_make_inst_G2E(mov, rsi, rs); + X64_INST_ADD_CHECK(c->instructions, inst); + + inst = x64_make_inst_M2G(&rela, lea, rdi, NULL, msg->dag_node->var); + X64_INST_ADD_CHECK(c->instructions, inst); + X64_RELA_ADD_CHECK(f->data_relas, rela, c, msg->dag_node->var, NULL); + + inst = x64_make_inst_G2E(xor, rax, rax); + X64_INST_ADD_CHECK(c->instructions, inst); + + // call printf() to show msg + inst = x64_make_inst_I(call, (uint8_t*)&imm, sizeof(imm)); + X64_INST_ADD_CHECK(c->instructions, inst); + + rela = calloc(1, sizeof(scf_rela_t)); + if (!rela) + return -ENOMEM; + rela->inst_offset = 1; + X64_RELA_ADD_CHECK(f->text_relas, rela, c, NULL, logf->dag_node->var->func_ptr); + + inst = x64_make_inst_G2E(xor, rax, rax); + X64_INST_ADD_CHECK(c->instructions, inst); + + inst = x64_make_inst_G2P(mov, rax, 0, rax); + X64_INST_ADD_CHECK(c->instructions, inst); + + for ( ; i < c->instructions->size; i++) { + inst = c->instructions->data[i]; + jcc->code[1] += inst->len; + } + + // alloc VLA + imm = 0xf; + inst = x64_make_inst_I2E(add, rs, (uint8_t*)&imm, sizeof(imm)); + X64_INST_ADD_CHECK(c->instructions, inst); + + imm = ~0xf; + inst = x64_make_inst_I2E(and, rs, (uint8_t*)&imm, sizeof(imm)); + X64_INST_ADD_CHECK(c->instructions, inst); + + inst = x64_make_inst_E2G(sub, rsp, rs); + X64_INST_ADD_CHECK(c->instructions, inst); + + inst = x64_make_inst_G2E(mov, rd, rsp); + X64_INST_ADD_CHECK(c->instructions, inst); + + return x64_save_var(src->dag_node, c, f); +} + +static int _x64_inst_vla_free_handler(scf_native_t* ctx, scf_3ac_code_t* c) +{ + if (!c->dsts || c->dsts->size != 1) + return -EINVAL; + + if (!c->srcs || c->srcs->size != 3) + return -EINVAL; + + scf_x64_context_t* x64 = ctx->priv; + scf_function_t* f = x64->f; + scf_3ac_operand_t* src = c->srcs->data[0]; + + if (!src || !src->dag_node) + return -EINVAL; + + scf_instruction_t* inst = NULL; + scf_register_t* rs = NULL; + scf_register_t* rsp = x64_find_register("rsp"); + scf_x64_OpCode_t* add = x64_find_OpCode(SCF_X64_ADD, 8, 8, SCF_X64_E2G); + scf_x64_OpCode_t* xor = x64_find_OpCode(SCF_X64_XOR, 8, 8, SCF_X64_G2E); + + if (!c->instructions) { + c->instructions = scf_vector_alloc(); + if (!c->instructions) + return -ENOMEM; + } + + X64_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1); + + inst = x64_make_inst_E2G(add, rsp, rs); + X64_INST_ADD_CHECK(c->instructions, inst); + + inst = x64_make_inst_G2E(xor, rs, rs); + X64_INST_ADD_CHECK(c->instructions, inst); + + return x64_save_var(src->dag_node, c, f); +} + static int _x64_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c) { if (!c->srcs || c->srcs->size < 1) @@ -2272,6 +2426,9 @@ static x64_inst_handler_pt x64_inst_handlers[] = [SCF_OP_AND_ASSIGN ] = _x64_inst_and_assign_handler, [SCF_OP_OR_ASSIGN ] = _x64_inst_or_assign_handler, + [SCF_OP_VLA_ALLOC ] = _x64_inst_vla_alloc_handler, + [SCF_OP_VLA_FREE ] = _x64_inst_vla_free_handler, + [SCF_OP_RETURN ] = _x64_inst_return_handler, [SCF_OP_GOTO ] = _x64_inst_goto_handler, diff --git a/native/x64/scf_x64_rcg.c b/native/x64/scf_x64_rcg.c index 332b805..25cbab8 100644 --- a/native/x64/scf_x64_rcg.c +++ b/native/x64/scf_x64_rcg.c @@ -920,6 +920,24 @@ static int _x64_rcg_or_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_ return _x64_rcg_make(c, g, dst->dag_node, NULL, NULL); } +static int _x64_rcg_vla_alloc_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) +{ + int ret = _x64_rcg_make2(c, NULL, NULL, NULL); + if (ret < 0) + return ret; + + return _x64_rcg_make(c, g, NULL, NULL, NULL); +} + +static int _x64_rcg_vla_free_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) +{ + int ret = _x64_rcg_make2(c, NULL, NULL, NULL); + if (ret < 0) + return ret; + + return _x64_rcg_make(c, g, NULL, NULL, NULL); +} + static int _x64_rcg_return_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g) { int i; @@ -1285,6 +1303,9 @@ static x64_rcg_handler_pt x64_rcg_handlers[SCF_N_3AC_OPS] = [SCF_OP_AND_ASSIGN ] = _x64_rcg_and_assign_handler, [SCF_OP_OR_ASSIGN ] = _x64_rcg_or_assign_handler, + [SCF_OP_VLA_ALLOC ] = _x64_rcg_vla_alloc_handler, + [SCF_OP_VLA_FREE ] = _x64_rcg_vla_free_handler, + [SCF_OP_RETURN ] = _x64_rcg_return_handler, [SCF_OP_3AC_CMP ] = _x64_rcg_cmp_handler, diff --git a/native/x64/scf_x64_reg.c b/native/x64/scf_x64_reg.c index 3c998db..f157508 100644 --- a/native/x64/scf_x64_reg.c +++ b/native/x64/scf_x64_reg.c @@ -1154,7 +1154,7 @@ int x64_array_index_reg(x64_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* in int32_t disp = 0; - if (vb->nb_pointers > 0 && 0 == vb->nb_dimentions) { + if ((vb->nb_pointers > 0 && 0 == vb->nb_dimentions) || vb->vla_flag) { ret = x64_select_reg(&rb, base, c, f, 1); if (ret < 0) { diff --git a/parse/Makefile b/parse/Makefile index 5750f47..e6dddae 100644 --- a/parse/Makefile +++ b/parse/Makefile @@ -38,6 +38,7 @@ CFILES += ../native/risc/scf_risc_rcg.c CFILES += ../native/risc/scf_risc_reg.c CFILES += ../native/risc/scf_risc_reg_arm64.c CFILES += ../native/risc/scf_risc_reg_arm32.c +CFILES += ../native/risc/scf_risc_reg_naja.c CFILES += ../native/risc/scf_arm64.c CFILES += ../native/risc/scf_arm32.c CFILES += ../native/risc/scf_naja.c @@ -114,6 +115,7 @@ CFILES += ../core/scf_optimizer_dominators.c CFILES += ../core/scf_optimizer_basic_block.c CFILES += ../core/scf_optimizer_const_teq.c CFILES += ../core/scf_optimizer_loop.c +CFILES += ../core/scf_optimizer_vla.c CFILES += ../core/scf_optimizer_group.c CFILES += ../core/scf_optimizer_generate_loads_saves.c diff --git a/parse/main.c b/parse/main.c index 7e7d854..0217073 100644 --- a/parse/main.c +++ b/parse/main.c @@ -206,8 +206,10 @@ int main(int argc, char* argv[]) for (i = 0; i < srcs->size; i++) { char* file = srcs->data[i]; + assert(file); + if (scf_parse_file(parse, file) < 0) { - scf_loge("\n"); + scf_loge("parse file '%s' failed\n", file); return -1; } } diff --git a/parse/scf_dfa.c b/parse/scf_dfa.c index ea01777..d8a1a93 100644 --- a/parse/scf_dfa.c +++ b/parse/scf_dfa.c @@ -405,7 +405,7 @@ static int _scf_dfa_node_parse_word(scf_dfa_t* dfa, scf_dfa_node_t* node, scf_ve } else if (SCF_DFA_CONTINUE == ret) { } else { - scf_loge("SCF_DFA: %d\n", ret); + scf_logd("SCF_DFA: %d\n", ret); return SCF_DFA_ERROR; } @@ -453,6 +453,5 @@ int scf_dfa_parse_word(scf_dfa_t* dfa, void* word, void* data) scf_vector_clear(words, (void (*)(void*) )dfa->ops->free_word); scf_vector_free(words); words = NULL; - return ret; } diff --git a/parse/scf_dfa_class.c b/parse/scf_dfa_class.c index 669d517..db09080 100644 --- a/parse/scf_dfa_class.c +++ b/parse/scf_dfa_class.c @@ -123,13 +123,13 @@ static int _class_calculate_size(scf_dfa_t* dfa, scf_type_t* s) for (j = 0; j < v->nb_dimentions; j++) { - if (v->dimentions[j] < 0) { + if (v->dimentions[j].num < 0) { scf_loge("number of %d-dimention for array '%s' is less than 0, size: %d, file: %s, line: %d\n", - j, v->w->text->data, v->dimentions[j], v->w->file->data, v->w->line); + j, v->w->text->data, v->dimentions[j].num, v->w->file->data, v->w->line); return SCF_DFA_ERROR; } - v->capacity *= v->dimentions[j]; + v->capacity *= v->dimentions[j].num; } size = v->offset + v->size * v->capacity; diff --git a/parse/scf_dfa_enum.c b/parse/scf_dfa_enum.c index 7ab4727..aab35a0 100644 --- a/parse/scf_dfa_enum.c +++ b/parse/scf_dfa_enum.c @@ -183,6 +183,11 @@ static int _enum_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_ERROR; } + if (!scf_variable_const(r) && SCF_OP_ASSIGN != d->expr->nodes[0]->type) { + scf_loge("enum var must be inited by constant, file: %s, line: %d\n", w->file->data, w->line); + return -1; + } + md->current_v->data.i64 = r->data.i64; scf_variable_free(r); @@ -224,6 +229,11 @@ static int _enum_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_ERROR; } + if (!scf_variable_const(r) && SCF_OP_ASSIGN != d->expr->nodes[0]->type) { + scf_loge("enum var must be inited by constant, file: %s, line: %d\n", w->file->data, w->line); + return -1; + } + md->current_v->data.i64 = r->data.i64; scf_variable_free(r); diff --git a/parse/scf_dfa_union.c b/parse/scf_dfa_union.c index 10727b9..f9255e0 100644 --- a/parse/scf_dfa_union.c +++ b/parse/scf_dfa_union.c @@ -112,20 +112,20 @@ static int _union_calculate_size(scf_dfa_t* dfa, scf_type_t* s) for (j = 0; j < v->nb_dimentions; j++) { - if (v->dimentions[j] < 0) { + if (v->dimentions[j].num < 0) { scf_loge("number of %d-dimention for array '%s' is less than 0, number: %d, file: %s, line: %d\n", - j, v->w->text->data, v->dimentions[j], v->w->file->data, v->w->line); + j, v->w->text->data, v->dimentions[j].num, v->w->file->data, v->w->line); return SCF_DFA_ERROR; } - if (0 == v->dimentions[j] && j < v->nb_dimentions - 1) { + if (0 == v->dimentions[j].num && j < v->nb_dimentions - 1) { scf_loge("only the number of array's last dimention can be 0, array '%s', dimention: %d, file: %s, line: %d\n", v->w->text->data, j, v->w->file->data, v->w->line); return SCF_DFA_ERROR; } - v->capacity *= v->dimentions[j]; + v->capacity *= v->dimentions[j].num; } size = v->size * v->capacity; diff --git a/parse/scf_dfa_var.c b/parse/scf_dfa_var.c index 7eb38ce..dd193de 100644 --- a/parse/scf_dfa_var.c +++ b/parse/scf_dfa_var.c @@ -47,8 +47,6 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d) if (id && id->identity) { - scf_logd("d->current_identity: %p\n", id->identity); - scf_variable_t* v = scf_scope_find_variable(parse->ast->current_block->scope, id->identity->text->data); if (v) { scf_loge("repeated declare var '%s', line: %d\n", id->identity->text->data, id->identity->line); @@ -157,9 +155,11 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d) return 0; } -static int _var_init_expr(scf_dfa_t* dfa, dfa_data_t* d, int semi_flag) +static int _var_init_expr(scf_dfa_t* dfa, dfa_data_t* d, scf_vector_t* words, int semi_flag) { - scf_parse_t* parse = dfa->priv; + scf_parse_t* parse = dfa->priv; + scf_variable_t* r = NULL; + scf_lex_word_t* w = words->data[words->size - 1]; if (!d->expr) { scf_loge("\n"); @@ -173,11 +173,19 @@ static int _var_init_expr(scf_dfa_t* dfa, dfa_data_t* d, int semi_flag) if (d->current_var->global_flag || (d->current_var->const_flag && 0 == d->current_var->nb_pointers + d->current_var->nb_dimentions)) { - scf_logd("d->expr: %p, d->current_var: %p, global_flag: %d\n", - d->expr, d->current_var, d->current_var->global_flag); - - if (scf_expr_calculate(parse->ast, d->expr, NULL) < 0) { + if (scf_expr_calculate(parse->ast, d->expr, &r) < 0) { scf_loge("\n"); + + scf_expr_free(d->expr); + d->expr = NULL; + return SCF_DFA_ERROR; + } + + if (!scf_variable_const(r) && SCF_OP_ASSIGN != d->expr->nodes[0]->type) { + scf_loge("number of array should be constant, file: %s, line: %d\n", w->file->data, w->line); + + scf_expr_free(d->expr); + d->expr = NULL; return SCF_DFA_ERROR; } @@ -202,6 +210,239 @@ static int _var_init_expr(scf_dfa_t* dfa, dfa_data_t* d, int semi_flag) return 0; } +static int _var_add_vla(scf_ast_t* ast, scf_variable_t* vla) +{ + scf_function_t* f = NULL; + scf_expr_t* e = NULL; + scf_expr_t* e2 = NULL; + scf_node_t* mul = NULL; + + if (scf_ast_find_function(&f, ast, "printf") < 0 || !f) { + scf_loge("printf() NOT found, which used to print error message when the variable length of array '%s' <= 0, file: %s, line: %d\n", + vla->w->text->data, vla->w->file->data, vla->w->line); + return SCF_DFA_ERROR; + } + + int size = vla->data_size; + int i; + + for (i = 0; i < vla->nb_dimentions; i++) { + + if (vla->dimentions[i].num > 0) { + size *= vla->dimentions[i].num; + continue; + } + + if (0 == vla->dimentions[i].num) { + scf_loge("\n"); + + scf_expr_free(e); + return SCF_DFA_ERROR; + } + + if (!vla->dimentions[i].vla) { + scf_loge("\n"); + + scf_expr_free(e); + return SCF_DFA_ERROR; + } + + if (!e) { + e = scf_expr_clone(vla->dimentions[i].vla); + if (!e) + return -ENOMEM; + continue; + } + + e2 = scf_expr_clone(vla->dimentions[i].vla); + if (!e2) { + scf_expr_free(e); + return -ENOMEM; + } + + mul = scf_node_alloc(vla->w, SCF_OP_MUL, NULL); + if (!mul) { + scf_expr_free(e2); + scf_expr_free(e); + return -ENOMEM; + } + + int ret = scf_expr_add_node(e, mul); + if (ret < 0) { + scf_expr_free(mul); + scf_expr_free(e2); + scf_expr_free(e); + return ret; + } + + ret = scf_expr_add_node(e, e2); + if (ret < 0) { + scf_expr_free(e2); + scf_expr_free(e); + return ret; + } + } + + assert(e); + + scf_variable_t* v; + scf_type_t* t; + scf_node_t* node; + + if (size > 1) { + mul = scf_node_alloc(vla->w, SCF_OP_MUL, NULL); + if (!mul) { + scf_expr_free(e); + return -ENOMEM; + } + + int ret = scf_expr_add_node(e, mul); + if (ret < 0) { + scf_expr_free(mul); + scf_expr_free(e); + return ret; + } + + t = scf_block_find_type_type(ast->current_block, SCF_VAR_INT); + v = SCF_VAR_ALLOC_BY_TYPE(vla->w, t, 1, 0, NULL); + if (!v) { + scf_expr_free(e); + return SCF_DFA_ERROR; + } + v->data.i64 = size; + v->global_flag = 1; + v->const_literal_flag = 1; + + node = scf_node_alloc(NULL, v->type, v); + scf_variable_free(v); + v = NULL; + if (!node) { + scf_expr_free(e); + return SCF_DFA_ERROR; + } + + ret = scf_expr_add_node(e, node); + if (ret < 0) { + scf_node_free(node); + scf_expr_free(e); + return ret; + } + } + + scf_node_t* assign; + scf_node_t* len; + scf_node_t* alloc; + + // len = e + assign = scf_node_alloc(vla->w, SCF_OP_ASSIGN, NULL); + if (!assign) { + scf_expr_free(e); + return SCF_DFA_ERROR; + } + + scf_node_add_child(assign, e->nodes[0]); + e->nodes[0] = assign; + assign->parent = e; + + scf_node_add_child((scf_node_t*)ast->current_block, e); + e = NULL; + + t = scf_block_find_type_type(ast->current_block, SCF_VAR_INT); + v = SCF_VAR_ALLOC_BY_TYPE(vla->w, t, 0, 0, NULL); + if (!v) + return SCF_DFA_ERROR; + v->tmp_flag = 1; + + len = scf_node_alloc(NULL, v->type, v); + if (!len) { + scf_variable_free(v); + return SCF_DFA_ERROR; + } + + scf_node_add_child(assign, len); + SCF_XCHG(assign->nodes[0], assign->nodes[1]); + + // vla_alloc(vla, len, printf, msg) + len = scf_node_alloc(NULL, v->type, v); + scf_variable_free(v); + v = NULL; + if (!len) + return SCF_DFA_ERROR; + + alloc = scf_node_alloc(vla->w, SCF_OP_VLA_ALLOC, NULL); + if (!alloc) { + scf_node_free(len); + return -ENOMEM; + } + + // vla node + node = scf_node_alloc(NULL, vla->type, vla); + if (!node) { + scf_node_free(len); + scf_node_free(alloc); + return SCF_DFA_ERROR; + } + + scf_node_add_child(alloc, node); + scf_node_add_child(alloc, len); + node = NULL; + len = NULL; + + // printf() node + t = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR); + v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 1, 1, f); + if (!v) { + scf_node_free(alloc); + return SCF_DFA_ERROR; + } + v->const_literal_flag = 1; + + node = scf_node_alloc(NULL, v->type, v); + scf_variable_free(v); + v = NULL; + if (!node) { + scf_node_free(alloc); + return SCF_DFA_ERROR; + } + + scf_node_add_child(alloc, node); + node = NULL; + + // msg + char msg[1024]; + snprintf(msg, sizeof(msg) - 1, "\033[31merror:\033[0m variable length '%%d' of array '%s' not more than 0, file: %s, line: %d\n", + vla->w->text->data, vla->w->file->data, vla->w->line); + + t = scf_block_find_type_type(ast->current_block, SCF_VAR_CHAR); + v = SCF_VAR_ALLOC_BY_TYPE(vla->w, t, 1, 1, NULL); + if (!v) { + scf_node_free(alloc); + return SCF_DFA_ERROR; + } + v->const_literal_flag = 1; + v->global_flag = 1; + + v->data.s = scf_string_cstr(msg); + if (!v->data.s) { + scf_node_free(alloc); + scf_variable_free(v); + return -ENOMEM; + } + + node = scf_node_alloc(NULL, v->type, v); + scf_variable_free(v); + v = NULL; + if (!node) { + scf_node_free(alloc); + return SCF_DFA_ERROR; + } + scf_node_add_child(alloc, node); + node = NULL; + + scf_node_add_child((scf_node_t*)ast->current_block, alloc); + return 0; +} + static int _var_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data) { scf_parse_t* parse = dfa->priv; @@ -215,10 +456,17 @@ static int _var_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data) d->nb_lss = 0; d->nb_rss = 0; - if (d->current_var) + if (d->current_var) { scf_variable_size(d->current_var); - if (d->expr_local_flag > 0 && _var_init_expr(dfa, d, 0) < 0) + if (d->current_var->vla_flag) { + + if (_var_add_vla(parse->ast, d->current_var) < 0) + return SCF_DFA_ERROR; + } + } + + if (d->expr_local_flag > 0 && _var_init_expr(dfa, d, words, 0) < 0) return SCF_DFA_ERROR; return SCF_DFA_SWITCH_TO; @@ -245,13 +493,19 @@ static int _var_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data free(id); id = NULL; - if (d->current_var) + if (d->current_var) { scf_variable_size(d->current_var); + if (d->current_var->vla_flag) { + + if (_var_add_vla(parse->ast, d->current_var) < 0) + return SCF_DFA_ERROR; + } + } if (d->expr_local_flag > 0) { - if (_var_init_expr(dfa, d, 1) < 0) + if (_var_init_expr(dfa, d, words, 1) < 0) return SCF_DFA_ERROR; } else if (d->expr) { @@ -293,6 +547,12 @@ static int _var_action_assign(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_ERROR; } + if (d->current_var->vla_flag) { + + if (_var_add_vla(parse->ast, d->current_var) < 0) + return SCF_DFA_ERROR; + } + if (d->current_var->nb_dimentions > 0) { scf_logi("var array '%s' init, nb_dimentions: %d\n", d->current_var->w->text->data, d->current_var->nb_dimentions); @@ -343,7 +603,7 @@ static int _var_action_ls(scf_dfa_t* dfa, scf_vector_t* words, void* data) } assert(!d->expr); - scf_variable_add_array_dimention(d->current_var, -1); + scf_variable_add_array_dimention(d->current_var, -1, NULL); d->current_var->const_literal_flag = 1; SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "var_rs"), SCF_DFA_HOOK_POST); @@ -355,8 +615,10 @@ static int _var_action_ls(scf_dfa_t* dfa, scf_vector_t* words, void* data) static int _var_action_rs(scf_dfa_t* dfa, scf_vector_t* words, void* data) { - scf_parse_t* parse = dfa->priv; - dfa_data_t* d = data; + scf_parse_t* parse = dfa->priv; + dfa_data_t* d = data; + scf_variable_t* r = NULL; + scf_lex_word_t* w = words->data[words->size - 1]; d->nb_rss++; @@ -366,25 +628,49 @@ static int _var_action_rs(scf_dfa_t* dfa, scf_vector_t* words, void* data) while(d->expr->parent) d->expr = d->expr->parent; - scf_logd("d->expr: %p, d->expr->parent: %p\n", d->expr, d->expr->parent); - - scf_variable_t* r = NULL; if (scf_expr_calculate(parse->ast, d->expr, &r) < 0) { scf_loge("scf_expr_calculate\n"); + + scf_expr_free(d->expr); + d->expr = NULL; return SCF_DFA_ERROR; } assert(d->current_var->dim_index < d->current_var->nb_dimentions); - d->current_var->dimentions[d->current_var->dim_index++] = r->data.i; - scf_logi("dimentions: %d, size: %d\n", - d->current_var->dim_index, d->current_var->dimentions[d->current_var->dim_index - 1]); + if (!scf_variable_const(r) && SCF_OP_ASSIGN != d->expr->nodes[0]->type) { + + if (!d->current_var->local_flag) { + scf_loge("variable length array '%s' must in local scope, file: %s, line: %d\n", + d->current_var->w->text->data, w->file->data, w->line); + + scf_variable_free(r); + r = NULL; + + scf_expr_free(d->expr); + d->expr = NULL; + return SCF_DFA_ERROR; + } + + scf_logw("define variable length array, file: %s, line: %d\n", w->file->data, w->line); + + d->current_var->dimentions[d->current_var->dim_index].vla = d->expr; + d->current_var->vla_flag = 1; + d->expr = NULL; + } else { + d->current_var->dimentions[d->current_var->dim_index].num = r->data.i; + + scf_logi("dimentions: %d, size: %d\n", + d->current_var->dim_index, d->current_var->dimentions[d->current_var->dim_index].num); + + scf_expr_free(d->expr); + d->expr = NULL; + } + + d->current_var->dim_index++; scf_variable_free(r); r = NULL; - - scf_expr_free(d->expr); - d->expr = NULL; } return SCF_DFA_SWITCH_TO; diff --git a/parse/scf_operator_handler_const.c b/parse/scf_operator_handler_const.c index d8a1037..b3bb010 100644 --- a/parse/scf_operator_handler_const.c +++ b/parse/scf_operator_handler_const.c @@ -367,6 +367,13 @@ static int _scf_op_const_default(scf_ast_t* ast, scf_node_t** nodes, int nb_node return 0; } +static int _scf_op_const_vla_alloc(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + assert(4 == nb_nodes); + + return 0; +} + static int _scf_op_const_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { assert(4 == nb_nodes); @@ -987,6 +994,8 @@ scf_operator_handler_pt const_operator_handlers[SCF_N_OPS] = [SCF_OP_SWITCH ] = _scf_op_const_switch, [SCF_OP_CASE ] = _scf_op_const_case, [SCF_OP_DEFAULT ] = _scf_op_const_default, + + [SCF_OP_VLA_ALLOC ] = _scf_op_const_vla_alloc, }; scf_operator_handler_pt scf_find_const_operator_handler(const int type) diff --git a/parse/scf_operator_handler_expr.c b/parse/scf_operator_handler_expr.c index edef075..d5f6437 100644 --- a/parse/scf_operator_handler_expr.c +++ b/parse/scf_operator_handler_expr.c @@ -199,8 +199,7 @@ static int _scf_op_expr_type_cast(scf_ast_t* ast, scf_node_t** nodes, int nb_nod return 0; } - scf_loge("\n"); - return -1; + return 0; } static int _scf_op_expr_sizeof(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) @@ -283,8 +282,7 @@ static int _scf_op_expr_binary(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, if (scf_type_is_number(v0->type) && scf_type_is_number(v1->type)) { if (!scf_variable_const(v0) || !scf_variable_const(v1)) { - scf_loge("\n"); - return -1; + return 0; } assert(v0->type == v1->type); @@ -727,11 +725,6 @@ int scf_expr_calculate(scf_ast_t* ast, scf_expr_t* e, scf_variable_t** pret) v = _scf_operand_get(e->nodes[0]); - if (!scf_variable_const(v) && SCF_OP_ASSIGN != e->nodes[0]->type) { - scf_loge("\n"); - return -1; - } - if (pret) *pret = scf_variable_ref(v); diff --git a/parse/scf_operator_handler_semantic.c b/parse/scf_operator_handler_semantic.c index 0e90030..9e1974e 100644 --- a/parse/scf_operator_handler_semantic.c +++ b/parse/scf_operator_handler_semantic.c @@ -926,7 +926,7 @@ static int _scf_op_semantic_pointer(scf_ast_t* ast, scf_node_t** nodes, int nb_n int i; for (i = 0; i < v1->nb_dimentions; i++) - scf_variable_add_array_dimention(r, v1->dimentions[i]); + scf_variable_add_array_dimention(r, v1->dimentions[i].num, NULL); *d->pret = r; return 0; @@ -973,7 +973,7 @@ static int _scf_op_semantic_array_index(scf_ast_t* ast, scf_node_t** nodes, int int nb_pointers = 0; if (v0->nb_dimentions > 0) { - if (v0->dimentions[0] < 0) { + if (v0->dimentions[0].num < 0 && !v0->dimentions[0].vla) { scf_loge("\n"); return -1; } @@ -987,23 +987,23 @@ static int _scf_op_semantic_array_index(scf_ast_t* ast, scf_node_t** nodes, int return -1; } - if (v1->data.i >= v0->dimentions[0]) { + if (v1->data.i >= v0->dimentions[0].num && !v0->dimentions[0].vla) { if (!v0->member_flag) { scf_loge("array index '%s' >= size %d, real: %d, file: %s, line: %d\n", - v1->w->text->data, v0->dimentions[0], v1->data.i, v1->w->file->data, v1->w->line); + v1->w->text->data, v0->dimentions[0].num, v1->data.i, v1->w->file->data, v1->w->line); return -1; } scf_logw("array index '%s' >= size %d, real: %d, confirm it for a zero-array end of a struct? file: %s, line: %d\n", - v1->w->text->data, v0->dimentions[0], v1->data.i, v1->w->file->data, v1->w->line); + v1->w->text->data, v0->dimentions[0].num, v1->data.i, v1->w->file->data, v1->w->line); } } } else if (0 == v0->nb_dimentions && v0->nb_pointers > 0) { nb_pointers = v0->nb_pointers - 1; } else { - scf_loge("index out, v0: %s, v0->nb_dimentions: %d, v0->nb_pointers: %d, v0->arg_flag: %d, v0->output_flag: %d\n", - v0->w->text->data, v0->nb_dimentions, v0->nb_pointers, v0->arg_flag, v0->output_flag); + scf_loge("index out, v0: %s, v0->nb_dimentions: %d, v0->nb_pointers: %d, v0->arg_flag: %d\n", + v0->w->text->data, v0->nb_dimentions, v0->nb_pointers, v0->arg_flag); return -1; } @@ -1020,8 +1020,19 @@ static int _scf_op_semantic_array_index(scf_ast_t* ast, scf_node_t** nodes, int r->member_flag = v0->member_flag; int i; - for (i = 1; i < v0->nb_dimentions; i++) - scf_variable_add_array_dimention(r, v0->dimentions[i]); + for (i = 1; i < v0->nb_dimentions; i++) { + scf_expr_t* vla = NULL; + + if (v0->dimentions[i].vla) { + vla = scf_expr_clone(v0->dimentions[i].vla); + if (!vla) { + scf_variable_free(r); + return -ENOMEM; + } + } + + scf_variable_add_array_dimention(r, v0->dimentions[i].num, vla); + } *d->pret = r; return 0; @@ -1478,6 +1489,14 @@ static int _scf_op_semantic_default(scf_ast_t* ast, scf_node_t** nodes, int nb_n return 0; } +static int _scf_op_semantic_vla_alloc(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + assert(4 == nb_nodes); + + scf_logw("\n"); + return 0; +} + static int _scf_op_semantic_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { assert(4 == nb_nodes); @@ -3202,6 +3221,8 @@ scf_operator_handler_pt semantic_operator_handlers[SCF_N_OPS] = [SCF_OP_SWITCH ] = _scf_op_semantic_switch, [SCF_OP_CASE ] = _scf_op_semantic_case, [SCF_OP_DEFAULT ] = _scf_op_semantic_default, + + [SCF_OP_VLA_ALLOC ] = _scf_op_semantic_vla_alloc, }; scf_operator_handler_pt scf_find_semantic_operator_handler(const int type) diff --git a/parse/scf_parse.c b/parse/scf_parse.c index 1c5344d..ffc248c 100644 --- a/parse/scf_parse.c +++ b/parse/scf_parse.c @@ -216,10 +216,8 @@ int scf_parse_file(scf_parse_t* parse, const char* path) assert(!d->expr); ret = scf_dfa_parse_word(parse->dfa, w, d); - if (ret < 0) { - scf_loge("dfa parse failed\n"); + if (ret < 0) break; - } } fclose(parse->lex->fp); diff --git a/parse/scf_struct_array.c b/parse/scf_struct_array.c index 69d42a5..8e8c720 100644 --- a/parse/scf_struct_array.c +++ b/parse/scf_struct_array.c @@ -18,19 +18,19 @@ static int __reshape_index(dfa_index_t** out, scf_variable_t* array, dfa_index_t int j; for (j = array->nb_dimentions - 1; j >= 0; j--) { - if (array->dimentions[j] <= 0) { + if (array->dimentions[j].num <= 0) { scf_logw("array's %d-dimention size not set, file: %s, line: %d\n", j, array->w->file->data, array->w->line); free(p); return -1; } - p[j].i = i % array->dimentions[j]; - i = i / array->dimentions[j]; + p[j].i = i % array->dimentions[j].num; + i = i / array->dimentions[j].num; } for (j = 0; j < array->nb_dimentions; j++) - scf_logi("\033[32m dim: %d, size: %d, index: %ld\033[0m\n", j, array->dimentions[j], p[j].i); + scf_logi("\033[32m dim: %d, size: %d, index: %ld\033[0m\n", j, array->dimentions[j].num, p[j].i); *out = p; return 0; @@ -64,9 +64,9 @@ static int __array_member_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t intptr_t k = index[i].i; - if (k >= array->dimentions[i]) { + if (k >= array->dimentions[i].num) { scf_loge("index [%ld] out of size [%d], in dim: %d, file: %s, line: %d\n", - k, array->dimentions[i], i, w->file->data, w->line); + k, array->dimentions[i].num, i, w->file->data, w->line); if (n < array->nb_dimentions) { free(index); @@ -243,9 +243,9 @@ int scf_array_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* v, scf_vec for (i = 0; i < v->nb_dimentions; i++) { assert(v->dimentions); - scf_logi("dim[%d]: %d\n", i, v->dimentions[i]); + scf_logi("dim[%d]: %d\n", i, v->dimentions[i].num); - if (v->dimentions[i] < 0) { + if (v->dimentions[i].num < 0) { if (unset > 0) { scf_loge("array '%s' should only unset 1-dimention size, file: %s, line: %d\n", @@ -256,7 +256,7 @@ int scf_array_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* v, scf_vec unset++; unset_dim = i; } else - capacity *= v->dimentions[i]; + capacity *= v->dimentions[i].num; } if (unset) { @@ -274,12 +274,12 @@ int scf_array_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* v, scf_vec if (-1 == unset_max) { unset_max = init_exprs->size / capacity; - v->dimentions[unset_dim] = unset_max; + v->dimentions[unset_dim].num = unset_max; scf_logw("don't set %d-dimention size of array '%s', use '%d' as calculated, file: %s, line: %d\n", unset_dim, v->w->text->data, unset_max, w->file->data, w->line); } else - v->dimentions[unset_dim] = unset_max + 1; + v->dimentions[unset_dim].num = unset_max + 1; } for (i = 0; i < init_exprs->size; i++) { @@ -302,13 +302,13 @@ int scf_array_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* v, scf_vec for (j = v->nb_dimentions - 1; j >= 0; j--) { - ie->index[j].i = index % v->dimentions[j]; - index = index / v->dimentions[j]; + ie->index[j].i = index % v->dimentions[j].num; + index = index / v->dimentions[j].num; } } for (j = 0; j < v->nb_dimentions; j++) - scf_logi("\033[32mi: %d, dim: %d, size: %d, index: %ld\033[0m\n", i, j, v->dimentions[j], ie->index[j].i); + scf_logi("\033[32mi: %d, dim: %d, size: %d, index: %ld\033[0m\n", i, j, v->dimentions[j].num, ie->index[j].i); } for (i = 0; i < init_exprs->size; i++) { diff --git a/vm/Makefile b/vm/Makefile index cbc0a74..3eed753 100644 --- a/vm/Makefile +++ b/vm/Makefile @@ -20,7 +20,7 @@ CFILES += ../elf/scf_dwarf_line.c CFILES += ../vm/scf_vm.c CFILES += ../vm/scf_vm_naja.c CFILES += ../vm/scf_vm_naja_asm.c -CFILES += ../vm/scf_vm_test.c +CFILES += ../vm/main.c CFLAGS += -g #CFLAGS += -Wall diff --git a/vm/main.c b/vm/main.c new file mode 100644 index 0000000..d0f6daf --- /dev/null +++ b/vm/main.c @@ -0,0 +1,35 @@ +#include"scf_vm.h" + +int main(int argc, char* argv[]) +{ + if (argc < 2) { + printf("usage: ./nvm file [opt]\n\n"); + printf("file: an ELF file with naja bytecode\n"); + printf("opt : 0 to run, 1 to disassemble, default 0\n"); + return -1; + } + + char* arch = "naja"; + + if (argc > 2) { + if (1 == atoi(argv[2])) + arch = "naja_asm"; + } + + scf_vm_t* vm = NULL; + + int ret = scf_vm_open(&vm, arch); + if (ret < 0) { + scf_loge("\n"); + return -1; + } + + ret = scf_vm_run(vm, argv[1], "x64"); + if (ret < 0) { + scf_loge("\n"); + return -1; + } + + printf("main ok\n"); + return ret; +} diff --git a/vm/scf_vm.h b/vm/scf_vm.h index 85031ef..98d32ed 100644 --- a/vm/scf_vm.h +++ b/vm/scf_vm.h @@ -10,9 +10,9 @@ #define NAJA_PRINTF #endif -#define NAJA_REG_FP 29 -#define NAJA_REG_LR 30 -#define NAJA_REG_SP 31 +#define NAJA_REG_FP 28 +#define NAJA_REG_LR 29 +#define NAJA_REG_SP 30 typedef struct scf_vm_s scf_vm_t; typedef struct scf_vm_ops_s scf_vm_ops_t; @@ -81,28 +81,6 @@ typedef struct { } scf_vm_naja_t; -#define NAJA_ADD 0 -#define NAJA_SUB 1 -#define NAJA_MUL 2 -#define NAJA_DIV 3 -#define NAJA_LDR_DISP 4 -#define NAJA_STR_DISP 5 -#define NAJA_AND 6 -#define NAJA_OR 7 -#define NAJA_JMP_DISP 8 -#define NAJA_CMP 9 -#define NAJA_JMP_REG 10 -#define NAJA_SETCC 11 -#define NAJA_LDR_SIB 12 -#define NAJA_STR_SIB 13 -#define NAJA_TEQ 14 -#define NAJA_MOV 15 - -#define NAJA_CALL_DISP 24 -#define NAJA_CALL_REG 26 -#define NAJA_ADRP 42 -#define NAJA_RET 56 - typedef int (*naja_opcode_pt)(scf_vm_t* vm, uint32_t inst); int scf_vm_open (scf_vm_t** pvm, const char* arch); @@ -116,4 +94,3 @@ int naja_vm_close(scf_vm_t* vm); int naja_vm_init(scf_vm_t* vm, const char* path, const char* sys); #endif - diff --git a/vm/scf_vm_naja.c b/vm/scf_vm_naja.c index d98eb32..bf1f0df 100644 --- a/vm/scf_vm_naja.c +++ b/vm/scf_vm_naja.c @@ -55,10 +55,10 @@ static int naja_vm_dynamic_link(scf_vm_t* vm) int64_t sp = naja->regs[NAJA_REG_SP]; - uint64_t r30 = *(uint64_t*)(naja->stack - (sp + 8)); + uint64_t lr = *(uint64_t*)(naja->stack - (sp + 8)); uint64_t r16 = *(uint64_t*)(naja->stack - (sp + 16)); - scf_logw("sp: %ld, r16: %#lx, r30: %#lx, vm->jmprel_size: %ld\n", sp, r16, r30, vm->jmprel_size); + scf_logw("sp: %ld, r16: %#lx, lr: %#lx, vm->jmprel_size: %ld\n", sp, r16, lr, vm->jmprel_size); if (r16 > (uint64_t)vm->data->data) { r16 -= (uint64_t)vm->data->data; @@ -93,6 +93,8 @@ static int naja_vm_dynamic_link(scf_vm_t* vm) return -1; } + scf_logw("f: %p\n", f); + *(void**)(vm->data->data + offset) = f; naja->regs[0] = f(naja->regs[0], @@ -294,34 +296,36 @@ static int __naja_add(scf_vm_t* vm, uint32_t inst) int rs0 = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int I = (inst >> 20) & 0x1; + int SH = (inst >> 19) & 0x3; - if (I) { - uint64_t uimm15 = (inst >> 5) & 0x7fff; + if (0x3 == SH) { + uint64_t uimm14 = (inst >> 5) & 0x3fff; - naja->regs[rd] = naja->regs[rs0] + uimm15; + naja->regs[rd] = naja->regs[rs0] + uimm14; - NAJA_PRINTF("add r%d, r%d, %lu\n", rd, rs0, uimm15); + NAJA_PRINTF("add r%d, r%d, %lu\n", rd, rs0, uimm14); } else { - uint64_t sh = (inst >> 18) & 0x3; - uint64_t uimm8 = (inst >> 10) & 0xff; - int rs1 = (inst >> 5) & 0x1f; - - if (0 == sh) { - naja->regs[rd] = naja->regs[rs0] + (naja->regs[rs1] << uimm8); + uint64_t uimm9 = (inst >> 10) & 0x1ff; + int rs1 = (inst >> 5) & 0x1f; - NAJA_PRINTF("add r%d, r%d, r%d << %lu\n", rd, rs0, rs1, uimm8); + switch (SH) { + case 0: + naja->regs[rd] = naja->regs[rs0] + (naja->regs[rs1] << uimm9); - } else if (1 == sh) { - naja->regs[rd] = naja->regs[rs0] + (naja->regs[rs1] >> uimm8); + NAJA_PRINTF("add r%d, r%d, r%d << %lu\n", rd, rs0, rs1, uimm9); + break; - NAJA_PRINTF("add r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm8); + case 1: + naja->regs[rd] = naja->regs[rs0] + (naja->regs[rs1] >> uimm9); - } else { - naja->regs[rd] = naja->regs[rs0] + (((int64_t)naja->regs[rs1]) >> uimm8); + NAJA_PRINTF("add r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm9); + break; + default: + naja->regs[rd] = naja->regs[rs0] + (((int64_t)naja->regs[rs1]) >> uimm9); - NAJA_PRINTF("add r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm8); - } + NAJA_PRINTF("add r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm9); + break; + }; } naja->ip += 4; @@ -354,29 +358,19 @@ static int __naja_fsub(scf_vm_t* vm, uint32_t inst) naja->fvec[rd].d[0] = naja->fvec[rs0].d[0] - naja->fvec[rs1].d[0]; - NAJA_PRINTF("fsub r%d, r%d, r%d\n", rd, rs0, rs1); - - naja->ip += 4; - return 0; -} - -static int __naja_fcmp(scf_vm_t* vm, uint32_t inst) -{ - scf_vm_naja_t* naja = vm->priv; - - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; + if (31 == rd) { + double d = naja->fvec[rd].d[0]; - double d = naja->fvec[rs0].d[0] - naja->fvec[rs1].d[0]; - - NAJA_PRINTF("fcmp d%d, d%d\n", rs0, rs1); + if (d > 0.0) + naja->flags = 0x4; + else if (d < 0.0) + naja->flags = 0x2; + else + naja->flags = 0x1; - if (d > 0.0) - naja->flags = 0x4; - else if (d < 0.0) - naja->flags = 0x2; - else - naja->flags = 0x1; + NAJA_PRINTF("fcmp d%d, d%d\n", rs0, rs1); + } else + NAJA_PRINTF("fsub r%d, r%d, r%d\n", rd, rs0, rs1); naja->ip += 4; return 0; @@ -388,85 +382,49 @@ static int __naja_sub(scf_vm_t* vm, uint32_t inst) int rs0 = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int I = (inst >> 20) & 0x1; + int SH = (inst >> 19) & 0x3; - if (I) { - uint64_t uimm15 = (inst >> 5) & 0x7fff; + if (0x3 == SH) { + uint64_t uimm14 = (inst >> 5) & 0x3fff; - naja->regs[rd] = naja->regs[rs0] - uimm15; + naja->regs[rd] = naja->regs[rs0] - uimm14; - NAJA_PRINTF("sub r%d, r%d, %lu\n", rd, rs0, uimm15); + NAJA_PRINTF("sub r%d, r%d, %lu\n", rd, rs0, uimm14); } else { - uint64_t sh = (inst >> 18) & 0x3; - uint64_t uimm8 = (inst >> 10) & 0xff; - int rs1 = (inst >> 5) & 0x1f; - - if (0 == sh) { - naja->regs[rd] = naja->regs[rs0] - (naja->regs[rs1] << uimm8); + uint64_t uimm9 = (inst >> 10) & 0x1ff; + int rs1 = (inst >> 5) & 0x1f; - NAJA_PRINTF("sub r%d, r%d, r%d << %lu\n", rd, rs0, rs1, uimm8); + switch (SH) { + case 0: + naja->regs[rd] = naja->regs[rs0] - (naja->regs[rs1] << uimm9); - } else if (1 == sh) { - naja->regs[rd] = naja->regs[rs0] - (naja->regs[rs1] >> uimm8); + NAJA_PRINTF("sub r%d, r%d, r%d << %lu\n", rd, rs0, rs1, uimm9); + break; - NAJA_PRINTF("sub r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm8); + case 1: + naja->regs[rd] = naja->regs[rs0] - (naja->regs[rs1] >> uimm9); - } else { - naja->regs[rd] = naja->regs[rs0] - (((int64_t)naja->regs[rs1]) >> uimm8); + NAJA_PRINTF("sub r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm9); + break; + default: + naja->regs[rd] = naja->regs[rs0] - (((int64_t)naja->regs[rs1]) >> uimm9); - NAJA_PRINTF("sub r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm8); + NAJA_PRINTF("sub r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm9); + break; } } - naja->ip += 4; - return 0; -} - -static int __naja_cmp(scf_vm_t* vm, uint32_t inst) -{ - scf_vm_naja_t* naja = vm->priv; - - int rs0 = inst & 0x1f; - int I = (inst >> 20) & 0x1; - - int ret = 0; - - if (I) { - uint64_t uimm15 = (inst >> 5) & 0x7fff; - - ret = naja->regs[rs0] - uimm15; - - NAJA_PRINTF("cmp r%d, %ld, rs0: %lx, ret: %d\n", rs0, uimm15, naja->regs[rs0], ret); - - } else { - uint64_t sh = (inst >> 18) & 0x3; - uint64_t uimm8 = (inst >> 10) & 0xff; - int rs1 = (inst >> 5) & 0x1f; - - if (0 == sh) { - ret = naja->regs[rs0] - (naja->regs[rs1] << uimm8); + if (31 == rd) { // cmp + int ret = naja->regs[rd]; - NAJA_PRINTF("cmp r%d, r%d LSL %ld, rs0: %#lx, rs1: %#lx, ret: %d\n", rs0, rs1, uimm8, naja->regs[rs0], naja->regs[rs1], ret); - - } else if (1 == sh) { - ret = naja->regs[rs0] - (naja->regs[rs1] >> uimm8); - - NAJA_PRINTF("cmp r%d, r%d LSR %ld, rs0: %#lx, rs1: %#lx, ret: %d\n", rs0, rs1, uimm8, naja->regs[rs0], naja->regs[rs1], ret); - - } else { - ret = naja->regs[rs0] - (((int64_t)naja->regs[rs1]) >> uimm8); - - NAJA_PRINTF("cmp r%d, r%d ASR %ld, rs0: %#lx, rs1: %ld, ret: %d\n", rs0, rs1, uimm8, naja->regs[rs0], naja->regs[rs1], ret); - } + if (0 == ret) + naja->flags = 0x1; + else if (ret > 0) + naja->flags = 0x4; + else + naja->flags = 0x2; } - if (0 == ret) - naja->flags = 0x1; - else if (ret > 0) - naja->flags = 0x4; - else - naja->flags = 0x2; - naja->ip += 4; return 0; } @@ -479,8 +437,8 @@ static int __naja_mul(scf_vm_t* vm, uint32_t inst) int rs1 = (inst >> 5) & 0x1f; int rs2 = (inst >> 10) & 0x1f; int rd = (inst >> 21) & 0x1f; - int S = (inst >> 20) & 0x1; - int opt = (inst >> 15) & 0x3; + int S = (inst >> 18) & 0x1; + int opt = (inst >> 19) & 0x3; if (S) naja->regs[rd] = (int64_t)naja->regs[rs0] * (int64_t)naja->regs[rs1]; @@ -570,8 +528,8 @@ static int __naja_div(scf_vm_t* vm, uint32_t inst) int rs1 = (inst >> 5) & 0x1f; int rs2 = (inst >> 10) & 0x1f; int rd = (inst >> 21) & 0x1f; - int S = (inst >> 20) & 0x1; - int opt = (inst >> 15) & 0x3; + int S = (inst >> 18) & 0x1; + int opt = (inst >> 19) & 0x3; if (S) naja->regs[rd] = (int64_t)naja->regs[rs0] / (int64_t)naja->regs[rs1]; @@ -633,7 +591,7 @@ static int __naja_mem(scf_vm_t* vm, int64_t addr, uint8_t** pdata, int64_t* poff offset = addr - vm->data->addr; if (offset >= vm->data->len) { - scf_loge("\n"); + scf_loge("offset: %#lx, vm->data->len: %ld\n", offset, vm->data->len); return -1; } @@ -671,14 +629,13 @@ static int __naja_fstr_disp(scf_vm_t* vm, uint32_t inst) int rb = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int A = (inst >> 20) & 0x1; - int ext = (inst >> 17) & 0x7; - int s12 = (inst >> 5) & 0xfff; + int SH = (inst >> 19) & 0x3; + int s13 = (inst >> 5) & 0x1fff; - if (s12 & 0x800) - s12 |= 0xfffff000; + if (s13 & 0x1000) + s13 |= 0xffffe000; - scf_logd("rd: %d, rb: %d, s12: %d, ext: %d\n", rd, rb, s12, ext); + scf_logd("rd: %d, rb: %d, s13: %d, SH: %d\n", rd, rb, s13, SH); int64_t addr = naja->regs[rb]; int64_t offset = 0; @@ -688,47 +645,98 @@ static int __naja_fstr_disp(scf_vm_t* vm, uint32_t inst) if (ret < 0) return ret; - if (!A) - offset += s12 << (ext & 0x3); + offset += s13 << SH; if (data == naja->stack) { offset = -offset; - scf_logd("offset0: %ld, size: %ld\n", offset, naja->size); - assert(offset >= 0); + assert(offset > 0); if (naja->size < offset) { - scf_loge("offset: %ld, size: %ld\n", offset, naja->size); + scf_loge("offset0: %ld, size: %ld\n", offset, naja->size); return -EINVAL; } - offset -= 1 << (ext & 0x3); + offset -= 1 << SH; } - switch (ext) { + switch (SH) { + case 2: + *(float*)(data + offset) = naja->fvec[rd].d[0]; + + NAJA_PRINTF("fstr f%d, [r%d, %d]\n", rd, rb, s13 << 2); + break; + case 3: *(double*)(data + offset) = naja->fvec[rd].d[0]; - if (A) { - naja->regs[rb] += s12 << 3; - NAJA_PRINTF("fstr d%d, [r%d, %d]!, rd: %lg, rb: %ld, %p\n", rd, rb, s12 << 3, naja->fvec[rd].d[0], naja->regs[rb], data + offset); - } else - NAJA_PRINTF("fstr d%d, [r%d, %d]\n", rd, rb, s12 << 3); + + NAJA_PRINTF("fstr d%d, [r%d, %d]\n", rd, rb, s13 << 3); break; + default: + scf_loge("SH: %d\n", SH); + return -1; + break; + }; + + naja->ip += 4; + return 0; +} + +static int __naja_fpush(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rb = inst & 0x1f; + int rd = (inst >> 21) & 0x1f; + int SH = (inst >> 19) & 0x3; + + int64_t addr = naja->regs[rb]; + int64_t offset = 0; + uint8_t* data = NULL; + + int ret = __naja_mem(vm, addr, &data, &offset); + if (ret < 0) + return ret; + + if (data == naja->stack) { + offset = -offset; + + assert(offset >= 0); + + offset += 1 << SH; + + if (naja->size < offset) { + data = realloc(naja->stack, offset + STACK_INC); + if (!data) + return -ENOMEM; + + naja->stack = data; + naja->size = offset + STACK_INC; + } + + offset -= 1 << SH; + } - case 6: + switch (SH) { + case 2: *(float*)(data + offset) = naja->fvec[rd].d[0]; - if (A) { - naja->regs[rb] += s12 << 2; - NAJA_PRINTF("fstrf f%d, [r%d, %d]!\n", rd, rb, s12 << 2); - } else - NAJA_PRINTF("fstrf f%d, [r%d, %d]\n", rd, rb, s12 << 2); + + NAJA_PRINTF("fpush f%d, [r%d]\n", rd, rb); + break; + + case 3: + *(double*)(data + offset) = naja->fvec[rd].d[0]; + + NAJA_PRINTF("fpush d%d, [r%d]\n", rd, rb); break; default: - scf_loge("ext: %d\n", ext); + scf_loge("SH: %d\n", SH); return -1; break; }; + naja->regs[rb] -= 1 << SH; + naja->ip += 4; return 0; } @@ -739,14 +747,13 @@ static int __naja_fldr_disp(scf_vm_t* vm, uint32_t inst) int rb = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int A = (inst >> 20) & 0x1; - int ext = (inst >> 17) & 0x7; - int s12 = (inst >> 5) & 0xfff; + int SH = (inst >> 19) & 0x3; + int s13 = (inst >> 5) & 0x1fff; - if (s12 & 0x800) - s12 |= 0xfffff000; + if (s13 & 0x1000) + s13 |= 0xffffe000; - scf_logd("rd: %d, rb: %d, s12: %d, ext: %d\n", rd, rb, s12, ext); + scf_logd("rd: %d, rb: %d, s13: %d, SH: %d\n", rd, rb, s13, SH); int64_t addr = naja->regs[rb]; int64_t offset = 0; @@ -756,47 +763,94 @@ static int __naja_fldr_disp(scf_vm_t* vm, uint32_t inst) if (ret < 0) return ret; - if (!A) - offset += s12 << (ext & 0x3); + offset += s13 << SH; if (data == naja->stack) { offset = -offset; scf_logd("offset0: %ld, size: %ld\n", offset, naja->size); - assert(offset >= 0); + assert(offset > 0); if (naja->size < offset) { scf_loge("offset: %ld, size: %ld\n", offset, naja->size); return -EINVAL; } - offset -= 1 << (ext & 0x3); + offset -= 1 << SH; } - switch (ext) { + switch (SH) { + case 2: + naja->fvec[rd].d[0] = *(float*)(data + offset); + + NAJA_PRINTF("fldr f%d, [r%d, %d], rd: %lg, rb: %ld, %p\n", rd, rb, s13 << 2, naja->fvec[rd].d[0], naja->regs[rb], data + offset); + break; case 3: naja->fvec[rd].d[0] = *(double*)(data + offset); - if (A) { - naja->regs[rb] += s12 << 3; - NAJA_PRINTF("fldr d%d, [r%d, %d]!, rd: %lg, rb: %ld, %p\n", rd, rb, s12 << 3, naja->fvec[rd].d[0], naja->regs[rb], data + offset); - } else - NAJA_PRINTF("fldr d%d, [r%d, %d], rd: %lg, rb: %ld, %p\n", rd, rb, s12 << 3, naja->fvec[rd].d[0], naja->regs[rb], data + offset); + + NAJA_PRINTF("fldr d%d, [r%d, %d], rd: %lg, rb: %ld, %p\n", rd, rb, s13 << 3, naja->fvec[rd].d[0], naja->regs[rb], data + offset); + break; + default: + scf_loge("SH: %d\n", SH); + return -1; break; + }; + + naja->ip += 4; + return 0; +} + +static int __naja_fpop(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rb = inst & 0x1f; + int rd = (inst >> 21) & 0x1f; + int SH = (inst >> 19) & 0x3; + + scf_logd("rd: %d, rb: %d, SH: %d\n", rd, rb, SH); + + int64_t addr = naja->regs[rb]; + int64_t offset = 0; + uint8_t* data = NULL; + + int ret = __naja_mem(vm, addr, &data, &offset); + if (ret < 0) + return ret; + + if (data == naja->stack) { + offset = -offset; + + scf_logd("offset0: %ld, size: %ld\n", offset, naja->size); + assert(offset > 0); + + if (naja->size < offset) { + scf_loge("offset: %ld, size: %ld\n", offset, naja->size); + return -EINVAL; + } - case 6: + offset -= 1 << SH; + } + + switch (SH) { + case 2: naja->fvec[rd].d[0] = *(float*)(data + offset); - if (A) { - naja->regs[rb] += s12 << 2; - NAJA_PRINTF("fldrf f%d, [r%d, %d]!, rd: %lg, rb: %ld, %p\n", rd, rb, s12 << 2, naja->fvec[rd].d[0], naja->regs[rb], data + offset); - } else - NAJA_PRINTF("fldrf f%d, [r%d, %d], rd: %lg, rb: %ld, %p\n", rd, rb, s12 << 2, naja->fvec[rd].d[0], naja->regs[rb], data + offset); + + NAJA_PRINTF("fldr f%d, [r%d], rd: %lg, rb: %ld, %p\n", rd, rb, naja->fvec[rd].d[0], naja->regs[rb], data + offset); + break; + case 3: + naja->fvec[rd].d[0] = *(double*)(data + offset); + + NAJA_PRINTF("fldr d%d, [r%d], rd: %lg, rb: %ld, %p\n", rd, rb, naja->fvec[rd].d[0], naja->regs[rb], data + offset); break; default: - scf_loge("ext: %d\n", ext); + scf_loge("SH: %d\n", SH); return -1; break; }; + naja->regs[rb] += 1 << SH; + naja->ip += 4; return 0; } @@ -807,14 +861,14 @@ static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst) int rb = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int A = (inst >> 20) & 0x1; - int ext = (inst >> 17) & 0x7; - int s12 = (inst >> 5) & 0xfff; + int SH = (inst >> 19) & 0x3; + int s = (inst >> 18) & 0x1; + int s13 = (inst >> 5) & 0x1fff; - if (s12 & 0x800) - s12 |= 0xfffff000; + if (s13 & 0x1000) + s13 |= 0xffffe000; - scf_logd("rd: %d, rb: %d, s12: %d, ext: %d\n", rd, rb, s12, ext); + scf_logd("rd: %d, rb: %d, s13: %d, SH: %d\n", rd, rb, s13, SH); int64_t addr = naja->regs[rb]; int64_t offset = 0; @@ -824,8 +878,7 @@ static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst) if (ret < 0) return ret; - if (!A) - offset += s12 << (ext & 0x3); + offset += s13 << SH; if (data == naja->stack) { offset = -offset; @@ -838,78 +891,134 @@ static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst) return -EINVAL; } - offset -= 1 << (ext & 0x3); + offset -= 1 << SH; } - switch (ext) { + switch (SH) { case 0: - naja->regs[rd] = *(uint8_t*)(data + offset); - if (A) { - naja->regs[rb] += s12; - NAJA_PRINTF("ldrb r%d, [r%d, %d]!\n", rd, rb, s12); - } else - NAJA_PRINTF("ldrb r%d, [r%d, %d]\n", rd, rb, s12); + if (s) { + naja->regs[rd] = *(int8_t*)(data + offset); + + NAJA_PRINTF("ldrsb r%d, [r%d, %d]\n", rd, rb, s13); + } else { + naja->regs[rd] = *(uint8_t*)(data + offset); + + NAJA_PRINTF("ldrb r%d, [r%d, %d]\n", rd, rb, s13); + } break; case 1: - naja->regs[rd] = *(uint16_t*)(data + offset); - if (A) { - naja->regs[rb] += s12 << 1; - NAJA_PRINTF("ldrw r%d, [r%d, %d]!\n", rd, rb, s12 << 1); - } else - NAJA_PRINTF("ldrw r%d, [r%d, %d]\n", rd, rb, s12 << 1); + if (s) { + naja->regs[rd] = *(int16_t*)(data + offset); + + NAJA_PRINTF("ldrsw r%d, [r%d, %d]\n", rd, rb, s13 << 1); + } else { + naja->regs[rd] = *(uint16_t*)(data + offset); + + NAJA_PRINTF("ldrw r%d, [r%d, %d]\n", rd, rb, s13 << 1); + } break; case 2: - naja->regs[rd] = *(uint32_t*)(data + offset); - if (A) { - naja->regs[rb] += s12 << 2; - NAJA_PRINTF("ldrl r%d, [r%d, %d]!\n", rd, rb, s12 << 2); - } else - NAJA_PRINTF("ldrl r%d, [r%d, %d], %ld, %p\n", rd, rb, s12 << 2, naja->regs[rd], data + offset); + if (s) { + naja->regs[rd] = *(int32_t*)(data + offset); + + NAJA_PRINTF("ldrsl r%d, [r%d, %d]\n", rd, rb, s13 << 2); + } else { + naja->regs[rd] = *(uint32_t*)(data + offset); + + NAJA_PRINTF("ldrl r%d, [r%d, %d], %ld, %p\n", rd, rb, s13 << 2, naja->regs[rd], data + offset); + } break; - case 3: + default: naja->regs[rd] = *(uint64_t*)(data + offset); - if (A) { - naja->regs[rb] += s12 << 3; - NAJA_PRINTF("ldr r%d, [r%d, %d]!, rd: %#lx, rb: %ld, %p\n", rd, rb, s12 << 3, naja->regs[rd], naja->regs[rb], data + offset); - } else - NAJA_PRINTF("ldr r%d, [r%d, %d]\n", rd, rb, s12 << 3); + + NAJA_PRINTF("ldr r%d, [r%d, %d]\n", rd, rb, s13 << 3); break; + }; + + naja->ip += 4; + return 0; +} + +static int __naja_pop(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rb = inst & 0x1f; + int rd = (inst >> 21) & 0x1f; + int SH = (inst >> 19) & 0x3; + int s = (inst >> 18) & 0x1; - case 4: - naja->regs[rd] = *(int8_t*)(data + offset); - if (A) { - naja->regs[rb] += s12; - NAJA_PRINTF("ldrsb r%d, [r%d, %d]!\n", rd, rb, s12); - } else - NAJA_PRINTF("ldrsb r%d, [r%d, %d]\n", rd, rb, s12); + int64_t addr = naja->regs[rb]; + int64_t offset = 0; + uint8_t* data = NULL; + + int ret = __naja_mem(vm, addr, &data, &offset); + if (ret < 0) + return ret; + + if (data == naja->stack) { + offset = -offset; + + scf_logd("offset0: %ld, size: %ld\n", offset, naja->size); + assert(offset > 0); + + if (naja->size < offset) { + scf_loge("offset: %ld, size: %ld\n", offset, naja->size); + return -EINVAL; + } + + offset -= 1 << SH; + } + + switch (SH) { + case 0: + if (s) { + naja->regs[rd] = *(int8_t*)(data + offset); + + NAJA_PRINTF("popsb r%d, [r%d]\n", rd, rb); + } else { + naja->regs[rd] = *(uint8_t*)(data + offset); + + NAJA_PRINTF("popb r%d, [r%d]\n", rd, rb); + } break; - case 5: - naja->regs[rd] = *(int16_t*)(data + offset); - if (A) { - naja->regs[rb] += s12 << 1; - NAJA_PRINTF("ldrsw r%d, [r%d, %d]!\n", rd, rb, s12 << 1); - } else - NAJA_PRINTF("ldrsw r%d, [r%d, %d]\n", rd, rb, s12 << 1); + case 1: + if (s) { + naja->regs[rd] = *(int16_t*)(data + offset); + + NAJA_PRINTF("popsw r%d, [r%d]\n", rd, rb); + } else { + naja->regs[rd] = *(uint16_t*)(data + offset); + + NAJA_PRINTF("popw r%d, [r%d]\n", rd, rb); + } break; - case 6: - naja->regs[rd] = *(int32_t*)(data + offset); - if (A) { - naja->regs[rb] += s12 << 2; - NAJA_PRINTF("ldrsl r%d, [r%d, %d]!\n", rd, rb, s12 << 2); - } else - NAJA_PRINTF("ldrsl r%d, [r%d, %d]\n", rd, rb, s12 << 2); + case 2: + if (s) { + naja->regs[rd] = *(int32_t*)(data + offset); + + NAJA_PRINTF("popsl r%d, [r%d]\n", rd, rb); + } else { + naja->regs[rd] = *(uint32_t*)(data + offset); + + NAJA_PRINTF("popl r%d, [r%d], %ld, %p\n", rd, rb, naja->regs[rd], data + offset); + } break; + default: - scf_loge("\n"); - return -1; + naja->regs[rd] = *(uint64_t*)(data + offset); + + NAJA_PRINTF("popq r%d, [r%d]\n", rd, rb); break; }; + naja->regs[rb] += 1 << SH; + naja->ip += 4; return 0; } @@ -921,8 +1030,9 @@ static int __naja_ldr_sib(scf_vm_t* vm, uint32_t inst) int rb = inst & 0x1f; int ri = (inst >> 5) & 0x1f; int rd = (inst >> 21) & 0x1f; - int ext = (inst >> 17) & 0x7; - int u7 = (inst >> 10) & 0x7f; + int SH = (inst >> 19) & 0x3; + int s = (inst >> 18) & 0x1; + int u8 = (inst >> 10) & 0xff; int64_t addr = naja->regs[rb]; int64_t offset = 0; @@ -932,7 +1042,7 @@ static int __naja_ldr_sib(scf_vm_t* vm, uint32_t inst) if (ret < 0) return ret; - offset += (naja->regs[ri] << u7); + offset += (naja->regs[ri] << u8); if (data == naja->stack) { offset = -offset; @@ -944,50 +1054,100 @@ static int __naja_ldr_sib(scf_vm_t* vm, uint32_t inst) return -1; } - offset -= 1 << (ext & 0x3); + offset -= 1 << SH; } - switch (ext) { + switch (SH) { case 0: - NAJA_PRINTF("ldrb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + if (s) { + NAJA_PRINTF("ldrsb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + + naja->regs[rd] = *(int8_t*)(data + offset); + } else { + NAJA_PRINTF("ldrb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - naja->regs[rd] = *(uint8_t*)(data + offset); + naja->regs[rd] = *(uint8_t*)(data + offset); + } break; case 1: - NAJA_PRINTF("ldrw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + if (s) { + NAJA_PRINTF("ldrsw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + + naja->regs[rd] = *(int16_t*)(data + offset); + } else { + NAJA_PRINTF("ldrw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - naja->regs[rd] = *(uint16_t*)(data + offset); + naja->regs[rd] = *(uint16_t*)(data + offset); + } break; case 2: - NAJA_PRINTF("ldrl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + if (s) { + NAJA_PRINTF("ldrsl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - naja->regs[rd] = *(uint32_t*)(data + offset); - break; + naja->regs[rd] = *(int32_t*)(data + offset); + } else { + NAJA_PRINTF("ldrl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - case 3: - NAJA_PRINTF("ldr r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + naja->regs[rd] = *(uint32_t*)(data + offset); + } + break; + default: + NAJA_PRINTF("ldr r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); naja->regs[rd] = *(uint64_t*)(data + offset); break; + }; - case 4: - NAJA_PRINTF("ldrsb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + naja->ip += 4; + return 0; +} - naja->regs[rd] = *(int8_t*)(data + offset); - break; +static int __naja_fldr_sib(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rb = inst & 0x1f; + int ri = (inst >> 5) & 0x1f; + int rd = (inst >> 21) & 0x1f; + int SH = (inst >> 19) & 0x3; + int u8 = (inst >> 10) & 0xff; + + int64_t addr = naja->regs[rb]; + int64_t offset = 0; + uint8_t* data = NULL; + + int ret = __naja_mem(vm, addr, &data, &offset); + if (ret < 0) + return ret; + + offset += naja->regs[ri] << u8; + + if (data == naja->stack) { + offset = -offset; + + assert(offset > 0); - case 5: - NAJA_PRINTF("ldrsw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + if (naja->size < offset) { + scf_loge("\n"); + return -1; + } + + offset -= 1 << SH; + } - naja->regs[rd] = *(int16_t*)(data + offset); + switch (SH) { + case 2: + NAJA_PRINTF("fldr f%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + + naja->fvec[rd].d[0] = *(float*)(data + offset); break; - case 6: - NAJA_PRINTF("ldrsl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + case 3: + NAJA_PRINTF("fldr d%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - naja->regs[rd] = *(int32_t*)(data + offset); + naja->fvec[rd].d[0] = *(double*)(data + offset); break; default: scf_loge("\n"); @@ -999,15 +1159,15 @@ static int __naja_ldr_sib(scf_vm_t* vm, uint32_t inst) return 0; } -static int __naja_fldr_sib(scf_vm_t* vm, uint32_t inst) +static int __naja_fstr_sib(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; int rb = inst & 0x1f; int ri = (inst >> 5) & 0x1f; int rd = (inst >> 21) & 0x1f; - int ext = (inst >> 17) & 0x7; - int u7 = (inst >> 10) & 0x7f; + int SH = (inst >> 19) & 0x3; + int u8 = (inst >> 10) & 0xff; int64_t addr = naja->regs[rb]; int64_t offset = 0; @@ -1017,32 +1177,32 @@ static int __naja_fldr_sib(scf_vm_t* vm, uint32_t inst) if (ret < 0) return ret; - offset += (naja->regs[ri] << u7); + offset += naja->regs[ri] << u8; if (data == naja->stack) { offset = -offset; - assert(offset >= 0); + assert(offset > 0); if (naja->size < offset) { scf_loge("\n"); return -1; } - offset -= 1 << (ext & 0x3); + offset -= 1 << SH; } - switch (ext) { - case 3: - NAJA_PRINTF("fldr d%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + switch (SH) { + case 2: + NAJA_PRINTF("fstr f%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - naja->fvec[rd].d[0] = *(double*)(data + offset); + *(float*)(data + offset) = naja->fvec[rd].d[0]; break; - case 6: - NAJA_PRINTF("fldrf f%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + case 3: + NAJA_PRINTF("fstr d%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); - naja->fvec[rd].d[0] = *(float*)(data + offset); + *(double*)(data + offset) = naja->fvec[rd].d[0]; break; default: scf_loge("\n"); @@ -1054,15 +1214,17 @@ static int __naja_fldr_sib(scf_vm_t* vm, uint32_t inst) return 0; } -static int __naja_fstr_sib(scf_vm_t* vm, uint32_t inst) +static int __naja_str_disp(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; int rb = inst & 0x1f; - int ri = (inst >> 5) & 0x1f; int rd = (inst >> 21) & 0x1f; - int ext = (inst >> 17) & 0x3; - int u7 = (inst >> 10) & 0x7f; + int SH = (inst >> 19) & 0x3; + int s13 = (inst >> 5) & 0x1fff; + + if (s13 & 0x1000) + s13 |= 0xffffe000; int64_t addr = naja->regs[rb]; int64_t offset = 0; @@ -1072,36 +1234,44 @@ static int __naja_fstr_sib(scf_vm_t* vm, uint32_t inst) if (ret < 0) return ret; - offset += naja->regs[ri] << u7; + offset += s13 << SH; if (data == naja->stack) { offset = -offset; - assert(offset >= 0); + assert(offset > 0); if (naja->size < offset) { - scf_loge("\n"); - return -1; + scf_loge("offset0: %ld, size: %ld\n", offset, naja->size); + return -EINVAL; } - offset -= 1 << ext; + offset -= 1 << SH; } - switch (ext) { - case 3: - NAJA_PRINTF("fstr d%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + switch (SH) { + case 0: + *(uint8_t*)(data + offset) = naja->regs[rd]; - *(double*)(data + offset) = naja->fvec[rd].d[0]; + NAJA_PRINTF("strb r%d, [r%d, %d]\n", rd, rb, s13); break; - case 6: - NAJA_PRINTF("fldrf f%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + case 1: + *(uint16_t*)(data + offset) = naja->regs[rd]; - *(float*)(data + offset) = naja->fvec[rd].d[0]; + NAJA_PRINTF("strw r%d, [r%d, %d]\n", rd, rb, s13 << 1); break; + + case 2: + *(uint32_t*)(data + offset) = naja->regs[rd]; + + NAJA_PRINTF("strl r%d, [r%d, %d], s13: %d, %d, %p\n", rd, rb, s13 << 2, s13, *(uint32_t*)(data + offset), data + offset); + break; + default: - scf_loge("\n"); - return -1; + *(uint64_t*)(data + offset) = naja->regs[rd]; + + NAJA_PRINTF("str r%d, [r%d, %d]\n", rd, rb, s13 << 3); break; }; @@ -1109,18 +1279,13 @@ static int __naja_fstr_sib(scf_vm_t* vm, uint32_t inst) return 0; } -static int __naja_str_disp(scf_vm_t* vm, uint32_t inst) +static int __naja_push(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; int rb = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int A = (inst >> 20) & 0x1; - int ext = (inst >> 17) & 0x3; - int s12 = (inst >> 5) & 0xfff; - - if (s12 & 0x800) - s12 |= 0xfffff000; + int SH = (inst >> 19) & 0x3; int64_t addr = naja->regs[rb]; int64_t offset = 0; @@ -1130,14 +1295,14 @@ static int __naja_str_disp(scf_vm_t* vm, uint32_t inst) if (ret < 0) return ret; - offset += s12 << ext; - if (data == naja->stack) { offset = -offset; scf_logd("offset0: %ld, size: %ld\n", offset, naja->size); - assert(offset > 0); + assert(offset >= 0); + + offset += 1 << SH; if (naja->size < offset) { data = realloc(naja->stack, offset + STACK_INC); @@ -1148,52 +1313,37 @@ static int __naja_str_disp(scf_vm_t* vm, uint32_t inst) naja->size = offset + STACK_INC; } - offset -= 1 << ext; + offset -= 1 << SH; } - switch (ext) { + switch (SH) { case 0: *(uint8_t*)(data + offset) = naja->regs[rd]; - if (A) { - naja->regs[rb] += s12; - NAJA_PRINTF("strb r%d, [r%d, %d]!\n", rd, rb, s12); - } else - NAJA_PRINTF("strb r%d, [r%d, %d]\n", rd, rb, s12); + + NAJA_PRINTF("pushb r%d, [r%d]\n", rd, rb); break; case 1: *(uint16_t*)(data + offset) = naja->regs[rd]; - if (A) { - naja->regs[rb] += s12 << 1; - NAJA_PRINTF("strw r%d, [r%d, %d]!\n", rd, rb, s12 << 1); - } else - NAJA_PRINTF("strw r%d, [r%d, %d]\n", rd, rb, s12 << 1); + + NAJA_PRINTF("pushw r%d, [r%d]\n", rd, rb); break; case 2: *(uint32_t*)(data + offset) = naja->regs[rd]; - if (A) { - naja->regs[rb] += s12 << 2; - NAJA_PRINTF("strl r%d, [r%d, %d]!, s12: %d\n", rd, rb, s12 << 2, s12); - } else - NAJA_PRINTF("strl r%d, [r%d, %d], s12: %d, %d, %p\n", rd, rb, s12 << 2, s12, *(uint32_t*)(data + offset), data + offset); - break; - case 3: - *(uint64_t*)(data + offset) = naja->regs[rd]; - if (A) { - naja->regs[rb] += s12 << 3; - NAJA_PRINTF("str r%d, [r%d, %d]!, rd: %#lx, rb: %ld, %p\n", rd, rb, s12 << 3, naja->regs[rd], naja->regs[rb], data + offset); - } else - NAJA_PRINTF("str r%d, [r%d, %d]\n", rd, rb, s12 << 3); + NAJA_PRINTF("pushl r%d, [r%d], %d, %p\n", rd, rb, *(uint32_t*)(data + offset), data + offset); break; default: - scf_loge("\n"); - return -1; + *(uint64_t*)(data + offset) = naja->regs[rd]; + + NAJA_PRINTF("pushq r%d, [r%d]\n", rd, rb); break; }; + naja->regs[rb] -= 1 << SH; + naja->ip += 4; return 0; } @@ -1205,8 +1355,8 @@ static int __naja_str_sib(scf_vm_t* vm, uint32_t inst) int rb = inst & 0x1f; int ri = (inst >> 5) & 0x1f; int rd = (inst >> 21) & 0x1f; - int ext = (inst >> 17) & 0x3; - int u7 = (inst >> 10) & 0x7f; + int SH = (inst >> 19) & 0x3; + int u8 = (inst >> 10) & 0xff; int64_t addr = naja->regs[rb]; int64_t offset = 0; @@ -1216,7 +1366,7 @@ static int __naja_str_sib(scf_vm_t* vm, uint32_t inst) if (ret < 0) return ret; - offset += naja->regs[ri] << u7; + offset += naja->regs[ri] << u8; if (data == naja->stack) { offset = -offset; @@ -1228,38 +1378,33 @@ static int __naja_str_sib(scf_vm_t* vm, uint32_t inst) return -1; } - offset -= 1 << ext; + offset -= 1 << SH; } - switch (ext) { + switch (SH) { case 0: - NAJA_PRINTF("strb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + NAJA_PRINTF("strb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); *(uint8_t*)(data + offset) = naja->regs[rd]; break; case 1: - NAJA_PRINTF("strw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + NAJA_PRINTF("strw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); *(uint16_t*)(data + offset) = naja->regs[rd]; break; case 2: - NAJA_PRINTF("strl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + NAJA_PRINTF("strl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); *(uint32_t*)(data + offset) = naja->regs[rd]; break; - case 3: - NAJA_PRINTF("str r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + default: + NAJA_PRINTF("str r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); *(uint64_t*)(data + offset) = naja->regs[rd]; break; - - default: - scf_loge("\n"); - return -1; - break; }; naja->ip += 4; @@ -1272,57 +1417,26 @@ static int __naja_and(scf_vm_t* vm, uint32_t inst) int rs0 = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int I = (inst >> 20) & 0x1; + int SH = (inst >> 19) & 0x3; - scf_logw("\n"); - if (I) { - uint64_t uimm15 = (inst >> 5) & 0x7fff; + if (0x3 == SH) { + uint64_t uimm14 = (inst >> 5) & 0x3fff; - naja->regs[rd] = naja->regs[rs0] & uimm15; + naja->regs[rd] = naja->regs[rs0] & uimm14; } else { - uint64_t sh = (inst >> 18) & 0x3; - uint64_t uimm8 = (inst >> 10) & 0xff; - uint64_t rs1 = (inst >> 5) & 0x1f; - - if (0 == sh) - naja->regs[rd] = naja->regs[rs0] & (naja->regs[rs1] << uimm8); - else if (1 == sh) - naja->regs[rd] = naja->regs[rs0] & (naja->regs[rs1] >> uimm8); - else - naja->regs[rd] = naja->regs[rs0] & (((int64_t)naja->regs[rs1]) >> uimm8); - } - - naja->ip += 4; - return 0; -} + uint64_t uimm9 = (inst >> 10) & 0x1ff; + int rs1 = (inst >> 5) & 0x1f; -static int __naja_teq(scf_vm_t* vm, uint32_t inst) -{ - scf_vm_naja_t* naja = vm->priv; - - scf_logw("\n"); - int rs0 = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int I = (inst >> 20) & 0x1; - - if (I) { - uint64_t uimm15 = (inst >> 5) & 0x7fff; - - naja->flags = naja->regs[rs0] & uimm15; - } else { - uint64_t sh = (inst >> 18) & 0x3; - uint64_t uimm8 = (inst >> 10) & 0xff; - uint64_t rs1 = (inst >> 5) & 0x1f; - - if (0 == sh) - naja->flags = naja->regs[rs0] & (naja->regs[rs1] << uimm8); - else if (1 == sh) - naja->flags = naja->regs[rs0] & (naja->regs[rs1] >> uimm8); + if (0 == SH) + naja->regs[rd] = naja->regs[rs0] & (naja->regs[rs1] << uimm9); + else if (1 == SH) + naja->regs[rd] = naja->regs[rs0] & (naja->regs[rs1] >> uimm9); else - naja->flags = naja->regs[rs0] & (((int64_t)naja->regs[rs1]) >> uimm8); + naja->regs[rd] = naja->regs[rs0] & (((int64_t)naja->regs[rs1]) >> uimm9); } - naja->flags = !naja->flags; + if (31 == rd) + naja->flags = !naja->regs[rd]; naja->ip += 4; return 0; @@ -1334,24 +1448,22 @@ static int __naja_or(scf_vm_t* vm, uint32_t inst) int rs0 = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int I = (inst >> 20) & 0x1; + int SH = (inst >> 19) & 0x3; - scf_logw("\n"); - if (I) { - uint64_t uimm15 = (inst >> 5) & 0x7fff; + if (0x3 == SH) { + uint64_t uimm14 = (inst >> 5) & 0x3fff; - naja->regs[rd] = naja->regs[rs0] | uimm15; + naja->regs[rd] = naja->regs[rs0] | uimm14; } else { - uint64_t sh = (inst >> 18) & 0x3; - uint64_t uimm8 = (inst >> 10) & 0xff; - uint64_t rs1 = (inst >> 5) & 0x1f; - - if (0 == sh) - naja->regs[rd] = naja->regs[rs0] | (naja->regs[rs1] << uimm8); - else if (1 == sh) - naja->regs[rd] = naja->regs[rs0] | (naja->regs[rs1] >> uimm8); + uint64_t uimm9 = (inst >> 10) & 0x1ff; + int rs1 = (inst >> 5) & 0x1f; + + if (0 == SH) + naja->regs[rd] = naja->regs[rs0] | (naja->regs[rs1] << uimm9); + else if (1 == SH) + naja->regs[rd] = naja->regs[rs0] | (naja->regs[rs1] >> uimm9); else - naja->regs[rd] = naja->regs[rs0] | (((int64_t)naja->regs[rs1]) >> uimm8); + naja->regs[rd] = naja->regs[rs0] | (((int64_t)naja->regs[rs1]) >> uimm9); } naja->ip += 4; @@ -1544,7 +1656,7 @@ static int __naja_adrp(scf_vm_t* vm, uint32_t inst) if (s21 & 0x100000) s21 |= ~0x1fffff; - naja->regs[rd] = (naja->ip + ((int64_t)s21 << 15)) & ~0x7fffULL; + naja->regs[rd] = (naja->ip + ((int64_t)s21 << 14)) & ~0x3fffULL; if (naja->regs[rd] >= 0x800000) naja->regs[rd] = naja->regs[rd] - vm->data->addr + (uint64_t)vm->data->data; @@ -1591,7 +1703,7 @@ static int __naja_setcc(scf_vm_t* vm, uint32_t inst) scf_vm_naja_t* naja = vm->priv; int rd = (inst >> 21) & 0x1f; - int cc = (inst >> 17) & 0xf; + int cc = (inst >> 1) & 0xf; naja->regs[rd] = 0 == (cc & naja->flags); @@ -1626,125 +1738,119 @@ static int __naja_mov(scf_vm_t* vm, uint32_t inst) scf_vm_naja_t* naja = vm->priv; int rd = (inst >> 21) & 0x1f; - int I = (inst >> 20) & 0x1; - int X = (inst >> 19) & 0x1; - int opt = (inst >> 16) & 0x7; + int SH = (inst >> 19) & 0x3; + int s = (inst >> 18) & 0x1; + int opt = (inst >> 16) & 0x3; - if (I) { - if (0 == opt) { - naja->regs[rd] = inst & 0xffff; + if (0 == opt) { + int rs0 = inst & 0x1f; + int rs1 = (inst >> 5) & 0x1f; - if (X && (inst & 0x8000)) { - naja->regs[rd] |= ~0xffffULL; - NAJA_PRINTF("movsb r%d, %d\n", rd, inst & 0xffff); - } else { - NAJA_PRINTF("mov r%d, %d\n", rd, inst & 0xffff); - } + if (0 == SH) { + naja->regs[rd] = naja->regs[rs0] << naja->regs[rs1]; - } else if (1 == opt) { - naja->regs[rd] |= (inst & 0xffffULL) << 16; + NAJA_PRINTF("mov r%d, r%d LSL r%d\n", rd, rs0, rs1); - NAJA_PRINTF("mov r%d, %d << 16\n", rd, inst & 0xffff); + } else if (1 == SH) { + naja->regs[rd] = naja->regs[rs0] >> naja->regs[rs1]; - } else if (2 == opt) { - naja->regs[rd] |= (inst & 0xffffULL) << 32; + NAJA_PRINTF("mov r%d, r%d LSR r%d\n", rd, rs0, rs1); + } else { + naja->regs[rd] = (int64_t)naja->regs[rs0] >> naja->regs[rs1]; - NAJA_PRINTF("mov r%d, %d << 32\n", rd, inst & 0xffff); + NAJA_PRINTF("mov r%d, r%d ASR r%d\n", rd, rs0, rs1); + } - } else if (3 == opt) { - naja->regs[rd] |= (inst & 0xffffULL) << 48; + } else if (1 == opt) { + int rs0 = inst & 0x1f; + int u11 = (inst >> 5) & 0x7ff; - NAJA_PRINTF("mov r%d, %d << 48\n", rd, inst & 0xffff); + if (0 == SH) { + naja->regs[rd] = naja->regs[rs0] << u11; - } else if (7 == opt) { - naja->regs[rd] = ~(inst & 0xffffULL); + if (0 == u11) + NAJA_PRINTF("mov r%d, r%d\n", rd, rs0); + else + NAJA_PRINTF("mov r%d, r%d LSL %d\n", rd, rs0, u11); - NAJA_PRINTF("mvn r%d, %d\n", rd, inst & 0xffff); - } + } else if (1 == SH) { + naja->regs[rd] = naja->regs[rs0] >> u11; - } else { - int rs = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; - int u11 = (inst >> 5) & 0x7ff; + NAJA_PRINTF("mov r%d, r%d LSR %d\n", rd, rs0, u11); + } else { + naja->regs[rd] = (int64_t)naja->regs[rs0] >> u11; - if (0 == opt) { - if (X) { - NAJA_PRINTF("mov r%d, r%d LSL r%d\n", rd, rs, rs1); + NAJA_PRINTF("mov r%d, r%d ASR %d\n", rd, rs0, u11); + } - naja->regs[rd] = naja->regs[rs] << naja->regs[rs1]; - } else { - naja->regs[rd] = naja->regs[rs] << u11; + } else if (2 == opt) { + int rs = inst & 0x1f; - if (0 == u11) - NAJA_PRINTF("mov r%d, r%d\n", rd, rs); - else - NAJA_PRINTF("mov r%d, r%d LSL %d\n", rd, rs, u11); - } + switch (SH) { + case 0: + if (s) { + NAJA_PRINTF("movsb r%d, r%d\n", rd, rs); - } else if (1 == opt) { - if (X) { - NAJA_PRINTF("mov r%d, r%d LSR r%d\n", rd, rs, rs1); + naja->regs[rd] = (int8_t)naja->regs[rs]; + } else { + naja->regs[rd] = (uint8_t)naja->regs[rs]; - naja->regs[rd] = naja->regs[rs] >> naja->regs[rs1]; - } else { - naja->regs[rd] = naja->regs[rs] >> u11; + NAJA_PRINTF("movzb r%d, r%d\n", rd, rs); + } + break; - if (0 == u11) - NAJA_PRINTF("mov r%d, r%d\n", rd, rs); - else - NAJA_PRINTF("mov r%d, r%d LSR %d\n", rd, rs, u11); - } - } else if (2 == opt) { - if (X) { - NAJA_PRINTF("mov r%d, r%d ASR r%d\n", rd, rs, rs1); + case 1: + if (s) { + NAJA_PRINTF("movsw r%d, r%d\n", rd, rs); - naja->regs[rd] = (int64_t)naja->regs[rs] >> naja->regs[rs1]; - } else { - naja->regs[rd] = (int64_t)naja->regs[rs] >> u11; + naja->regs[rd] = (int16_t)naja->regs[rs]; + } else { + naja->regs[rd] = (uint16_t)naja->regs[rs]; - if (0 == u11) - NAJA_PRINTF("mov r%d, r%d\n", rd, rs); - else - NAJA_PRINTF("mov r%d, r%d ASR %d\n", rd, rs, u11); - } - } else if (3 == opt) { - NAJA_PRINTF("NOT r%d, r%d\n", rd, rs); + NAJA_PRINTF("movzw r%d, r%d\n", rd, rs); + } + break; - naja->regs[rd] = ~naja->regs[rs]; - } else if (4 == opt) { - naja->regs[rd] = -naja->regs[rs]; + case 2: + if (s) { + NAJA_PRINTF("movsl r%d, r%d\n", rd, rs); - NAJA_PRINTF("NEG r%d, r%d\n", rd, rs); + naja->regs[rd] = (int32_t)naja->regs[rs]; + } else { + naja->regs[rd] = (uint32_t)naja->regs[rs]; - } else if (5 == opt) { - if (X) { - NAJA_PRINTF("movsb r%d, r%d\n", rd, rs); + NAJA_PRINTF("movzl r%d, r%d\n", rd, rs); + } + break; + default: + if (s) { + NAJA_PRINTF("NEG r%d, r%d\n", rd, rs); - naja->regs[rd] = (int8_t)naja->regs[rs]; - } else { - naja->regs[rd] = (uint8_t)naja->regs[rs]; + naja->regs[rd] = -naja->regs[rs]; + } else { + naja->regs[rd] = ~naja->regs[rs]; - NAJA_PRINTF("movzb r%d, r%d\n", rd, rs); - } - } else if (6 == opt) { - if (X) { - NAJA_PRINTF("movsw r%d, r%d\n", rd, rs); + NAJA_PRINTF("NOT r%d, r%d\n", rd, rs); + } + break; + }; - naja->regs[rd] = (int16_t)naja->regs[rs]; - } else { - naja->regs[rd] = (uint16_t)naja->regs[rs]; + } else { + uint64_t u16 = inst & 0xffff; - NAJA_PRINTF("movzw r%d, r%d\n", rd, rs); - } - } else if (7 == opt) { - if (X) { - NAJA_PRINTF("movsl r%d, r%d\n", rd, rs); + if (s) { + naja->regs[rd] = ~u16; - naja->regs[rd] = (int32_t)naja->regs[rs]; + NAJA_PRINTF("mvn r%d, %#lx\n", rd, u16); + } else { + if (0 == SH) { + NAJA_PRINTF("mov r%d, %#lx\n", rd, u16); + + naja->regs[rd] = u16; } else { - naja->regs[rd] = (uint32_t)naja->regs[rs]; + naja->regs[rd] |= u16 << SH; - NAJA_PRINTF("movzl r%d, r%d\n", rd, rs); + NAJA_PRINTF("mov r%d, %#lx << %d\n", rd, u16, 16 << SH); } } } @@ -1759,70 +1865,52 @@ static int __naja_fmov(scf_vm_t* vm, uint32_t inst) int rs = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int opt = (inst >> 16) & 0xf; + int SH = (inst >> 19) & 0x3; + int s = (inst >> 18) & 0x1; + int opt = (inst >> 16) & 0x3; if (0 == opt) { - naja->fvec[rd].d[0] = naja->fvec[rs].d[0]; - - NAJA_PRINTF("fmov d%d, d%d\n", rd, rs); - - } else if (1 == opt) { - naja->fvec[rd].d[0] = naja->fvec[rs].d[0]; - - NAJA_PRINTF("fss2sd d%d, f%d\n", rd, rs); - - } else if (2 == opt) { - naja->fvec[rd].d[0] = naja->fvec[rs].d[0]; - - NAJA_PRINTF("fsd2ss d%d, f%d\n", rd, rs); + if (2 == SH) { + naja->fvec[rd].d[0] = naja->fvec[rs].d[0]; - } else if (3 == opt) { - naja->fvec[rd].d[0] = -naja->fvec[rs].d[0]; + NAJA_PRINTF("fss2sd d%d, f%d\n", rd, rs); - NAJA_PRINTF("fneg d%d, d%d\n", rd, rs); + } else if (3 == SH) { + naja->fvec[rd].d[0] = naja->fvec[rs].d[0]; - } else if (4 == opt) { - naja->regs[rd] = (int64_t)naja->fvec[rs].d[0]; - - NAJA_PRINTF("cvtss2si r%d, f%d\n", rd, rs); - - } else if (5 == opt) { - naja->regs[rd] = (int64_t)naja->fvec[rs].d[0]; - - NAJA_PRINTF("cvtsd2si r%d, d%d\n", rd, rs); + NAJA_PRINTF("fsd2ss f%d, d%d\n", rd, rs); + } else { + scf_loge("\n"); + return -EINVAL; + } - } else if (6 == opt) { - naja->regs[rd] = (uint64_t)naja->fvec[rs].d[0]; + } else if (1 == opt) { + if (s) { + naja->regs[rd] = (int64_t)naja->fvec[rs].d[0]; - NAJA_PRINTF("cvtss2ui r%d, f%d\n", rd, rs); + NAJA_PRINTF("cvtss2si r%d, f%d\n", rd, rs); + } else { + naja->regs[rd] = (uint64_t)naja->fvec[rs].d[0]; - } else if (7 == opt) { - naja->regs[rd] = (uint64_t)naja->fvec[rs].d[0]; + NAJA_PRINTF("cvtss2ui r%d, f%d\n", rd, rs); + } - NAJA_PRINTF("cvtsd2ui r%d, d%d\n", rd, rs); + } else if (2 == opt) { - } else if (0xc == opt) { naja->fvec[rd].d[0] = (double)naja->regs[rs]; NAJA_PRINTF("cvtsi2ss f%d, r%d\n", rd, rs); - } else if (0xd == opt) { - naja->fvec[rd].d[0] = (double)naja->regs[rs]; - - NAJA_PRINTF("cvtsi2sd d%d, r%d\n", rd, rs); - - } else if (0xe == opt) { - naja->fvec[rd].d[0] = (double)naja->regs[rs]; - - NAJA_PRINTF("cvtui2ss f%d, r%d\n", rd, rs); + } else { + if (s) { + NAJA_PRINTF("fneg d%d, d%d\n", rd, rs); - } else if (0xf == opt) { - naja->fvec[rd].d[0] = (double)naja->regs[rs]; + naja->fvec[rd].d[0] = -naja->fvec[rs].d[0]; + } else { + naja->fvec[rd].d[0] = naja->fvec[rs].d[0]; - NAJA_PRINTF("cvtui2sd f%d, r%d\n", rd, rs); - } else { - scf_loge("\n"); - return -EINVAL; + NAJA_PRINTF("fmov d%d, d%d\n", rd, rs); + } } naja->ip += 4; @@ -1835,69 +1923,75 @@ static naja_opcode_pt naja_opcodes[64] = __naja_sub, // 1 __naja_mul, // 2 __naja_div, // 3 + __naja_ldr_disp, // 4 - __naja_str_disp, // 5 - __naja_and, // 6 - __naja_or, // 7 - __naja_jmp_disp, // 8 - __naja_cmp, // 9 - __naja_jmp_reg, //10 - __naja_setcc, //11 - __naja_ldr_sib, //12 - __naja_str_sib, //13 - __naja_teq, //14 - __naja_mov, //15 - - __naja_fadd, //16 - __naja_fsub, //17 - __naja_fmul, //18 - __naja_fdiv, //19 - __naja_fldr_disp,//20 - __naja_fstr_disp,//21 - NULL, //22 - NULL, //23 - __naja_call_disp,//24 - __naja_fcmp, //25 - __naja_call_reg, //26 - NULL, //27 - __naja_fldr_sib, //28 - __naja_fstr_sib, //29 - NULL, //30 - __naja_fmov, //31 - - NULL, //32 - NULL, //33 - NULL, //34 - NULL, //35 - NULL, //36 - NULL, //37 - NULL, //38 - NULL, //39 - NULL, //40 - NULL, //41 - __naja_adrp, //42 - NULL, //43 - NULL, //44 - NULL, //45 - NULL, //46 - NULL, //47 - - NULL, //48 - NULL, //49 - NULL, //50 - NULL, //51 - NULL, //52 - NULL, //53 - NULL, //54 - NULL, //55 - __naja_ret, //56 - NULL, //57 - NULL, //58 - NULL, //59 - NULL, //60 - NULL, //61 - NULL, //62 - NULL, //63 + __naja_pop, // 5 + + __naja_str_disp, // 6 + __naja_push, // 7 + + __naja_and, // 8 + __naja_or, // 9 + __naja_jmp_disp, // 10 + __naja_jmp_reg, // 11 + __naja_setcc, // 12 + __naja_ldr_sib, // 13 + __naja_str_sib, // 14 + __naja_mov, // 15 + + __naja_fadd, // 16 + __naja_fsub, // 17 + __naja_fmul, // 18 + __naja_fdiv, // 19 + + __naja_fldr_disp,// 20 + __naja_fpop, // 21 + + __naja_fstr_disp,// 22 + __naja_fpush, // 23 + + NULL, // 24 + NULL, // 25 + __naja_call_disp,// 26 + __naja_call_reg, // 27 + NULL, // 28 + __naja_fldr_sib, // 29 + __naja_fstr_sib, // 30 + __naja_fmov, // 31 + + NULL, // 32 + NULL, // 33 + NULL, // 34 + NULL, // 35 + NULL, // 36 + NULL, // 37 + NULL, // 38 + NULL, // 39 + NULL, // 40 + NULL, // 41 + __naja_adrp, // 42 + NULL, // 43 + NULL, // 44 + NULL, // 45 + NULL, // 46 + NULL, // 47 + + NULL, // 48 + NULL, // 49 + NULL, // 50 + NULL, // 51 + NULL, // 52 + NULL, // 53 + NULL, // 54 + NULL, // 55 + __naja_ret, // 56 + NULL, // 57 + NULL, // 58 + NULL, // 59 + NULL, // 60 + NULL, // 61 + NULL, // 62 + NULL, // 63 }; static void __naja_vm_exit() @@ -1999,4 +2093,3 @@ scf_vm_ops_t vm_ops_naja = .close = naja_vm_close, .run = naja_vm_run, }; - diff --git a/vm/scf_vm_naja_asm.c b/vm/scf_vm_naja_asm.c index 5a2dd0f..9f39624 100644 --- a/vm/scf_vm_naja_asm.c +++ b/vm/scf_vm_naja_asm.c @@ -6,22 +6,26 @@ static int __naja_add(scf_vm_t* vm, uint32_t inst) int rs0 = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int I = (inst >> 20) & 0x1; + int SH = (inst >> 19) & 0x3; - if (I) { - uint64_t uimm15 = (inst >> 5) & 0x7fff; - printf("add r%d, r%d, %lu\n", rd, rs0, uimm15); + if (0x3 == SH) { + uint64_t uimm14 = (inst >> 5) & 0x3fff; + printf("add r%d, r%d, %lu\n", rd, rs0, uimm14); } else { - uint64_t sh = (inst >> 18) & 0x3; - uint64_t uimm8 = (inst >> 10) & 0xff; - int rs1 = (inst >> 5) & 0x1f; - - if (0 == sh) - printf("add r%d, r%d, r%d LSL %lu\n", rd, rs0, rs1, uimm8); - else if (1 == sh) - printf("add r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm8); - else - printf("add r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm8); + uint64_t uimm9 = (inst >> 10) & 0x1ff; + int rs1 = (inst >> 5) & 0x1f; + + switch (SH) { + case 0: + printf("add r%d, r%d, r%d LSL %lu\n", rd, rs0, rs1, uimm9); + break; + case 1: + printf("add r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm9); + break; + default: + printf("add r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm9); + break; + }; } return 0; @@ -33,50 +37,41 @@ static int __naja_sub(scf_vm_t* vm, uint32_t inst) int rs0 = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int I = (inst >> 20) & 0x1; + int SH = (inst >> 19) & 0x3; - if (I) { - uint64_t uimm15 = (inst >> 5) & 0x7fff; - printf("sub r%d, r%d, %lu\n", rd, rs0, uimm15); - } else { - uint64_t sh = (inst >> 18) & 0x3; - uint64_t uimm8 = (inst >> 10) & 0xff; - int rs1 = (inst >> 5) & 0x1f; - - if (0 == sh) - printf("sub r%d, r%d, r%d << %lu\n", rd, rs0, rs1, uimm8); - else if (1 == sh) - printf("sub r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm8); - else - printf("sub r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm8); - } - - return 0; -} + if (0x3 == SH) { + uint64_t uimm14 = (inst >> 5) & 0x3fff; -static int __naja_cmp(scf_vm_t* vm, uint32_t inst) -{ - scf_vm_naja_t* naja = vm->priv; + if (31 == rd) + printf("cmp r%d, %lu\n", rs0, uimm14); + else + printf("sub r%d, r%d, %lu\n", rd, rs0, uimm14); + } else { + uint64_t uimm9 = (inst >> 10) & 0x1ff; + int rs1 = (inst >> 5) & 0x1f; - int rs0 = inst & 0x1f; - int I = (inst >> 20) & 0x1; + switch (SH) { + case 0: + if (31 == rd) + printf("cmp r%d, r%d << %lu\n", rs0, rs1, uimm9); + else + printf("sub r%d, r%d, r%d << %lu\n", rd, rs0, rs1, uimm9); + break; - int ret = 0; + case 1: + if (31 == rd) + printf("cmp r%d, r%d LSR %lu\n", rs0, rs1, uimm9); + else + printf("sub r%d, r%d, r%d LSR %lu\n", rd, rs0, rs1, uimm9); + break; - if (I) { - int uimm15 = (inst >> 5) & 0x7fff; - printf("cmp r%d, %d\n", rs0, uimm15); - } else { - int sh = (inst >> 18) & 0x3; - int uimm8 = (inst >> 10) & 0xff; - int rs1 = (inst >> 5) & 0x1f; - - if (0 == sh) - printf("cmp r%d, r%d LSL %d\n", rs0, rs1, uimm8); - else if (1 == sh) - printf("cmp r%d, r%d LSR %d\n", rs0, rs1, uimm8); - else - printf("cmp r%d, r%d ASR %d\n", rs0, rs1, uimm8); + default: + if (31 == rd) + printf("cmp r%d, r%d ASR %lu\n", rs0, rs1, uimm9); + else + printf("sub r%d, r%d, r%d ASR %lu\n", rd, rs0, rs1, uimm9); + break; + }; } return 0; @@ -90,8 +85,8 @@ static int __naja_mul(scf_vm_t* vm, uint32_t inst) int rs1 = (inst >> 5) & 0x1f; int rs2 = (inst >> 10) & 0x1f; int rd = (inst >> 21) & 0x1f; - int S = (inst >> 20) & 0x1; - int opt = (inst >> 15) & 0x3; + int S = (inst >> 18) & 0x1; + int opt = (inst >> 19) & 0x3; if (S) { if (0 == opt) @@ -120,8 +115,8 @@ static int __naja_div(scf_vm_t* vm, uint32_t inst) int rs1 = (inst >> 5) & 0x1f; int rs2 = (inst >> 10) & 0x1f; int rd = (inst >> 21) & 0x1f; - int S = (inst >> 20) & 0x1; - int opt = (inst >> 15) & 0x3; + int S = (inst >> 18) & 0x1; + int opt = (inst >> 19) & 0x3; if (S) { if (0 == opt) @@ -148,65 +143,76 @@ static int __naja_ldr_disp(scf_vm_t* vm, uint32_t inst) int rb = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int A = (inst >> 20) & 0x1; - int ext = (inst >> 17) & 0x7; - int s12 = (inst >> 5) & 0xfff; + int SH = (inst >> 19) & 0x3; + int s = (inst >> 18) & 0x1; + int s13 = (inst >> 5) & 0x1fff; - if (s12 & 0x800) - s12 |= 0xfffff000; + if (s13 & 0x1000) + s13 |= 0xffffe000; - switch (ext) { + switch (SH) { case 0: - if (A) - printf("ldrb r%d, [r%d, %d]!\n", rd, rb, s12); + if (s) + printf("ldrsb r%d, [r%d, %d]\n", rd, rb, s13); else - printf("ldrb r%d, [r%d, %d]\n", rd, rb, s12); + printf("ldrb r%d, [r%d, %d]\n", rd, rb, s13); break; case 1: - if (A) - printf("ldrw r%d, [r%d, %d]!\n", rd, rb, s12 << 1); + if (s) + printf("ldrsw r%d, [r%d, %d]\n", rd, rb, s13 << 1); else - printf("ldrw r%d, [r%d, %d]\n", rd, rb, s12 << 1); + printf("ldrw r%d, [r%d, %d]\n", rd, rb, s13 << 1); break; case 2: - if (A) - printf("ldrl r%d, [r%d, %d]!\n", rd, rb, s12 << 2); + if (s) + printf("ldrsl r%d, [r%d, %d]\n", rd, rb, s13 << 2); else - printf("ldrl r%d, [r%d, %d]\n", rd, rb, s12 << 2); + printf("ldrl r%d, [r%d, %d]\n", rd, rb, s13 << 2); break; - case 3: - if (A) - printf("ldr r%d, [r%d, %d]!\n", rd, rb, s12 << 3); - else - printf("ldr r%d, [r%d, %d]\n", rd, rb, s12 << 3); + default: + printf("ldr r%d, [r%d, %d]\n", rd, rb, s13 << 3); break; + }; + + return 0; +} + +static int __naja_pop(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - case 4: - if (A) - printf("ldrsb r%d, [r%d, %d]!\n", rd, rb, s12); + int rb = inst & 0x1f; + int rd = (inst >> 21) & 0x1f; + int SH = (inst >> 19) & 0x3; + int s = (inst >> 18) & 0x1; + + switch (SH) { + case 0: + if (s) + printf("popsb r%d, [r%d]\n", rd, rb); else - printf("ldrsb r%d, [r%d, %d]\n", rd, rb, s12); + printf("popb r%d, [r%d]\n", rd, rb); break; - case 5: - if (A) - printf("ldrsw r%d, [r%d, %d]!\n", rd, rb, s12 << 1); + case 1: + if (s) + printf("popsw r%d, [r%d]\n", rd, rb); else - printf("ldrsw r%d, [r%d, %d]\n", rd, rb, s12 << 1); + printf("popw r%d, [r%d]\n", rd, rb); break; - case 6: - if (A) - printf("ldrsl r%d, [r%d, %d]!\n", rd, rb, s12 << 2); + case 2: + if (s) + printf("popsl r%d, [r%d]\n", rd, rb); else - printf("ldrsl r%d, [r%d, %d]\n", rd, rb, s12 << 2); + printf("popl r%d, [r%d]\n", rd, rb); break; + default: - scf_loge("\n"); - return -1; + printf("popq r%d, [r%d]\n", rd, rb); break; }; @@ -220,91 +226,96 @@ static int __naja_ldr_sib(scf_vm_t* vm, uint32_t inst) int rb = inst & 0x1f; int ri = (inst >> 5) & 0x1f; int rd = (inst >> 21) & 0x1f; - int ext = (inst >> 17) & 0x7; - int u7 = (inst >> 10) & 0x7f; + int SH = (inst >> 19) & 0x3; + int s = (inst >> 18) & 0x1; + int u8 = (inst >> 10) & 0xff; - switch (ext) { + switch (SH) { case 0: - printf("ldrb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + if (s) + printf("ldrsb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + else + printf("ldrb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); break; case 1: - printf("ldrw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + if (s) + printf("ldrsw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + else + printf("ldrw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); break; case 2: - printf("ldrl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + if (s) + printf("ldrsl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); + else + printf("ldrl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); break; - case 3: - printf("ldr r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + default: + printf("ldr r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); break; + }; + + return 0; +} + +static int __naja_str_disp(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; - case 4: - printf("ldrsb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + int rb = inst & 0x1f; + int rd = (inst >> 21) & 0x1f; + int SH = (inst >> 19) & 0x3; + int s13 = (inst >> 5) & 0x1fff; + + if (s13 & 0x1000) + s13 |= 0xffffe000; + + switch (SH) { + case 0: + printf("strb r%d, [r%d, %d]\n", rd, rb, s13); break; - case 5: - printf("ldrsw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + case 1: + printf("strw r%d, [r%d, %d]\n", rd, rb, s13 << 1); break; - case 6: - printf("ldrsl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + case 2: + printf("strl r%d, [r%d, %d]\n", rd, rb, s13 << 2); break; + default: - scf_loge("\n"); - return -1; + printf("str r%d, [r%d, %d]\n", rd, rb, s13 << 3); break; }; return 0; } -static int __naja_str_disp(scf_vm_t* vm, uint32_t inst) +static int __naja_push(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; int rb = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int A = (inst >> 20) & 0x1; - int ext = (inst >> 17) & 0x3; - int s12 = (inst >> 5) & 0xfff; + int SH = (inst >> 19) & 0x3; - if (s12 & 0x800) - s12 |= 0xfffff000; - - switch (ext) { + switch (SH) { case 0: - if (A) - printf("strb r%d, [r%d, %d]!\n", rd, rb, s12); - else - printf("strb r%d, [r%d, %d]\n", rd, rb, s12); + printf("pushb r%d, [r%d]\n", rd, rb); break; case 1: - if (A) - printf("strw r%d, [r%d, %d]!\n", rd, rb, s12 << 1); - else - printf("strw r%d, [r%d, %d]\n", rd, rb, s12 << 1); + printf("pushw r%d, [r%d]\n", rd, rb); break; case 2: - if (A) - printf("strl r%d, [r%d, %d]!\n", rd, rb, s12 << 2); - else - printf("strl r%d, [r%d, %d]\n", rd, rb, s12 << 2); - break; - - case 3: - if (A) - printf("str r%d, [r%d, %d]!\n", rd, rb, s12 << 3); - else - printf("str r%d, [r%d, %d]\n", rd, rb, s12 << 3); + printf("pushl r%d, [r%d]\n", rd, rb); break; default: - scf_loge("\n"); - return -1; + printf("pushq r%d, [r%d]\n", rd, rb); break; }; @@ -318,29 +329,24 @@ static int __naja_str_sib(scf_vm_t* vm, uint32_t inst) int rb = inst & 0x1f; int ri = (inst >> 5) & 0x1f; int rd = (inst >> 21) & 0x1f; - int ext = (inst >> 17) & 0x7; - int u7 = (inst >> 10) & 0x7f; + int SH = (inst >> 19) & 0x3; + int u8 = (inst >> 10) & 0xff; - switch (ext) { + switch (SH) { case 0: - printf("strb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + printf("strb r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); break; case 1: - printf("strw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + printf("strw r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); break; case 2: - printf("strl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); - break; - - case 3: - printf("str r%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + printf("strl r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); break; default: - scf_loge("\n"); - return -1; + printf("str r%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); break; }; @@ -353,51 +359,41 @@ static int __naja_and(scf_vm_t* vm, uint32_t inst) int rs0 = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int I = (inst >> 20) & 0x1; + int SH = (inst >> 19) & 0x3; - if (I) { - uint64_t uimm15 = (inst >> 5) & 0x7fff; + if (0x3 == SH) { + uint32_t uimm14 = (inst >> 5) & 0x3fff; - printf("and r%d, r%d, %#lx\n", rd, rs0, uimm15); - } else { - int sh = (inst >> 18) & 0x3; - int uimm8 = (inst >> 10) & 0xff; - int rs1 = (inst >> 5) & 0x1f; - - if (0 == sh) - printf("and r%d, r%d, r%d LSL %#x\n", rd, rs0, rs1, uimm8); - else if (1 == sh) - printf("and r%d, r%d, r%d LSR %#x\n", rd, rs0, rs1, uimm8); + if (31 == rd) + printf("teq r%d, %#x\n", rs0, uimm14); else - printf("and r%d, r%d, r%d ASR %#x\n", rd, rs0, rs1, uimm8); - } - - return 0; -} - -static int __naja_teq(scf_vm_t* vm, uint32_t inst) -{ - scf_vm_naja_t* naja = vm->priv; + printf("and r%d, r%d, %#x\n", rd, rs0, uimm14); + } else { + uint32_t uimm9 = (inst >> 10) & 0x1ff; + int rs1 = (inst >> 5) & 0x1f; - int rs0 = inst & 0x1f; - int rd = (inst >> 21) & 0x1f; - int I = (inst >> 20) & 0x1; + switch (SH) { + case 0: + if (31 == rd) + printf("teq r%d, r%d LSL %#x\n", rs0, rs1, uimm9); + else + printf("and r%d, r%d, r%d LSL %#x\n", rd, rs0, rs1, uimm9); + break; - if (I) { - uint64_t uimm15 = (inst >> 5) & 0x7fff; + case 1: + if (31 == rd) + printf("teq r%d, r%d LSR %#x\n", rs0, rs1, uimm9); + else + printf("and r%d, r%d, r%d LSR %#x\n", rd, rs0, rs1, uimm9); + break; - printf("teq r%d, %#lx\n", rs0, uimm15); - } else { - int sh = (inst >> 18) & 0x3; - int uimm8 = (inst >> 10) & 0xff; - int rs1 = (inst >> 5) & 0x1f; - - if (0 == sh) - printf("teq r%d, r%d LSL %#x\n", rs0, rs1, uimm8); - else if (1 == sh) - printf("teq r%d, r%d LSR %#x\n", rs0, rs1, uimm8); - else - printf("teq r%d, r%d ASR %#x\n", rs0, rs1, uimm8); + default: + if (31 == rd) + printf("teq r%d, r%d ASR %#x\n", rs0, rs1, uimm9); + else + printf("and r%d, r%d, r%d ASR %#x\n", rd, rs0, rs1, uimm9); + break; + }; } return 0; @@ -409,23 +405,22 @@ static int __naja_or(scf_vm_t* vm, uint32_t inst) int rs0 = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int I = (inst >> 20) & 0x1; + int SH = (inst >> 19) & 0x3; - if (I) { - uint64_t uimm15 = (inst >> 5) & 0x7fff; + if (0x3 == SH) { + uint32_t uimm14 = (inst >> 5) & 0x3fff; - printf("or r%d, r%d, %#lx\n", rd, rs0, uimm15); + printf("or r%d, r%d, %#x\n", rd, rs0, uimm14); } else { - int sh = (inst >> 18) & 0x3; - int uimm8 = (inst >> 10) & 0xff; - int rs1 = (inst >> 5) & 0x1f; - - if (0 == sh) - printf("or r%d, r%d, r%d LSL %#x\n", rd, rs0, rs1, uimm8); - else if (1 == sh) - printf("or r%d, r%d, r%d LSR %#x\n", rd, rs0, rs1, uimm8); + uint32_t uimm9 = (inst >> 10) & 0x1ff; + int rs1 = (inst >> 5) & 0x1f; + + if (0 == SH) + printf("or r%d, r%d, r%d LSL %#x\n", rd, rs0, rs1, uimm9); + else if (1 == SH) + printf("or r%d, r%d, r%d LSR %#x\n", rd, rs0, rs1, uimm9); else - printf("or r%d, r%d, r%d ASR %#x\n", rd, rs0, rs1, uimm8); + printf("or r%d, r%d, r%d ASR %#x\n", rd, rs0, rs1, uimm9); } return 0; @@ -505,7 +500,6 @@ static int __naja_jmp_reg(scf_vm_t* vm, uint32_t inst) return 0; } - static int __naja_call_reg(scf_vm_t* vm, uint32_t inst) { scf_vm_naja_t* naja = vm->priv; @@ -545,7 +539,7 @@ static int __naja_setcc(scf_vm_t* vm, uint32_t inst) scf_vm_naja_t* naja = vm->priv; int rd = (inst >> 21) & 0x1f; - int cc = (inst >> 17) & 0xf; + int cc = (inst >> 1) & 0xf; if (SCF_VM_Z == cc) printf("setz r%d\n", rd); @@ -577,82 +571,78 @@ static int __naja_mov(scf_vm_t* vm, uint32_t inst) scf_vm_naja_t* naja = vm->priv; int rd = (inst >> 21) & 0x1f; - int I = (inst >> 20) & 0x1; - int X = (inst >> 19) & 0x1; - int opt = (inst >> 16) & 0x7; - - if (I) { - if (0 == opt) { - if (X && (inst & 0x8000)) - printf("movsb r%d, %d\n", rd, inst & 0xffff); - else - printf("mov r%d, %d\n", rd, inst & 0xffff); - - } else if (1 == opt) - printf("mov r%d, %d << 16\n", rd, inst & 0xffff); - else if (2 == opt) - printf("mov r%d, %d << 32\n", rd, inst & 0xffff); - else if (3 == opt) - printf("mov r%d, %d << 48\n", rd, inst & 0xffff); - else if (7 == opt) - printf("mvn r%d, %d\n", rd, inst & 0xffff); + int SH = (inst >> 19) & 0x3; + int s = (inst >> 18) & 0x1; + int opt = (inst >> 16) & 0x3; - } else { - int rs = inst & 0x1f; + if (0 == opt) { + int rs0 = inst & 0x1f; int rs1 = (inst >> 5) & 0x1f; + + if (0 == SH) + printf("mov r%d, r%d LSL r%d\n", rd, rs0, rs1); + else if (1 == SH) + printf("mov r%d, r%d LSR r%d\n", rd, rs0, rs1); + else + printf("mov r%d, r%d ASR r%d\n", rd, rs0, rs1); + + } else if (1 == opt) { + int rs0 = inst & 0x1f; int u11 = (inst >> 5) & 0x7ff; - if (0 == opt) { - if (X) - printf("mov r%d, r%d LSL r%d\n", rd, rs, rs1); - else { - if (0 == u11) - printf("mov r%d, r%d\n", rd, rs); - else - printf("mov r%d, r%d LSL %d\n", rd, rs, u11); - } - } else if (1 == opt) { - if (X) - printf("mov r%d, r%d LSR r%d\n", rd, rs, rs1); - else { - if (0 == u11) - printf("mov r%d, r%d\n", rd, rs); - else - printf("mov r%d, r%d LSR %d\n", rd, rs, u11); - } + if (0 == SH) { + if (0 == u11) + printf("mov r%d, r%d\n", rd, rs0); + else + printf("mov r%d, r%d LSL %d\n", rd, rs0, u11); + + } else if (1 == SH) + printf("mov r%d, r%d LSR %d\n", rd, rs0, u11); + else + printf("mov r%d, r%d ASR %d\n", rd, rs0, u11); - } else if (2 == opt) { - if (X) - printf("mov r%d, r%d ASR r%d\n", rd, rs, rs1); - else { - if (0 == u11) - printf("mov r%d, r%d\n", rd, rs); + } else if (2 == opt) { + int rs = inst & 0x1f; + + switch (SH) { + case 0: + if (s) + printf("movsb r%d, r%d\n", rd, rs); else - printf("mov r%d, r%d ASR %d\n", rd, rs, u11); - } + printf("movzb r%d, r%d\n", rd, rs); + break; - } else if (3 == opt) - printf("NOT r%d, r%d\n", rd, rs); - else if (4 == opt) - printf("NEG r%d, r%d\n", rd, rs); + case 1: + if (s) + printf("movsw r%d, r%d\n", rd, rs); + else + printf("movzw r%d, r%d\n", rd, rs); + break; - else if (5 == opt) { - if (X) - printf("movsb r%d, r%d\n", rd, rs); - else - printf("movzb r%d, r%d\n", rd, rs); + case 2: + if (s) + printf("movsl r%d, r%d\n", rd, rs); + else + printf("movzl r%d, r%d\n", rd, rs); + break; + default: + if (s) + printf("NEG r%d, r%d\n", rd, rs); + else + printf("NOT r%d, r%d\n", rd, rs); + break; + }; - } else if (6 == opt) { - if (X) - printf("movsw r%d, r%d\n", rd, rs); - else - printf("movzw r%d, r%d\n", rd, rs); + } else { + uint64_t u16 = inst & 0xffff; - } else if (7 == opt) { - if (X) - printf("movsl r%d, r%d\n", rd, rs); + if (s) + printf("mvn r%d, %#lx\n", rd, u16); + else { + if (0 == SH) + printf("mov r%d, %#lx\n", rd, u16); else - printf("movzl r%d, r%d\n", rd, rs); + printf("mov r%d, %#lx << %d\n", rd, u16, 16 << SH); } } @@ -668,8 +658,6 @@ static int __naja_fadd(scf_vm_t* vm, uint32_t inst) int rd = (inst >> 21) & 0x1f; printf("fadd r%d, r%d, r%d\n", rd, rs0, rs1); - - naja->ip += 4; return 0; } @@ -681,22 +669,11 @@ static int __naja_fsub(scf_vm_t* vm, uint32_t inst) int rs1 = (inst >> 5) & 0x1f; int rd = (inst >> 21) & 0x1f; - printf("fsub r%d, r%d, r%d\n", rd, rs0, rs1); - - naja->ip += 4; - return 0; -} - -static int __naja_fcmp(scf_vm_t* vm, uint32_t inst) -{ - scf_vm_naja_t* naja = vm->priv; - - int rs0 = inst & 0x1f; - int rs1 = (inst >> 5) & 0x1f; - - printf("fcmp d%d, d%d\n", rs0, rs1); + if (31 == rd) + printf("fcmp d%d, d%d\n", rs0, rs1); + else + printf("fsub r%d, r%d, r%d\n", rd, rs0, rs1); - naja->ip += 4; return 0; } @@ -717,7 +694,6 @@ static int __naja_fmul(scf_vm_t* vm, uint32_t inst) else printf("fmul d%d, d%d, d%d", rd, rs0, rs1); - naja->ip += 4; return 0; } @@ -738,7 +714,6 @@ static int __naja_fdiv(scf_vm_t* vm, uint32_t inst) else printf("fdiv d%d, d%d, d%d", rd, rs0, rs1); - naja->ip += 4; return 0; } @@ -748,34 +723,51 @@ static int __naja_fstr_disp(scf_vm_t* vm, uint32_t inst) int rb = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int A = (inst >> 20) & 0x1; - int ext = (inst >> 17) & 0x7; - int s12 = (inst >> 5) & 0xfff; + int SH = (inst >> 19) & 0x3; + int s13 = (inst >> 5) & 0x1fff; + + if (s13 & 0x1000) + s13 |= 0xffffe000; - if (s12 & 0x800) - s12 |= 0xfffff000; + switch (SH) { + case 2: + printf("fstr f%d, [r%d, %d]\n", rd, rb, s13 << 2); + break; - switch (ext) { case 3: - if (A) - printf("fstr d%d, [r%d, %d]!\n", rd, rb, s12 << 3); - else - printf("fstr d%d, [r%d, %d]\n", rd, rb, s12 << 3); + printf("fstr d%d, [r%d, %d]\n", rd, rb, s13 << 3); break; + default: + scf_loge("SH: %d\n", SH); + return -1; + break; + }; - case 6: - if (A) - printf("fstrf f%d, [r%d, %d]!\n", rd, rb, s12 << 2); - else - printf("fstrf f%d, [r%d, %d]\n", rd, rb, s12 << 2); + return 0; +} + +static int __naja_fpush(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rb = inst & 0x1f; + int rd = (inst >> 21) & 0x1f; + int SH = (inst >> 19) & 0x3; + + switch (SH) { + case 2: + printf("fpush f%d, [r%d]\n", rd, rb); + break; + + case 3: + printf("fpush d%d, [r%d]\n", rd, rb); break; default: - scf_loge("ext: %d\n", ext); + scf_loge("SH: %d\n", SH); return -1; break; }; - naja->ip += 4; return 0; } @@ -785,34 +777,50 @@ static int __naja_fldr_disp(scf_vm_t* vm, uint32_t inst) int rb = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int A = (inst >> 20) & 0x1; - int ext = (inst >> 17) & 0x7; - int s12 = (inst >> 5) & 0xfff; + int SH = (inst >> 19) & 0x3; + int s13 = (inst >> 5) & 0x1fff; - if (s12 & 0x800) - s12 |= 0xfffff000; + if (s13 & 0x1000) + s13 |= 0xffffe000; + + switch (SH) { + case 2: + printf("fldr f%d, [r%d, %d]\n", rd, rb, s13 << 2); + break; - switch (ext) { case 3: - if (A) - printf("fldr d%d, [r%d, %d]!\n", rd, rb, s12 << 3); - else - printf("fldr d%d, [r%d, %d]\n", rd, rb, s12 << 3); + printf("fldr d%d, [r%d, %d]\n", rd, rb, s13 << 3); break; + default: + scf_loge("SH: %d\n", SH); + return -1; + break; + }; - case 6: - if (A) - printf("fldrf f%d, [r%d, %d]!\n", rd, rb, s12 << 2); - else - printf("fldrf f%d, [r%d, %d]\n", rd, rb, s12 << 2); + return 0; +} + +static int __naja_fpop(scf_vm_t* vm, uint32_t inst) +{ + scf_vm_naja_t* naja = vm->priv; + + int rb = inst & 0x1f; + int rd = (inst >> 21) & 0x1f; + int SH = (inst >> 19) & 0x3; + + switch (SH) { + case 2: + printf("fldr f%d, [r%d]\n", rd, rb); + break; + case 3: + printf("fldr d%d, [r%d]\n", rd, rb); break; default: - scf_loge("ext: %d\n", ext); + scf_loge("SH: %d\n", SH); return -1; break; }; - naja->ip += 4; return 0; } @@ -823,15 +831,15 @@ static int __naja_fldr_sib(scf_vm_t* vm, uint32_t inst) int rb = inst & 0x1f; int ri = (inst >> 5) & 0x1f; int rd = (inst >> 21) & 0x1f; - int ext = (inst >> 17) & 0x7; - int u7 = (inst >> 10) & 0x7f; + int SH = (inst >> 19) & 0x3; + int u8 = (inst >> 10) & 0xff; - switch (ext) { - case 3: - printf("fldr d%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + switch (SH) { + case 2: + printf("fldr f%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); break; - case 6: - printf("fldrf f%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + case 3: + printf("fldr d%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); break; default: scf_loge("\n"); @@ -839,7 +847,6 @@ static int __naja_fldr_sib(scf_vm_t* vm, uint32_t inst) break; }; - naja->ip += 4; return 0; } @@ -850,16 +857,15 @@ static int __naja_fstr_sib(scf_vm_t* vm, uint32_t inst) int rb = inst & 0x1f; int ri = (inst >> 5) & 0x1f; int rd = (inst >> 21) & 0x1f; - int ext = (inst >> 17) & 0x3; - int u7 = (inst >> 10) & 0x7f; + int SH = (inst >> 19) & 0x3; + int u8 = (inst >> 10) & 0xff; - switch (ext) { - case 3: - printf("fstr d%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + switch (SH) { + case 2: + printf("fstr f%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); break; - - case 6: - printf("fldrf f%d, [r%d, r%d, %d]\n", rd, rb, ri, u7); + case 3: + printf("fstr d%d, [r%d, r%d, %d]\n", rd, rb, ri, u8); break; default: scf_loge("\n"); @@ -867,7 +873,6 @@ static int __naja_fstr_sib(scf_vm_t* vm, uint32_t inst) break; }; - naja->ip += 4; return 0; } @@ -877,49 +882,36 @@ static int __naja_fmov(scf_vm_t* vm, uint32_t inst) int rs = inst & 0x1f; int rd = (inst >> 21) & 0x1f; - int opt = (inst >> 16) & 0xf; - - if (0 == opt) - printf("fmov d%d, d%d\n", rd, rs); - - else if (1 == opt) - printf("fss2sd d%d, f%d\n", rd, rs); - - else if (2 == opt) - printf("fsd2ss d%d, f%d\n", rd, rs); - - else if (3 == opt) - printf("fneg d%d, d%d\n", rd, rs); - - else if (4 == opt) - printf("cvtss2si r%d, f%d\n", rd, rs); - - else if (5 == opt) - printf("cvtsd2si r%d, d%d\n", rd, rs); - - else if (6 == opt) - printf("cvtss2ui r%d, f%d\n", rd, rs); + int SH = (inst >> 19) & 0x3; + int s = (inst >> 18) & 0x1; + int opt = (inst >> 16) & 0x3; + + if (0 == opt) { + if (2 == SH) + printf("fss2sd d%d, f%d\n", rd, rs); + else if (3 == SH) + printf("fsd2ss f%d, d%d\n", rd, rs); + else { + scf_loge("\n"); + return -EINVAL; + } - else if (7 == opt) - printf("cvtsd2ui r%d, d%d\n", rd, rs); + } else if (1 == opt) { + if (s) + printf("cvtss2si r%d, f%d\n", rd, rs); + else + printf("cvtss2ui r%d, f%d\n", rd, rs); - else if (0xc == opt) + } else if (2 == opt) { printf("cvtsi2ss f%d, r%d\n", rd, rs); - else if (0xd == opt) - printf("cvtsi2sd d%d, r%d\n", rd, rs); - - else if (0xe == opt) - printf("cvtui2ss f%d, r%d\n", rd, rs); - - else if (0xf == opt) - printf("cvtui2sd f%d, r%d\n", rd, rs); - else { - scf_loge("\n"); - return -EINVAL; + } else { + if (s) + printf("fneg d%d, d%d\n", rd, rs); + else + printf("fmov d%d, d%d\n", rd, rs); } - naja->ip += 4; return 0; } @@ -930,69 +922,75 @@ static naja_opcode_pt naja_opcodes[64] = __naja_sub, // 1 __naja_mul, // 2 __naja_div, // 3 + __naja_ldr_disp, // 4 - __naja_str_disp, // 5 - __naja_and, // 6 - __naja_or, // 7 - __naja_jmp_disp, // 8 - __naja_cmp, // 9 - __naja_jmp_reg, //10 - __naja_setcc, //11 - __naja_ldr_sib, //12 - __naja_str_sib, //13 - __naja_teq, //14 - __naja_mov, //15 - - __naja_fadd, //16 - __naja_fsub, //17 - __naja_fmul, //18 - __naja_fdiv, //19 - __naja_fldr_disp,//20 - __naja_fstr_disp,//21 - NULL, //22 - NULL, //23 - __naja_call_disp,//24 - __naja_fcmp, //25 - __naja_call_reg, //26 - NULL, //27 - __naja_fldr_sib, //28 - __naja_fstr_sib, //29 - NULL, //30 - __naja_fmov, //31 - - NULL, //32 - NULL, //33 - NULL, //34 - NULL, //35 - NULL, //36 - NULL, //37 - NULL, //38 - NULL, //39 - NULL, //40 - NULL, //41 - __naja_adrp, //42 - NULL, //43 - NULL, //44 - NULL, //45 - NULL, //46 - NULL, //47 - - NULL, //48 - NULL, //49 - NULL, //50 - NULL, //51 - NULL, //52 - NULL, //53 - NULL, //54 - NULL, //55 - __naja_ret, //56 - NULL, //57 - NULL, //58 - NULL, //59 - NULL, //60 - NULL, //61 - NULL, //62 - NULL, //63 + __naja_pop, // 5 + + __naja_str_disp, // 6 + __naja_push, // 7 + + __naja_and, // 8 + __naja_or, // 9 + __naja_jmp_disp, // 10 + __naja_jmp_reg, // 11 + __naja_setcc, // 12 + __naja_ldr_sib, // 13 + __naja_str_sib, // 14 + __naja_mov, // 15 + + __naja_fadd, // 16 + __naja_fsub, // 17 + __naja_fmul, // 18 + __naja_fdiv, // 19 + + __naja_fldr_disp,// 20 + __naja_fpop, // 21 + + __naja_fstr_disp,// 22 + __naja_fpush, // 23 + + NULL, // 24 + NULL, // 25 + __naja_call_disp,// 26 + __naja_call_reg, // 27 + NULL, // 28 + __naja_fldr_sib, // 29 + __naja_fstr_sib, // 30 + __naja_fmov, // 31 + + NULL, // 32 + NULL, // 33 + NULL, // 34 + NULL, // 35 + NULL, // 36 + NULL, // 37 + NULL, // 38 + NULL, // 39 + NULL, // 40 + NULL, // 41 + __naja_adrp, // 42 + NULL, // 43 + NULL, // 44 + NULL, // 45 + NULL, // 46 + NULL, // 47 + + NULL, // 48 + NULL, // 49 + NULL, // 50 + NULL, // 51 + NULL, // 52 + NULL, // 53 + NULL, // 54 + NULL, // 55 + __naja_ret, // 56 + NULL, // 57 + NULL, // 58 + NULL, // 59 + NULL, // 60 + NULL, // 61 + NULL, // 62 + NULL, // 63 }; static int __naja_vm_run(scf_vm_t* vm, const char* path, const char* sys) @@ -1065,4 +1063,3 @@ scf_vm_ops_t vm_ops_naja_asm = .close = naja_vm_close, .run = naja_vm_run, }; - -- 2.25.1