typedef struct scf_3ac_code_s scf_3ac_code_t;
typedef struct scf_inst_ops_s scf_inst_ops_t;
+typedef struct scf_regs_ops_s scf_regs_ops_t;
typedef struct scf_register_s scf_register_t;
typedef struct scf_OpCode_s scf_OpCode_t;
scf_vector_t* data_relas; // re-localtions in .data segment
scf_inst_ops_t* iops;
+ scf_regs_ops_t* rops;
scf_vector_t* init_insts;
int init_code_bytes;
int arm64_inst_ADR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_variable_t* vs)
{
- scf_register_t* fp = risc_find_register("fp");
+ scf_register_t* fp = f->rops->find_register("fp");
scf_instruction_t* inst = NULL;
scf_rela_t* rela = NULL;
int arm64_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_register_t* rb, scf_variable_t* vs)
{
- scf_register_t* fp = risc_find_register("fp");
+ scf_register_t* fp = f->rops->find_register("fp");
scf_register_t* ri = NULL;
scf_instruction_t* inst = NULL;
scf_rela_t* rela = NULL;
int arm64_inst_G2M(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_register_t* rb, scf_variable_t* vs)
{
- scf_register_t* fp = risc_find_register("fp");
+ scf_register_t* fp = f->rops->find_register("fp");
scf_register_t* ri = NULL;
scf_instruction_t* inst = NULL;
scf_rela_t* rela = NULL;
int arm64_inst_M2GF(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_register_t* rb, scf_variable_t* vs)
{
- scf_register_t* fp = risc_find_register("fp");
+ scf_register_t* fp = f->rops->find_register("fp");
scf_register_t* ro = NULL;
scf_instruction_t* inst = NULL;
scf_rela_t* rela = NULL;
int arm64_cmp_update(scf_3ac_code_t* c, scf_function_t* f, scf_instruction_t* cmp)
{
scf_instruction_t* inst;
- scf_register_t* r16 = risc_find_register_type_id_bytes(0, 16, 8);
- scf_register_t* r17 = risc_find_register_type_id_bytes(0, 17, 8);
+ scf_register_t* r16 = f->rops->find_register_type_id_bytes(0, 16, 8);
+ scf_register_t* r17 = f->rops->find_register_type_id_bytes(0, 17, 8);
scf_register_t* r0;
uint32_t opcode;
// arm64
case 0x71: // imm
i0 = (opcode >> 5) & 0x1f;
- r0 = risc_find_register_type_id_bytes(0, i0, 8);
+ r0 = f->rops->find_register_type_id_bytes(0, i0, 8);
inst = f->iops->MOV_G(c, r16, r0); // use r16 to backup r0
RISC_INST_ADD_CHECK(c->instructions, inst);
i0 = (opcode >> 5) & 0x1f;
i1 = (opcode >> 16) & 0x1f;
- r0 = risc_find_register_type_id_bytes(0, i0, 8);
+ r0 = f->rops->find_register_type_id_bytes(0, i0, 8);
inst = f->iops->MOV_G(c, r16, r0); // use r16 to backup r0
RISC_INST_ADD_CHECK(c->instructions, inst);
- r0 = risc_find_register_type_id_bytes(0, i1, 8);
+ r0 = f->rops->find_register_type_id_bytes(0, i1, 8);
inst = f->iops->MOV_G(c, r17, r0); // use r17 to backup r1
RISC_INST_ADD_CHECK(c->instructions, inst);
int naja_inst_ADR2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_variable_t* vs)
{
- scf_register_t* fp = risc_find_register("fp");
+ scf_register_t* fp = f->rops->find_register("fp");
scf_instruction_t* inst = NULL;
scf_rela_t* rela = NULL;
int naja_inst_M2G(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rd, scf_register_t* rb, scf_variable_t* vs)
{
- scf_register_t* fp = risc_find_register("fp");
+ scf_register_t* fp = f->rops->find_register("fp");
scf_register_t* ri = NULL;
scf_instruction_t* inst = NULL;
scf_rela_t* rela = NULL;
int naja_inst_G2M(scf_3ac_code_t* c, scf_function_t* f, scf_register_t* rs, scf_register_t* rb, scf_variable_t* vs)
{
- scf_register_t* fp = risc_find_register("fp");
+ scf_register_t* fp = f->rops->find_register("fp");
scf_register_t* ri = NULL;
scf_instruction_t* inst = NULL;
scf_rela_t* rela = NULL;
int naja_cmp_update(scf_3ac_code_t* c, scf_function_t* f, scf_instruction_t* cmp)
{
scf_instruction_t* inst;
- scf_register_t* r16 = risc_find_register_type_id_bytes(0, 16, 8);
- scf_register_t* r17 = risc_find_register_type_id_bytes(0, 17, 8);
+ scf_register_t* r16 = f->rops->find_register_type_id_bytes(0, 16, 8);
+ scf_register_t* r17 = f->rops->find_register_type_id_bytes(0, 17, 8);
scf_register_t* r0;
uint32_t opcode;
case 0x24:
if (cmp->code[2] & 0x10) {
i0 = opcode & 0x1f;
- r0 = risc_find_register_type_id_bytes(0, i0, 8);
+ r0 = f->rops->find_register_type_id_bytes(0, i0, 8);
inst = f->iops->MOV_G(c, r16, r0); // use r16 to backup r0
RISC_INST_ADD_CHECK(c->instructions, inst);
i0 = opcode & 0x1f;
i1 = (opcode >> 5) & 0x1f;
- r0 = risc_find_register_type_id_bytes(0, i0, 8);
+ r0 = f->rops->find_register_type_id_bytes(0, i0, 8);
inst = f->iops->MOV_G(c, r16, r0); // use r16 to backup r0
RISC_INST_ADD_CHECK(c->instructions, inst);
- r0 = risc_find_register_type_id_bytes(0, i1, 8);
+ r0 = f->rops->find_register_type_id_bytes(0, i1, 8);
inst = f->iops->MOV_G(c, r17, r0); // use r17 to backup r1
RISC_INST_ADD_CHECK(c->instructions, inst);
#include"scf_basic_block.h"
#include"scf_3ac.h"
+extern scf_regs_ops_t regs_ops_arm64;
+extern scf_regs_ops_t regs_ops_naja;
+
extern scf_inst_ops_t inst_ops_arm64;
extern scf_inst_ops_t inst_ops_naja;
NULL
};
+static scf_regs_ops_t* regs_ops_array[] =
+{
+ ®s_ops_arm64,
+ ®s_ops_naja,
+
+ NULL
+};
+
int scf_risc_open(scf_native_t* ctx, const char* arch)
{
scf_inst_ops_t* iops = NULL;
+ scf_regs_ops_t* rops = NULL;
int i;
for (i = 0; inst_ops_array[i]; i++) {
}
}
- if (!iops)
+ for (i = 0; regs_ops_array[i]; i++) {
+
+ if (!strcmp(regs_ops_array[i]->name, arch)) {
+ rops = regs_ops_array[i];
+ break;
+ }
+ }
+
+ if (!iops || !rops)
return -EINVAL;
scf_risc_context_t* risc = calloc(1, sizeof(scf_risc_context_t));
return -ENOMEM;
ctx->iops = iops;
+ ctx->rops = rops;
ctx->priv = risc;
return 0;
}
scf_risc_context_t* risc = ctx->priv;
if (risc) {
- risc_registers_clear();
+ ctx->rops->registers_clear();
free(risc);
risc = NULL;
if (f->args_float < RISC_ABI_NB) {
- v->rabi = risc_find_register_type_id_bytes(is_float, risc_abi_float_regs[f->args_float], size);
+ v->rabi = f->rops->find_register_type_id_bytes(is_float, risc_abi_float_regs[f->args_float], size);
v->bp_offset = bp_floats;
bp_floats -= 8;
f->args_float++;
}
} else if (f->args_int < RISC_ABI_NB) {
- v->rabi = risc_find_register_type_id_bytes(is_float, risc_abi_regs[f->args_int], size);
+ v->rabi = f->rops->find_register_type_id_bytes(is_float, risc_abi_regs[f->args_int], size);
v->bp_offset = bp_int;
bp_int -= 8;
f->args_int++;
{
scf_variable_t* v;
- int ret = risc_registers_init();
+ int ret = f->rops->registers_init();
if (ret < 0)
return ret;
inst = NULL;
mov = risc_find_OpCode(SCF_RISC_MOV, 8,8, SCF_RISC_G2E);
- rbp = risc_find_register("rbp");
+ rbp = f->rops->find_register("rbp");
- rdi = risc_find_register("rdi");
- rsi = risc_find_register("rsi");
- rdx = risc_find_register("rdx");
- rcx = risc_find_register("rcx");
- r8 = risc_find_register("r8");
- r9 = risc_find_register("r9");
+ rdi = f->rops->find_register("rdi");
+ rsi = f->rops->find_register("rsi");
+ rdx = f->rops->find_register("rdx");
+ rcx = f->rops->find_register("rcx");
+ r8 = f->rops->find_register("r8");
+ r9 = f->rops->find_register("r9");
#define RISC_SAVE_RABI(offset, rabi) \
do { \
mov = risc_find_OpCode(SCF_RISC_MOVSD, 8,8, SCF_RISC_G2E);
- xmm0 = risc_find_register("xmm0");
- xmm1 = risc_find_register("xmm1");
- xmm2 = risc_find_register("xmm2");
- xmm3 = risc_find_register("xmm3");
+ xmm0 = f->rops->find_register("xmm0");
+ xmm1 = f->rops->find_register("xmm1");
+ xmm2 = f->rops->find_register("xmm2");
+ xmm3 = f->rops->find_register("xmm3");
RISC_SAVE_RABI(-56, xmm0);
RISC_SAVE_RABI(-64, xmm1);
} else
scf_vector_clear(f->init_insts, free);
- scf_register_t* sp = risc_find_register("sp");
- scf_register_t* fp = risc_find_register("fp");
+ scf_register_t* sp = f->rops->find_register("sp");
+ scf_register_t* fp = f->rops->find_register("fp");
scf_register_t* r;
scf_instruction_t* inst = NULL;
int i;
for (i = 0; i < RISC_ABI_CALLEE_SAVES_NB; i++) {
- r = risc_find_register_type_id_bytes(0, risc_abi_callee_saves[i], 8);
+ r = f->rops->find_register_type_id_bytes(0, risc_abi_callee_saves[i], 8);
if (!r->used) {
- r = risc_find_register_type_id_bytes(0, risc_abi_callee_saves[i], 4);
+ r = f->rops->find_register_type_id_bytes(0, risc_abi_callee_saves[i], 4);
if (!r->used)
continue;
f->init_code_bytes += inst->len;
}
- risc_registers_clear();
+ f->rops->registers_clear();
return 0;
}
-static void _risc_rcg_node_printf(risc_rcg_node_t* rn)
+static void _risc_rcg_node_printf(risc_rcg_node_t* rn, scf_function_t* f)
{
if (rn->dag_node) {
scf_variable_t* v = rn->dag_node->var;
}
if (rn->dag_node->color > 0) {
- scf_register_t* r = risc_find_register_color(rn->dag_node->color);
+ scf_register_t* r = f->rops->find_register_color(rn->dag_node->color);
printf(", reg: %s\n", r->name);
} else {
printf("\n");
return 0;
}
-static int _risc_bb_regs_from_graph(scf_basic_block_t* bb, scf_graph_t* g)
+static int _risc_bb_regs_from_graph(scf_basic_block_t* bb, scf_graph_t* g, scf_function_t* f)
{
int i;
for (i = 0; i < g->nodes->size; i++) {
scf_dn_status_t* ds;
if (!dn) {
- _risc_rcg_node_printf(rn);
+ _risc_rcg_node_printf(rn, f);
continue;
}
ds->color = gn->color;
dn->color = gn->color;
- _risc_rcg_node_printf(rn);
+ _risc_rcg_node_printf(rn, f);
}
printf("\n");
if (ret < 0)
goto error;
- colors = risc_register_colors();
+ colors = f->rops->register_colors();
if (!colors) {
ret = -ENOMEM;
goto error;
if (ret < 0)
goto error;
- ret = _risc_bb_regs_from_graph(bb, g);
+ ret = _risc_bb_regs_from_graph(bb, g, f);
error:
if (colors)
static int _risc_select_bb_group_regs(scf_bb_group_t* bbg, scf_native_t* ctx)
{
scf_risc_context_t* risc = ctx->priv;
- scf_function_t* f = risc->f;
+ scf_function_t* f = risc->f;
scf_graph_t* g = scf_graph_alloc();
if (!g)
goto error;
}
- colors = risc_register_colors();
+ colors = f->rops->register_colors();
if (!colors) {
ret = -ENOMEM;
goto error;
if (ret < 0)
goto error;
- ret = _risc_bb_regs_from_graph(bbg->pre, g);
+ ret = _risc_bb_regs_from_graph(bbg->pre, g, f);
if (ret < 0)
goto error;
if (ret < 0)
return ret;
- risc_init_bb_colors(bb);
+ risc_init_bb_colors(bb, f);
if (0 == bb->index) {
ret = _risc_argv_save(bb, f);
if (ret < 0)
return ret;
- risc_init_bb_colors(bbg->pre);
+ risc_init_bb_colors(bbg->pre, f);
if (0 == bbg->pre->index) {
ret = _risc_argv_save(bbg->pre, f);
if (ret < 0)
return ret;
- risc_init_bb_colors(bbg->pre);
+ risc_init_bb_colors(bbg->pre, f);
if (0 == bbg->pre->index) {
ret = _risc_argv_save(bbg->pre, f);
risc->f = f;
f->iops = ctx->iops;
+ f->rops = ctx->rops;
scf_vector_t* local_vars = scf_vector_alloc();
if (!local_vars)
int risc_fix_bb_colors (scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_t* f);
int risc_load_bb_colors (scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_t* f);
int risc_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_t* f);
-void risc_init_bb_colors (scf_basic_block_t* bb);
+void risc_init_bb_colors (scf_basic_block_t* bb, scf_function_t* f);
scf_instruction_t* risc_make_inst (scf_3ac_code_t* c, uint32_t opcode);
#include"scf_basic_block.h"
#include"scf_3ac.h"
-void risc_init_bb_colors(scf_basic_block_t* bb)
+void risc_init_bb_colors(scf_basic_block_t* bb, scf_function_t* f)
{
scf_dag_node_t* dn;
scf_dn_status_t* ds;
+ scf_variable_t* v;
+ scf_register_t* r;
- int i;
-
- risc_registers_reset();
+ f->rops->registers_reset();
+ int i;
for (i = 0; i < bb->dn_colors_entry->size; i++) {
ds = bb->dn_colors_entry->data[i];
dn->loaded = 1;
if (scf_vector_find(bb->dn_loads, dn)) {
- scf_variable_t* v = dn->var;
+
+ v = dn->var;
if (v->w)
scf_loge("v_%d_%d/%s, ", v->w->line, v->w->pos, v->w->text->data);
else
printf("color: %ld, loaded: %d", dn->color, dn->loaded);
if (dn->color > 0) {
- scf_register_t* r = risc_find_register_color(dn->color);
+ r = f->rops->find_register_color(dn->color);
printf(", reg: %s", r->name);
}
printf("\n");
dn->loaded = 0;
- r = risc_find_register_color(color);
+ r = f->rops->find_register_color(color);
ret = risc_load_reg(r, dn, c, f);
if (ret < 0) {
return -ENOMEM;
}
- r = risc_find_register_color(color);
+ r = f->rops->find_register_color(color);
ret = risc_save_var2(dn, r, c, f);
if (ret < 0) {
int risc_bb_load_dn2(intptr_t color, scf_dag_node_t* dn, scf_basic_block_t* bb, scf_function_t* f)
{
- scf_register_t* r16 = risc_find_register_type_id_bytes(0, 16, 8);
- scf_register_t* r17 = risc_find_register_type_id_bytes(0, 17, 8);
- scf_register_t* r0;
+ scf_register_t* r0;
+ scf_register_t* r16 = f->rops->find_register_type_id_bytes(0, 16, 8);
+ scf_register_t* r17 = f->rops->find_register_type_id_bytes(0, 17, 8);
scf_instruction_t* cmp = NULL;
scf_instruction_t* inst;
scf_3ac_code_t* c;
}
if (color != dn->color && color > 0) {
- scf_register_t* r = risc_find_register_color(color);
+ scf_register_t* r = f->rops->find_register_color(color);
scf_vector_del(r->dag_nodes, dn);
}
printf("v_%#lx", 0xffff & (uintptr_t)v);
if (dn->color > 0) {
- scf_register_t* r = risc_find_register_color(dn->color);
+ scf_register_t* r = f->rops->find_register_color(dn->color);
printf(", %s", r->name);
}
int risc_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function_t* f)
{
- scf_register_t* r;
scf_basic_block_t* prev;
scf_dn_status_t* ds;
scf_dn_status_t* ds2;
scf_dag_node_t* dn;
scf_variable_t* v;
+ scf_register_t* r;
int i;
int j;
}
if (color != dn->color && color > 0) {
- r = risc_find_register_color(color);
+ r = f->rops->find_register_color(color);
scf_vector_del(r->dag_nodes, dn);
}
printf("v_%#lx", 0xffff & (uintptr_t)v);
#endif
if (dn->color > 0) {
- r = risc_find_register_color(dn->color);
+ r = f->rops->find_register_color(dn->color);
if (dn->loaded)
assert(0 == scf_vector_add_unique(r->dag_nodes, dn));
static int _risc_inst_call_argv(scf_native_t* ctx, scf_3ac_code_t* c, scf_function_t* f)
{
- scf_register_t* sp = risc_find_register("sp");
+ scf_register_t* sp = f->rops->find_register("sp");
scf_risc_OpCode_t* lea;
scf_risc_OpCode_t* mov;
int is_float = scf_variable_float(v);
if (!rabi) {
- rabi = risc_find_register_type_id_bytes(is_float, SCF_RISC_REG_X0, size);
+ rabi = f->rops->find_register_type_id_bytes(is_float, SCF_RISC_REG_X0, size);
- ret = risc_overflow_reg(rabi, c, f);
+ ret = f->rops->overflow_reg(rabi, c, f);
if (ret < 0) {
scf_loge("\n");
return ret;
if (0 == src->dag_node->color) {
- ret = risc_overflow_reg(rabi, c, f);
+ ret = f->rops->overflow_reg(rabi, c, f);
if (ret < 0) {
scf_loge("\n");
return ret;
return ret;
}
- rabi = risc_find_register_color_bytes(rabi->color, 8);
+ rabi = f->rops->find_register_color_bytes(rabi->color, 8);
rs = rabi;
} else {
if (src->dag_node->color < 0)
if (rd && RISC_COLOR_CONFLICT(rd->color, src->dag_node->color)) {
- ret = risc_overflow_reg2(rd, src->dag_node, c, f);
+ ret = f->rops->overflow_reg2(rd, src->dag_node, c, f);
if (ret < 0) {
scf_loge("\n");
return ret;
}
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
- rs = risc_find_register_color_bytes(rs->color, 8);
+ rs = f->rops->find_register_color_bytes(rs->color, 8);
}
if (movx) {
continue;
}
- ret = risc_overflow_reg2(rd, src->dag_node, c, f);
+ ret = f->rops->overflow_reg2(rd, src->dag_node, c, f);
if (ret < 0) {
scf_loge("\n");
return ret;
}
if (!RISC_COLOR_CONFLICT(rd->color, rs->color)) {
- rd = risc_find_register_color_bytes(rd->color, rs->bytes);
+ rd = f->rops->find_register_color_bytes(rd->color, rs->bytes);
if (!is_float)
inst = ctx->iops->MOV_G(c, rd, rs);
return -1;
}
- r = risc_find_register_type_id_bytes(is_float, 0, 8);
+ r = f->rops->find_register_type_id_bytes(is_float, 0, 8);
} else
- r = risc_find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], 8);
+ r = f->rops->find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], 8);
- int ret = risc_overflow_reg(r, c, f);
+ int ret = f->rops->overflow_reg(r, c, f);
if (ret < 0) {
scf_loge("\n");
return ret;
return 0;
}
-static int _risc_dst_reg_valid(scf_register_t* rd, scf_register_t** updated_regs, int nb_updated, int abi_idx, int abi_total)
+static int _risc_dst_reg_valid(scf_function_t* f, scf_register_t* rd, scf_register_t** updated_regs, int nb_updated, int abi_idx, int abi_total)
{
scf_register_t* r;
for (i = abi_idx; i < abi_total; i++) {
- r = risc_find_register_type_id_bytes(RISC_COLOR_TYPE(rd->color), risc_abi_ret_regs[i], rd->bytes);
+ r = f->rops->find_register_type_id_bytes(RISC_COLOR_TYPE(rd->color), risc_abi_ret_regs[i], rd->bytes);
if (RISC_COLOR_CONFLICT(r->color, rd->color))
return 0;
scf_loge("\n");
return -EINVAL;
- rs = risc_find_register_type_id_bytes(is_float, SCF_RISC_REG_X0, dst_size);
+ rs = f->rops->find_register_type_id_bytes(is_float, SCF_RISC_REG_X0, dst_size);
if (SCF_VAR_FLOAT == dn->var->type)
mov = risc_find_OpCode(SCF_RISC_MOVSS, dst_size, dst_size, SCF_RISC_G2E);
idx_float++;
} else {
- rs = risc_find_register_type_id_bytes(is_float, risc_abi_ret_regs[idx_int], dst_size);
+ rs = f->rops->find_register_type_id_bytes(is_float, risc_abi_ret_regs[idx_int], dst_size);
mov = risc_find_OpCode(SCF_RISC_MOV, dst_size, dst_size, SCF_RISC_G2E);
scf_instruction_t* inst;
if (dn->color > 0) {
- rd = risc_find_register_color(dn->color);
+ rd = f->rops->find_register_color(dn->color);
- int rd_vars = risc_reg_cached_vars(rd);
+ int rd_vars = f->rops->reg_cached_vars(rd);
if (rd_vars > 1) {
dn->color = -1;
continue;
}
- int valid = _risc_dst_reg_valid(rd, updated_regs, nb_updated, idx_int, nb_int);
+ int valid = _risc_dst_reg_valid(f, rd, updated_regs, nb_updated, idx_int, nb_int);
if (valid) {
inst = ctx->iops->MOV_G(c, rd, rs);
RISC_INST_ADD_CHECK(c->instructions, inst);
}
}
- int rs_vars = risc_reg_cached_vars(rs);
+ int rs_vars = f->rops->reg_cached_vars(rs);
if (0 == rs_vars) {
if (scf_vector_add(rs->dag_nodes, dn) < 0)
return -ENOMEM;
}
- scf_register_t* lr = risc_find_register("lr");
- scf_register_t* sp = risc_find_register("sp");
- scf_register_t* x0 = risc_find_register("x0");
+ scf_register_t* lr = f->rops->find_register("lr");
+ scf_register_t* sp = f->rops->find_register("sp");
+ scf_register_t* x0 = f->rops->find_register("x0");
scf_instruction_t* inst;
scf_instruction_t* inst_sp = NULL;
scf_instruction_t* inst_sp2 = NULL;
}
}
- ret = risc_overflow_reg(x0, c, f);
+ ret = f->rops->overflow_reg(x0, c, f);
if (ret < 0) {
scf_loge("\n");
return ret;
}
- risc_call_rabi(NULL, NULL, c);
+ risc_call_rabi(NULL, NULL, c, f);
int32_t stack_size = _risc_inst_call_stack_size(c);
if (stack_size > 0) {
scf_register_t* saved_regs[RISC_ABI_CALLER_SAVES_NB];
- int save_size = risc_caller_save_regs(c, f, risc_abi_caller_saves, RISC_ABI_CALLER_SAVES_NB, stack_size, saved_regs);
+ int save_size = f->rops->caller_save_regs(c, f, risc_abi_caller_saves, RISC_ABI_CALLER_SAVES_NB, stack_size, saved_regs);
if (save_size < 0) {
scf_loge("\n");
return save_size;
}
if (save_size > 0) {
- ret = risc_pop_regs(c, f, saved_regs, save_size >> 3, updated_regs, nb_updated);
+ ret = f->rops->pop_regs(c, f, saved_regs, save_size >> 3, updated_regs, nb_updated);
if (ret < 0) {
scf_loge("\n");
return ret;
if (ret < 0)
return ret;
- r = risc_find_register_color_bytes(r->color, size);
+ r = f->rops->find_register_color_bytes(r->color, size);
if (sib.index)
ret = ctx->iops->SIB2G(c, f, r, &sib);
if (ret < 0)
return ret;
- r = risc_find_register_color_bytes(r->color, size);
+ r = f->rops->find_register_color_bytes(r->color, size);
if (sib.index)
ret = ctx->iops->SIB2G(c, f, r, &sib);
if (!c->dsts || c->dsts->size != 1)
return -EINVAL;
- scf_register_t* rd = NULL;
- scf_risc_context_t* risc = ctx->priv;
- scf_3ac_operand_t* base = c->srcs->data[0];
- scf_3ac_operand_t* dst = c->dsts->data[0];
- scf_instruction_t* inst;
- scf_function_t* f = risc->f;
+ scf_risc_context_t* risc = ctx->priv;
+ scf_3ac_operand_t* base = c->srcs->data[0];
+ scf_3ac_operand_t* dst = c->dsts->data[0];
+ scf_instruction_t* inst = NULL;
+ scf_function_t* f = risc->f;
+ scf_register_t* rd = NULL;
if (!base || !base->dag_node)
return -EINVAL;
return -ENOMEM;
}
- scf_register_t* rax = risc_find_register("rax");
+ scf_risc_context_t* risc = ctx->priv;
+ scf_function_t* f = risc->f;
+ scf_register_t* rax = f->rops->find_register("rax");
scf_risc_OpCode_t* push;
- scf_instruction_t* inst;
+ scf_instruction_t* inst;
#if 0
push = risc_find_OpCode(SCF_RISC_PUSH, 8,8, SCF_RISC_G);
return -ENOMEM;
}
- scf_register_t* rax = risc_find_register("rax");
+ scf_risc_context_t* risc = ctx->priv;
+ scf_function_t* f = risc->f;
+ scf_register_t* rax = f->rops->find_register("rax");
scf_risc_OpCode_t* pop;
- scf_instruction_t* inst;
+ scf_instruction_t* inst;
#if 0
pop = risc_find_OpCode(SCF_RISC_POP, 8,8, SCF_RISC_G);
inst = ctx->iops->G(pop, rax);
scf_loge("c->srcs->size: %d\n", c->srcs->size);
assert(3 == c->srcs->size);
- scf_register_t* rbp = risc_find_register("rbp");
+ scf_register_t* rbp = f->rops->find_register("rbp");
scf_register_t* rptr = NULL;
scf_register_t* rap = NULL;
scf_instruction_t* inst = NULL;
assert(2 == c->srcs->size);
- scf_register_t* rbp = risc_find_register("rbp");
+ scf_register_t* rbp = f->rops->find_register("rbp");
scf_register_t* rptr = NULL;
scf_register_t* rap = NULL;
scf_instruction_t* inst = NULL;
assert(1 == c->dsts->size && 3 == c->srcs->size);
- scf_register_t* rbp = risc_find_register("rbp");
+ scf_register_t* rbp = f->rops->find_register("rbp");
scf_register_t* rd = NULL; // result
scf_register_t* rap = NULL; // ap
scf_register_t* rptr = NULL; // ptr
}
assert(dst->dag_node->color > 0);
- ret = risc_overflow_reg2(rd, dst->dag_node, c, f);
+ ret = f->rops->overflow_reg2(rd, dst->dag_node, c, f);
if (ret < 0) {
scf_loge("\n");
return ret;
scf_register_t* rd = NULL;
scf_register_t* rs = NULL;
- scf_register_t* sp = risc_find_register("sp");
- scf_register_t* fp = risc_find_register("fp");
+ scf_register_t* sp = f->rops->find_register("sp");
+ scf_register_t* fp = f->rops->find_register("fp");
scf_risc_OpCode_t* pop;
scf_risc_OpCode_t* mov;
int retsize = size > 4 ? 8 : 4;
if (is_float) {
- rd = risc_find_register_type_id_bytes(is_float, 0, retsize);
+ rd = f->rops->find_register_type_id_bytes(is_float, 0, retsize);
if (0 == src->dag_node->color) {
src->dag_node->color = -1;
return -1;
} else {
- rd = risc_find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], retsize);
+ rd = f->rops->find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], retsize);
if (0 == src->dag_node->color) {
if (rd->bytes > size)
if (!c->srcs || c->srcs->size != 3)
return -EINVAL;
- scf_risc_context_t* risc = ctx->priv;
+ scf_risc_context_t* risc = ctx->priv;
scf_function_t* f = risc->f;
scf_3ac_operand_t* dst = c->srcs->data[0];
scf_3ac_operand_t* data = c->srcs->data[1];
scf_3ac_operand_t* count = c->srcs->data[2];
scf_instruction_t* inst = NULL;
- scf_register_t* rax = risc_find_register("rax");
- scf_register_t* rcx = risc_find_register("rcx");
- scf_register_t* rdi = risc_find_register("rdi");
+ scf_register_t* rax = f->rops->find_register("rax");
+ scf_register_t* rcx = f->rops->find_register("rcx");
+ scf_register_t* rdi = f->rops->find_register("rdi");
scf_register_t* rd;
scf_risc_OpCode_t* mov;
scf_risc_OpCode_t* stos;
return -ENOMEM;
}
- int ret = risc_overflow_reg2(rdi, dst->dag_node, c, f);
+ int ret = f->rops->overflow_reg2(rdi, dst->dag_node, c, f);
if (ret < 0)
return ret;
- ret = risc_overflow_reg2(rax, data->dag_node, c, f);
+ ret = f->rops->overflow_reg2(rax, data->dag_node, c, f);
if (ret < 0)
return ret;
- ret = risc_overflow_reg2(rcx, count->dag_node, c, f);
+ ret = f->rops->overflow_reg2(rcx, count->dag_node, c, f);
if (ret < 0)
return ret;
static int _risc_inst_end_handler(scf_native_t* ctx, scf_3ac_code_t* c)
{
+ scf_risc_context_t* risc = ctx->priv;
+ scf_instruction_t* inst = NULL;
+ scf_function_t* f = risc->f;
+
if (!c->instructions) {
c->instructions = scf_vector_alloc();
if (!c->instructions)
return -ENOMEM;
}
- scf_register_t* sp = risc_find_register("sp");
- scf_register_t* fp = risc_find_register("fp");
+ scf_register_t* sp = f->rops->find_register("sp");
+ scf_register_t* fp = f->rops->find_register("fp");
scf_register_t* r;
-
- scf_instruction_t* inst = NULL;
-
int i;
for (i = RISC_ABI_CALLEE_SAVES_NB - 1; i >= 0; i--) {
- r = risc_find_register_type_id_bytes(0, risc_abi_callee_saves[i], 8);
+ r = f->rops->find_register_type_id_bytes(0, risc_abi_callee_saves[i], 8);
if (!r->used) {
- r = risc_find_register_type_id_bytes(0, risc_abi_callee_saves[i], 4);
+ r = f->rops->find_register_type_id_bytes(0, risc_abi_callee_saves[i], 4);
if (!r->used)
continue;
return -ENOMEM;
}
- r = risc_find_register_color(dn->color);
+ r = f->rops->find_register_color(dn->color);
- if (risc_reg_used(r, dn)) {
+ if (f->rops->reg_used(r, dn)) {
dn->color = -1;
dn->loaded = 0;
scf_vector_del(r->dag_nodes, dn);
return -ENOMEM;
}
- r = risc_find_register_color(dn->color);
+ r = f->rops->find_register_color(dn->color);
- ret = risc_overflow_reg2(r, dn, c, f);
+ ret = f->rops->overflow_reg2(r, dn, c, f);
if (ret < 0) {
scf_loge("\n");
return ret;
if (ret < 0)
return ret;
- rs = risc_find_register_color_bytes(rs->color, sib.size);
+ rs = f->rops->find_register_color_bytes(rs->color, sib.size);
}
} else
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
if (ret < 0)
return ret;
- rs = risc_find_register_color_bytes(rs->color, sib.size);
+ rs = f->rops->find_register_color_bytes(rs->color, sib.size);
}
} else
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
if (ret < 0)
return ret;
- rs = risc_find_register_color_bytes(rs->color, sib.size);
+ rs = f->rops->find_register_color_bytes(rs->color, sib.size);
}
} else
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
if (ret < 0)
return ret;
- rs = risc_find_register_color_bytes(rs->color, sib.size);
+ rs = f->rops->find_register_color_bytes(rs->color, sib.size);
} else
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
if (ret < 0)
return ret;
- rs = risc_find_register_color_bytes(rs->color, sib.size);
+ rs = f->rops->find_register_color_bytes(rs->color, sib.size);
}
} else
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
if (!c->srcs || c->srcs->size != 3)
return -EINVAL;
- scf_risc_context_t* risc = ctx->priv;
+ scf_risc_context_t* risc = ctx->priv;
scf_function_t* f = risc->f;
scf_3ac_operand_t* base = c->srcs->data[0];
if (ret < 0)
return ret;
- rs = risc_find_register_color_bytes(rs->color, sib.size);
+ rs = f->rops->find_register_color_bytes(rs->color, sib.size);
}
} else
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
if (ret < 0)
return ret;
- rs = risc_find_register_color_bytes(rs->color, sib.size);
+ rs = f->rops->find_register_color_bytes(rs->color, sib.size);
}
} else
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
if (ret < 0)
return ret;
- rs = risc_find_register_color_bytes(rs->color, sib.size);
+ rs = f->rops->find_register_color_bytes(rs->color, sib.size);
}
} else
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
if (ret < 0)
return ret;
- rs = risc_find_register_color_bytes(rs->color, sib.size);
+ rs = f->rops->find_register_color_bytes(rs->color, sib.size);
}
} else
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
if (ret < 0)
return ret;
- rs = risc_find_register_color_bytes(rs->color, sib.size);
+ rs = f->rops->find_register_color_bytes(rs->color, sib.size);
}
} else
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
if (ret < 0)
return ret;
- rs = risc_find_register_color_bytes(rs->color, size);
+ rs = f->rops->find_register_color_bytes(rs->color, size);
}
} else
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
if (ret < 0)
return ret;
- rs = risc_find_register_color_bytes(rs->color, size);
+ rs = f->rops->find_register_color_bytes(rs->color, size);
}
} else
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
if (ret < 0)
return ret;
- rs = risc_find_register_color_bytes(rs->color, size);
+ rs = f->rops->find_register_color_bytes(rs->color, size);
}
} else
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
if (ret < 0)
return ret;
- rs = risc_find_register_color_bytes(rs->color, size);
+ rs = f->rops->find_register_color_bytes(rs->color, size);
} else
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
if (ret < 0)
return ret;
- rs = risc_find_register_color_bytes(rs->color, size);
+ rs = f->rops->find_register_color_bytes(rs->color, size);
} else
RISC_SELECT_REG_CHECK(&rs, src->dag_node, c, f, 1);
ret = risc_select_free_reg(&r, c, f, 0);
if (ret < 0)
return ret;
- r = risc_find_register_color_bytes(r->color, size);
+ r = f->rops->find_register_color_bytes(r->color, size);
ret = ctx->iops->P2G(c, f, r, sib.base, 0, size);
if (ret < 0)
ret = risc_select_free_reg(&r, c, f, 0);
if (ret < 0)
return ret;
- r = risc_find_register_color_bytes(r->color, size);
+ r = f->rops->find_register_color_bytes(r->color, size);
ret = ctx->iops->P2G(c, f, r, sib.base, 0, size);
if (ret < 0)
static int _risc_rcg_call(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
- scf_risc_context_t* risc = ctx->priv;
- scf_function_t* f = risc->f;
- scf_dag_node_t* dn = NULL;
- scf_register_t* r = NULL;
- scf_3ac_operand_t* src = NULL;
- scf_3ac_operand_t* dst = NULL;
- scf_graph_node_t* gn = NULL;
+ scf_risc_context_t* risc = ctx->priv;
+ scf_function_t* f = risc->f;
+ scf_dag_node_t* dn = NULL;
+ scf_register_t* r = NULL;
+ scf_3ac_operand_t* src = NULL;
+ scf_3ac_operand_t* dst = NULL;
+ scf_graph_node_t* gn = NULL;
int i;
int ret;
int size = risc_variable_size (dn->var);
if (0 == i)
- r = risc_find_register_type_id_bytes(is_float, SCF_RISC_REG_X0, size);
+ r = f->rops->find_register_type_id_bytes(is_float, SCF_RISC_REG_X0, size);
else if (!is_float)
- r = risc_find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], size);
+ r = f->rops->find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], size);
else
r = NULL;
int nb_ints = 0;
int nb_floats = 0;
- risc_call_rabi(&nb_ints, &nb_floats, c);
+ risc_call_rabi(&nb_ints, &nb_floats, c, f);
for (i = 1; i < c->srcs->size; i++) {
src = c->srcs->data[i];
for (i = 0; i < nb_ints; i++) {
- scf_register_t* rabi = NULL;
+ scf_register_t* rabi = NULL;
scf_graph_node_t* gn_rabi = NULL;
- rabi = risc_find_register_type_id_bytes(0, risc_abi_regs[i], dn_pf->var->size);
+ rabi = f->rops->find_register_type_id_bytes(0, risc_abi_regs[i], dn_pf->var->size);
ret = _risc_rcg_make_node(&gn_rabi, g, NULL, rabi);
if (ret < 0) {
static int _risc_rcg_return_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
{
- int i;
+ scf_risc_context_t* risc = ctx->priv;
+ scf_function_t* f = risc->f;
- scf_register_t* r;
scf_3ac_operand_t* src;
scf_graph_node_t* gn;
scf_dag_node_t* dn;
+ scf_register_t* r;
int ret = _risc_rcg_make2(c, NULL, NULL);
if (ret < 0)
if (!c->srcs)
return 0;
+ int i;
for (i = 0; i < c->srcs->size; i++) {
src = c->srcs->data[i];
dn = src->dag_node;
int is_float = scf_variable_float(dn->var);
- int size = risc_variable_size (dn->var);
+ int size = risc_variable_size(dn->var);
size = size > 4 ? 8 : 4;
return -1;
}
- r = risc_find_register_type_id_bytes(is_float, 0, size);
+ r = f->rops->find_register_type_id_bytes(is_float, 0, size);
} else
- r = risc_find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], size);
+ r = f->rops->find_register_type_id_bytes(is_float, risc_abi_ret_regs[i], size);
ret = _risc_rcg_make_node(&gn, g, dn, r);
if (ret < 0)
#include"scf_risc.h"
-scf_register_t risc_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},
-
- {28, 4, "w28", RISC_COLOR(0, 28, 0xf), NULL, 0, 0},
- {28, 8, "x28", RISC_COLOR(0, 28, 0xff), NULL, 0, 0},
-
-// fp = x29 = bp
- {29, 4, "w29", RISC_COLOR(0, 29, 0xf), NULL, 0, 0},
- {29, 8, "fp", RISC_COLOR(0, 29, 0xff), NULL, 0, 0},
-// lr = x30
- {30, 4, "w30", RISC_COLOR(0, 30, 0xf), NULL, 0, 0},
- {30, 8, "lr", RISC_COLOR(0, 30, 0xff), NULL, 0, 0},
- {31, 8, "sp", 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},
-};
-
-int risc_reg_cached_vars(scf_register_t* r)
-{
- int nb_vars = 0;
- int i;
-
- for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) {
-
- scf_register_t* r2 = &(risc_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 (!RISC_COLOR_CONFLICT(r->color, r2->color))
- continue;
-
- nb_vars += r2->dag_nodes->size;
- }
-
- return nb_vars;
-}
-
-int risc_registers_init()
-{
- int i;
- for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) {
-
- scf_register_t* r = &(risc_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 risc_registers_clear()
-{
- int i;
- for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) {
-
- scf_register_t* r = &(risc_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;
- }
-}
-
-int risc_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 = risc_find_register("sp");
-
- uint32_t opcode;
-
- int ret;
- int size = 0;
- int k = 0;
-
- for (j = 0; j < nb_regs; j++) {
- r2 = risc_find_register_type_id_bytes(0, regs[j], 8);
-
- for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) {
- r = &(risc_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 (RISC_COLOR_CONFLICT(r2->color, r->color))
- break;
- }
-
- if (i == sizeof(risc_registers) / sizeof(risc_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 risc_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 = risc_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(risc_registers) / sizeof(risc_registers[0]); i++) {
- r = &(risc_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 (RISC_COLOR_CONFLICT(r2->color, r->color))
- break;
- }
-
- if (i == sizeof(risc_registers) / sizeof(risc_registers[0]))
- continue;
-
- for (i = 0; i < nb_updated; i++) {
-
- r = updated_regs[i];
-
- if (RISC_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, sp, sp, 8);
- RISC_INST_ADD_CHECK(c->instructions, inst);
- }
- }
- return 0;
-}
-
-int risc_registers_reset()
-{
- int i;
- for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) {
-
- scf_register_t* r = &(risc_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;
-}
-
-scf_register_t* risc_find_register(const char* name)
-{
- int i;
- for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) {
-
- scf_register_t* r = &(risc_registers[i]);
-
- if (!strcmp(r->name, name))
- return r;
- }
- return NULL;
-}
-
-scf_register_t* risc_find_register_type_id_bytes(uint32_t type, uint32_t id, int bytes)
-{
- int i;
- for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) {
-
- scf_register_t* r = &(risc_registers[i]);
-
- if (RISC_COLOR_TYPE(r->color) == type && r->id == id && r->bytes == bytes)
- return r;
- }
- return NULL;
-}
-
-scf_register_t* risc_find_register_color(intptr_t color)
-{
- int i;
- for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) {
-
- scf_register_t* r = &(risc_registers[i]);
-
- if (r->color == color)
- return r;
- }
- return NULL;
-}
-
-scf_register_t* risc_find_register_color_bytes(intptr_t color, int bytes)
-{
- int i;
- for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) {
-
- scf_register_t* r = &(risc_registers[i]);
-
- if (RISC_COLOR_CONFLICT(r->color, color) && r->bytes == bytes)
- return r;
- }
- return NULL;
-}
-
-scf_vector_t* risc_register_colors()
-{
- scf_vector_t* colors = scf_vector_alloc();
- if (!colors)
- return NULL;
-
- int i;
- for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) {
-
- scf_register_t* r = &(risc_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 risc_save_var2(scf_dag_node_t* dn, scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f)
{
scf_variable_t* v = dn->var;
if (dn->color <= 0)
return -EINVAL;
- scf_register_t* r = risc_find_register_color(dn->color);
+ scf_register_t* r = f->rops->find_register_color(dn->color);
return risc_save_var2(dn, r, c, f);
}
return 0;
}
-int risc_overflow_reg(scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f)
-{
- int i;
-
- for (i = 0; i < sizeof(risc_registers) / sizeof(risc_registers[0]); i++) {
-
- scf_register_t* r2 = &(risc_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 (!RISC_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 risc_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(risc_registers) / sizeof(risc_registers[0]); i++) {
-
- r2 = &(risc_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 (!RISC_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;
-}
-
-static int _risc_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(risc_registers) / sizeof(risc_registers[0]); i++) {
-
- r2 = &(risc_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 (!RISC_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 risc_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(risc_registers) / sizeof(risc_registers[0]); i++) {
-
- r2 = &(risc_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 (!RISC_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;
-}
-
-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 = risc_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;
-}
-
-scf_register_t* risc_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(risc_registers) / sizeof(risc_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 = risc_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(risc_registers) / sizeof(risc_registers[0]); i++) {
-
- scf_register_t* r = &(risc_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 (RISC_COLOR_CONFLICT(r->color, rn->dag_node->color))
- break;
- } else {
- assert(rn->reg);
-
- if (RISC_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(risc_registers) / sizeof(risc_registers[0]); i++) {
-
- scf_register_t* r = &(risc_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
- && RISC_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
- && RISC_COLOR_CONFLICT(r->color, src->dag_node->color))
- break;
- }
-
- if (j < c->srcs->size)
- continue;
- }
-
- return r;
- }
-
- return NULL;
-}
-
int risc_load_const(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f)
{
scf_instruction_t* inst;
int var_size = risc_variable_size(dn->var);
if (dn->color > 0) {
- r = risc_find_register_color(dn->color);
+ r = f->rops->find_register_color(dn->color);
#if 1
- ret = _risc_overflow_reg3(r, dn, c, f);
+ ret = f->rops->overflow_reg3(r, dn, c, f);
if (ret < 0) {
scf_loge("\n");
return -1;
}
#endif
} else {
- r = risc_select_overflowed_reg(dn, c, is_float);
+ r = f->rops->select_overflowed_reg(dn, c, is_float);
if (!r) {
scf_loge("\n");
return -1;
}
- ret = risc_overflow_reg(r, c, f);
+ ret = f->rops->overflow_reg(r, c, f);
if (ret < 0) {
scf_loge("overflow reg failed\n");
return ret;
}
assert(0 == r->dag_nodes->size);
- r = risc_find_register_type_id_bytes(is_float, r->id, var_size);
+ r = f->rops->find_register_type_id_bytes(is_float, r->id, var_size);
assert(0 == r->dag_nodes->size);
dn->color = r->color;
{
scf_register_t* r;
- r = risc_select_overflowed_reg(NULL, c, is_float);
+ r = f->rops->select_overflowed_reg(NULL, c, is_float);
if (!r) {
scf_loge("\n");
return -1;
}
- int ret = risc_overflow_reg(r, c, f);
+ int ret = f->rops->overflow_reg(r, c, f);
if (ret < 0) {
scf_loge("overflow reg failed\n");
return ret;
}
assert(0 == r->dag_nodes->size);
- r = risc_find_register_type_id_bytes(0, r->id, 8);
+ r = f->rops->find_register_type_id_bytes(0, r->id, 8);
assert(0 == r->dag_nodes->size);
ret = risc_rcg_make(c, c->rcg, NULL, r);
} else if (vb->local_flag) {
- rb = risc_find_register("fp");
+ rb = f->rops->find_register("fp");
disp = vb->bp_offset;
} else if (vb->global_flag) {
}
} else if (vb->local_flag) {
- rb = risc_find_register("fp");
+ rb = f->rops->find_register("fp");
disp = vb->bp_offset;
} else if (vb->global_flag) {
return ret;
}
- scf_register_t* ri2 = risc_find_register_color_bytes(ri->color, 8);
+ scf_register_t* ri2 = f->rops->find_register_color_bytes(ri->color, 8);
if (ri->bytes < ri2->bytes) {
return 0;
}
-void risc_call_rabi(int* p_nints, int* p_nfloats, scf_3ac_code_t* c)
+void risc_call_rabi(int* p_nints, int* p_nfloats, scf_3ac_code_t* c, scf_function_t* f)
{
scf_3ac_operand_t* src = NULL;
scf_dag_node_t* dn = NULL;
if (is_float) {
if (nfloats < RISC_ABI_NB)
- dn->rabi2 = risc_find_register_type_id_bytes(is_float, risc_abi_float_regs[nfloats++], size);
+ dn->rabi2 = f->rops->find_register_type_id_bytes(is_float, risc_abi_float_regs[nfloats++], size);
else
dn->rabi2 = NULL;
} else {
if (nints < RISC_ABI_NB)
- dn->rabi2 = risc_find_register_type_id_bytes(is_float, risc_abi_regs[nints++], size);
+ dn->rabi2 = f->rops->find_register_type_id_bytes(is_float, risc_abi_regs[nints++], size);
else
dn->rabi2 = NULL;
}
void risc_registers_clear();
scf_vector_t* risc_register_colors();
-scf_register_t* risc_find_register(const char* name);
+scf_register_t* risc_find_register(const char* name);
-scf_register_t* risc_find_register_type_id_bytes(uint32_t type, uint32_t id, int bytes);
+scf_register_t* risc_find_register_type_id_bytes(uint32_t type, uint32_t id, int bytes);
-scf_register_t* risc_find_register_color(intptr_t color);
+scf_register_t* risc_find_register_color(intptr_t color);
-scf_register_t* risc_find_register_color_bytes(intptr_t color, int bytes);
+scf_register_t* risc_find_register_color_bytes(intptr_t color, int bytes);
-scf_register_t* risc_find_abi_register(int index, int bytes);
+scf_register_t* risc_find_abi_register(int index, int bytes);
-scf_register_t* risc_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c, int is_float);
+scf_register_t* risc_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c, int is_float);
int risc_reg_cached_vars(scf_register_t* r);
int risc_overflow_reg (scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f);
int risc_overflow_reg2(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f);
+int risc_overflow_reg3(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f);
int risc_select_reg(scf_register_t** preg, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f, int load_flag);
int risc_array_index_reg(scf_sib_t* sib, scf_dag_node_t* base, scf_dag_node_t* index, scf_dag_node_t* scale, scf_3ac_code_t* c, scf_function_t* f);
-void risc_call_rabi(int* p_nints, int* p_nfloats, scf_3ac_code_t* c);
-
+void risc_call_rabi(int* p_nints, int* p_nfloats, scf_3ac_code_t* c, scf_function_t* f);
static inline int risc_inst_data_is_reg(scf_inst_data_t* id)
{
--- /dev/null
+#include"scf_risc.h"
+
+scf_register_t arm64_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},
+
+ {28, 4, "w28", RISC_COLOR(0, 28, 0xf), NULL, 0, 0},
+ {28, 8, "x28", RISC_COLOR(0, 28, 0xff), NULL, 0, 0},
+
+// fp = x29 = bp
+ {29, 4, "w29", RISC_COLOR(0, 29, 0xf), NULL, 0, 0},
+ {29, 8, "fp", RISC_COLOR(0, 29, 0xff), NULL, 0, 0},
+// lr = x30
+ {30, 4, "w30", RISC_COLOR(0, 30, 0xf), NULL, 0, 0},
+ {30, 8, "lr", RISC_COLOR(0, 30, 0xff), NULL, 0, 0},
+ {31, 8, "sp", 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},
+};
+
+scf_register_t* arm64_find_register(const char* name)
+{
+ int i;
+ for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+
+ scf_register_t* r = &(arm64_registers[i]);
+
+ if (!strcmp(r->name, name))
+ return r;
+ }
+ return NULL;
+}
+
+scf_register_t* arm64_find_register_type_id_bytes(uint32_t type, uint32_t id, int bytes)
+{
+ int i;
+ for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+
+ scf_register_t* r = &(arm64_registers[i]);
+
+ if (RISC_COLOR_TYPE(r->color) == type && r->id == id && r->bytes == bytes)
+ return r;
+ }
+ return NULL;
+}
+
+scf_register_t* arm64_find_register_color(intptr_t color)
+{
+ int i;
+ for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+
+ scf_register_t* r = &(arm64_registers[i]);
+
+ if (r->color == color)
+ return r;
+ }
+ return NULL;
+}
+
+scf_register_t* arm64_find_register_color_bytes(intptr_t color, int bytes)
+{
+ int i;
+ for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+
+ scf_register_t* r = &(arm64_registers[i]);
+
+ if (RISC_COLOR_CONFLICT(r->color, color) && r->bytes == bytes)
+ return r;
+ }
+ return NULL;
+}
+
+scf_vector_t* arm64_register_colors()
+{
+ scf_vector_t* colors = scf_vector_alloc();
+ if (!colors)
+ return NULL;
+
+ int i;
+ for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+
+ scf_register_t* r = &(arm64_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 arm64_reg_cached_vars(scf_register_t* r)
+{
+ int nb_vars = 0;
+ int i;
+
+ for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+
+ scf_register_t* r2 = &(arm64_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 (!RISC_COLOR_CONFLICT(r->color, r2->color))
+ continue;
+
+ nb_vars += r2->dag_nodes->size;
+ }
+
+ return nb_vars;
+}
+
+int arm64_registers_init()
+{
+ int i;
+ for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+
+ scf_register_t* r = &(arm64_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 arm64_registers_clear()
+{
+ int i;
+ for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+
+ scf_register_t* r = &(arm64_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;
+ }
+}
+
+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 = arm64_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 arm64_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 = arm64_find_register("sp");
+
+ uint32_t opcode;
+
+ int ret;
+ int size = 0;
+ int k = 0;
+
+ for (j = 0; j < nb_regs; j++) {
+ r2 = arm64_find_register_type_id_bytes(0, regs[j], 8);
+
+ for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+ r = &(arm64_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 (RISC_COLOR_CONFLICT(r2->color, r->color))
+ break;
+ }
+
+ if (i == sizeof(arm64_registers) / sizeof(arm64_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 arm64_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 = arm64_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(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+ r = &(arm64_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 (RISC_COLOR_CONFLICT(r2->color, r->color))
+ break;
+ }
+
+ if (i == sizeof(arm64_registers) / sizeof(arm64_registers[0]))
+ continue;
+
+ for (i = 0; i < nb_updated; i++) {
+
+ r = updated_regs[i];
+
+ if (RISC_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, sp, sp, 8);
+ RISC_INST_ADD_CHECK(c->instructions, inst);
+ }
+ }
+ return 0;
+}
+
+int arm64_registers_reset()
+{
+ int i;
+ for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+
+ scf_register_t* r = &(arm64_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 arm64_overflow_reg(scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f)
+{
+ int i;
+
+ for (i = 0; i < sizeof(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+
+ scf_register_t* r2 = &(arm64_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 (!RISC_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 arm64_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(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+
+ r2 = &(arm64_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 (!RISC_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 arm64_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(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+
+ r2 = &(arm64_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 (!RISC_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 arm64_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(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+
+ r2 = &(arm64_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 (!RISC_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* arm64_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(arm64_registers) / sizeof(arm64_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 = risc_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(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+
+ scf_register_t* r = &(arm64_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 (RISC_COLOR_CONFLICT(r->color, rn->dag_node->color))
+ break;
+ } else {
+ assert(rn->reg);
+
+ if (RISC_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(arm64_registers) / sizeof(arm64_registers[0]); i++) {
+
+ scf_register_t* r = &(arm64_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
+ && RISC_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
+ && RISC_COLOR_CONFLICT(r->color, src->dag_node->color))
+ break;
+ }
+
+ if (j < c->srcs->size)
+ continue;
+ }
+
+ return r;
+ }
+
+ return NULL;
+}
+
+scf_regs_ops_t regs_ops_arm64 =
+{
+ .name = "arm64",
+
+ .registers_init = arm64_registers_init,
+ .registers_reset = arm64_registers_reset,
+ .registers_clear = arm64_registers_clear,
+ .register_colors = arm64_register_colors,
+
+ .reg_used = arm64_reg_used,
+ .reg_cached_vars = arm64_reg_cached_vars,
+
+ .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,
+};
+
+scf_regs_ops_t regs_ops_naja =
+{
+ .name = "naja",
+
+ .registers_init = arm64_registers_init,
+ .registers_reset = arm64_registers_reset,
+ .registers_clear = arm64_registers_clear,
+ .register_colors = arm64_register_colors,
+
+ .reg_used = arm64_reg_used,
+ .reg_cached_vars = arm64_reg_cached_vars,
+
+ .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,
+};
+
scf_native_ops_t* ops;
scf_inst_ops_t* iops;
+ scf_regs_ops_t* rops;
void* priv;
int (*select_inst)(scf_native_t* ctx, scf_function_t* f);
};
+struct scf_regs_ops_s
+{
+ const char* name;
+
+ int (*registers_init )();
+ int (*registers_reset )();
+ void (*registers_clear )();
+ scf_vector_t* (*register_colors )();
+
+ int (*reg_used )(scf_register_t* r, scf_dag_node_t* dn);
+ int (*reg_cached_vars )(scf_register_t* r);
+
+ int (*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 (*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);
+
+ scf_register_t* (*find_register )(const char* name);
+ scf_register_t* (*find_register_color )(intptr_t color);
+ scf_register_t* (*find_register_color_bytes )(intptr_t color, int bytes);
+ scf_register_t* (*find_register_type_id_bytes)(uint32_t type, uint32_t id, int bytes);
+
+ scf_register_t* (*select_overflowed_reg )(scf_dag_node_t* dn, scf_3ac_code_t* c, int is_float);
+
+ int (*overflow_reg )(scf_register_t* r, scf_3ac_code_t* c, scf_function_t* f);
+ int (*overflow_reg2)(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f);
+ int (*overflow_reg3)(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c, scf_function_t* f);
+};
+
struct scf_inst_ops_s
{
const char* name;
CFILES += ../native/risc/scf_risc_opcode.c
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_arm64.c
CFILES += ../native/risc/scf_naja.c
#include"scf_elf.h"
#include<dlfcn.h>
-#if 1
+#if 0
#define NAJA_PRINTF printf
#else
#define NAJA_PRINTF