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;
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, // +
void* rabi;
void* rabi2;
-#define SCF_EDA_MAX_BITS 256
ScfEpin* pins[SCF_EDA_MAX_BITS];
int n_pins;
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;
_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);
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
uint32_t vargs_flag:1;
uint32_t void_flag :1;
+ uint32_t call_flag :1;
uint32_t vla_flag :1;
};
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;
&scf_optimizer_group,
&scf_optimizer_generate_loads_saves,
+
+ &scf_optimizer_dominators_reverse,
};
int scf_optimize(scf_ast_t* ast, scf_vector_t* functions)
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))
}
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)
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");
--- /dev/null
+#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,
+};
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
_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;
_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;
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;
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;
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;
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;
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];
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);
}
}
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)
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
#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;
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;
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;
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;
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];
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;
}
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;
}
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;
}
}
- 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;
}
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]
= ~(~(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)]);
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);
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;
= (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;
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()
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);
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;
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;
}
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;
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) {
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)
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)
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)
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;
}
}
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++) {
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)
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;
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,
__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[] =
{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)
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];
continue;
}
+ el->pf = f;
el->c_pins = el->n_pins;
i++;
}
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,
};
#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
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,
};
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 {
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);
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)
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)
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);
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);
#endif
_x64_set_offsets(f);
- _x64_set_offset_for_jmps( ctx, f);
+ _x64_set_offset_for_jmps(ctx, f);
return 0;
}
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)
}
}
+ f->call_flag = 1;
return 0;
}
if (!f->void_flag) {
n = f->rets->size;
-
if (n > X64_ABI_RET_NB)
return -EINVAL;
}
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;
}
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);
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
return ret;
}
- scf_loge("len: %ld\n", len);
+ scf_logi("len: %ld\n", len);
ScfEboard_free(b);
b = NULL;