From: yu.dongliang <18588496441@163.com> Date: Fri, 11 Apr 2025 12:19:45 +0000 (+0800) Subject: use TTL Nand to combine the circuit graph in 'eda/native' module X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=scf.git use TTL Nand to combine the circuit graph in 'eda/native' module --- diff --git a/core/scf_basic_block.h b/core/scf_basic_block.h index 4f193ac..f823032 100644 --- a/core/scf_basic_block.h +++ b/core/scf_basic_block.h @@ -77,6 +77,12 @@ struct scf_basic_block_s void* ds_auto_gc; +#define SCF_EDA_FLAG_BITS 4 +#define SCF_EDA_FLAG_ZERO 1 +#define SCF_EDA_FLAG_SIGN 2 + ScfEpin* flag_pins[SCF_EDA_FLAG_BITS]; + ScfEpin* mask_pin; + int code_bytes; int index; diff --git a/core/scf_core_types.h b/core/scf_core_types.h index af2aea8..f27bdb0 100644 --- a/core/scf_core_types.h +++ b/core/scf_core_types.h @@ -29,6 +29,8 @@ typedef struct scf_ecomponent_s ScfEcomponent; typedef struct scf_efunction_s ScfEfunction; typedef struct scf_eboard_s ScfEboard; +#define SCF_EDA_MAX_BITS 256 + enum scf_core_types { SCF_OP_ADD = 0, // + diff --git a/core/scf_dag.h b/core/scf_dag.h index 65191e1..052366d 100644 --- a/core/scf_dag.h +++ b/core/scf_dag.h @@ -37,7 +37,6 @@ struct scf_dag_node_s void* rabi; void* rabi2; -#define SCF_EDA_MAX_BITS 256 ScfEpin* pins[SCF_EDA_MAX_BITS]; int n_pins; diff --git a/core/scf_function.c b/core/scf_function.c index 46bf26b..1b537a4 100644 --- a/core/scf_function.c +++ b/core/scf_function.c @@ -45,10 +45,6 @@ scf_function_t* scf_function_alloc(scf_lex_word_t* w) if (!f->jmps) goto _jmps_error; - f->dfs_tree = scf_vector_alloc(); - if (!f->dfs_tree) - goto _dfs_tree_error; - f->bb_loops = scf_vector_alloc(); if (!f->bb_loops) goto _loop_error; @@ -74,8 +70,6 @@ _text_rela_error: _group_error: scf_vector_free(f->bb_loops); _loop_error: - scf_vector_free(f->dfs_tree); -_dfs_tree_error: scf_vector_free(f->jmps); _jmps_error: scf_vector_free(f->caller_functions); diff --git a/core/scf_function.h b/core/scf_function.h index 87e02da..be10c7e 100644 --- a/core/scf_function.h +++ b/core/scf_function.h @@ -31,10 +31,8 @@ struct scf_function_s { scf_list_t dag_list_head; - scf_vector_t* dfs_tree; scf_vector_t* bb_loops; scf_vector_t* bb_groups; - int max_dfo; scf_vector_t* text_relas; // re-localtions in .text segment scf_vector_t* data_relas; // re-localtions in .data segment @@ -61,6 +59,7 @@ struct scf_function_s { uint32_t vargs_flag:1; uint32_t void_flag :1; + uint32_t call_flag :1; uint32_t vla_flag :1; }; diff --git a/core/scf_optimizer.c b/core/scf_optimizer.c index 49440a9..79fd61c 100644 --- a/core/scf_optimizer.c +++ b/core/scf_optimizer.c @@ -15,6 +15,7 @@ extern scf_optimizer_t scf_optimizer_pointer_aliases; extern scf_optimizer_t scf_optimizer_loads_saves; extern scf_optimizer_t scf_optimizer_dominators; +extern scf_optimizer_t scf_optimizer_dominators_reverse; extern scf_optimizer_t scf_optimizer_auto_gc_find; extern scf_optimizer_t scf_optimizer_auto_gc; @@ -59,6 +60,8 @@ static scf_optimizer_t* scf_optimizers[] = &scf_optimizer_group, &scf_optimizer_generate_loads_saves, + + &scf_optimizer_dominators_reverse, }; int scf_optimize(scf_ast_t* ast, scf_vector_t* functions) diff --git a/core/scf_optimizer_dominators.c b/core/scf_optimizer_dominators.c index 7085819..207845d 100644 --- a/core/scf_optimizer_dominators.c +++ b/core/scf_optimizer_dominators.c @@ -38,9 +38,9 @@ static int __bb_dfs_tree(scf_basic_block_t* root, scf_vector_t* edges, int* tota return 0; } -static int _bb_dfs_tree(scf_list_t* bb_list_head, scf_function_t* f) +static int _bb_dfs_tree(scf_list_t* bb_list_head, scf_vector_t* tree) { - if (!bb_list_head) + if (!bb_list_head || !tree) return -EINVAL; if (scf_list_empty(bb_list_head)) @@ -61,9 +61,7 @@ static int _bb_dfs_tree(scf_list_t* bb_list_head, scf_function_t* f) } assert(&bb->list == scf_list_head(bb_list_head)); - f->max_dfo = total - 1; - - return __bb_dfs_tree(bb, f->dfs_tree, &total); + return __bb_dfs_tree(bb, tree, &total); } static int _bb_cmp_dfo(const void* p0, const void* p1) @@ -292,23 +290,32 @@ static int _optimize_dominators(scf_ast_t* ast, scf_function_t* f, scf_vector_t* return -EINVAL; scf_bb_edge_t* edge; + scf_vector_t* tree; scf_list_t* bb_list_head = &f->basic_block_list_head; + int ret; + int i; + if (scf_list_empty(bb_list_head)) return 0; - scf_vector_clear(f->dfs_tree, free); + tree = scf_vector_alloc(); + if (!tree) + return -ENOMEM; - int ret = _bb_dfs_tree(bb_list_head, f); + ret = _bb_dfs_tree(bb_list_head, tree); if (ret < 0) return ret; - int i; - for (i = 0; i < f->dfs_tree->size; i++) { - edge = f->dfs_tree->data[i]; + for (i = 0; i < tree->size; i++) { + edge = tree->data[i]; scf_logd("bb_%p_%d --> bb_%p_%d\n", edge->start, edge->start->dfo, edge->end, edge->end->dfo); } + scf_vector_clear(tree, free); + scf_vector_free(tree); + tree = NULL; + ret = _bb_find_dominators(bb_list_head); if (ret < 0) { scf_loge("\n"); diff --git a/core/scf_optimizer_dominators_reverse.c b/core/scf_optimizer_dominators_reverse.c new file mode 100644 index 0000000..86811a8 --- /dev/null +++ b/core/scf_optimizer_dominators_reverse.c @@ -0,0 +1,334 @@ +#include"scf_optimizer.h" + +static int __bb_dfs_tree(scf_basic_block_t* root, scf_vector_t* edges, int* total) +{ + scf_basic_block_t* bb; + scf_bb_edge_t* edge; + + int ret; + int i; + + assert(!root->jmp_flag); + + root->visit_flag = 1; + + for (i = 0; i < root->prevs->size; ++i) { + bb = root->prevs->data[i]; + + if (bb->visit_flag) + continue; + + edge = malloc(sizeof(scf_bb_edge_t)); + if (!edge) + return -ENOMEM; + + edge->start = root; + edge->end = bb; + + ret = scf_vector_add(edges, edge); + if ( ret < 0) + return ret; + + ret = __bb_dfs_tree(bb, edges, total); + if ( ret < 0) + return ret; + } + + root->dfo = --*total; + return 0; +} + +static int _bb_dfs_tree(scf_list_t* bb_list_head, scf_vector_t* tree) +{ + if (!bb_list_head) + return -EINVAL; + + if (scf_list_empty(bb_list_head)) + return 0; + + scf_basic_block_t* bb; + scf_list_t* l; + + int total = 0; + + for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); l = scf_list_next(l)) { + bb = scf_list_data(l, scf_basic_block_t, list); + + bb->visit_flag = 0; + + if (!bb->jmp_flag) + ++total; + } + assert(&bb->list == scf_list_tail(bb_list_head)); + + return __bb_dfs_tree(bb, tree, &total); +} + +static int _bb_cmp_dfo(const void* p0, const void* p1) +{ + scf_basic_block_t* bb0 = *(scf_basic_block_t**)p0; + scf_basic_block_t* bb1 = *(scf_basic_block_t**)p1; + + if (bb0->dfo < bb1->dfo) + return -1; + if (bb0->dfo > bb1->dfo) + return 1; + return 0; +} + +static int _bb_intersection(scf_vector_t* dst, scf_vector_t* src) +{ + int k0 = 0; + int k1 = 0; + + while (k0 < dst->size && k1 < src->size) { + + scf_basic_block_t* bb0 = dst->data[k0]; + scf_basic_block_t* bb1 = src->data[k1]; + + if (bb0->dfo < bb1->dfo) { + + int ret = scf_vector_del(dst, bb0); + if (ret < 0) + return ret; + continue; + } + + if (bb0->dfo > bb1->dfo) { + ++k1; + continue; + } + + ++k0; + ++k1; + } + + dst->size = k0; + return 0; +} + +static int __find_reverse_dominators(scf_list_t* bb_list_head) +{ + if (!bb_list_head) + return -EINVAL; + + if (scf_list_empty(bb_list_head)) + return 0; + + scf_list_t* l; + scf_basic_block_t* bb; + scf_vector_t* all; + + int i; + int j; + int ret; + int changed; + + all = scf_vector_alloc(); + if (!all) + return -ENOMEM; + + for (l = scf_list_tail(bb_list_head); l != scf_list_sentinel(bb_list_head); l = scf_list_prev(l)) { + + bb = scf_list_data(l, scf_basic_block_t, list); + if (bb->jmp_flag) + continue; + + ret = scf_vector_add(all, bb); + if (ret < 0) + goto error; + } + + scf_vector_qsort(all, _bb_cmp_dfo); + + for (i = 0; i < all->size; i++) { + bb = all->data[i]; + + scf_vector_qsort(bb->prevs, _bb_cmp_dfo); + scf_vector_qsort(bb->nexts, _bb_cmp_dfo); + + if (0 == bb->dfo) { + + if (!bb->dominators) { + bb->dominators = scf_vector_alloc(); + if (!bb->dominators) { + ret = -ENOMEM; + goto error; + } + } else + scf_vector_clear(bb->dominators, NULL); + + ret = scf_vector_add(bb->dominators, bb); + if (ret < 0) + goto error; + + scf_logd("bb: %p_%d, dom size: %d\n", bb, bb->dfo, bb->dominators->size); + continue; + } + + if (bb->dominators) + scf_vector_free(bb->dominators); + + bb->dominators = scf_vector_clone(all); + if (!bb->dominators) { + ret = -ENOMEM; + goto error; + } + + scf_logd("bb: %p_%d, dom size: %d\n", bb, bb->dfo, bb->dominators->size); + } + + do { + changed = 0; + + for (i = 1; i < all->size; i++) { + bb = all->data[i]; + + scf_vector_t* dominators = NULL; + + for (j = 0; j < bb->nexts->size; j++) { + scf_basic_block_t* next = bb->nexts->data[j]; + + if (!dominators) { + dominators = scf_vector_clone(next->dominators); + if (!dominators) { + ret = -ENOMEM; + goto error; + } + continue; + } + + ret = _bb_intersection(dominators, next->dominators); + if (ret < 0) { + scf_vector_free(dominators); + goto error; + } + } + + scf_logd("bb: %p, dominators: %p, bb->nexts->size: %d\n", + bb, dominators, bb->nexts->size); + + scf_basic_block_t* dom = NULL; + scf_basic_block_t* dom1 = bb; + + for (j = 0; j < dominators->size; j++) { + dom = dominators->data[j]; + + if (bb->dfo == dom->dfo) + break; + + if (bb->dfo < dom->dfo) + break; + } + if (bb->dfo < dom->dfo) { + + for (; j < dominators->size; j++) { + dom = dominators->data[j]; + dominators->data[j] = dom1; + dom1 = dom; + } + } + if (j == dominators->size) { + ret = scf_vector_add(dominators, dom1); + if (ret < 0) { + scf_vector_free(dominators); + goto error; + } + } + + if (dominators->size != bb->dominators->size) + ++changed; + else { + int k0 = 0; + int k1 = 0; + + while (k0 < dominators->size && k1 < bb->dominators->size) { + + scf_basic_block_t* dom0 = dominators->data[k0]; + scf_basic_block_t* dom1 = bb->dominators->data[k1]; + + if (dom0->dfo < dom1->dfo) { + ++changed; + break; + } else if (dom0->dfo > dom1->dfo) { + ++changed; + break; + } else { + ++k0; + ++k1; + } + } + } + + scf_vector_free(bb->dominators); + bb->dominators = dominators; + dominators = NULL; + } + } while (changed > 0); +#if 0 + for (i = 0; i < all->size; i++) { + bb = all->data[i]; + + int j; + for (j = 0; j < bb->dominators->size; j++) { + + scf_basic_block_t* dom = bb->dominators->data[j]; + scf_logi("bb: %p_%d, dom: %p_%d\n", bb, bb->dfo, dom, dom->dfo); + } + printf("\n"); + } +#endif + ret = 0; +error: + scf_vector_free(all); + return ret; +} + +static int _optimize_dominators_reverse(scf_ast_t* ast, scf_function_t* f, scf_vector_t* functions) +{ + if (!f) + return -EINVAL; + + scf_bb_edge_t* edge; + scf_vector_t* tree; + scf_list_t* bb_list_head = &f->basic_block_list_head; + + int ret; + int i; + + if (scf_list_empty(bb_list_head)) + return 0; + + tree = scf_vector_alloc(); + if (!tree) + return -ENOMEM; + + ret = _bb_dfs_tree(bb_list_head, tree); + if (ret < 0) + return ret; + + for (i = 0; i < tree->size; i++) { + edge = tree->data[i]; + scf_logd("bb_%p_%d --> bb_%p_%d\n", edge->start, edge->start->dfo, edge->end, edge->end->dfo); + } + + scf_vector_clear(tree, free); + scf_vector_free(tree); + tree = NULL; + + ret = __find_reverse_dominators(bb_list_head); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + +// scf_basic_block_print_list(bb_list_head); + return 0; +} + +scf_optimizer_t scf_optimizer_dominators_reverse = +{ + .name = "dominators_reverse", + + .optimize = _optimize_dominators_reverse, +}; diff --git a/core/scf_variable.h b/core/scf_variable.h index 18169e0..7eff81d 100644 --- a/core/scf_variable.h +++ b/core/scf_variable.h @@ -27,9 +27,13 @@ struct scf_variable_s { int size; int data_size; - int bit_offset; + int bit_offset; // for bit-flag like: uint8_t flag:1; int bit_size; + int n_pins; + ScfEpin* r_pins[SCF_EDA_MAX_BITS]; // read pins to get var + ScfEpin* w_pins[SCF_EDA_MAX_BITS]; // write pins to set var + int offset; int bp_offset; // offset based on RBP / EBP register int sp_offset; // offset based on RSP / ESP register diff --git a/elf/scf_elf_x64.c b/elf/scf_elf_x64.c index 0c5fd56..10abfd8 100644 --- a/elf/scf_elf_x64.c +++ b/elf/scf_elf_x64.c @@ -443,8 +443,8 @@ static int _x64_elf_write_exec(scf_elf_context_t* elf, const char* sysroot) _x64_elf_process_sections(x64, §ion_offset, &cs, &ros, &ds, &crela, &drela); - uint64_t cs_align = (cs ->offset + cs ->data_len + 0x200000 - 1) >> 21 << 21; - uint64_t ro_align = (ros->offset + ros->data_len + 0x200000 - 1) >> 21 << 21; + uint64_t cs_align = (cs ->offset + cs ->data_len + 0x2000 - 1) >> 13 << 13; + uint64_t ro_align = (ros->offset + ros->data_len + 0x2000 - 1) >> 13 << 13; uint64_t rx_base = 0x400000; uint64_t r_base = 0x400000 + cs_align; @@ -578,8 +578,8 @@ static int _x64_elf_write_dyn(scf_elf_context_t* elf, const char* sysroot) _x64_elf_process_sections(x64, §ion_offset, &cs, &ros, &ds, &crela, &drela); - uint64_t cs_align = (cs ->offset + cs ->data_len + 0x200000 - 1) >> 21 << 21; - uint64_t ro_align = (ros->offset + ros->data_len + 0x200000 - 1) >> 21 << 21; + uint64_t cs_align = (cs ->offset + cs ->data_len + 0x2000 - 1) >> 13 << 13; + uint64_t ro_align = (ros->offset + ros->data_len + 0x2000 - 1) >> 13 << 13; uint64_t rx_base = 0; uint64_t r_base = cs_align; diff --git a/elf/scf_elf_x64_so.c b/elf/scf_elf_x64_so.c index 5912959..236e9a4 100644 --- a/elf/scf_elf_x64_so.c +++ b/elf/scf_elf_x64_so.c @@ -1145,7 +1145,7 @@ int __x64_elf_write_text(scf_elf_context_t* elf, uint64_t rx_base, uint64_t offs ph_text.p_paddr = ph_text.p_vaddr; ph_text.p_filesz = len; ph_text.p_memsz = ph_text.p_filesz; - ph_text.p_align = 0x200000; + ph_text.p_align = 0x2000; fwrite(&ph_text, sizeof(ph_text), 1, elf->fp); return 0; @@ -1162,7 +1162,7 @@ int __x64_elf_write_rodata(scf_elf_context_t* elf, uint64_t r_base, uint64_t off ph_rodata.p_paddr = ph_rodata.p_vaddr; ph_rodata.p_filesz = len; ph_rodata.p_memsz = ph_rodata.p_filesz; - ph_rodata.p_align = 0x200000; + ph_rodata.p_align = 0x2000; fwrite(&ph_rodata, sizeof(ph_rodata), 1, elf->fp); return 0; @@ -1179,7 +1179,7 @@ int __x64_elf_write_data(scf_elf_context_t* elf, uint64_t rw_base, uint64_t offs ph_data.p_paddr = ph_data.p_vaddr; ph_data.p_filesz = len; ph_data.p_memsz = ph_data.p_filesz; - ph_data.p_align = 0x200000; + ph_data.p_align = 0x2000; fwrite(&ph_data, sizeof(ph_data), 1, elf->fp); return 0; diff --git a/lib/x64/scf_object.o b/lib/x64/scf_object.o index a32511e..00fd525 100644 Binary files a/lib/x64/scf_object.o and b/lib/x64/scf_object.o differ diff --git a/native/eda/scf_eda.c b/native/eda/scf_eda.c index 17c6d20..6fa664f 100644 --- a/native/eda/scf_eda.c +++ b/native/eda/scf_eda.c @@ -65,6 +65,194 @@ static int _eda_make_insts_for_list(scf_native_t* ctx, scf_list_t* h, int bb_off return bb_offset; } +static int __eda_dfs_mask(scf_function_t* f, ScfEpin* mask, scf_basic_block_t* root) +{ + ScfEpin* p0; + ScfEpin* p1; + ScfEpin* po; + + if (root->visit_flag) + return 0; + root->visit_flag = 1; + + if (root->mask_pin) { + int ret = __eda_bit_and(f, &p0, &p1, &po); + if (ret < 0) + return ret; + EDA_PIN_ADD_PIN_EF(f->ef, p0, root->mask_pin); + EDA_PIN_ADD_PIN_EF(f->ef, p1, mask); + root->mask_pin = po; + } else + root->mask_pin = mask; + + int i; + for (i = 0; i < root->nexts->size; i++) { + int ret = __eda_dfs_mask(f, mask, root->nexts->data[i]); + if (ret < 0) + return ret; + } + return 0; +} + +static int __eda_bb_mask(scf_function_t* f, ScfEpin* mask, scf_basic_block_t* root) +{ + scf_basic_block_t* bb; + scf_list_t* l; + int i; + + for (l = scf_list_head(&f->basic_block_list_head); l != scf_list_sentinel(&f->basic_block_list_head); l = scf_list_next(l)) { + bb = scf_list_data(l, scf_basic_block_t, list); + bb->visit_flag = 0; + } + + for (i = 0; i < root->dominators->size; i++) { + bb = root->dominators->data[i]; + + if (bb->dfo < root->dfo) { + bb->visit_flag = 1; + scf_logw("dom->index: %d, dfo: %d, root->index: %d, dfo: %d\n", bb->index, bb->dfo, root->index, root->dfo); + break; + } + } + + return __eda_dfs_mask(f, mask, root); +} + +static int __eda_jmp_mask(scf_function_t* f, scf_3ac_code_t* c, scf_basic_block_t* bb) +{ + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_basic_block_t* bb2; + scf_list_t* l; + + ScfEpin* __true = NULL; + ScfEpin* __false = NULL; + ScfEpin* p0; + ScfEpin* p1; + ScfEpin* p2; + ScfEpin* po; + + int ret; + int i; + switch (c->op->type) { + + case SCF_OP_3AC_JZ: + ret = __eda_bit_not(f, &__false, &__true); + if (ret < 0) + return ret; + EDA_PIN_ADD_CONN(f->ef, bb->flag_pins[SCF_EDA_FLAG_ZERO], __false); + break; + case SCF_OP_3AC_JNZ: + ret = __eda_bit_not(f, &__true, &__false); + if (ret < 0) + return ret; + EDA_PIN_ADD_CONN(f->ef, bb->flag_pins[SCF_EDA_FLAG_ZERO], __true); + break; + + case SCF_OP_3AC_JLT: + ret = __eda_bit_not(f, &__true, &__false); + if (ret < 0) + return ret; + EDA_PIN_ADD_CONN(f->ef, bb->flag_pins[SCF_EDA_FLAG_SIGN], __true); + break; + case SCF_OP_3AC_JGE: + ret = __eda_bit_not(f, &__false, &__true); + if (ret < 0) + return ret; + EDA_PIN_ADD_CONN(f->ef, bb->flag_pins[SCF_EDA_FLAG_SIGN], __false); + break; + + case SCF_OP_3AC_JGT: + ret = __eda_bit_not(f, &p1, &p2); + if (ret < 0) + return ret; + EDA_PIN_ADD_CONN(f->ef, bb->flag_pins[SCF_EDA_FLAG_SIGN], p1); + + ret = __eda_bit_and(f, &p0, &p1, &po); + if (ret < 0) + return ret; + EDA_PIN_ADD_PIN_EF(f->ef, p1, p2); + EDA_PIN_ADD_CONN(f->ef, bb->flag_pins[SCF_EDA_FLAG_ZERO], p0); + + ret = __eda_bit_not(f, &__true, &__false); + if (ret < 0) + return ret; + EDA_PIN_ADD_PIN_EF(f->ef, po, __true); + break; + + case SCF_OP_3AC_JLE: + ret = __eda_bit_not(f, &p0, &p2); + if (ret < 0) + return ret; + EDA_PIN_ADD_CONN(f->ef, bb->flag_pins[SCF_EDA_FLAG_ZERO], p0); + + ret = __eda_bit_or(f, &p0, &p1, &po); + if (ret < 0) + return ret; + EDA_PIN_ADD_PIN_EF(f->ef, p0, p2); + EDA_PIN_ADD_CONN(f->ef, bb->flag_pins[SCF_EDA_FLAG_SIGN], p1); + + ret = __eda_bit_not(f, &__true, &__false); + if (ret < 0) + return ret; + EDA_PIN_ADD_PIN_EF(f->ef, po, __true); + break; + + case SCF_OP_GOTO: + scf_logi("'%s'\n", c->op->name); + return 0; + break; + default: + scf_loge("'%s' not support\n", c->op->name); + return -EINVAL; + break; + }; + + if (__true) + __true->flags |= SCF_EDA_PIN_CF; + + for (i = 0; i < bb->nexts->size; i++) { + bb2 = bb->nexts->data[i]; + + if (bb2 == dst->bb) + ret = __eda_bb_mask(f, __true, bb2); + else + ret = __eda_bb_mask(f, __false, bb2); + if (ret < 0) + return ret; + } + return 0; +} + +static int _eda_fix_jmps(scf_native_t* ctx, scf_function_t* f) +{ + scf_basic_block_t* cur_bb; + scf_basic_block_t* bb; + scf_3ac_code_t* c; + scf_list_t* l; + + int i; + for (i = 0; i < f->jmps->size; i++) { + c = f->jmps->data[i]; + + cur_bb = c->basic_block; + + for (l = scf_list_prev(&cur_bb->list); l != scf_list_sentinel(&f->basic_block_list_head); l = scf_list_prev(l)) { + bb = scf_list_data(l, scf_basic_block_t, list); + + if (!bb->jmp_flag) + break; + } + + if (l == scf_list_sentinel(&f->basic_block_list_head)) + continue; + + int ret = __eda_jmp_mask(f, c, bb); + if (ret < 0) + return ret; + } + return 0; +} + int _scf_eda_select_inst(scf_native_t* ctx) { scf_eda_context_t* eda = ctx->priv; @@ -76,6 +264,8 @@ int _scf_eda_select_inst(scf_native_t* ctx) int j; int ret = 0; + _eda_fix_jmps(ctx, f); + for (i = 0; i < f->bb_groups->size; i++) { bbg = f->bb_groups->data[i]; @@ -84,12 +274,12 @@ int _scf_eda_select_inst(scf_native_t* ctx) assert(!bb->native_flag); - scf_loge("************ bb: %d\n", bb->index); + scf_logd("************ bb: %d\n", bb->index); ret = _eda_make_insts_for_list(ctx, &bb->code_list_head, 0); if (ret < 0) return ret; bb->native_flag = 1; - scf_loge("************ bb: %d\n", bb->index); + scf_logd("************ bb: %d\n", bb->index); } } diff --git a/native/eda/scf_eda.h b/native/eda/scf_eda.h index 5bf6999..92dce45 100644 --- a/native/eda/scf_eda.h +++ b/native/eda/scf_eda.h @@ -18,6 +18,20 @@ int scf_eda_open (scf_native_t* ctx, const char* arch); int scf_eda_close (scf_native_t* ctx); int scf_eda_select(scf_native_t* ctx); +int __eda_bit_nand(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** out); +int __eda_bit_nor (scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** out); +int __eda_bit_not (scf_function_t* f, ScfEpin** in, ScfEpin** out); +int __eda_bit_and (scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** out); +int __eda_bit_or (scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** out); + +#define EDA_PIN_ADD_CONN(_ef, _dst, _p) \ + do { \ + if (_dst) \ + EDA_PIN_ADD_PIN_EF(_ef, _dst, _p); \ + else \ + _dst = _p; \ + } while (0) + static inline int eda_variable_size(scf_variable_t* v) { if (v->nb_dimentions + v->nb_pointers > 0) @@ -38,4 +52,17 @@ static inline int eda_variable_size(scf_variable_t* v) return v->size << 3; } +static inline int eda_find_argv_index(scf_function_t* f, scf_variable_t* v) +{ + int i; + if (f->argv) { + for (i = 0; i < f->argv->size; i++) { + if (v == f->argv->data[i]) + return i; + } + } + + return -1; +} + #endif diff --git a/native/eda/scf_eda_inst.c b/native/eda/scf_eda_inst.c index 4597298..2902533 100644 --- a/native/eda/scf_eda_inst.c +++ b/native/eda/scf_eda_inst.c @@ -92,24 +92,15 @@ #define EDA_PIN_ADD_INPUT(_in, _i, _ef, _p) \ do { \ - ScfEcomponent* c = (_ef)->components[(_p)->cid]; \ - ScfEcomponent* R = NULL; \ - \ - if (!(_in)->pins[_i]) { \ - EDA_INST_ADD_COMPONENT(_ef, R, SCF_EDA_Resistor); \ - \ - EDA_PIN_ADD_PIN(c, (_p)->id, R, 0); \ - \ - (_in)->pins[_i] = R->pins[1]; \ - } else { \ - R = (_ef)->components[(_in)->pins[_i]->cid]; \ - \ - EDA_PIN_ADD_PIN(c, (_p)->id, R, 0); \ - } \ + if (!(_in)->pins[_i]) \ + (_in)->pins[_i] = _p; \ + else if (_p) \ + EDA_PIN_ADD_PIN_EF(_ef, _p, (_in)->pins[_i]); \ + else \ + _p = (_in)->pins[_i]; \ } while (0) - -static int __eda_bit_nand(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** out) +int __eda_bit_nand(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** out) { ScfEcomponent* B = f->ef->components[0]; ScfEcomponent* NAND = NULL; @@ -125,7 +116,7 @@ static int __eda_bit_nand(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEp return 0; } -static int __eda_bit_nor(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** out) +int __eda_bit_nor(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** out) { ScfEcomponent* B = f->ef->components[0]; ScfEcomponent* NOR = NULL; @@ -141,22 +132,23 @@ static int __eda_bit_nor(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpi return 0; } -static int __eda_bit_not(scf_function_t* f, ScfEpin** in, ScfEpin** out) +int __eda_bit_not(scf_function_t* f, ScfEpin** in, ScfEpin** out) { ScfEcomponent* B = f->ef->components[0]; ScfEcomponent* NOT = NULL; EDA_INST_ADD_COMPONENT(f->ef, NOT, SCF_EDA_NOT); - EDA_PIN_ADD_PIN(NOT, SCF_EDA_NOT_POS, B, SCF_EDA_Battery_POS); - EDA_PIN_ADD_PIN(NOT, SCF_EDA_NOT_NEG, B, SCF_EDA_Battery_NEG); + EDA_PIN_ADD_PIN(NOT, SCF_EDA_NOT_POS, B, SCF_EDA_Battery_POS); + EDA_PIN_ADD_PIN(NOT, SCF_EDA_NOT_NEG, B, SCF_EDA_Battery_NEG); + EDA_PIN_ADD_PIN(NOT, SCF_EDA_NOT_IN, NOT, SCF_EDA_NOT_IN); *in = NOT->pins[SCF_EDA_NOT_IN]; *out = NOT->pins[SCF_EDA_NOT_OUT]; return 0; } -static int __eda_bit_and(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** out) +int __eda_bit_and(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** out) { ScfEcomponent* B = f->ef->components[0]; ScfEcomponent* AND = NULL; @@ -172,7 +164,7 @@ static int __eda_bit_and(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpi return 0; } -static int __eda_bit_or(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** out) +int __eda_bit_or(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** out) { ScfEcomponent* B = f->ef->components[0]; ScfEcomponent* OR = NULL; @@ -188,6 +180,41 @@ static int __eda_bit_or(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin return 0; } +int __eda_bit_if(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** in2, ScfEpin** out) +{ + ScfEcomponent* B = f->ef->components[0]; + ScfEcomponent* IF = NULL; + + EDA_INST_ADD_COMPONENT(f->ef, IF, SCF_EDA_IF); + + EDA_PIN_ADD_PIN(IF, SCF_EDA_IF_POS, B, SCF_EDA_Battery_POS); + EDA_PIN_ADD_PIN(IF, SCF_EDA_IF_NEG, B, SCF_EDA_Battery_NEG); + + *in0 = IF->pins[SCF_EDA_IF_TRUE]; + *in1 = IF->pins[SCF_EDA_IF_COND]; + *in2 = IF->pins[SCF_EDA_IF_FALSE]; + *out = IF->pins[SCF_EDA_IF_OUT]; + return 0; +} + +int __eda_bit_and2_or(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** in2, ScfEpin** in3, ScfEpin** out) +{ + ScfEcomponent* B = f->ef->components[0]; + ScfEcomponent* AND2_OR = NULL; + + EDA_INST_ADD_COMPONENT(f->ef, AND2_OR, SCF_EDA_AND2_OR); + + EDA_PIN_ADD_PIN(AND2_OR, SCF_EDA_AND2_OR_POS, B, SCF_EDA_Battery_POS); + EDA_PIN_ADD_PIN(AND2_OR, SCF_EDA_AND2_OR_NEG, B, SCF_EDA_Battery_NEG); + + *in0 = AND2_OR->pins[SCF_EDA_AND2_OR_IN0]; + *in1 = AND2_OR->pins[SCF_EDA_AND2_OR_IN1]; + *in2 = AND2_OR->pins[SCF_EDA_AND2_OR_IN2]; + *in3 = AND2_OR->pins[SCF_EDA_AND2_OR_IN3]; + *out = AND2_OR->pins[SCF_EDA_AND2_OR_OUT]; + return 0; +} + static int __eda_bit_xor(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** out) { ScfEcomponent* B = f->ef->components[0]; @@ -206,19 +233,20 @@ static int __eda_bit_xor(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpi static int __eda_bit_add(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** out, ScfEpin** cf) { - ScfEpin* and0 = NULL; - ScfEpin* and1 = NULL; + ScfEcomponent* B = f->ef->components[0]; + ScfEcomponent* ADD = NULL; - int ret = __eda_bit_xor(f, in0, in1, out); - if (ret < 0) - return ret; + EDA_INST_ADD_COMPONENT(f->ef, ADD, SCF_EDA_ADD); - ret = __eda_bit_and(f, &and0, &and1, cf); - if (ret < 0) - return ret; + EDA_PIN_ADD_PIN(ADD, SCF_EDA_ADD_POS, B, SCF_EDA_Battery_POS); + EDA_PIN_ADD_PIN(ADD, SCF_EDA_ADD_NEG, B, SCF_EDA_Battery_NEG); + + ADD->pins[SCF_EDA_ADD_CF]->flags = SCF_EDA_PIN_CF; - EDA_PIN_ADD_PIN_EF(f->ef, and0, *in0); - EDA_PIN_ADD_PIN_EF(f->ef, and1, *in1); + *in0 = ADD->pins[SCF_EDA_ADD_IN0]; + *in1 = ADD->pins[SCF_EDA_ADD_IN1]; + *out = ADD->pins[SCF_EDA_ADD_OUT]; + *cf = ADD->pins[SCF_EDA_ADD_CF]; return 0; } @@ -250,56 +278,39 @@ static int __eda_bit_adc(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpi return 0; } -static int _eda_inst_logic_not_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int __eda_teq(scf_function_t* f, scf_dag_node_t* in, ScfEpin** res) { - if (!c->dsts || c->dsts->size != 1) - return -EINVAL; - if (!c->srcs || c->srcs->size != 1) - return -EINVAL; - - scf_eda_context_t* eda = ctx->priv; - scf_function_t* f = eda->f; - - scf_3ac_operand_t* dst = c->dsts->data[0]; - scf_3ac_operand_t* src = c->srcs->data[0]; - - if (!src || !src->dag_node) - return -EINVAL; - if (!dst || !dst->dag_node) - return -EINVAL; - - scf_dag_node_t* in = src->dag_node; - scf_dag_node_t* out = dst->dag_node; + ScfEpin* prev = NULL; + ScfEpin* p0; + ScfEpin* p1; + ScfEpin* po; int N = eda_variable_size(in->var); - int M = eda_variable_size(out->var); - - EDA_INST_IN_CHECK(in, N); + int ret; + int i; - in ->n_pins = N; - out->n_pins = M; + if (1 == N) { + EDA_PIN_ADD_INPUT(in, 0, f->ef, prev); + *res = prev; - ScfEpin* p2 = NULL; - ScfEpin* not = NULL; - ScfEpin* res = NULL; + if (in->var->arg_flag) { + in->pins[0]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0; + in->pins[0]->io_lid = 0; + } + return 0; + } - int i; for (i = 0; i + 1 < N; i += 2) { - ScfEpin* p0 = NULL; - ScfEpin* p1 = NULL; - ScfEpin* po = NULL; - - int ret = __eda_bit_nor(f, &p0, &p1, &po); + ret = __eda_bit_nor(f, &p0, &p1, &po); if (ret < 0) return ret; - EDA_PIN_ADD_INPUT(in, i, f->ef, p0); EDA_PIN_ADD_INPUT(in, i + 1, f->ef, p1); - if (!p2) - p2 = po; + if (!prev) + prev = po; else - EDA_PIN_ADD_PIN_EF(f->ef, p2, po); + EDA_PIN_ADD_PIN_EF(f->ef, prev, po); if (in->var->arg_flag) { in->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0; @@ -311,17 +322,15 @@ static int _eda_inst_logic_not_handler(scf_native_t* ctx, scf_3ac_code_t* c) } if (N & 0x1) { - ScfEpin* p0 = NULL; - ScfEpin* po = NULL; - - int ret = __eda_bit_not(f, &p0, &po); + ret = __eda_bit_not(f, &p0, &po); if (ret < 0) return ret; + EDA_PIN_ADD_INPUT(in, N - 1, f->ef, p0); - if (!p2) - p2 = po; + if (!prev) + prev = po; else - EDA_PIN_ADD_PIN_EF(f->ef, p2, po); + EDA_PIN_ADD_PIN_EF(f->ef, prev, po); if (in->var->arg_flag) { in->pins[N - 1]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0; @@ -329,13 +338,64 @@ static int _eda_inst_logic_not_handler(scf_native_t* ctx, scf_3ac_code_t* c) } } - int ret = __eda_bit_not(f, ¬, &res); + ret = __eda_bit_not(f, &po, res); if (ret < 0) return ret; - EDA_PIN_ADD_PIN_EF(f->ef, not, p2); + EDA_PIN_ADD_PIN_EF(f->ef, po, prev); + return 0; +} - for (i = 0; i < M; i++) { - out->pins[i] = res; +static int _eda_inst_logic_not_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 != 1) + return -EINVAL; + + scf_eda_context_t* eda = ctx->priv; + scf_function_t* f = eda->f; + + scf_3ac_operand_t* dst = c->dsts->data[0]; + scf_3ac_operand_t* src = c->srcs->data[0]; + + if (!src || !src->dag_node) + return -EINVAL; + if (!dst || !dst->dag_node) + return -EINVAL; + + scf_dag_node_t* in = src->dag_node; + scf_dag_node_t* out = dst->dag_node; + + ScfEpin* res = NULL; + ScfEpin* p0 = NULL; + ScfEpin* p1 = NULL; + ScfEpin* p2 = NULL; + + int N = eda_variable_size(in->var); + int i; + + EDA_INST_IN_CHECK(in, N); + + in ->n_pins = N; + out->n_pins = eda_variable_size(out->var); + + int ret = __eda_teq(f, in, &res); + if (ret < 0) + return ret; + + for (i = 0; i < out->n_pins; i++) { + if (i > 0) { + ret = __eda_bit_not(f, &p0, &p1); + if (ret < 0) + return ret; + + ret = __eda_bit_not(f, &p2, &(out->pins[i])); + if (ret < 0) + return ret; + EDA_PIN_ADD_PIN_EF(f->ef, p0, res); + EDA_PIN_ADD_PIN_EF(f->ef, p1, p2); + } else + out->pins[i] = res; } return 0; } @@ -523,14 +583,8 @@ static int _eda_inst_shl_handler(scf_native_t* ctx, scf_3ac_code_t* c) for ( ; i < N; i++) { ScfEpin* p00 = NULL; ScfEpin* p01 = NULL; - ScfEpin* po0 = NULL; - ScfEpin* p10 = NULL; ScfEpin* p11 = NULL; - ScfEpin* po1 = NULL; - - ScfEpin* p20 = NULL; - ScfEpin* p21 = NULL; ScfEpin* po = NULL; /* x = sht[j] @@ -541,24 +595,12 @@ out[i] = (x & y) | (~x & z) = ~(~(x & y) & ~(~x & z)) = (x NAND y) NAND (~x NAND z) */ - ret = __eda_bit_nand(f, &p00, &p10, &po0); + ret = __eda_bit_and2_or(f, &p00, &p10, &p01, &p11, &po); if (ret < 0) return ret; - - ret = __eda_bit_nand(f, &p01, &p11, &po1); - if (ret < 0) - return ret; - - ret = __eda_bit_nand(f, &p20, &p21, &po); - if (ret < 0) - return ret; - EDA_PIN_ADD_PIN_EF(f->ef, p10, p2); EDA_PIN_ADD_PIN_EF(f->ef, p11, p1); - EDA_PIN_ADD_PIN_EF(f->ef, p20, po0); - EDA_PIN_ADD_PIN_EF(f->ef, p21, po1); - if (j > 0) { EDA_PIN_ADD_PIN_EF(f->ef, p00, res[i]); EDA_PIN_ADD_PIN_EF(f->ef, p01, res[i - (1 << j)]); @@ -595,78 +637,67 @@ out[i] = (x & y) | (~x & z) return 0; } -static int __eda_shr(scf_function_t* f, scf_dag_node_t* src, int shift, int sign, ScfEpin* cur, ScfEpin* high, ScfEpin** res, int N) +static int __eda_shr(scf_function_t* f, scf_dag_node_t* src, int shift, int sign, ScfEpin** cur, ScfEpin** res, int i, int N) { ScfEpin* tmp[SCF_EDA_MAX_BITS]; ScfEpin* p00 = NULL; ScfEpin* p10 = NULL; - ScfEpin* po0 = NULL; - ScfEpin* p01 = NULL; ScfEpin* p11 = NULL; - ScfEpin* po1 = NULL; - ScfEpin* p20 = NULL; - ScfEpin* p21 = NULL; + ScfEpin* po2 = NULL; ScfEpin* po = NULL; int ret; - int i; - - for (i = 0; i < N - (1 << shift); i++) { - - ret = __eda_bit_nand(f, &p00, &p10, &po0); - if (ret < 0) - return ret; + int j; - ret = __eda_bit_nand(f, &p01, &p11, &po1); - if (ret < 0) - return ret; + for (j = i ; j < N - (1 << shift); j++) { - ret = __eda_bit_nand(f, &p20, &p21, &po); + ret = __eda_bit_if(f, &p00, &p10, &p01, &po); if (ret < 0) return ret; - - EDA_PIN_ADD_PIN_EF(f->ef, p10, cur); - EDA_PIN_ADD_PIN_EF(f->ef, p11, high); - - EDA_PIN_ADD_PIN_EF(f->ef, p21, po1); - EDA_PIN_ADD_PIN_EF(f->ef, p20, po0); + if (*cur) + EDA_PIN_ADD_PIN_EF(f->ef, p10, *cur); + else + *cur = p10; if (!src) - EDA_PIN_ADD_PIN_EF(f->ef, p01, res[i + (1 << shift)]); + EDA_PIN_ADD_PIN_EF(f->ef, p01, res[j + (1 << shift)]); else - EDA_PIN_ADD_INPUT(src, i + (1 << shift), f->ef, p01); + EDA_PIN_ADD_INPUT(src, j + (1 << shift), f->ef, p01); if (!src) - EDA_PIN_ADD_PIN_EF(f->ef, p00, res[i]); + EDA_PIN_ADD_PIN_EF(f->ef, p00, res[j]); else - EDA_PIN_ADD_INPUT(src, i, f->ef, p00); + EDA_PIN_ADD_INPUT(src, j, f->ef, p00); - tmp[i] = po; + tmp[j] = po; } - for ( ; i < N; i++) { + for ( ; j < N; j++) { - if (sign && N - 1 == i) { + if (sign && N - 1 == j) { ret = __eda_bit_not(f, &p00, &p10); if (ret < 0) return ret; - ret = __eda_bit_not(f, &p20, &po); + ret = __eda_bit_not(f, &po2, &po); if (ret < 0) return ret; - EDA_PIN_ADD_PIN_EF(f->ef, p20, p10); + EDA_PIN_ADD_PIN_EF(f->ef, po2, p10); } else { ret = __eda_bit_and(f, &p00, &p10, &po); if (ret < 0) return ret; - EDA_PIN_ADD_PIN_EF(f->ef, p10, cur); + if (*cur) + EDA_PIN_ADD_PIN_EF(f->ef, p10, *cur); + else + *cur = p10; if (sign) { - ret = __eda_bit_or(f, &p01, &p11, &po1); + ret = __eda_bit_or(f, &p01, &p11, &po2); if (ret < 0) return ret; EDA_PIN_ADD_PIN_EF(f->ef, p11, po); @@ -676,23 +707,23 @@ static int __eda_shr(scf_function_t* f, scf_dag_node_t* src, int shift, int sign else EDA_PIN_ADD_INPUT(src, N - 1, f->ef, p01); - po = po1; + po = po2; } } if (!src) - EDA_PIN_ADD_PIN_EF(f->ef, p00, res[i]); + EDA_PIN_ADD_PIN_EF(f->ef, p00, res[j]); else - EDA_PIN_ADD_INPUT(src, i, f->ef, p00); + EDA_PIN_ADD_INPUT(src, j, f->ef, p00); - tmp[i] = po; + tmp[j] = po; } - for (i = 0; i < N; i++) { - res[i] = tmp[i]; + for (j = i; j < N; j++) { + res[j] = tmp[j]; - res[i]->flags |= SCF_EDA_PIN_SHIFT; - res[i]->io_lid = i; + res[j]->flags |= SCF_EDA_PIN_SHIFT; + res[j]->io_lid = j; } return 0; @@ -740,9 +771,9 @@ out[i] = (x & y) | (~x & z) = (x NAND y) NAND (~x NAND z) */ if (j > 0) - ret = __eda_shr(f, NULL, j, sign, p2, p1, res, N); + ret = __eda_shr(f, NULL, j, sign, &p2, res, 0, N); else - ret = __eda_shr(f, src, j, sign, p2, p1, res, N); + ret = __eda_shr(f, src, j, sign, &p2, res, 0, N); if (ret < 0) return ret; @@ -829,6 +860,39 @@ static int _eda_inst_add_handler(scf_native_t* ctx, scf_3ac_code_t* c) return 0; } +static int __eda_sub(scf_function_t* f, ScfEpin** a, ScfEpin** b, ScfEpin** res, ScfEpin** cf, int N) +{ + ScfEcomponent* B = f->ef->components[0]; + ScfEcomponent* R0 = NULL; + ScfEpin* pc = NULL; + + EDA_INST_ADD_COMPONENT(f->ef, R0, SCF_EDA_Resistor); + + EDA_PIN_ADD_PIN(R0, 1, B, SCF_EDA_Battery_POS); + pc = R0->pins[0]; + + int i; + for (i = 0; i < N; i++) { + ScfEpin* p1 = NULL; + ScfEpin* p2 = NULL; + ScfEpin* p3 = NULL; + + int ret = __eda_bit_not(f, &b[i], &p1); + if (ret < 0) + return ret; + + ret = __eda_bit_adc(f, &a[i], &p2, &p3, &res[i], cf); + if (ret < 0) + return ret; + EDA_PIN_ADD_PIN_EF(f->ef, p2, p1); + EDA_PIN_ADD_PIN_EF(f->ef, p3, pc); + + pc = *cf; + pc->flags |= SCF_EDA_PIN_CF; + } + return 0; +} + static int _eda_inst_sub_handler(scf_native_t* ctx, scf_3ac_code_t* c) { EDA_INST_OP3_CHECK() @@ -837,11 +901,6 @@ static int _eda_inst_sub_handler(scf_native_t* ctx, scf_3ac_code_t* c) scf_dag_node_t* in1 = src1->dag_node; scf_dag_node_t* out = dst ->dag_node; - ScfEcomponent* B = f->ef->components[0]; - ScfEcomponent* R0 = NULL; - ScfEpin* pc = NULL; - - int i; int N = eda_variable_size(in0->var); EDA_INST_IN_CHECK(in0, N); @@ -851,36 +910,21 @@ static int _eda_inst_sub_handler(scf_native_t* ctx, scf_3ac_code_t* c) in1->n_pins = N; out->n_pins = N; - EDA_INST_ADD_COMPONENT(f->ef, R0, SCF_EDA_Resistor); + ScfEpin* a[SCF_EDA_MAX_BITS]; + ScfEpin* b[SCF_EDA_MAX_BITS]; + ScfEpin* res[SCF_EDA_MAX_BITS]; + ScfEpin* cf; - EDA_PIN_ADD_PIN(R0, 1, B, SCF_EDA_Battery_POS); - pc = R0->pins[0]; + int ret = __eda_sub(f, a, b, res, &cf, N); + if (ret < 0) + return ret; + int i; for (i = 0; i < N; i++) { + EDA_PIN_ADD_INPUT(in0, i, f->ef, a[i]); + EDA_PIN_ADD_INPUT(in1, i, f->ef, b[i]); - ScfEpin* p0 = NULL; - ScfEpin* p1 = NULL; - ScfEpin* p2 = NULL; - ScfEpin* p3 = NULL; - ScfEpin* not = NULL; - ScfEpin* cf = NULL; - ScfEpin* res = NULL; - - int ret = __eda_bit_not(f, &p1, ¬); - if (ret < 0) - return ret; - - ret = __eda_bit_adc(f, &p0, &p2, &p3, &res, &cf); - if (ret < 0) - return ret; - EDA_PIN_ADD_PIN_EF(f->ef, p2, not); - EDA_PIN_ADD_PIN_EF(f->ef, p3, pc); - - EDA_PIN_ADD_INPUT(in0, i, f->ef, p0); - EDA_PIN_ADD_INPUT(in1, i, f->ef, p1); - - pc = cf; - cf->flags |= SCF_EDA_PIN_CF; + out->pins[i] = res[i]; if (in0->var->arg_flag) { in0->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0; @@ -891,35 +935,26 @@ static int _eda_inst_sub_handler(scf_native_t* ctx, scf_3ac_code_t* c) in1->pins[i]->flags |= SCF_EDA_PIN_IN; in1->pins[i]->io_lid = i; } - - out->pins[i] = res; } - return 0; } static int __eda_bit_mla(scf_function_t* f, ScfEpin** a, ScfEpin** b, ScfEpin** c, ScfEpin** d, ScfEpin** out, ScfEpin** cf) { - ScfEpin* ab0 = NULL; - ScfEpin* cd0 = NULL; - - ScfEpin* ab1 = NULL; - ScfEpin* cd1 = NULL; - - int ret = __eda_bit_and(f, a, b, &ab0); - if (ret < 0) - return ret; + ScfEcomponent* B = f->ef->components[0]; + ScfEcomponent* MLA = NULL; - ret = __eda_bit_and(f, c, d, &cd0); - if (ret < 0) - return ret; + EDA_INST_ADD_COMPONENT(f->ef, MLA, SCF_EDA_MLA); - ret = __eda_bit_add(f, &ab1, &cd1, out, cf); - if (ret < 0) - return ret; + EDA_PIN_ADD_PIN(MLA, SCF_EDA_MLA_POS, B, SCF_EDA_Battery_POS); + EDA_PIN_ADD_PIN(MLA, SCF_EDA_MLA_NEG, B, SCF_EDA_Battery_NEG); - EDA_PIN_ADD_PIN_EF(f->ef, ab0, ab1); - EDA_PIN_ADD_PIN_EF(f->ef, cd0, cd1); + *a = MLA->pins[SCF_EDA_MLA_IN0]; + *b = MLA->pins[SCF_EDA_MLA_IN1]; + *c = MLA->pins[SCF_EDA_MLA_IN2]; + *d = MLA->pins[SCF_EDA_MLA_IN3]; + *out = MLA->pins[SCF_EDA_MLA_OUT]; + *cf = MLA->pins[SCF_EDA_MLA_CF]; return 0; } @@ -1117,21 +1152,19 @@ static int __eda_div(scf_function_t* f, ScfEpin** a, ScfEpin** b, ScfEpin** x, i k = n_adds - 1; while (j < k) { - int ret = __eda_bit_xor(f, &p0, &p1, &res); + int ret; + + if (i < N - 1) + ret = __eda_bit_add(f, &p0, &p1, &res, &cfs[n_cfs]); + else + ret = __eda_bit_xor(f, &p0, &p1, &res); if (ret < 0) return ret; EDA_PIN_ADD_PIN_EF(f->ef, p0, adds[j]); EDA_PIN_ADD_PIN_EF(f->ef, p1, adds[k]); - if (i < N - 1) { - ret = __eda_bit_and(f, &p0, &p1, &cfs[n_cfs]); - if (ret < 0) - return ret; - EDA_PIN_ADD_PIN_EF(f->ef, p0, adds[j]); - EDA_PIN_ADD_PIN_EF(f->ef, p1, adds[k]); - + if (i < N - 1) cfs[n_cfs++]->flags |= SCF_EDA_PIN_CF; - } adds[j] = res; @@ -1194,50 +1227,41 @@ static int _eda_inst_div_handler(scf_native_t* ctx, scf_3ac_code_t* c) ScfEpin* sh1[SCF_EDA_MAX_BITS] = {NULL}; ScfEpin* mask = NULL; + ScfEpin* high; + ScfEpin* cur; + ScfEpin* pm0; + ScfEpin* pm1; + ScfEpin* pm; + int ret; int i; for (i = 0; i < N - 1; i++) { - ScfEpin* high = NULL; - ScfEpin* cur = NULL; - ScfEpin* pm0 = NULL; - ScfEpin* pm1 = NULL; - ScfEpin* pm = NULL; -// high = ~p1 & mask -// cur = ~p1 NAND mask -// high = ~cur - ret = __eda_bit_not(f, &cur, &high); - if (ret < 0) - return ret; - EDA_PIN_ADD_INPUT(in1, i, f->ef, cur); - if (mask) { - ret = __eda_bit_nand(f, &pm0, &pm1, &cur); + ret = __eda_bit_or(f, &pm0, &pm1, &cur); if (ret < 0) return ret; EDA_PIN_ADD_PIN_EF(f->ef, pm0, mask); - EDA_PIN_ADD_PIN_EF(f->ef, pm1, high); - - ret = __eda_bit_not(f, &pm, &high); - if (ret < 0) - return ret; - EDA_PIN_ADD_PIN_EF(f->ef, pm, cur); + EDA_PIN_ADD_INPUT(in1, i, f->ef, pm1); } - mask = high; if (i > 0) - ret = __eda_shr(f, NULL, 0, sign, cur, high, sh0, N); + ret = __eda_shr(f, NULL, 0, sign, &cur, sh0, 0, N); else - ret = __eda_shr(f, in0, 0, sign, cur, high, sh0, N); + ret = __eda_shr(f, in0, 0, sign, &cur, sh0, 0, N); if (ret < 0) return ret; if (i > 0) - ret = __eda_shr(f, NULL, 0, sign, cur, high, sh1, N); + ret = __eda_shr(f, NULL, 0, sign, &cur, sh1, 1, N); else - ret = __eda_shr(f, in1, 0, sign, cur, high, sh1, N); + ret = __eda_shr(f, in1, 0, sign, &cur, sh1, 1, N); if (ret < 0) return ret; + + if (!mask) + EDA_PIN_ADD_INPUT(in1, i, f->ef, cur); + mask = cur; } if (1 == N) { @@ -1247,9 +1271,17 @@ static int _eda_inst_div_handler(scf_native_t* ctx, scf_3ac_code_t* c) EDA_PIN_ADD_INPUT(in0, 0, f->ef, sh0[0]); EDA_PIN_ADD_INPUT(in1, 0, f->ef, sh1[0]); - } - sh1[0]->flags |= SCF_EDA_PIN_DIV0; + sh1[0]->flags |= SCF_EDA_PIN_DIV0; + } else { + ret = __eda_bit_or(f, &pm0, &pm1, &cur); + if (ret < 0) + return ret; + EDA_PIN_ADD_PIN_EF(f->ef, pm0, mask); + EDA_PIN_ADD_INPUT(in1, N - 1, f->ef, pm1); + + cur->flags |= SCF_EDA_PIN_DIV0; + } ret = __eda_div(f, sh0, sh1, res, N); if (ret < 0) @@ -1468,12 +1500,108 @@ static int _eda_inst_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c) static int _eda_inst_teq_handler(scf_native_t* ctx, scf_3ac_code_t* c) { - return -EINVAL; + EDA_INST_SRC_CHECK() + + scf_basic_block_t* bb = c->basic_block; + scf_dag_node_t* in = src->dag_node; + ScfEpin* res = NULL; + + int ret = __eda_teq(f, in, &res); + if (ret < 0) + return ret; + + EDA_PIN_ADD_CONN(f->ef, bb->flag_pins[SCF_EDA_FLAG_ZERO], res); + return 0; } static int _eda_inst_cmp_handler(scf_native_t* ctx, scf_3ac_code_t* c) { - return -EINVAL; + if (!c->srcs || c->srcs->size != 2) + return -EINVAL; + scf_eda_context_t* eda = ctx->priv; + scf_function_t* f = eda->f; + scf_basic_block_t* bb = c->basic_block; + scf_3ac_operand_t* src0 = c->srcs->data[0]; + scf_3ac_operand_t* src1 = c->srcs->data[1]; + + if (!src0 || !src0->dag_node) + return -EINVAL; + if (!src1 || !src1->dag_node) + return -EINVAL; + scf_dag_node_t* in0 = src0->dag_node; + scf_dag_node_t* in1 = src1->dag_node; + + int N = eda_variable_size(in0->var); + + EDA_INST_IN_CHECK(in0, N); + EDA_INST_IN_CHECK(in1, N); + + in0->n_pins = N; + in1->n_pins = N; + + ScfEpin* a[SCF_EDA_MAX_BITS]; + ScfEpin* b[SCF_EDA_MAX_BITS]; + ScfEpin* res[SCF_EDA_MAX_BITS]; + ScfEpin* cf; + + int ret = __eda_sub(f, a, b, res, &cf, N); + if (ret < 0) + return ret; + + int i; + for (i = 0; i < N; i++) { + EDA_PIN_ADD_INPUT(in0, i, f->ef, a[i]); + EDA_PIN_ADD_INPUT(in1, i, f->ef, b[i]); + + if (in0->var->arg_flag) { + in0->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0; + in0->pins[i]->io_lid = i; + } + + if (in1->var->arg_flag) { + in1->pins[i]->flags |= SCF_EDA_PIN_IN; + in1->pins[i]->io_lid = i; + } + } + + ScfEpin* prev = NULL; + ScfEpin* p0; + ScfEpin* p1; + ScfEpin* po; + + for (i = 0; i + 1 < N; i += 2) { + ret = __eda_bit_nor(f, &p0, &p1, &po); + if (ret < 0) + return ret; + EDA_PIN_ADD_PIN_EF(f->ef, p0, res[i]); + EDA_PIN_ADD_PIN_EF(f->ef, p1, res[i + 1]); + + if (prev) + EDA_PIN_ADD_PIN_EF(f->ef, po, prev); + else + prev = po; + } + + if (N & 0x1) { + ret = __eda_bit_not(f, &p0, &po); + if (ret < 0) + return ret; + EDA_PIN_ADD_PIN_EF(f->ef, p0, res[N - 1]); + + if (prev) + EDA_PIN_ADD_PIN_EF(f->ef, po, prev); + else + prev = po; + } + + ret = __eda_bit_not(f, &p0, &po); + if (ret < 0) + return ret; + EDA_PIN_ADD_PIN_EF(f->ef, p0, prev); + + EDA_PIN_ADD_CONN(f->ef, bb->flag_pins[SCF_EDA_FLAG_ZERO], po); + EDA_PIN_ADD_CONN(f->ef, bb->flag_pins[SCF_EDA_FLAG_SIGN], res[N - 1]); + return 0; } static int _eda_inst_setz_handler(scf_native_t* ctx, scf_3ac_code_t* c) @@ -1536,6 +1664,62 @@ static int _eda_inst_le_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -EINVAL; } +static int __eda_cast(scf_function_t* f, scf_dag_node_t* in, ScfEpin** res, int N) +{ + ScfEpin* zero = NULL; + + int M = eda_variable_size(in->var); + int sign = scf_variable_signed(in->var); + int ret; + int i; + + for (i = 0; i < N; i++) { + ScfEpin* p0 = NULL; + ScfEpin* p1 = NULL; + ScfEpin* p2 = NULL; + ScfEpin* po = NULL; + + if (i == M && !sign && !zero) { + + ret = __eda_bit_xor(f, &p0, &p1, &zero); + if (ret < 0) + return ret; + EDA_PIN_ADD_PIN_EF(f->ef, p0, zero); + EDA_PIN_ADD_INPUT(in, M - 1, f->ef, p0); + EDA_PIN_ADD_INPUT(in, M - 1, f->ef, p1); + + res[i] = zero; + } else { + ScfEcomponent* R; + + if (!in->pins[i]) { + EDA_INST_ADD_COMPONENT(f->ef, R, SCF_EDA_Resistor); + in->pins[i] = R->pins[1]; + res[i] = R->pins[0]; + + } else if (i < M) + res[i] = in->pins[i]; + else if (sign) + res[i] = in->pins[M - 1]; + else + res[i] = zero; + } + } + + for (i = 0; i < M; i++) { + if (in->pins[i] && in->var->arg_flag) { + in->pins[i]->flags |= SCF_EDA_PIN_IN; + + int j = eda_find_argv_index(f, in->var); + if (0 == j) + in->pins[i]->flags |= SCF_EDA_PIN_IN0; + + in->pins[i]->io_lid = j; + } + } + return 0; +} + static int _eda_inst_cast_handler(scf_native_t* ctx, scf_3ac_code_t* c) { if (!c->dsts || c->dsts->size != 1) @@ -1555,40 +1739,93 @@ static int _eda_inst_cast_handler(scf_native_t* ctx, scf_3ac_code_t* c) if (!dst || !dst->dag_node) return -EINVAL; - if (0 == dst->dag_node->color) - return -EINVAL; + scf_dag_node_t* in = src->dag_node; + scf_dag_node_t* out = dst->dag_node; - return -EINVAL; + int M = eda_variable_size(in->var); + int N = eda_variable_size(out->var); + int i; + + EDA_INST_IN_CHECK(in, M); + + in ->n_pins = M; + out->n_pins = N; + + return __eda_cast(f, in, out->pins, N); } static int _eda_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c) { + scf_eda_context_t* eda = ctx->priv; + scf_function_t* f = eda->f; + scf_basic_block_t* bb = c->basic_block; + + scf_3ac_operand_t* src = NULL; + scf_3ac_operand_t* dst = NULL; + scf_dag_node_t* in = NULL; + scf_variable_t* v = NULL; + if (!c->srcs || c->srcs->size < 1) { scf_loge("\n"); return -EINVAL; } - scf_eda_context_t* eda = ctx->priv; - scf_function_t* f = eda->f; - scf_3ac_operand_t* src = NULL; - scf_dag_node_t* out = NULL; + if (!f->rets || f->rets->size < c->srcs->size) { + scf_loge("\n"); + return -EINVAL; + } + + ScfEpin* res[SCF_EDA_MAX_BITS]; + ScfEpin* p0; + ScfEpin* p1; + ScfEpin* p2; + ScfEpin* po; int i; int j; - for (i = 0; i < c->srcs->size; i++) { src = c->srcs->data[i]; - out = src->dag_node; + v = f->rets->data[i]; + in = src->dag_node; - if (out->n_pins <= 0) { - scf_loge("out: %p\n", out); - return -EINVAL; - } + v->n_pins = eda_variable_size(v); - for (j = 0; j < out->n_pins; j++) { - out->pins[j]->flags |= SCF_EDA_PIN_OUT; - out->pins[j]->io_lid = j; + int ret = __eda_cast(f, in, res, v->n_pins); + if (ret < 0) + return ret; + + for (j = 0; j < v->n_pins; j++) { + + if (bb->mask_pin) { + ret = __eda_bit_and(f, &p0, &p1, &po); + if (ret < 0) + return ret; + + EDA_PIN_ADD_PIN_EF(f->ef, p0, res[j]); + EDA_PIN_ADD_PIN_EF(f->ef, p1, bb->mask_pin); + + res[j] = po; + } + + if (v->w_pins[j]) { + ret = __eda_bit_or(f, &p0, &p1, &po); + if (ret < 0) + return ret; + + EDA_PIN_ADD_PIN_EF(f->ef, p0, v->w_pins[j]); + EDA_PIN_ADD_PIN_EF(f->ef, p1, res[j]); + + res[j] = po; + } + + if (v->w_pins[j]) + v->w_pins[j]->flags &= ~SCF_EDA_PIN_OUT; + + v->w_pins[j] = res[j]; + + v->w_pins[j]->flags |= SCF_EDA_PIN_OUT; + v->w_pins[j]->io_lid = j; } } @@ -1663,11 +1900,15 @@ static int _eda_inst_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c) scf_dag_node_t* out = dst->dag_node; int i; - int N = eda_variable_size(in->var); + int M = eda_variable_size(in->var); + int N = eda_variable_size(out->var); - EDA_INST_IN_CHECK(in, N); + if (M < N) + return _eda_inst_cast_handler(ctx, c); - in ->n_pins = N; + EDA_INST_IN_CHECK(in, M); + + in ->n_pins = M; out->n_pins = N; for (i = 0; i < N; i++) { diff --git a/native/eda/scf_eda_pack.c b/native/eda/scf_eda_pack.c index c45fd95..a798e62 100644 --- a/native/eda/scf_eda_pack.c +++ b/native/eda/scf_eda_pack.c @@ -20,6 +20,14 @@ static int component_pins[SCF_EDA_Components_NB] = SCF_EDA_AND_NB, SCF_EDA_OR_NB, SCF_EDA_XOR_NB, + + SCF_EDA_ADD_NB, + + SCF_EDA_NAND4_NB, + SCF_EDA_AND2_OR_NB, + + SCF_EDA_IF_NB, + SCF_EDA_MLA_NB, }; static int __diode_path_off(ScfEpin* p0, ScfEpin* p1, int flags) @@ -63,17 +71,20 @@ static int __pnp_shared(ScfEpin* p, int flags) return 0; } -static int __nand_path_off(ScfEpin* p0, ScfEpin* p1, int flags) +static int __ttl_nand_path_off(ScfEpin* p0, ScfEpin* p1, int flags) { if (SCF_EDA_NAND_NEG == p0->id) return 1; + if (flags && (SCF_EDA_NAND_IN0 == p0->id || SCF_EDA_NAND_IN1 == p0->id)) + return 1; if (SCF_EDA_NAND_POS == p0->id) { if (p1 && (SCF_EDA_NAND_IN0 == p1->id || SCF_EDA_NAND_IN1 == p1->id)) return 1; } else { if (p1) { - if (!flags && (SCF_EDA_NAND_IN0 == p0->id || SCF_EDA_NAND_IN1 == p0->id) + if (!flags + && (SCF_EDA_NAND_IN0 == p0->id || SCF_EDA_NAND_IN1 == p0->id) && SCF_EDA_NAND_OUT == p1->id) return 0; @@ -84,61 +95,177 @@ static int __nand_path_off(ScfEpin* p0, ScfEpin* p1, int flags) return 0; } -static int __nand_shared(ScfEpin* p, int flags) +static int __ttl_nand_shared(ScfEpin* p, int flags) { - if (SCF_EDA_NAND_NEG == p->id || SCF_EDA_NAND_POS == p->id) - return 1; + if (!flags) { + if (SCF_EDA_NAND_OUT == p->id) + return 0; + } + return 1; +} - if (!flags && SCF_EDA_NAND_OUT != p->id) +static int __ttl_not_path_off(ScfEpin* p0, ScfEpin* p1, int flags) +{ + if (SCF_EDA_NOT_NEG == p0->id) + return 1; + if (flags && SCF_EDA_NOT_IN == p0->id) return 1; + + if (SCF_EDA_NOT_POS == p0->id) { + if (p1 && SCF_EDA_NOT_IN == p1->id) + return 1; + } else { + if (p1) { + if (!flags && SCF_EDA_NOT_IN == p0->id && SCF_EDA_NOT_OUT == p1->id) + return 0; + if (SCF_EDA_NOT_NEG != p1->id) + return 1; + } + } return 0; } -#define SCF_EDA_GATE(name, off, shared) \ -static int __##name##_path_off(ScfEpin* p0, ScfEpin* p1, int flags) \ -{ \ - return off(p0, p1, flags); \ -} \ -static int __##name##_shared(ScfEpin* p, int flags) \ -{ \ - return shared(p, flags); \ +static int __ttl_not_shared(ScfEpin* p, int flags) +{ + if (!flags) { + if (SCF_EDA_NOT_OUT == p->id) + return 0; + } + return 1; +} + +static int __ttl_add_path_off(ScfEpin* p0, ScfEpin* p1, int flags) +{ + if (SCF_EDA_ADD_NEG == p0->id) + return 1; + if (flags && (SCF_EDA_ADD_IN0 == p0->id || SCF_EDA_ADD_IN1 == p0->id)) + return 1; + + if (SCF_EDA_ADD_POS == p0->id) { + if (p1 && (SCF_EDA_ADD_IN0 == p1->id || SCF_EDA_ADD_IN1 == p1->id)) + return 1; + } else { + if (p1) { + if (!flags + && (SCF_EDA_ADD_IN0 == p0->id || SCF_EDA_ADD_IN1 == p0->id) + && (SCF_EDA_ADD_OUT == p1->id || SCF_EDA_ADD_CF == p1->id)) + return 0; + + if (SCF_EDA_ADD_NEG != p1->id) + return 1; + } + } + return 0; } -SCF_EDA_GATE(nor, __nand_path_off, __nand_shared) -SCF_EDA_GATE(and, __nand_path_off, __nand_shared) -SCF_EDA_GATE(or, __nand_path_off, __nand_shared) -SCF_EDA_GATE(xor, __nand_path_off, __nand_shared) +static int __ttl_add_shared(ScfEpin* p, int flags) +{ + if (!flags) { + if (SCF_EDA_ADD_OUT == p->id || SCF_EDA_ADD_CF == p->id) + return 0; + } + return 1; +} -static int __not_path_off(ScfEpin* p0, ScfEpin* p1, int flags) +static int __ttl_nand4_path_off(ScfEpin* p0, ScfEpin* p1, int flags) { - if (SCF_EDA_NOT_NEG == p0->id) + if (SCF_EDA_NAND4_NEG == p0->id) + return 1; + if (flags && (SCF_EDA_NAND4_IN0 <= p0->id && p0->id <= SCF_EDA_NAND4_IN3)) return 1; - if (SCF_EDA_NOT_POS == p0->id) { - if (p1 && SCF_EDA_NOT_IN == p1->id) + if (SCF_EDA_NAND4_POS == p0->id) { + if (p1 && (SCF_EDA_NAND4_IN0 <= p0->id && p0->id <= SCF_EDA_NAND4_IN3)) return 1; } else { if (p1) { - if (!flags && SCF_EDA_NOT_IN == p0->id && SCF_EDA_NOT_OUT == p1->id) + if (!flags + && (SCF_EDA_NAND4_IN0 <= p0->id && p0->id <= SCF_EDA_NAND4_IN3) + && SCF_EDA_NAND4_OUT == p1->id) return 0; - if (SCF_EDA_NOT_NEG != p1->id) + if (SCF_EDA_NAND4_NEG != p1->id) return 1; } } return 0; } -static int __not_shared(ScfEpin* p, int flags) +static int __ttl_nand4_shared(ScfEpin* p, int flags) { - if (SCF_EDA_NOT_NEG == p->id || SCF_EDA_NOT_POS == p->id) + if (!flags) { + if (SCF_EDA_NAND4_OUT == p->id) + return 0; + } + return 1; +} + +static int __ttl_if_path_off(ScfEpin* p0, ScfEpin* p1, int flags) +{ + if (SCF_EDA_IF_NEG == p0->id) + return 1; + if (flags && (SCF_EDA_IF_TRUE <= p0->id && p0->id <= SCF_EDA_IF_FALSE)) return 1; - if (!flags && SCF_EDA_NOT_OUT != p->id) + if (SCF_EDA_IF_POS == p0->id) { + if (p1 && (SCF_EDA_IF_TRUE <= p0->id && p0->id <= SCF_EDA_IF_FALSE)) + return 1; + } else { + if (p1) { + if (!flags + && (SCF_EDA_IF_TRUE <= p0->id && p0->id <= SCF_EDA_IF_FALSE) + && SCF_EDA_IF_OUT == p1->id) + return 0; + + if (SCF_EDA_IF_NEG != p1->id) + return 1; + } + } + return 0; +} + +static int __ttl_if_shared(ScfEpin* p, int flags) +{ + if (!flags) { + if (SCF_EDA_IF_OUT == p->id) + return 0; + } + return 1; +} + +static int __ttl_mla_path_off(ScfEpin* p0, ScfEpin* p1, int flags) +{ + if (SCF_EDA_MLA_NEG == p0->id) + return 1; + if (flags && (SCF_EDA_MLA_IN0 <= p0->id && p0->id <= SCF_EDA_MLA_IN3)) return 1; + + if (SCF_EDA_MLA_POS == p0->id) { + if (p1 && (SCF_EDA_MLA_IN0 <= p1->id && p1->id <= SCF_EDA_MLA_IN3)) + return 1; + } else { + if (p1) { + if (!flags + && (SCF_EDA_MLA_IN0 <= p0->id && p0->id <= SCF_EDA_MLA_IN3) + && (SCF_EDA_MLA_OUT == p1->id && p1->id <= SCF_EDA_MLA_CF)) + return 0; + + if (SCF_EDA_MLA_NEG != p1->id) + return 1; + } + } return 0; } +static int __ttl_mla_shared(ScfEpin* p, int flags) +{ + if (!flags) { + if (SCF_EDA_MLA_OUT == p->id && p->id <= SCF_EDA_MLA_CF) + return 0; + } + return 1; +} + static ScfEops __diode_ops = { __diode_path_off, @@ -157,62 +284,78 @@ static ScfEops __pnp_ops = __pnp_shared, }; -static ScfEops __nand_ops = +static ScfEops __ttl_nand_ops = +{ + __ttl_nand_path_off, + __ttl_nand_shared, +}; + +static ScfEops __ttl_gate_ops = { - __nand_path_off, - __nand_shared, + __ttl_nand_path_off, + __ttl_nand_shared, }; -static ScfEops __nor_ops = +static ScfEops __ttl_not_ops = { - __nor_path_off, - __nor_shared, + __ttl_not_path_off, + __ttl_not_shared, }; -static ScfEops __and_ops = +static ScfEops __ttl_add_ops = { - __and_path_off, - __and_shared, + __ttl_add_path_off, + __ttl_add_shared, }; -static ScfEops __or_ops = +static ScfEops __ttl_nand4_ops = +{ + __ttl_nand4_path_off, + __ttl_nand4_shared, +}; +static ScfEops __ttl_and2_or_ops = { - __or_path_off, - __or_shared, + __ttl_nand4_path_off, + __ttl_nand4_shared, }; -static ScfEops __xor_ops = +static ScfEops __ttl_if_ops = { - __xor_path_off, - __xor_shared, + __ttl_if_path_off, + __ttl_if_shared, }; -static ScfEops __not_ops = +static ScfEops __ttl_mla_ops = { - __not_path_off, - __not_shared, + __ttl_mla_path_off, + __ttl_mla_shared, }; static ScfEdata component_datas[] = { {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_Battery, 0, 0, 0, 0, 1e-9, 1e9, 0, 0, NULL, 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, NULL}, + {SCF_EDA_Diode, 0, 0, 0, 0, 0, 0, 0, 0, &__diode_ops, NULL, "./cpk/9013.txt"}, {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, "./cpk/9012.txt"}, - {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}, - - {SCF_EDA_AND, 0, 0, 0, 0, 0, 0, 0, 0, &__and_ops, "./cpk/and.cpk", NULL}, - {SCF_EDA_OR, 0, 0, 0, 0, 0, 0, 0, 0, &__or_ops, "./cpk/or.cpk", NULL}, - {SCF_EDA_XOR, 0, 0, 0, 0, 0, 0, 0, 0, &__xor_ops, "./cpk/xor.cpk", NULL}, + {SCF_EDA_NAND, 0, 0, 0, 0, 0, 0, 0, 0, &__ttl_nand_ops, "./cpk/ttl_nand.cpk", NULL}, + {SCF_EDA_NOT, 0, 0, 0, 0, 0, 0, 0, 0, &__ttl_not_ops, "./cpk/ttl_not.cpk", NULL}, + {SCF_EDA_AND, 0, 0, 0, 0, 0, 0, 0, 0, &__ttl_gate_ops, "./cpk/ttl_and.cpk", NULL}, + {SCF_EDA_OR, 0, 0, 0, 0, 0, 0, 0, 0, &__ttl_gate_ops, "./cpk/ttl_or.cpk", NULL}, + {SCF_EDA_NOR, 0, 0, 0, 0, 0, 0, 0, 0, &__ttl_gate_ops, "./cpk/ttl_nor.cpk", NULL}, + {SCF_EDA_XOR, 0, 0, 0, 0, 0, 0, 0, 0, &__ttl_gate_ops, "./cpk/ttl_xor.cpk", NULL}, + {SCF_EDA_ADD, 0, 0, 0, 0, 0, 0, 0, 0, &__ttl_add_ops, "./cpk/ttl_add.cpk", NULL}, + + {SCF_EDA_NAND4, 0, 0, 0, 0, 0, 0, 0, 0, &__ttl_nand4_ops, "./cpk/ttl_nand4.cpk", NULL}, + {SCF_EDA_AND2_OR, 0, 0, 0, 0, 0, 0, 0, 0, &__ttl_and2_or_ops, "./cpk/ttl_and2_or.cpk", NULL}, + {SCF_EDA_IF, 0, 0, 0, 0, 0, 0, 0, 0, &__ttl_if_ops, "./cpk/ttl_if.cpk", NULL}, + {SCF_EDA_MLA, 0, 0, 0, 0, 0, 0, 0, 0, &__ttl_mla_ops, "./cpk/ttl_mla.cpk", NULL}, }; static ScfEdata pin_datas[] = @@ -222,10 +365,10 @@ static ScfEdata pin_datas[] = {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, NULL}, - {SCF_EDA_NPN, 0, SCF_EDA_NPN_C, 0, 0, 3, 0, 0, 250, NULL, NULL, NULL}, + {SCF_EDA_NPN, 0, SCF_EDA_NPN_C, 0, 0, 3, 0, 0, 150, NULL, 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}, + {SCF_EDA_PNP, 0, SCF_EDA_PNP_C, 0, 0, 3, 0, 0, 150, NULL, NULL, NULL}, }; static ScfEdata* _pin_find_data(const uint64_t type, const uint64_t model, const uint64_t pid) @@ -828,13 +971,20 @@ int scf_pins_same_line(ScfEfunction* f) long n; for (i = 0; i < f->n_components; i++) { - c = f->components[i]; + c = f->components[i]; + c->pf = f; for (j = 0; j < c->n_pins; j++) { - p = c->pins[j]; + p = c->pins[j]; + p->c = c; qsort(p->tos, p->n_tos / 2, sizeof(uint64_t) * 2, epin_cmp); + for (k = 0; k < p->n_tos; k += 2) { + if (p->tos[k] == c->id) + scf_logw("c%ldp%ld connect to its own pin %ld\n", c->id, p->id, p->tos[k + 1]); + } + for (k = 0; k < f->n_elines; k++) { el = f->elines[k]; @@ -940,6 +1090,7 @@ next: continue; } + el->pf = f; el->c_pins = el->n_pins; i++; } diff --git a/native/eda/scf_eda_pack.h b/native/eda/scf_eda_pack.h index 865aef5..6c76b8e 100644 --- a/native/eda/scf_eda_pack.h +++ b/native/eda/scf_eda_pack.h @@ -23,6 +23,13 @@ enum { SCF_EDA_OR, SCF_EDA_XOR, + SCF_EDA_ADD, + + SCF_EDA_NAND4, + SCF_EDA_AND2_OR, + SCF_EDA_IF, + SCF_EDA_MLA, + SCF_EDA_Components_NB, }; @@ -36,6 +43,7 @@ enum { #define SCF_EDA_PIN_SHIFT 64 #define SCF_EDA_PIN_IN0 128 #define SCF_EDA_PIN_DIV0 256 +#define SCF_EDA_PIN_KEY 512 #define SCF_EDA_V_INIT -10001001.0 #define SCF_EDA_V_MIN -10000000.0 @@ -83,6 +91,16 @@ enum { SCF_EDA_PNP_NB = SCF_EDA_NPN_NB, }; +enum { + SCF_EDA_NOT_NEG, + SCF_EDA_NOT_POS, + + SCF_EDA_NOT_IN, + SCF_EDA_NOT_OUT, + + SCF_EDA_NOT_NB, +}; + enum { SCF_EDA_NAND_NEG, SCF_EDA_NAND_POS, @@ -139,13 +157,68 @@ enum { }; enum { - SCF_EDA_NOT_NEG, - SCF_EDA_NOT_POS, + SCF_EDA_ADD_NEG = SCF_EDA_NAND_NEG, + SCF_EDA_ADD_POS = SCF_EDA_NAND_POS, - SCF_EDA_NOT_IN, - SCF_EDA_NOT_OUT, + SCF_EDA_ADD_IN0 = SCF_EDA_NAND_IN0, + SCF_EDA_ADD_IN1 = SCF_EDA_NAND_IN1, + SCF_EDA_ADD_OUT = SCF_EDA_NAND_OUT, + SCF_EDA_ADD_CF, - SCF_EDA_NOT_NB, + SCF_EDA_ADD_NB, +}; + +enum { + SCF_EDA_NAND4_NEG, + SCF_EDA_NAND4_POS, + + SCF_EDA_NAND4_IN0, + SCF_EDA_NAND4_IN1, + SCF_EDA_NAND4_IN2, + SCF_EDA_NAND4_IN3, + SCF_EDA_NAND4_OUT, + + SCF_EDA_NAND4_NB, +}; + +enum { + SCF_EDA_AND2_OR_NEG = SCF_EDA_NAND4_NEG, + SCF_EDA_AND2_OR_POS = SCF_EDA_NAND4_POS, + + SCF_EDA_AND2_OR_IN0 = SCF_EDA_NAND4_IN0, + SCF_EDA_AND2_OR_IN1 = SCF_EDA_NAND4_IN1, + SCF_EDA_AND2_OR_IN2 = SCF_EDA_NAND4_IN2, + SCF_EDA_AND2_OR_IN3 = SCF_EDA_NAND4_IN3, + SCF_EDA_AND2_OR_OUT = SCF_EDA_NAND4_OUT, + + SCF_EDA_AND2_OR_NB, +}; + +enum { + SCF_EDA_IF_NEG, + SCF_EDA_IF_POS, + + SCF_EDA_IF_TRUE, + SCF_EDA_IF_COND, + SCF_EDA_IF_FALSE, + SCF_EDA_IF_OUT, + + SCF_EDA_IF_NB, +}; + +enum { + SCF_EDA_MLA_NEG, + SCF_EDA_MLA_POS, + + SCF_EDA_MLA_IN0, + SCF_EDA_MLA_IN1, + SCF_EDA_MLA_IN2, + SCF_EDA_MLA_IN3, + + SCF_EDA_MLA_OUT, + SCF_EDA_MLA_CF, + + SCF_EDA_MLA_NB, }; typedef struct { @@ -217,7 +290,7 @@ struct scf_epin_s SCF_PACK_DEF_VAR(int64_t, io_lid); SCF_PACK_DEF_VAR(int64_t, ic_lid); - SCF_PACK_DEF_OBJ(ScfEcomponent, IC); + SCF_PACK_DEF_OBJ(ScfEcomponent, c); SCF_PACK_DEF_VAR(double, v); SCF_PACK_DEF_VAR(double, a); @@ -308,7 +381,7 @@ typedef struct { SCF_PACK_DEF_VAR(uint8_t, vconst); SCF_PACK_DEF_VAR(uint8_t, aconst); SCF_PACK_DEF_VAR(uint8_t, vflag); - SCF_PACK_DEF_VAR(uint8_t, vinit); + SCF_PACK_DEF_VAR(uint8_t, open_flag); } ScfEline; SCF_PACK_TYPE(ScfEline) @@ -476,7 +549,7 @@ int scf_pins_same_line(ScfEfunction* f); return ret; \ } \ \ - for (size_t i = 0; i < (_c)->n_pins; i++) \ + for (long i = 0; i < (_c)->n_pins; i++) \ (_c)->pins[i]->cid = (_c)->id; \ } while (0) diff --git a/native/x64/scf_x64.c b/native/x64/scf_x64.c index 3d7aa7e..9d7da3b 100644 --- a/native/x64/scf_x64.c +++ b/native/x64/scf_x64.c @@ -217,7 +217,7 @@ static int _x64_function_finish(scf_function_t* f) l = scf_list_tail(&bb->code_list_head); end = scf_list_data(l, scf_3ac_code_t, list); - if (f->bp_used_flag || f->vla_flag) { + if (f->bp_used_flag || f->vla_flag || f->call_flag) { inst = x64_make_inst_G2E(mov, rsp, rbp); X64_INST_ADD_CHECK(end->instructions, inst); @@ -242,7 +242,7 @@ static int _x64_function_finish(scf_function_t* f) uint32_t local = f->bp_used_flag ? f->local_vars_size : 0; - if (f->bp_used_flag || f->vla_flag) { + if (f->bp_used_flag || f->vla_flag || f->call_flag) { inst = x64_make_inst_G(push, rbp); X64_INST_ADD_CHECK(f->init_code->instructions, inst); @@ -1096,7 +1096,7 @@ int _scf_x64_select_inst(scf_native_t* ctx) #endif _x64_set_offsets(f); - _x64_set_offset_for_jmps( ctx, f); + _x64_set_offset_for_jmps(ctx, f); return 0; } @@ -1151,6 +1151,7 @@ int scf_x64_select_inst(scf_native_t* ctx, scf_function_t* f) f->local_vars_size = local_vars_size; f->bp_used_flag = 1; + f->call_flag = 0; ret = _scf_x64_select_inst(ctx); if (ret < 0) diff --git a/native/x64/scf_x64_inst.c b/native/x64/scf_x64_inst.c index ab0fc3b..be69b2e 100644 --- a/native/x64/scf_x64_inst.c +++ b/native/x64/scf_x64_inst.c @@ -616,6 +616,7 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c) } } + f->call_flag = 1; return 0; } @@ -2029,7 +2030,6 @@ static int _x64_inst_push_rets_handler(scf_native_t* ctx, scf_3ac_code_t* c) if (!f->void_flag) { n = f->rets->size; - if (n > X64_ABI_RET_NB) return -EINVAL; } @@ -2041,6 +2041,11 @@ static int _x64_inst_push_rets_handler(scf_native_t* ctx, scf_3ac_code_t* c) X64_INST_ADD_CHECK(c->instructions, inst); } + if (n & 0x1) { + r = x64_find_register_type_id_bytes(0, x64_abi_ret_regs[n - 1], 8); + inst = x64_make_inst_G(push, r); + X64_INST_ADD_CHECK(c->instructions, inst); + } return 0; } @@ -2064,11 +2069,16 @@ static int _x64_inst_pop_rets_handler(scf_native_t* ctx, scf_3ac_code_t* c) if (!f->void_flag) { n = f->rets->size; - if (n > X64_ABI_RET_NB) return -EINVAL; } + if (n & 0x1) { + r = x64_find_register_type_id_bytes(0, x64_abi_ret_regs[n - 1], 8); + inst = x64_make_inst_G(pop, r); + X64_INST_ADD_CHECK(c->instructions, inst); + } + for (i = n - 1; i >= 0; i--) { r = x64_find_register_type_id_bytes(0, x64_abi_ret_regs[i], 8); diff --git a/parse/Makefile b/parse/Makefile index 900c49f..8b4576e 100644 --- a/parse/Makefile +++ b/parse/Makefile @@ -113,6 +113,7 @@ CFILES += ../core/scf_optimizer_loads_saves.c CFILES += ../core/scf_optimizer_auto_gc_find.c CFILES += ../core/scf_optimizer_auto_gc.c CFILES += ../core/scf_optimizer_dominators.c +CFILES += ../core/scf_optimizer_dominators_reverse.c CFILES += ../core/scf_optimizer_basic_block.c CFILES += ../core/scf_optimizer_const_teq.c CFILES += ../core/scf_optimizer_loop.c diff --git a/parse/scf_parse.c b/parse/scf_parse.c index 357527d..823669c 100644 --- a/parse/scf_parse.c +++ b/parse/scf_parse.c @@ -2084,7 +2084,7 @@ int scf_eda_write_cpk(scf_parse_t* parse, const char* out, scf_vector_t* functio return ret; } - scf_loge("len: %ld\n", len); + scf_logi("len: %ld\n", len); ScfEboard_free(b); b = NULL;