update for native/eda master
authoryu.dongliang <18588496441@163.com>
Sun, 6 Jul 2025 15:08:14 +0000 (23:08 +0800)
committeryu.dongliang <18588496441@163.com>
Sun, 6 Jul 2025 15:08:14 +0000 (23:08 +0800)
core/scf_variable.h
native/eda/scf_eda.c
native/eda/scf_eda_inst.c
native/eda/scf_eda_pack.c
native/eda/scf_eda_pack.h
parse/Makefile
parse/scf_parse.c

index 7eff81d0f6d53ffaa7749dc7bed2eb509ab3010f..b36a75909caac004133e6d8ce46b9716332465c0 100644 (file)
@@ -33,6 +33,7 @@ struct scf_variable_s {
        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
+       ScfEcomponent*      DFFs  [SCF_EDA_MAX_BITS]; // D flip-flops to save var
 
        int                                     offset;
        int                                     bp_offset;  // offset based on RBP / EBP register
index 6fa664f2ee8f4d26f455c26c32e5c7d501302344..3836e2cf9a49436003535dc7978b58683cf8786d 100644 (file)
@@ -2,17 +2,6 @@
 #include"scf_basic_block.h"
 #include"scf_3ac.h"
 
-static char* component_types[SCF_EDA_Components_NB] =
-{
-    "None",
-    "Battery",
-    "Resistor",
-    "Capacitor",
-    "Inductor",
-    "Diode",
-    "Transistor",
-};
-
 int    scf_eda_open(scf_native_t* ctx, const char* arch)
 {
        scf_eda_context_t* eda = calloc(1, sizeof(scf_eda_context_t));
@@ -34,14 +23,13 @@ int scf_eda_close(scf_native_t* ctx)
        return 0;
 }
 
-static int _eda_make_insts_for_list(scf_native_t* ctx, scf_list_t* h, int bb_offset)
+static int _eda_make_insts_for_list(scf_native_t* ctx, scf_list_t* h)
 {
-       scf_list_t* l;
-       int ret;
+       scf_3ac_code_t* c;
+       scf_list_t*     l;
 
        for (l = scf_list_head(h); l != scf_list_sentinel(h); l = scf_list_next(l)) {
-
-               scf_3ac_code_t* c = scf_list_data(l, scf_3ac_code_t, list);
+               c  = scf_list_data(l, scf_3ac_code_t, list);
 
                eda_inst_handler_pt h = scf_eda_find_inst_handler(c->op->type);
                if (!h) {
@@ -49,7 +37,7 @@ static int _eda_make_insts_for_list(scf_native_t* ctx, scf_list_t* h, int bb_off
                        return -EINVAL;
                }
 
-               ret = h(ctx, c);
+               int ret = h(ctx, c);
                if (ret < 0) {
                        scf_3ac_code_print(c, NULL);
                        scf_loge("3ac op '%s' make inst failed\n", c->op->name);
@@ -62,7 +50,7 @@ static int _eda_make_insts_for_list(scf_native_t* ctx, scf_list_t* h, int bb_off
                scf_3ac_code_print(c, NULL);
        }
 
-       return bb_offset;
+       return 0;
 }
 
 static int __eda_dfs_mask(scf_function_t* f, ScfEpin* mask, scf_basic_block_t* root)
@@ -82,8 +70,11 @@ static int __eda_dfs_mask(scf_function_t* f, ScfEpin* mask, scf_basic_block_t* r
                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
+               scf_logi("root->index: %d, mask_pin: c%ldp%ld\n", root->index, root->mask_pin->cid, root->mask_pin->id);
+       } else {
                root->mask_pin = mask;
+               scf_logi("root->index: %d, mask_pin: c%ldp%ld\n", root->index, root->mask_pin->cid, root->mask_pin->id);
+       }
 
        int i;
        for (i = 0; i < root->nexts->size; i++) {
@@ -94,7 +85,7 @@ static int __eda_dfs_mask(scf_function_t* f, ScfEpin* mask, scf_basic_block_t* r
        return 0;
 }
 
-static int __eda_bb_mask(scf_function_t* f, ScfEpin* mask, scf_basic_block_t* root)
+static int __eda_bb_mask(scf_function_t* f, ScfEpin* mask, scf_basic_block_t* root, scf_basic_block_t* cmp)
 {
        scf_basic_block_t* bb;
        scf_list_t*        l;
@@ -105,23 +96,24 @@ static int __eda_bb_mask(scf_function_t* f, ScfEpin* mask, scf_basic_block_t* ro
                bb->visit_flag = 0;
        }
 
-       for (i = 0; i < root->dominators->size; i++) {
-               bb =        root->dominators->data[i];
+       for (i = cmp->dominators->size - 1; i >= 0; i--) {
+               bb = cmp->dominators->data[i];
 
-               if (bb->dfo < root->dfo) {
+               if (bb->dfo < cmp->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);
+                       scf_logw("dom->index: %d, dfo: %d, cmp->index: %d, dfo: %d\n", bb->index, bb->dfo, cmp->index, cmp->dfo);
                        break;
                }
        }
 
+       cmp->visit_flag = 1;
        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)
+static int __eda_jmp_mask(scf_function_t* f, scf_3ac_code_t* c, scf_basic_block_t* cmp)
 {
        scf_3ac_operand_t* dst = c->dsts->data[0];
-       scf_basic_block_t* bb2;
+       scf_basic_block_t* bb;
        scf_list_t*        l;
 
        ScfEpin* __true  = NULL;
@@ -139,39 +131,39 @@ static int __eda_jmp_mask(scf_function_t* f, scf_3ac_code_t* c, scf_basic_block_
                        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);
+                       EDA_PIN_ADD_CONN(f->ef, cmp->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);
+                       EDA_PIN_ADD_CONN(f->ef, cmp->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);
+                       EDA_PIN_ADD_CONN(f->ef, cmp->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);
+                       EDA_PIN_ADD_CONN(f->ef, cmp->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);
+                       EDA_PIN_ADD_CONN(f->ef, cmp->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);
+                       EDA_PIN_ADD_CONN(f->ef, cmp->flag_pins[SCF_EDA_FLAG_ZERO], p0);
 
                        ret = __eda_bit_not(f, &__true, &__false);
                        if (ret < 0)
@@ -183,13 +175,13 @@ static int __eda_jmp_mask(scf_function_t* f, scf_3ac_code_t* c, scf_basic_block_
                        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);
+                       EDA_PIN_ADD_CONN(f->ef, cmp->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);
+                       EDA_PIN_ADD_CONN(f->ef, cmp->flag_pins[SCF_EDA_FLAG_SIGN], p1);
 
                        ret = __eda_bit_not(f, &__true, &__false);
                        if (ret < 0)
@@ -210,13 +202,13 @@ static int __eda_jmp_mask(scf_function_t* f, scf_3ac_code_t* c, scf_basic_block_
        if (__true)
                __true->flags |= SCF_EDA_PIN_CF;
 
-       for (i = 0; i < bb->nexts->size; i++) {
-               bb2       = bb->nexts->data[i];
+       for (i = 0; i < cmp->nexts->size; i++) {
+               bb =        cmp->nexts->data[i];
 
-               if (bb2 == dst->bb)
-                       ret = __eda_bb_mask(f, __true, bb2);
+               if (bb == dst->bb)
+                       ret = __eda_bb_mask(f, __true, bb, cmp);
                else
-                       ret = __eda_bb_mask(f, __false, bb2);
+                       ret = __eda_bb_mask(f, __false, bb, cmp);
                if (ret < 0)
                        return ret;
        }
@@ -253,12 +245,121 @@ static int _eda_fix_jmps(scf_native_t* ctx, scf_function_t* f)
        return 0;
 }
 
+static void _eda_peep_hole_2not(ScfEfunction* f, ScfEpin* p0, ScfEpin* p3)
+{
+       ScfEcomponent* c;
+       ScfEline*      el = f->elines[p3->lid];
+       ScfEpin*       p;
+
+       assert(0 == scf_eline__del_pin(el, p3->cid, p3->id));
+
+       long i;
+       for (i = 0; i + 1 < el->n_pins; i += 2) {
+
+               c  = f->components[el->pins[i]];
+               p  = c->pins      [el->pins[i + 1]];
+
+               scf_epin__del_component(p, p3->cid, p3->id);
+
+               p->flags |= p0->flags;
+
+               if (p0->io_lid >= 0)
+                       p->io_lid = p0->io_lid;
+       }
+}
+
+static int _eda_peep_hole(ScfEfunction* f)
+{
+       int ret = scf_pins_same_line(f);
+       if (ret < 0)
+               return ret;
+
+       ScfEcomponent* c0;
+       ScfEcomponent* c1;
+       ScfEline*      el0;
+       ScfEline*      el1;
+       ScfEpin*       p0;
+       ScfEpin*       p1;
+       ScfEpin*       p2;
+       ScfEpin*       p3;
+
+       long i;
+       long j;
+
+       for (i = f->n_components - 1; i >= 0; i--) {
+               c0 = f->components[i];
+
+               if (SCF_EDA_NOT != c0->type)
+                       continue;
+
+               p0  = c0->pins[SCF_EDA_NOT_IN];
+               p1  = c0->pins[SCF_EDA_NOT_OUT];
+
+               el0 = f->elines[p0->lid];
+               el1 = f->elines[p1->lid];
+
+               if (2 == el1->n_pins) {
+                       assert(0 == scf_efunction__del_component(f, c0));
+                       ScfEcomponent_free(c0);
+
+                       for (j = 2; j + 1 < el0->n_pins; j += 2) {
+
+                               c1 = f->components[el0->pins[j]];
+                               p1 = c1->pins     [el0->pins[j + 1]];
+
+                               int ret = scf_epin__add_component(p1, el0->pins[0], el0->pins[1]);
+                               if (ret < 0)
+                                       return ret;
+                       }
+                       continue;
+               }
+
+               if (2 != el0->n_pins || 4 != el1->n_pins)
+                       continue;
+
+               if (el1->pins[0] == c0->id) {
+                       c1 = f->components[el1->pins[2]];
+                       p2 = c1->pins     [el1->pins[3]];
+               } else {
+                       c1 = f->components[el1->pins[0]];
+                       p2 = c1->pins     [el1->pins[1]];
+               }
+
+               if (SCF_EDA_NOT != c1->type || SCF_EDA_NOT_IN != p2->id)
+                       continue;
+               p3 = c1->pins[SCF_EDA_NOT_OUT];
+
+               _eda_peep_hole_2not(f, p0, p3);
+
+               if (i > c1->id)
+                       i--;
+
+               assert(0 == scf_efunction__del_component(f, c0));
+               assert(0 == scf_efunction__del_component(f, c1));
+
+               ScfEcomponent_free(c0);
+               ScfEcomponent_free(c1);
+       }
+
+       for (i = 0; i < f->n_elines; i++) {
+               el0       = f->elines[i];
+
+               ScfEline_free(el0);
+       }
+
+       free(f->elines);
+       f->elines = NULL;
+       f->n_elines = 0;
+       return 0;
+}
+
 int    _scf_eda_select_inst(scf_native_t* ctx)
 {
        scf_eda_context_t*      eda = ctx->priv;
        scf_function_t*     f   = eda->f;
        scf_basic_block_t*  bb;
        scf_bb_group_t*     bbg;
+       scf_list_t*         l;
 
        int i;
        int j;
@@ -266,38 +367,34 @@ int       _scf_eda_select_inst(scf_native_t* ctx)
 
        _eda_fix_jmps(ctx, f);
 
-       for (i  = 0; i < f->bb_groups->size; i++) {
-               bbg =        f->bb_groups->data[i];
+       for (i = 0; i < f->bb_loops->size; i++) {
+               bbg       = f->bb_loops->data[i];
 
-               for (j = 0; j < bbg->body->size; j++) {
-                       bb =        bbg->body->data[j];
+               for (j = 0; j < bbg->posts->size; j++) {
+                       bb =        bbg->posts->data[j];
 
-                       assert(!bb->native_flag);
-
-                       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_logd("************ bb: %d\n", bb->index);
+                       scf_list_mov2(&bb->code_list_head, &bb->save_list_head);
                }
        }
 
-       for (i  = 0; i < f->bb_loops->size; i++) {
-               bbg =        f->bb_loops->data[i];
-
-               for (j = 0; j < bbg->body->size; j++) {
-                       bb =        bbg->body->data[j];
+       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);
 
-                       assert(!bb->native_flag);
+               if (bb->jmp_flag)
+                       continue;
 
-                       ret = _eda_make_insts_for_list(ctx, &bb->code_list_head, 0);
-                       if (ret < 0)
-                               return ret;
-                       bb->native_flag = 1;
-               }
+               scf_logd("************ bb: %d\n", bb->index);
+               ret = _eda_make_insts_for_list(ctx, &bb->code_list_head);
+               if (ret < 0)
+                       return ret;
+               scf_logd("************ bb: %d\n", bb->index);
        }
 
+#if 1
+       ret = _eda_peep_hole(f->ef);
+       if (ret < 0)
+               return ret;
+#endif
        return 0;
 }
 
@@ -305,7 +402,6 @@ int scf_eda_select_inst(scf_native_t* ctx, scf_function_t* f)
 {
        scf_eda_context_t* eda = ctx->priv;
        ScfEcomponent*     B   = NULL;
-
        scf_dag_node_t*    dn;
        scf_list_t*        l;
 
@@ -326,29 +422,95 @@ int scf_eda_select_inst(scf_native_t* ctx, scf_function_t* f)
        if (ret < 0)
                return ret;
 
-#if 0
-       ScfEcomponent* c;
-       ScfEpin*       p;
-       size_t i;
-       size_t j;
-       size_t k;
+       ScfEcomponent*  c;
+       ScfEpin*        p;
+       ScfEpin*        ck    = NULL;
+       ScfEpin*        delay = NULL;
 
+       long i;
+       long j;
        for (i = 0; i < f->ef->n_components; i++) {
                c  =        f->ef->components[i];
 
-               printf("c: %ld, type: %s\n", c->id, component_types[c->type]);
+               scf_logd("c: %ld, type: %s\n", c->id, component_types[c->type]);
 
                for (j = 0; j < c->n_pins; j++) {
                        p  =        c->pins[j];
 
-                       printf("cid: %ld, pid: %ld, flags: %#lx\n", p->cid, p->id, p->flags);
+                       scf_logd("cid: %ld, pid: %ld, flags: %#lx\n", p->cid, p->id, p->flags);
+
+                       if (p->flags & SCF_EDA_PIN_CK) {
+                               if (ck)
+                                       EDA_PIN_ADD_PIN_EF(f->ef, ck, p);
+                               else
+                                       ck = p;
+
+                               p->flags &= ~SCF_EDA_PIN_CK;
+                       }
 
+                       if (p->flags & SCF_EDA_PIN_DELAY) {
+                               if (delay)
+                                       EDA_PIN_ADD_PIN_EF(f->ef, delay, p);
+                               else
+                                       delay = p;
+
+                               p->flags &= ~SCF_EDA_PIN_DELAY;
+                       }
+#if 0
+                       long k;
                        for (k = 0; k + 1 < p->n_tos; k += 2)
                                printf("to cid: %ld, pid: %ld\n", p->tos[k], p->tos[k + 1]);
+                       printf("\n");
+#endif
                }
-               printf("\n");
+               scf_logd("-----\n\n");
        }
-#endif
+
+       if (ck) {
+               ScfEcomponent*  NAND;
+               ScfEcomponent*  AND;
+
+               EDA_INST_ADD_COMPONENT(f->ef, NAND, SCF_EDA_NAND);
+               EDA_INST_ADD_COMPONENT(f->ef, AND,  SCF_EDA_AND);
+
+               EDA_PIN_ADD_PIN(NAND, SCF_EDA_NAND_POS, B, SCF_EDA_Battery_POS);
+               EDA_PIN_ADD_PIN(NAND, SCF_EDA_NAND_NEG, B, SCF_EDA_Battery_NEG);
+
+               EDA_PIN_ADD_PIN(AND,  SCF_EDA_AND_POS,  B, SCF_EDA_Battery_POS);
+               EDA_PIN_ADD_PIN(AND,  SCF_EDA_AND_NEG,  B, SCF_EDA_Battery_NEG);
+
+               EDA_PIN_ADD_PIN(NAND, SCF_EDA_NAND_IN0, NAND, SCF_EDA_NAND_IN1);
+               EDA_PIN_ADD_PIN(NAND, SCF_EDA_NAND_IN0, AND,  SCF_EDA_AND_IN0);
+               EDA_PIN_ADD_PIN(NAND, SCF_EDA_NAND_OUT, AND,  SCF_EDA_AND_IN1);
+
+               EDA_PIN_ADD_PIN_EF(f->ef, ck, AND->pins[SCF_EDA_AND_OUT]);
+
+               NAND->pins[SCF_EDA_NAND_IN0]->flags |= SCF_EDA_PIN_CK | SCF_EDA_PIN_IN;
+
+               NAND->model = SCF_EDA_TTL_DELAY;
+       }
+
+       if (delay) {
+               ScfEcomponent*  R;
+               ScfEcomponent*  C;
+               ScfEcomponent*  T;
+
+               EDA_INST_ADD_COMPONENT(f->ef, R, SCF_EDA_Resistor);
+               EDA_INST_ADD_COMPONENT(f->ef, C, SCF_EDA_Capacitor);
+               EDA_INST_ADD_COMPONENT(f->ef, T, SCF_EDA_NPN);
+
+               EDA_PIN_ADD_PIN(R, 1, B, SCF_EDA_Battery_POS);
+               EDA_PIN_ADD_PIN(R, 0, C, 1);
+               EDA_PIN_ADD_PIN(R, 0, T, SCF_EDA_NPN_B);
+               EDA_PIN_ADD_PIN(C, 0, T, SCF_EDA_NPN_E);
+               EDA_PIN_ADD_PIN(C, 0, B, SCF_EDA_Battery_NEG);
+
+               EDA_PIN_ADD_PIN_EF(f->ef, delay, T->pins[SCF_EDA_NPN_C]);
+
+               R->r  = 1600;
+               C->uf = 4e-4;
+       }
+
        return 0;
 }
 
index 2902533c7b9c19e1d7f675309cf07a33785faa48..337d8e945ddbcdaa9227d9d95897651d5e1877c7 100644 (file)
@@ -252,29 +252,21 @@ static int __eda_bit_add(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpi
 
 static int __eda_bit_adc(scf_function_t* f, ScfEpin** in0, ScfEpin** in1, ScfEpin** in2, ScfEpin** out, ScfEpin** cf)
 {
-       ScfEpin* out0 = NULL;
-       ScfEpin* cf0  = NULL;
-
-       ScfEpin* in3  = NULL;
-       ScfEpin* cf1  = NULL;
+       ScfEcomponent*  B   = f->ef->components[0];
+       ScfEcomponent*  ADC = NULL;
 
-       ScfEpin* or0  = NULL;
-       ScfEpin* or1  = NULL;
+       EDA_INST_ADD_COMPONENT(f->ef, ADC, SCF_EDA_ADC);
 
-       int ret = __eda_bit_add(f, in0, in1, &out0, &cf0);
-       if (ret < 0)
-               return ret;
+       EDA_PIN_ADD_PIN(ADC, SCF_EDA_ADC_POS, B, SCF_EDA_Battery_POS);
+       EDA_PIN_ADD_PIN(ADC, SCF_EDA_ADC_NEG, B, SCF_EDA_Battery_NEG);
 
-       ret = __eda_bit_add(f, in2, &in3, out, &cf1);
-       if (ret < 0)
-               return ret;
-       EDA_PIN_ADD_PIN_EF(f->ef, out0, in3);
+       ADC->pins[SCF_EDA_ADC_CF]->flags = SCF_EDA_PIN_CF;
 
-       ret = __eda_bit_or(f, &or0, &or1, cf);
-       if (ret < 0)
-               return ret;
-       EDA_PIN_ADD_PIN_EF(f->ef, or0,  cf0);
-       EDA_PIN_ADD_PIN_EF(f->ef, or1,  cf1);
+       *in0 = ADC->pins[SCF_EDA_ADC_IN0];
+       *in1 = ADC->pins[SCF_EDA_ADC_IN1];
+       *in2 = ADC->pins[SCF_EDA_ADC_CI];
+       *out = ADC->pins[SCF_EDA_ADC_OUT];
+       *cf  = ADC->pins[SCF_EDA_ADC_CF];
        return 0;
 }
 
@@ -289,17 +281,6 @@ static int __eda_teq(scf_function_t* f, scf_dag_node_t* in, ScfEpin** res)
        int ret;
        int i;
 
-       if (1 == N) {
-               EDA_PIN_ADD_INPUT(in, 0, f->ef, prev);
-               *res = prev;
-
-               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;
-       }
-
        for (i = 0; i + 1 < N; i += 2) {
                ret = __eda_bit_nor(f, &p0, &p1, &po);
                if (ret < 0)
@@ -313,11 +294,19 @@ static int __eda_teq(scf_function_t* f, scf_dag_node_t* in, ScfEpin** res)
                        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;
-                       in->pins[i]->io_lid = i;
+                       if (!in->var->r_pins[i]) {
+                               in ->var->r_pins[i] = in->pins[i];
+
+                               in->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
+                               in->pins[i]->io_lid = i;
+                       }
+
+                       if (!in->var->r_pins[i + 1]) {
+                               in ->var->r_pins[i + 1] = in->pins[i + 1];
 
-                       in->pins[i + 1]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
-                       in->pins[i + 1]->io_lid = i + 1;
+                               in->pins[i + 1]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
+                               in->pins[i + 1]->io_lid = i + 1;
+                       }
                }
        }
 
@@ -333,8 +322,12 @@ static int __eda_teq(scf_function_t* f, scf_dag_node_t* in, ScfEpin** res)
                        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;
-                       in->pins[N - 1]->io_lid = N - 1;
+                       if (!in->var->r_pins[N - 1]) {
+                               in ->var->r_pins[N - 1] = in->pins[N - 1];
+
+                               in->pins[N - 1]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
+                               in->pins[N - 1]->io_lid = N - 1;
+                       }
                }
        }
 
@@ -426,8 +419,12 @@ static int _eda_inst_bit_not_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                EDA_PIN_ADD_INPUT(in, i, f->ef, pi);
 
                if (in->var->arg_flag) {
-                       in->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
-                       in->pins[i]->io_lid = i;
+                       if (!in->var->r_pins[i]) {
+                               in ->var->r_pins[i] = in->pins[i];
+
+                               in->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
+                               in->pins[i]->io_lid = i;
+                       }
                }
 
                out->pins[i] = po;
@@ -468,13 +465,21 @@ static int _eda_inst_bit_and_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                EDA_PIN_ADD_INPUT(in1, i, f->ef, p1);
 
                if (in0->var->arg_flag) {
-                       in0->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
-                       in0->pins[i]->io_lid = i;
+                       if (!in0->var->r_pins[i]) {
+                               in0 ->var->r_pins[i] = in0->pins[i];
+
+                               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;
+                       if (!in1->var->r_pins[i]) {
+                               in1 ->var->r_pins[i] = in1->pins[i];
+
+                               in1->pins[i]->flags |= SCF_EDA_PIN_IN;
+                               in1->pins[i]->io_lid = i;
+                       }
                }
 
                out->pins[i] = po;
@@ -515,13 +520,21 @@ static int _eda_inst_bit_or_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                EDA_PIN_ADD_INPUT(in1, i, f->ef, p1);
 
                if (in0->var->arg_flag) {
-                       in0->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
-                       in0->pins[i]->io_lid = i;
+                       if (!in0->var->r_pins[i]) {
+                               in0 ->var->r_pins[i] = in0->pins[i];
+
+                               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;
+                       if (!in1->var->r_pins[i]) {
+                               in1 ->var->r_pins[i] = in1->pins[i];
+
+                               in1->pins[i]->flags |= SCF_EDA_PIN_IN;
+                               in1->pins[i]->io_lid = i;
+                       }
                }
 
                out->pins[i] = po;
@@ -622,13 +635,21 @@ out[i] =     (x & y) |   (~x & z)
 
        for (i = 0; i < N; i++) {
                if (src->var->arg_flag) {
-                       src->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
-                       src->pins[i]->io_lid = i;
+                       if (!src->var->r_pins[i]) {
+                               src ->var->r_pins[i] = src->pins[i];
+
+                               src->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
+                               src->pins[i]->io_lid = i;
+                       }
                }
 
                if (sht->var->arg_flag) {
-                       sht->pins[i]->flags |= SCF_EDA_PIN_IN;
-                       sht->pins[i]->io_lid = i;
+                       if (!sht->var->r_pins[i]) {
+                               sht ->var->r_pins[i] = sht->pins[i];
+
+                               sht->pins[i]->flags |= SCF_EDA_PIN_IN;
+                               sht->pins[i]->io_lid = i;
+                       }
                }
 
                out->pins[i] = res[i];
@@ -781,13 +802,21 @@ out[i] =     (x & y) |   (~x & z)
 
        for (i = 0; i < N; i++) {
                if (src->var->arg_flag) {
-                       src->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
-                       src->pins[i]->io_lid = i;
+                       if (!src->var->r_pins[i]) {
+                               src ->var->r_pins[i] = src->pins[i];
+
+                               src->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
+                               src->pins[i]->io_lid = i;
+                       }
                }
 
                if (sht->var->arg_flag) {
-                       sht->pins[i]->flags |= SCF_EDA_PIN_IN;
-                       sht->pins[i]->io_lid = i;
+                       if (!sht->var->r_pins[i]) {
+                               sht ->var->r_pins[i] = sht->pins[i];
+
+                               sht->pins[i]->flags |= SCF_EDA_PIN_IN;
+                               sht->pins[i]->io_lid = i;
+                       }
                }
 
                out->pins[i] = res[i];
@@ -845,13 +874,21 @@ static int _eda_inst_add_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                cf->flags |= SCF_EDA_PIN_CF;
 
                if (in0->var->arg_flag) {
-                       in0->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
-                       in0->pins[i]->io_lid = i;
+                       if (!in0->var->r_pins[i]) {
+                               in0 ->var->r_pins[i] = in0->pins[i];
+
+                               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;
+                       if (!in1->var->r_pins[i]) {
+                               in1 ->var->r_pins[i] = in1->pins[i];
+
+                               in1->pins[i]->flags |= SCF_EDA_PIN_IN;
+                               in1->pins[i]->io_lid = i;
+                       }
                }
 
                out->pins[i] = res; // result
@@ -864,12 +901,7 @@ static int __eda_sub(scf_function_t* f, ScfEpin** a, ScfEpin** b, ScfEpin** res,
 {
        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];
+       ScfEpin*        pc = B->pins[SCF_EDA_Battery_POS];
 
        int i;
        for (i = 0; i < N; i++) {
@@ -927,13 +959,21 @@ static int _eda_inst_sub_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                out->pins[i] = res[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 (!in0->var->r_pins[i]) {
+                               in0 ->var->r_pins[i] = in0->pins[i];
+
+                               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;
+                       if (!in1->var->r_pins[i]) {
+                               in1 ->var->r_pins[i] = in1->pins[i];
+
+                               in1->pins[i]->flags |= SCF_EDA_PIN_IN;
+                               in1->pins[i]->io_lid = i;
+                       }
                }
        }
        return 0;
@@ -1002,13 +1042,21 @@ static int _eda_inst_mul_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                        out->pins[0] = res;
 
                        if (in0->var->arg_flag) {
-                               in0->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
-                               in0->pins[i]->io_lid = i;
+                               if (!in0->var->r_pins[i]) {
+                                       in0 ->var->r_pins[i] = in0->pins[i];
+
+                                       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;
+                               if (!in1->var->r_pins[i]) {
+                                       in1 ->var->r_pins[i] = in1->pins[i];
+
+                                       in1->pins[i]->flags |= SCF_EDA_PIN_IN;
+                                       in1->pins[i]->io_lid = i;
+                               }
                        }
                        continue;
                }
@@ -1091,13 +1139,21 @@ static int _eda_inst_mul_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                n_cfs  = 0;
 
                if (in0->var->arg_flag) {
-                       in0->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
-                       in0->pins[i]->io_lid = i;
+                       if (!in0->var->r_pins[i]) {
+                               in0 ->var->r_pins[i] = in0->pins[i];
+
+                               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;
+                       if (!in1->var->r_pins[i]) {
+                               in1 ->var->r_pins[i] = in1->pins[i];
+
+                               in1->pins[i]->flags |= SCF_EDA_PIN_IN;
+                               in1->pins[i]->io_lid = i;
+                       }
                }
        }
 
@@ -1294,24 +1350,72 @@ static int _eda_inst_div_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                out->pins[i]->io_lid = 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 (!in0->var->r_pins[i]) {
+                               in0 ->var->r_pins[i] = in0->pins[i];
+
+                               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;
+                       if (!in1->var->r_pins[i]) {
+                               in1 ->var->r_pins[i] = in1->pins[i];
+
+                               in1->pins[i]->flags |= SCF_EDA_PIN_IN;
+                               in1->pins[i]->io_lid = i;
+                       }
                }
        }
        return 0;
 }
 
+static int __eda_loop_var(scf_function_t* f, scf_dag_node_t* in, int i, ScfEpin* cond)
+{
+       ScfEcomponent* B = f->ef->components[0];
+       ScfEcomponent* IF;
+       ScfEcomponent* IF2;
+       ScfEcomponent* DFF;
+
+       EDA_INST_ADD_COMPONENT(f->ef, IF,  SCF_EDA_IF);
+       EDA_INST_ADD_COMPONENT(f->ef, IF2, SCF_EDA_IF);
+       EDA_INST_ADD_COMPONENT(f->ef, DFF, SCF_EDA_DFF);
+
+       EDA_PIN_ADD_PIN(IF,  SCF_EDA_IF_POS,  B,   SCF_EDA_Battery_POS);
+       EDA_PIN_ADD_PIN(IF2, SCF_EDA_IF_POS,  B,   SCF_EDA_Battery_POS);
+       EDA_PIN_ADD_PIN(DFF, SCF_EDA_DFF_POS, B,   SCF_EDA_Battery_POS);
+
+       EDA_PIN_ADD_PIN(IF,  SCF_EDA_IF_NEG,  B,   SCF_EDA_Battery_NEG);
+       EDA_PIN_ADD_PIN(IF2, SCF_EDA_IF_NEG,  B,   SCF_EDA_Battery_NEG);
+       EDA_PIN_ADD_PIN(DFF, SCF_EDA_DFF_NEG, B,   SCF_EDA_Battery_NEG);
+
+       EDA_PIN_ADD_PIN(IF,  SCF_EDA_IF_OUT,   DFF, SCF_EDA_DFF_IN);
+       EDA_PIN_ADD_PIN(IF,  SCF_EDA_IF_FALSE, IF2, SCF_EDA_IF_OUT);
+       EDA_PIN_ADD_PIN(IF2, SCF_EDA_IF_FALSE, DFF, SCF_EDA_DFF_OUT);
+
+       assert(cond);
+       EDA_PIN_ADD_PIN_EF(f->ef, IF2->pins[SCF_EDA_IF_COND], cond);
+
+       IF ->pins[SCF_EDA_IF_COND]->flags = SCF_EDA_PIN_DELAY;
+       DFF->pins[SCF_EDA_DFF_CK ]->flags = SCF_EDA_PIN_CK;
+
+       in->var->w_pins[i] = IF2->pins[SCF_EDA_IF_TRUE];
+       in->var->DFFs[i]   = DFF;
+
+       EDA_PIN_ADD_INPUT(in, i, f->ef, IF->pins[SCF_EDA_IF_TRUE]);
+
+       in->pins[i] = DFF->pins[SCF_EDA_DFF_OUT];
+       return 0;
+}
+
 static int _eda_inst_inc_handler(scf_native_t* ctx, scf_3ac_code_t* c)
 {
        EDA_INST_SRC_CHECK()
 
-       scf_dag_node_t* in = src->dag_node;
-       ScfEpin*        pc = NULL;
+       scf_basic_block_t* bb = c->basic_block;
+       scf_dag_node_t*    in = src->dag_node;
+       ScfEcomponent*     B  = f->ef->components[0];
+       ScfEpin*           pc = NULL;
 
        int i;
        int N = eda_variable_size(in->var);
@@ -1334,7 +1438,6 @@ static int _eda_inst_inc_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                                return ret;
 
                        EDA_PIN_ADD_PIN_EF(f->ef, p1, pc);
-
                } else {
                        int ret = __eda_bit_not(f, &p0, &res);
                        if (ret < 0)
@@ -1343,14 +1446,25 @@ static int _eda_inst_inc_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                        cf = p0;
                }
 
+               if (bb->loop_flag) {
+                       if (!in->var->DFFs[i]) {
+                               int ret = __eda_loop_var(f, in, i, bb->mask_pin);
+                               if (ret < 0)
+                                       return ret;
+                       }
+               }
                EDA_PIN_ADD_INPUT(in, i, f->ef, p0);
 
                pc         = cf;
                cf->flags |= SCF_EDA_PIN_CF;
 
                if (in->var->arg_flag) {
-                       in->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
-                       in->pins[i]->io_lid = i;
+                       if (!in->var->r_pins[i]) {
+                               in ->var->r_pins[i] = in->pins[i];
+
+                               in->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
+                               in->pins[i]->io_lid = i;
+                       }
                }
 
                in->pins[i] = res;
@@ -1421,8 +1535,12 @@ static int _eda_inst_dec_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                cf->flags |= SCF_EDA_PIN_CF;
 
                if (in->var->arg_flag) {
-                       in->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
-                       in->pins[i]->io_lid = i;
+                       if (!in->var->r_pins[i]) {
+                               in ->var->r_pins[i] = in->pins[i];
+
+                               in->pins[i]->flags |= SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
+                               in->pins[i]->io_lid = i;
+                       }
                }
 
                in->pins[i] = res;
@@ -1554,13 +1672,21 @@ static int _eda_inst_cmp_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                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 (!in0->var->r_pins[i]) {
+                               in0 ->var->r_pins[i] = in0->pins[i];
+
+                               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;
+                       if (!in1->var->r_pins[i]) {
+                               in1 ->var->r_pins[i] = in1->pins[i];
+
+                               in1->pins[i]->flags |= SCF_EDA_PIN_IN;
+                               in1->pins[i]->io_lid = i;
+                       }
                }
        }
 
@@ -1690,12 +1816,19 @@ static int __eda_cast(scf_function_t* f, scf_dag_node_t* in, ScfEpin** res, int
 
                        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];
+                               ret = __eda_bit_not(f, &p0, &p1);
+                               if (ret < 0)
+                                       return ret;
+
+                               ret = __eda_bit_not(f, &p2, &po);
+                               if (ret < 0)
+                                       return ret;
+
+                               EDA_PIN_ADD_PIN_EF(f->ef, p2, p1);
+
+                               in->pins[i] = p0;
+                               res[i]      = po;
 
                        } else if (i < M)
                                res[i] = in->pins[i];
@@ -1708,13 +1841,18 @@ static int __eda_cast(scf_function_t* f, scf_dag_node_t* in, ScfEpin** res, int
 
        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;
+                       if (!in->var->r_pins[i]) {
+                               in ->var->r_pins[i] = in->pins[i];
 
-                       in->pins[i]->io_lid = j;
+                               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;
@@ -1805,6 +1943,7 @@ static int _eda_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                                EDA_PIN_ADD_PIN_EF(f->ef, p0, res[j]);
                                EDA_PIN_ADD_PIN_EF(f->ef, p1, bb->mask_pin);
 
+                               scf_logi("bb->index: %d, mask_pin: c%ldp%ld\n", bb->index, bb->mask_pin->cid, bb->mask_pin->id);
                                res[j] = po;
                        }
 
@@ -1889,6 +2028,26 @@ static int _eda_inst_reload_handler(scf_native_t* ctx, scf_3ac_code_t* c)
 
 static int _eda_inst_save_handler(scf_native_t* ctx, scf_3ac_code_t* c)
 {
+       EDA_INST_SRC_CHECK()
+
+       scf_basic_block_t*  bb  = c->basic_block;
+       scf_dag_node_t*     in  = src->dag_node;
+
+       if (!bb->loop_flag)
+               return 0;
+
+       int i;
+       int N = eda_variable_size(in->var);
+
+       EDA_INST_IN_CHECK(in, N);
+       in->n_pins = N;
+
+       for (i = 0; i < N; i++) {
+               assert(in->var->w_pins[i]);
+
+               EDA_PIN_ADD_PIN_EF(f->ef, in->var->w_pins[i], in->pins[i]);
+       }
+
        return 0;
 }
 
@@ -1896,24 +2055,65 @@ static int _eda_inst_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c)
 {
        EDA_INST_OP2_CHECK()
 
-       scf_dag_node_t* in  = src->dag_node;
-       scf_dag_node_t* out = dst->dag_node;
+       scf_basic_block_t*  bb  = c->basic_block;
+       scf_dag_node_t*     in  = src->dag_node;
+       scf_dag_node_t*     out = dst->dag_node;
+       scf_variable_t*     v   = out->var;
 
        int i;
        int M = eda_variable_size(in->var);
        int N = eda_variable_size(out->var);
 
-       if (M < N)
-               return _eda_inst_cast_handler(ctx, c);
-
-       EDA_INST_IN_CHECK(in, M);
+//     EDA_INST_IN_CHECK(in, M);
 
        in ->n_pins = M;
        out->n_pins = N;
+       v->n_pins   = N;
+
+       ScfEpin* res[SCF_EDA_MAX_BITS];
+       ScfEpin* p0;
+       ScfEpin* p1;
+       ScfEpin* p2;
+       ScfEpin* po;
+
+       int ret = __eda_cast(f, in, res, N);
+       if (ret < 0)
+               return ret;
 
        for (i = 0; i < N; i++) {
-               out->pins[i] = in->pins[i];
+               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[i]);
+                       EDA_PIN_ADD_PIN_EF(f->ef, p1, bb->mask_pin);
+
+                       res[i] = po;
+               }
+
+               if (v->w_pins[i]) {
+                       ret = __eda_bit_or(f, &p0, &p1, &po);
+                       if (ret < 0)
+                               return ret;
+
+                       EDA_PIN_ADD_PIN_EF(f->ef, p0, v->w_pins[i]);
+                       EDA_PIN_ADD_PIN_EF(f->ef, p1, res[i]);
+
+                       res[i] = po;
+               }
+
+               if (v->w_pins[i])
+                       v->w_pins[i]->flags &= ~SCF_EDA_PIN_OUT;
+
+               v->w_pins[i] = res[i];
+
+               v->w_pins[i]->flags |= SCF_EDA_PIN_OUT;
+               v->w_pins[i]->io_lid = i;
+
+               out->pins[i] = v->w_pins[i];
        }
+
        return 0;
 }
 
index a798e62a4daca776bbb965df0b0fb8c81646edfa..d00f2ccd97d33d52438e28878db4eee534c79413 100644 (file)
@@ -28,6 +28,14 @@ static int component_pins[SCF_EDA_Components_NB] =
 
        SCF_EDA_IF_NB,
        SCF_EDA_MLA_NB,
+       SCF_EDA_ADC_NB,
+
+       SCF_EDA_DFF_NB,
+
+       SCF_EDA_Signal_NB,
+
+       SCF_EDA_OP_AMP_NB,
+       2, // crystal oscillator
 };
 
 static int __diode_path_off(ScfEpin* p0, ScfEpin* p1, int flags)
@@ -266,6 +274,70 @@ static int __ttl_mla_shared(ScfEpin* p, int flags)
        return 1;
 }
 
+static int __ttl_adc_path_off(ScfEpin* p0, ScfEpin* p1, int flags)
+{
+       if (SCF_EDA_ADC_NEG == p0->id)
+               return 1;
+       if (flags && (SCF_EDA_ADC_CI <= p0->id && p0->id <= SCF_EDA_ADC_IN1))
+               return 1;
+
+       if (SCF_EDA_ADC_POS == p0->id) {
+               if (p1 && (SCF_EDA_ADC_CI <= p1->id && p1->id <= SCF_EDA_ADC_IN1))
+                       return 1;
+       } else {
+               if (p1) {
+                       if (!flags
+                                       && (SCF_EDA_ADC_CI  <= p0->id && p0->id <= SCF_EDA_ADC_IN1)
+                                       && (SCF_EDA_ADC_OUT == p1->id && p1->id <= SCF_EDA_ADC_CF))
+                               return 0;
+
+                       if (SCF_EDA_ADC_NEG != p1->id)
+                               return 1;
+               }
+       }
+       return 0;
+}
+
+static int __ttl_adc_shared(ScfEpin* p, int flags)
+{
+       if (!flags) {
+               if (SCF_EDA_ADC_OUT == p->id && p->id <= SCF_EDA_ADC_CF)
+                       return 0;
+       }
+       return 1;
+}
+
+static int __741_op_amp_path_off(ScfEpin* p0, ScfEpin* p1, int flags)
+{
+       if (SCF_EDA_OP_AMP_NEG == p0->id)
+               return 1;
+
+       if (SCF_EDA_OP_AMP_POS == p0->id) {
+               if (p1 && (SCF_EDA_OP_AMP_IN == p1->id || SCF_EDA_OP_AMP_INVERT == p1->id))
+                       return 1;
+       } else {
+               if (p1) {
+                       if (!flags
+                                       && (SCF_EDA_OP_AMP_IN == p0->id || SCF_EDA_OP_AMP_INVERT == p0->id)
+                                       &&  SCF_EDA_OP_AMP_OUT == p1->id)
+                               return 0;
+
+                       if (SCF_EDA_OP_AMP_NEG != p1->id)
+                               return 1;
+               }
+       }
+       return 0;
+}
+
+static int __741_op_amp_shared(ScfEpin* p, int flags)
+{
+       if (!flags) {
+               if (SCF_EDA_OP_AMP_OUT == p->id)
+                       return 0;
+       }
+       return 1;
+}
+
 static ScfEops __diode_ops =
 {
        __diode_path_off,
@@ -331,44 +403,66 @@ static ScfEops __ttl_mla_ops =
        __ttl_mla_shared,
 };
 
+static ScfEops __ttl_adc_ops =
+{
+       __ttl_adc_path_off,
+       __ttl_adc_shared,
+};
+
+static ScfEops __741_op_amp_ops =
+{
+       __741_op_amp_path_off,
+       __741_op_amp_shared,
+};
+
 static ScfEdata  component_datas[] =
 {
-       {SCF_EDA_None,       0,                   0, 0, 0,    0,   0,   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, "./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, &__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},
+       {SCF_EDA_None,       0,                   0, 0, 0,    0,   0,   0, 0, 0,   NULL, NULL, NULL},
+       {SCF_EDA_Battery,    0,                   0, 5, 0, 1e-9, 1e9,   0, 0, 0,   NULL, NULL, NULL},
+       {SCF_EDA_Signal,     0,                   0, 0, 0, 1e-9, 1e9,   0, 0, 0,   NULL, NULL, NULL},
+
+       {SCF_EDA_Resistor,   0,                   0, 0, 0,  1e4,   0,   0, 0, 0,   NULL, NULL, NULL},
+       {SCF_EDA_Capacitor,  0,                   0, 0, 0,   10, 0.1,   0, 0, 0,   NULL, NULL, NULL},
+       {SCF_EDA_Inductor,   0,                   0, 0, 0,   10,   0, 1e3, 0, 0,   NULL, NULL, NULL},
+
+       {SCF_EDA_Diode,      0,                   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, 0,   &__npn_ops,   NULL, "./cpk/9013.txt"},
+       {SCF_EDA_PNP,        0,                   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, 0,   &__ttl_nand_ops, "./cpk/ttl_nand.cpk", NULL},
+       {SCF_EDA_NOT,        0,                   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, 0,   &__ttl_gate_ops, "./cpk/ttl_and.cpk",  NULL},
+       {SCF_EDA_OR,         0,                   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, 0,   &__ttl_gate_ops, "./cpk/ttl_nor.cpk",  NULL},
+       {SCF_EDA_XOR,        0,                   0, 0, 0,    0,   0,   0, 0, 0,   &__ttl_gate_ops, "./cpk/ttl_xor.cpk",  NULL},
+       {SCF_EDA_DFF,        0,                   0, 0, 0,    0,   0,   0, 0, 0,   &__ttl_gate_ops, "./cpk/ttl_dff.cpk",  NULL},
+
+       {SCF_EDA_ADD,        0,                   0, 0, 0,    0,   0,   0, 0, 0,   &__ttl_add_ops,  "./cpk/ttl_add.cpk",  NULL},
+       {SCF_EDA_ADC,        0,                   0, 0, 0,    0,   0,   0, 0, 0,   &__ttl_adc_ops,  "./cpk/ttl_adc.cpk",  NULL},
+
+       {SCF_EDA_NAND4,      0,                   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, 0,   &__ttl_and2_or_ops, "./cpk/ttl_and2_or.cpk", NULL},
+       {SCF_EDA_IF,         0,                   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, 0,   &__ttl_mla_ops,     "./cpk/ttl_mla.cpk",     NULL},
+
+       {SCF_EDA_NOT,        SCF_EDA_TTL_DELAY,   0, 0, 0,    0,   0,   0, 0, 0,   &__ttl_not_ops,     "./cpk/ttl_not_delay.cpk", NULL},
+
+       {SCF_EDA_OP_AMP,     0,                   0, 0, 0,    0,   0,   0, 0, 0,   &__741_op_amp_ops, "./cpk/op_amp_f007.cpk",   NULL},
+
+       {SCF_EDA_Crystal,    0,                   0, 0, 0,    0,   0,   0, 0, 1e7, NULL,              "./cpk/crystal.cpk",       NULL},
 };
 
 static ScfEdata  pin_datas[] =
 {
-       {SCF_EDA_None,       0,                   0, 0, 0,    0,   0,   0,   0, NULL, NULL, NULL},
+       {SCF_EDA_None,       0,                   0, 0, 0,    0,   0,   0,   0, 0, NULL, NULL, NULL},
 
-       {SCF_EDA_Diode,      0,   SCF_EDA_Diode_NEG, 0, 0,  750,   0,   0,   0, NULL, NULL, NULL},
+       {SCF_EDA_Diode,      0,   SCF_EDA_Diode_NEG, 0, 0,  750,   0,   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, 150, NULL, NULL, NULL},
+       {SCF_EDA_NPN,        0,       SCF_EDA_NPN_B, 0, 0,  750,   0,   0,   0, 0, NULL, NULL, NULL},
+       {SCF_EDA_NPN,        0,       SCF_EDA_NPN_C, 0, 0,    3,   0,   0, 200, 0, 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, 150, NULL, NULL, NULL},
+       {SCF_EDA_PNP,        0,       SCF_EDA_PNP_B, 0, 0,  750,   0,   0,   0, 0, NULL, NULL, NULL},
+       {SCF_EDA_PNP,        0,       SCF_EDA_PNP_C, 0, 0,    3,   0,   0, 200, 0, NULL, NULL, NULL},
 };
 
 static ScfEdata* _pin_find_data(const uint64_t type, const uint64_t model, const uint64_t pid)
@@ -447,8 +541,10 @@ int scf_econn__del_cid(ScfEconn* ec, uint64_t cid)
                        ec->n_cids--;
 
                        p = realloc(ec->cids, sizeof(uint64_t) * ec->n_cids);
-                       if (p)
-                               ec->cids = p;
+                       if (!p && ec->n_cids)
+                               return -ENOMEM;
+
+                       ec->cids = p;
                        return 0;
                }
        }
@@ -468,16 +564,10 @@ int scf_eline__add_line(ScfEline* el, ScfLine*  l)
        if (!el || !l)
                return -EINVAL;
 
-       for (size_t i = 0; i < el->n_lines; i++) {
+       for (long i = 0; i < el->n_lines; i++) {
 
                if (el->lines[i] == l)
                        return 0;
-
-               if (el->lines[i]->x0 == l->x0
-                && el->lines[i]->y0 == l->y0
-                && el->lines[i]->x1 == l->x1
-                && el->lines[i]->y1 == l->y1)
-                       return 0;
        }
 
        void* p = realloc(el->lines, sizeof(ScfLine*) * (el->n_lines + 1));
@@ -489,21 +579,18 @@ int scf_eline__add_line(ScfEline* el, ScfLine*  l)
        return 0;
 }
 
-int scf_eline__del_line(ScfEline* el, ScfLine*  l)
+int scf_eline__del_line(ScfEline* el, ScfLine* l)
 {
        if (!el || !l)
                return -EINVAL;
 
-       void*   p;
-       size_t  i;
-       size_t  j;
+       void*  p;
+       long   i;
+       long   j;
 
        for (i = 0; i < el->n_lines; i++) {
 
-               if (el->lines[i]->x0 == l->x0
-                && el->lines[i]->y0 == l->y0
-                && el->lines[i]->x1 == l->x1
-                && el->lines[i]->y1 == l->y1) {
+               if (el->lines[i] == l) {
 
                        for (j = i + 1;  j  < el->n_lines; j++)
                                el->lines[j - 1] = el->lines[j];
@@ -511,8 +598,10 @@ int scf_eline__del_line(ScfEline* el, ScfLine*  l)
                        el->n_lines--;
 
                        p = realloc(el->lines, sizeof(ScfLine*) * el->n_lines);
-                       if (p)
-                               el->lines = p;
+                       if (!p && el->n_lines > 0)
+                               return -ENOMEM;
+
+                       el->lines = p;
                        return 0;
                }
        }
@@ -560,8 +649,10 @@ int scf_eline__del_pin(ScfEline* el, uint64_t  cid, uint64_t pid)
                        el->n_pins -= 2;
 
                        p = realloc(el->pins, sizeof(uint64_t) * el->n_pins);
-                       if (p)
-                               el->pins = p;
+                       if (!p && el->n_pins > 0)
+                               return -EINVAL;
+
+                       el->pins = p;
                        return 0;
                }
        }
@@ -608,8 +699,10 @@ int scf_eline__del_conn(ScfEline* el, ScfEconn* ec)
                        el->n_conns--;
 
                        p = realloc(el->conns, sizeof(ScfEconn*) * el->n_conns);
-                       if (p)
-                               el->conns = p;
+                       if (!p && el->n_conns > 0)
+                               return -EINVAL;
+
+                       el->conns = p;
                        return 0;
                }
        }
@@ -619,9 +712,11 @@ int scf_eline__del_conn(ScfEline* el, ScfEconn* ec)
 
 ScfEpin* scf_epin__alloc()
 {
-       ScfEpin* pin = calloc(1, sizeof(ScfEpin));
+       ScfEpin* p = calloc(1, sizeof(ScfEpin));
+       if (p)
+               p->lid = -1;
 
-       return pin;
+       return p;
 }
 
 int scf_epin__add_component(ScfEpin* pin, uint64_t cid, uint64_t pid)
@@ -664,8 +759,10 @@ int scf_epin__del_component(ScfEpin* pin, uint64_t cid, uint64_t pid)
                        pin->n_tos -= 2;
 
                        p = realloc(pin->tos, sizeof(uint64_t) * pin->n_tos);
-                       if (p)
-                               pin->tos = p;
+                       if (!p && pin->n_tos > 0)
+                               return -ENOMEM;
+
+                       pin->tos = p;
                        return 0;
                }
        }
@@ -685,7 +782,8 @@ ScfEcomponent* scf_ecomponent__alloc(uint64_t type)
        if (!c)
                return NULL;
 
-       c->type = type;
+       c->type      = type;
+       c->mirror_id = -1;
 
        ed = scf_ecomponent__find_data(c->type, c->model);
        if (ed) {
@@ -694,6 +792,7 @@ ScfEcomponent* scf_ecomponent__alloc(uint64_t type)
                c->r   = ed->r;
                c->uf  = ed->uf;
                c->uh  = ed->uh;
+               c->Hz  = ed->Hz;
                c->ops = ed->ops;
        }
 
@@ -778,8 +877,10 @@ int scf_ecomponent__del_pin(ScfEcomponent* c, ScfEpin* pin)
                        c->n_pins--;
 
                        p = realloc(c->pins, sizeof(ScfEpin*) * c->n_pins);
-                       if (p)
-                               c->pins = p;
+                       if (!p && c->n_pins > 0)
+                               return -ENOMEM;
+
+                       c->pins = p;
                        return 0;
                }
        }
@@ -818,18 +919,75 @@ int scf_efunction__add_component(ScfEfunction* f, ScfEcomponent* c)
        return 0;
 }
 
+static int __efunction__del_component(ScfEfunction* f, ScfEcomponent* c)
+{
+       ScfEcomponent* c2;
+       ScfEline*      el;
+       ScfEpin*       p;
+
+       long  i;
+       long  j;
+       long  k;
+
+       for (i = 0; i < f->n_elines; i++) {
+               el =        f->elines[i];
+
+               for (j = 0; j + 1 < el->n_pins; ) {
+
+                       if (el->pins[j] == c->id)
+                               assert(0 == scf_eline__del_pin(el, c->id, el->pins[j + 1]));
+                       else {
+                               if (el->pins[j] > c->id)
+                                       el->pins[j]--;
+
+                               j += 2;
+                       }
+               }
+       }
+
+       for (i = 0; i < f->n_components; i++) {
+               c2 =        f->components[i];
+
+               if (c2 == c)
+                       continue;
+
+               if (c2->id > c->id)
+                       c2->id--;
+
+               for (j = 0; j < c2->n_pins; j++) {
+                       p  =        c2->pins[j];
+
+                       for (k = 0; k + 1 < p->n_tos; ) {
+
+                               if (p->tos[k] == c->id)
+                                       assert(0 == scf_epin__del_component(p, c->id, p->tos[k + 1]));
+                               else {
+                                       if (p->tos[k] > c->id)
+                                               p->tos[k]--;
+
+                                       k += 2;
+                               }
+                       }
+
+                       if (p->cid > c->id)
+                               p->cid--;
+               }
+       }
+}
+
 int scf_efunction__del_component(ScfEfunction* f, ScfEcomponent* c)
 {
        if (!f || !c)
                return -EINVAL;
 
-       size_t   i;
-       size_t   j;
-       void*    p;
+       void* p;
+       long  i;
+       long  j;
 
        for (i = 0; i < f->n_components; i++) {
 
                if (f->components[i] == c) {
+                       __efunction__del_component(f, c);
 
                        for (j = i + 1;  j < f->n_components; j++)
                                f->components[j - 1] = f->components[j];
@@ -837,8 +995,10 @@ int scf_efunction__del_component(ScfEfunction* f, ScfEcomponent* c)
                        f->n_components--;
 
                        p = realloc(f->components, sizeof(ScfEcomponent*) * f->n_components);
-                       if (p)
-                               f->components = p;
+                       if (!p && f->n_components > 0)
+                               return -EINVAL;
+
+                       f->components = p;
                        return 0;
                }
        }
@@ -879,8 +1039,10 @@ int scf_efunction__del_eline(ScfEfunction* f, ScfEline* el)
                        f->n_elines--;
 
                        p = realloc(f->elines, sizeof(ScfEline*) * f->n_elines);
-                       if (p)
-                               f->elines = p;
+                       if (!p && f->n_elines > 0)
+                               return -ENOMEM;
+
+                       f->elines = p;
                        return 0;
                }
        }
@@ -928,8 +1090,10 @@ int scf_eboard__del_function(ScfEboard* b, ScfEfunction* f)
                        b->n_functions--;
 
                        p = realloc(b->functions, sizeof(ScfEfunction*) * b->n_functions);
-                       if (p)
-                               b->functions = p;
+                       if (!p && b->n_functions > 0)
+                               return -ENOMEM;
+
+                       b->functions = p;
                        return 0;
                }
        }
@@ -980,7 +1144,7 @@ int scf_pins_same_line(ScfEfunction* f)
 
                        qsort(p->tos, p->n_tos / 2, sizeof(uint64_t) * 2, epin_cmp);
 
-                       for (k = 0; k < p->n_tos; k += 2) {
+                       for (k = 0; k + 1 < 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]);
                        }
@@ -1151,3 +1315,139 @@ next:
 
        return 0;
 }
+
+void scf_efunction_find_pin(ScfEfunction* f, ScfEcomponent** pc, ScfEpin** pp, int x, int y)
+{
+       ScfEcomponent*  c;
+       ScfEpin*        p;
+
+       long i;
+       long j;
+
+       for (i = 0; i < f->n_components; i++) {
+               c  =        f->components[i];
+
+               scf_logd("c%ld, c->x: %d, c->y: %d, c->w: %d, c->h: %d, x: %d, y: %d\n", c->id, c->x, c->y, c->w, c->y, x, y);
+               if (x > c->x - c->w / 2
+                               && x < c->x + c->w / 2
+                               && y > c->y - c->h / 2
+                               && y < c->y + c->h / 2) {
+                       *pc = c;
+                       *pp = NULL;
+
+                       scf_logd("c%ld, %d,%d, x: %d, y: %d\n", c->id, c->x, c->y, x, y);
+                       return;
+               }
+
+               for (j = 0; j < c->n_pins; j++) {
+                       p  =        c->pins[j];
+
+                       if (x > p->x - 5
+                                       && x < p->x + 5
+                                       && y > p->y - 5
+                                       && y < p->y + 5) {
+                               *pc = c;
+                               *pp = p;
+
+                               scf_logi("c%ldp%ld, %d,%d, x: %d, y: %d\n", c->id, p->id, p->x, p->y, x, y);
+                               return;
+                       }
+               }
+       }
+}
+
+int scf_epin_in_line(int px, int py, int x0, int y0, int x1, int y1)
+{
+       if (x0 == x1) {
+               if (x0 - 5 < px && px < x0 + 5) {
+
+                       if (y0 > y1)
+                               SCF_XCHG(y0, y1);
+
+                       if (y0 - 5 < py && py < y1 + 5)
+                               return 1;
+               }
+       } else if (y0 == y1) {
+               if (y0 - 5 < py && py < y0 + 5) {
+
+                       if (x0 > x1)
+                               SCF_XCHG(x0, x1);
+
+                       if (x0 - 5 < px && px < x1 + 5)
+                               return 1;
+               }
+       } else {
+               if (x0 > x1) {
+                       SCF_XCHG(x0, x1);
+                       SCF_XCHG(y0, y1);
+               }
+
+               double Y0 = y0;
+               double Y1 = y1;
+
+               if (y0 > y1) {
+                       Y0 = y1;
+                       Y1 = y0;
+               }
+
+               double k = (y1 - y0) / (double)(x1 - x0);
+               double x = (py - y0  + px / k + x0 * k) / (k + 1.0 / k);
+               double y = (x  - x0) * k  + y0;
+
+               double dx = px - x;
+               double dy = py - y;
+               double d  = sqrt(dx * dx + dy * dy);
+
+               if (x > x0 - 5
+                               && x < x1 + 5
+                               && y > Y0 - 5
+                               && y < Y1 + 5
+                               && d < 5) {
+                       scf_logi("--- k: %lg, px: %d, py: %d, x: %lg, y: %lg, d: %lg, (%d,%d)-->(%d,%d)\n", k, px, py, x, y, d, x0, y0, x1, y1);
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+void scf_efunction_find_eline(ScfEfunction* f, ScfEline** pel, ScfLine** pl, int x, int y)
+{
+       ScfEline*  el;
+       ScfLine*   l;
+
+       long i;
+       long j;
+
+       for (i = 0; i < f->n_elines; i++) {
+               el =        f->elines[i];
+
+               for (j = el->n_lines - 1; j >= 0; j--) {
+                       l  = el->lines[j];
+
+                       if (scf_epin_in_line(x, y, l->x0, l->y0, l->x1, l->y1)) {
+
+                               scf_logi("j: %ld, (%d, %d)-->(%d, %d), x: %d, y: %d\n", j, l->x0, l->y0, l->x1, l->y1, x, y);
+
+                               *pel = el;
+                               *pl  = l;
+                               return;
+                       }
+               }
+       }
+}
+
+long scf_find_eline_index(ScfEfunction* f, int64_t lid)
+{
+       ScfEline* el;
+       long      j;
+
+       for (j = 0; j < f->n_elines; j++) {
+               el        = f->elines[j];
+
+               if (el->id == lid)
+                       return j;
+       }
+
+       return -1;
+}
index 6c76b8eb5c71db026201c2f388c91873840bd3ee..71ab58386c8105c29c64c5efaf8de07b2e83e0c3 100644 (file)
@@ -30,6 +30,16 @@ enum {
        SCF_EDA_IF,
        SCF_EDA_MLA,
 
+       SCF_EDA_ADC,
+
+       SCF_EDA_DFF, // D flip flop
+
+       SCF_EDA_Signal,
+
+       SCF_EDA_OP_AMP,
+
+       SCF_EDA_Crystal,
+
        SCF_EDA_Components_NB,
 };
 
@@ -41,9 +51,12 @@ enum {
 #define SCF_EDA_PIN_CF     16
 #define SCF_EDA_PIN_BORDER 32
 #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_PIN_IN0    128
+#define SCF_EDA_PIN_DIV0   256
+#define SCF_EDA_PIN_KEY    512
+#define SCF_EDA_PIN_DELAY  1024
+#define SCF_EDA_PIN_CK     2048
+#define SCF_EDA_PIN_GND    4096
 
 #define SCF_EDA_V_INIT   -10001001.0
 #define SCF_EDA_V_MIN    -10000000.0
@@ -64,6 +77,14 @@ enum {
        SCF_EDA_Battery_NB,
 };
 
+#define SCF_EDA_Signal_SIN  0
+#define SCF_EDA_Signal_DC   1
+enum {
+       SCF_EDA_Signal_NEG,
+       SCF_EDA_Signal_POS,
+       SCF_EDA_Signal_NB,
+};
+
 enum {
        SCF_EDA_Diode_NEG,
        SCF_EDA_Diode_POS,
@@ -91,6 +112,7 @@ enum {
        SCF_EDA_PNP_NB = SCF_EDA_NPN_NB,
 };
 
+#define SCF_EDA_TTL_DELAY 1
 enum {
        SCF_EDA_NOT_NEG,
        SCF_EDA_NOT_POS,
@@ -156,6 +178,28 @@ enum {
        SCF_EDA_XOR_NB,
 };
 
+enum {
+       SCF_EDA_OP_AMP_NEG = SCF_EDA_NAND_NEG,
+       SCF_EDA_OP_AMP_POS = SCF_EDA_NAND_POS,
+
+       SCF_EDA_OP_AMP_IN     = SCF_EDA_NAND_IN0,
+       SCF_EDA_OP_AMP_INVERT = SCF_EDA_NAND_IN1,
+       SCF_EDA_OP_AMP_OUT    = SCF_EDA_NAND_OUT,
+
+       SCF_EDA_OP_AMP_NB,
+};
+
+enum {
+       SCF_EDA_DFF_NEG = SCF_EDA_NAND_NEG,
+       SCF_EDA_DFF_POS = SCF_EDA_NAND_POS,
+
+       SCF_EDA_DFF_IN  = SCF_EDA_NAND_IN0,
+       SCF_EDA_DFF_CK  = SCF_EDA_NAND_IN1,
+       SCF_EDA_DFF_OUT = SCF_EDA_NAND_OUT,
+
+       SCF_EDA_DFF_NB,
+};
+
 enum {
        SCF_EDA_ADD_NEG = SCF_EDA_NAND_NEG,
        SCF_EDA_ADD_POS = SCF_EDA_NAND_POS,
@@ -168,6 +212,19 @@ enum {
        SCF_EDA_ADD_NB,
 };
 
+enum {
+       SCF_EDA_ADC_NEG,
+       SCF_EDA_ADC_POS,
+
+       SCF_EDA_ADC_CI,
+       SCF_EDA_ADC_IN0,
+       SCF_EDA_ADC_IN1,
+       SCF_EDA_ADC_OUT,
+       SCF_EDA_ADC_CF,
+
+       SCF_EDA_ADC_NB,
+};
+
 enum {
        SCF_EDA_NAND4_NEG,
        SCF_EDA_NAND4_POS,
@@ -233,6 +290,7 @@ typedef struct {
        double    uf;
        double    uh;
        double    hfe;
+       double    Hz;
 
        void*     ops;
        char*     cpk;
@@ -240,33 +298,20 @@ typedef struct {
 } ScfEdata;
 
 typedef struct {
-       SCF_PACK_DEF_VAR(int, x0);
-       SCF_PACK_DEF_VAR(int, y0);
-       SCF_PACK_DEF_VAR(int, x1);
-       SCF_PACK_DEF_VAR(int, y1);
-} ScfLine;
-
-SCF_PACK_TYPE(ScfLine)
-SCF_PACK_INFO_VAR(ScfLine, x0),
-SCF_PACK_INFO_VAR(ScfLine, y0),
-SCF_PACK_INFO_VAR(ScfLine, x1),
-SCF_PACK_INFO_VAR(ScfLine, y1),
-SCF_PACK_END(ScfLine)
-
-typedef struct {
-       SCF_PACK_DEF_VAR(double, v);
-       SCF_PACK_DEF_VAR(double, a);
-       SCF_PACK_DEF_VAR(double, hfe);
+       SCF_PACK_DEF_VAR(double, Vb);
+       SCF_PACK_DEF_VAR(double, Ib);
+       SCF_PACK_DEF_VAR(double, Vc);
 } ScfEcurve;
 
 SCF_PACK_TYPE(ScfEcurve)
-SCF_PACK_INFO_VAR(ScfEcurve, v),
-SCF_PACK_INFO_VAR(ScfEcurve, a),
-SCF_PACK_INFO_VAR(ScfEcurve, hfe),
+SCF_PACK_INFO_VAR(ScfEcurve, Vb),
+SCF_PACK_INFO_VAR(ScfEcurve, Ib),
+SCF_PACK_INFO_VAR(ScfEcurve, Vc),
 SCF_PACK_END(ScfEcurve)
 
 typedef struct scf_eops_s        ScfEops;
 typedef struct scf_epin_s        ScfEpin;
+typedef struct scf_eline_s       ScfEline;
 typedef struct scf_ecomponent_s  ScfEcomponent;
 typedef struct scf_efunction_s   ScfEfunction;
 typedef struct scf_eboard_s      ScfEboard;
@@ -278,11 +323,26 @@ struct scf_eops_s
        int (*shared)(ScfEpin* p,  int flags);
 };
 
+typedef struct {
+       SCF_PACK_DEF_VAR(int, x0);
+       SCF_PACK_DEF_VAR(int, y0);
+       SCF_PACK_DEF_VAR(int, x1);
+       SCF_PACK_DEF_VAR(int, y1);
+       SCF_PACK_DEF_OBJ(ScfEline, el);
+} ScfLine;
+
+SCF_PACK_TYPE(ScfLine)
+SCF_PACK_INFO_VAR(ScfLine, x0),
+SCF_PACK_INFO_VAR(ScfLine, y0),
+SCF_PACK_INFO_VAR(ScfLine, x1),
+SCF_PACK_INFO_VAR(ScfLine, y1),
+SCF_PACK_END(ScfLine)
+
 struct scf_epin_s
 {
        SCF_PACK_DEF_VAR(uint64_t, id);
        SCF_PACK_DEF_VAR(uint64_t, cid);
-       SCF_PACK_DEF_VAR(uint64_t, lid);
+       SCF_PACK_DEF_VAR(int64_t,  lid);
        SCF_PACK_DEF_VAR(uint64_t, flags);
        SCF_PACK_DEF_VARS(uint64_t, tos);
        SCF_PACK_DEF_VAR(uint64_t, c_lid);
@@ -362,7 +422,8 @@ SCF_PACK_INFO_VAR(ScfEconn, lid),
 SCF_PACK_INFO_VARS(ScfEconn, cids, uint64_t),
 SCF_PACK_END(ScfEconn)
 
-typedef struct {
+struct scf_eline_s
+{
        SCF_PACK_DEF_VAR(uint64_t, id);
        SCF_PACK_DEF_VARS(uint64_t, pins);
        SCF_PACK_DEF_VAR(uint64_t, c_pins);
@@ -382,7 +443,7 @@ typedef struct {
        SCF_PACK_DEF_VAR(uint8_t, aconst);
        SCF_PACK_DEF_VAR(uint8_t, vflag);
        SCF_PACK_DEF_VAR(uint8_t, open_flag);
-} ScfEline;
+};
 
 SCF_PACK_TYPE(ScfEline)
 SCF_PACK_INFO_VAR(ScfEline, id),
@@ -425,6 +486,9 @@ struct scf_ecomponent_s
        SCF_PACK_DEF_VAR(double, uf);
        SCF_PACK_DEF_VAR(double, uh);
 
+       SCF_PACK_DEF_VAR(double, Hz);
+
+       SCF_PACK_DEF_VAR(int64_t, mirror_id);
 
        SCF_PACK_DEF_VAR(int64_t, count);
        SCF_PACK_DEF_VAR(int64_t, color);
@@ -442,6 +506,7 @@ SCF_PACK_INFO_VAR(ScfEcomponent, id),
 SCF_PACK_INFO_VAR(ScfEcomponent, type),
 SCF_PACK_INFO_VAR(ScfEcomponent, model),
 SCF_PACK_INFO_OBJS(ScfEcomponent, pins,   ScfEpin),
+
 SCF_PACK_INFO_OBJS(ScfEcomponent, curves, ScfEcurve),
 
 SCF_PACK_INFO_VAR(ScfEcomponent, v),
@@ -452,6 +517,9 @@ SCF_PACK_INFO_VAR(ScfEcomponent, dr),
 SCF_PACK_INFO_VAR(ScfEcomponent, r),
 SCF_PACK_INFO_VAR(ScfEcomponent, uf),
 SCF_PACK_INFO_VAR(ScfEcomponent, uh),
+SCF_PACK_INFO_VAR(ScfEcomponent, Hz),
+
+SCF_PACK_INFO_VAR(ScfEcomponent, mirror_id),
 
 SCF_PACK_INFO_VAR(ScfEcomponent, count),
 SCF_PACK_INFO_VAR(ScfEcomponent, color),
@@ -532,7 +600,15 @@ ScfEboard*     scf_eboard__alloc();
 int            scf_eboard__add_function(ScfEboard* b, ScfEfunction* f);
 int            scf_eboard__del_function(ScfEboard* b, ScfEfunction* f);
 
-int            scf_pins_same_line(ScfEfunction* f);
+int            scf_pins_same_line  (ScfEfunction* f);
+
+long           scf_find_eline_index(ScfEfunction* f, int64_t lid);
+
+void           scf_efunction_find_pin  (ScfEfunction* f, ScfEcomponent** pc,  ScfEpin** pp, int x, int y);
+void           scf_efunction_find_eline(ScfEfunction* f, ScfEline**      pel, ScfLine** pl, int x, int y);
+
+int            scf_epin_in_line(int px, int py, int x0, int y0, int x1, int y1);
+
 
 #define EDA_INST_ADD_COMPONENT(_ef, _c, _type) \
        do { \
@@ -574,4 +650,38 @@ int            scf_pins_same_line(ScfEfunction* f);
 #define EDA_PIN_ADD_PIN_EF(_ef, _p0, _p1) \
        EDA_PIN_ADD_PIN((_ef)->components[(_p0)->cid], (_p0)->id, (_ef)->components[(_p1)->cid], (_p1)->id)
 
+#define EDA_SET_MIRROR(_c0, _c1) \
+       do { \
+               (_c0)->mirror_id = (_c1)->id; \
+               (_c1)->mirror_id = (_c0)->id; \
+       } while (0)
+
+static char* component_types[SCF_EDA_Components_NB] =
+{
+       "None",
+       "Battery",
+
+       "Resistor",
+       "Capacitor",
+       "Inductor",
+
+       "Diode",
+       "NPN",
+       "PNP",
+
+       "NAND",
+       "NOR",
+       "NOT",
+
+       "AND",
+       "OR",
+       "XOR",
+
+       "ADD",
+
+       "NAND4",
+       "AND2_OR",
+       "IF",
+       "MLA",
+};
 #endif
index 8b4576e8b6bc7e42da1e532e6709398c0b2a13f0..7cb3b8f6a40004d4694183df68c493c1d90ff68f 100644 (file)
@@ -180,8 +180,7 @@ CFLAGS += -I../native/x64
 CFLAGS += -I../native/risc
 CFLAGS += -I../native/eda
 
-LDFLAGS += -ldl
-#LDFLAGS += -lprotobuf-c
+LDFLAGS += -ldl -lm
 
 all:
        gcc $(CFLAGS) $(CFILES) $(LDFLAGS) -o scf
index 823669c2060ef0bdaa7a524cc5d0aa3871705943..66e2993b7ec8726525aecd5295788fa94d5f6fa4 100644 (file)
@@ -2099,185 +2099,144 @@ int scf_eda_write_cpk(scf_parse_t* parse, const char* out, scf_vector_t* functio
        return 0;
 }
 
-int scf_parse_native_functions(scf_parse_t* parse, scf_vector_t* functions, scf_native_t* native)
+int scf_parse_native_functions(scf_parse_t* parse, scf_vector_t* functions, const char* arch)
 {
-       scf_function_t* f;
+       scf_function_t*  f;
+       scf_native_t*    native;
 
-       int i;
+       int ret = scf_native_open(&native, arch);
+       if (ret < 0) {
+               scf_loge("open native '%s' failed\n", arch);
+               return ret;
+       }
 
+       int i;
        for (i = 0; i < functions->size; i++) {
                f  =        functions->data[i];
 
                if (!f->node.define_flag)
                        continue;
 
-               int ret = scf_native_select_inst(native, f);
+               ret = scf_native_select_inst(native, f);
                if (ret < 0) {
                        scf_loge("\n");
-                       return ret;
+                       goto error;
                }
        }
 
-       return 0;
+       ret = 0;
+error:
+       scf_native_close(native);
+       return ret;
 }
 
-int scf_parse_compile(scf_parse_t* parse, const char* out, const char* arch, int _3ac)
+int scf_parse_write_elf(scf_parse_t* parse, scf_vector_t* functions, scf_vector_t* global_vars, scf_string_t* code, const char* arch, const char* out)
 {
-       scf_block_t* b = parse->ast->root_block;
-       if (!b)
-               return -EINVAL;
-
-       int ret = 0;
+       scf_elf_context_t*  elf = NULL;
+       scf_elf_section_t   cs  = {0};
 
-       scf_vector_t*      functions   = NULL;
-       scf_vector_t*      global_vars = NULL;
-       scf_native_t*      native      = NULL;
-       scf_string_t*      code        = NULL;
-
-       scf_elf_context_t* elf         = NULL;
-       scf_elf_section_t  cs          = {0};
-
-       functions = scf_vector_alloc();
-       if (!functions)
-               return -ENOMEM;
-
-       ret = scf_node_search_bfs((scf_node_t*)b, NULL, functions, -1, _find_function);
+       int ret = scf_elf_open(&elf, arch, out, "wb");
        if (ret < 0) {
-               scf_loge("\n");
-               goto open_native_error;
-       }
-
-       scf_logi("all functions: %d\n",   functions->size);
-
-       ret = scf_native_open(&native, arch);
-       if (ret < 0) {
-               scf_loge("open native failed\n");
-               goto open_native_error;
-       }
-
-       ret = scf_parse_compile_functions(parse, functions);
-       if (ret < 0) {
-               scf_loge("\n");
-               goto open_native_error;
+               scf_loge("open '%s' elf file '%s' failed\n", arch, out);
+               return ret;
        }
 
-       if (_3ac)
-               return 0;
+       cs.name         = ".text";
+       cs.sh_type      = SHT_PROGBITS;
+       cs.sh_flags     = SHF_ALLOC | SHF_EXECINSTR;
+       cs.sh_addralign = 1;
+       cs.data         = code->data;
+       cs.data_len     = code->len;
+       cs.index        = SCF_SHNDX_TEXT;
 
-       ret = scf_parse_native_functions(parse, functions, native);
-       if (ret < 0) {
-               scf_loge("\n");
-               goto open_native_error;
-       }
+       ret = scf_elf_add_section(elf, &cs);
+       if (ret < 0)
+               goto error;
 
-       if (!strcmp(arch, "eda"))
-               return scf_eda_write_cpk(parse, out, functions, NULL);
+       ret = _scf_parse_add_ds(parse, elf, global_vars);
+       if (ret < 0)
+               goto error;
 
-       global_vars = scf_vector_alloc();
-       if (!global_vars) {
-               ret = -ENOMEM;
-               goto global_vars_error;
-       }
+       ret = scf_dwarf_debug_encode(parse->debug);
+       if (ret < 0)
+               goto error;
 
-       ret = scf_node_search_bfs((scf_node_t*)b, NULL, global_vars, -1, _find_global_var);
-       if (ret < 0) {
-               scf_loge("\n");
-               goto code_error;
-       }
+       ret = _add_debug_sections(parse, elf);
+       if (ret < 0)
+               goto error;
 
-       scf_logd("all global_vars: %d\n", global_vars->size);
+       qsort(parse->symtab->data, parse->symtab->size, sizeof(void*), _sym_cmp);
 
-       parse->debug->arch = (char*)arch;
+       ret = _scf_parse_add_data_relas(parse, elf);
+       if (ret < 0)
+               goto error;
 
-       code = scf_string_alloc();
-       if (!code) {
-               ret = -ENOMEM;
-               goto code_error;
-       }
+       ret = _scf_parse_add_text_relas(parse, elf, functions);
+       if (ret < 0)
+               goto error;
 
-       ret = scf_elf_open(&elf, arch, out, "wb");
-       if (ret < 0) {
-               scf_loge("open elf file failed\n");
-               goto open_elf_error;
+       if (parse->debug->line_relas->size > 0) {
+               ret = _add_debug_relas(parse->debug->line_relas, parse, elf, SCF_SHNDX_DEBUG_LINE, ".rela.debug_line");
+               if (ret < 0)
+                       goto error;
        }
 
-       ret = _add_debug_file_names(parse);
-       if (ret < 0) {
-               scf_loge("\n");
-               goto error;
+       if (parse->debug->info_relas->size > 0) {
+               ret = _add_debug_relas(parse->debug->info_relas, parse, elf, SCF_SHNDX_DEBUG_INFO, ".rela.debug_info");
+               if (ret < 0)
+                       goto error;
        }
-       assert(parse->debug->file_names->size > 0);
-       scf_string_t* file_name = parse->debug->file_names->data[0];
-       const char*   path      = file_name->data;
 
-       ADD_SECTION_SYMBOL(SCF_SHNDX_TEXT,   ".text");
-       ADD_SECTION_SYMBOL(SCF_SHNDX_RODATA, ".rodata");
-       ADD_SECTION_SYMBOL(SCF_SHNDX_DATA,   ".data");
-
-       scf_dwarf_info_entry_t*  cu = NULL;
-       scf_dwarf_line_result_t* r  = NULL;
-       scf_dwarf_line_result_t* r2 = NULL;
+       scf_elf_sym_t* sym;
+       int i;
 
-       r = calloc(1, sizeof(scf_dwarf_line_result_t));
-       if (!r)
-               return -ENOMEM;
+       for (i = 0; i < parse->symtab->size; i++) {
+               sym       = parse->symtab->data[i];
 
-       r->file_name = scf_string_cstr(path);
-       if (!r->file_name) {
-               free(r);
-               return -ENOMEM;
+               ret = scf_elf_add_sym(elf, sym, ".symtab");
+               if (ret < 0)
+                       goto error;
        }
-       r->address = 0;
-       r->line    = 1;
-       r->is_stmt = 1;
 
-       if (scf_vector_add(parse->debug->lines, r) < 0) {
-               scf_string_free(r->file_name);
-               free(r);
-               return -ENOMEM;
-       }
+       ret = scf_elf_write_rel(elf);
+error:
+       scf_elf_close(elf);
+       return ret;
+}
+
+int64_t scf_parse_fill_code2(scf_parse_t* parse, scf_vector_t* functions, scf_vector_t* global_vars, scf_string_t* code, scf_dwarf_info_entry_t** cu)
+{
+       scf_function_t*  f;
+       scf_rela_t*      r;
 
        int64_t offset = 0;
+
        int i;
-       for (i = 0; i < functions->size; i++) {
+       int j;
 
-               scf_function_t* f = functions->data[i];
+       for (i = 0; i < functions->size; i++) {
+               f  =        functions->data[i];
 
                if (!f->node.define_flag)
                        continue;
 
-               scf_logd("f: %s, code_bytes: %d\n", f->node.w->text->data, f->code_bytes);
-
-               if (!cu) {
-                       ret = _debug_add_cu(&cu, parse, f, offset);
+               if (!*cu) {
+                       int ret = _debug_add_cu(cu, parse, f, offset);
                        if (ret < 0)
                                return ret;
                }
 
-               if (scf_function_signature(f) < 0) {
-                       ret = -ENOMEM;
-                       goto error;
-               }
-
-               ret = _fill_function_inst(code, f, offset, parse);
-               if (ret < 0) {
-                       scf_loge("\n");
-                       goto error;
-               }
+               if (scf_function_signature(f) < 0)
+                       return -ENOMEM;
 
-               scf_logd("f: %s, code_bytes: %d\n", f->node.w->text->data, f->code_bytes);
+               int ret = _fill_function_inst(code, f, offset, parse);
+               if (ret < 0)
+                       return ret;
 
                ret = _scf_parse_add_sym(parse, f->signature->data, f->code_bytes, offset, SCF_SHNDX_TEXT, ELF64_ST_INFO(STB_GLOBAL, STT_FUNC));
-               if (ret < 0) {
-                       ret = -ENOMEM;
-                       goto error;
-               }
-
-               scf_logd("f->text_relas->size: %d\n", f->text_relas->size);
-               scf_logd("f->data_relas->size: %d\n", f->data_relas->size);
+               if (ret < 0)
+                       return ret;
 
-               scf_rela_t* r;
-               int j;
                for (j = 0; j < f->text_relas->size; j++) {
                        r  =        f->text_relas->data[j];
 
@@ -2296,11 +2255,8 @@ int scf_parse_compile(scf_parse_t* parse, const char* out, const char* arch, int
                                ret = scf_vector_add_unique(parse->global_consts, r->var);
                        else
                                ret = scf_vector_add_unique(global_vars, r->var);
-
-                       if (ret < 0) {
-                               scf_loge("\n");
-                               goto error;
-                       }
+                       if (ret < 0)
+                               return ret;
 
                        r->text_offset = offset + r->inst_offset;
 
@@ -2311,6 +2267,52 @@ int scf_parse_compile(scf_parse_t* parse, const char* out, const char* arch, int
                offset += f->code_bytes;
        }
 
+       return offset;
+}
+
+int scf_parse_fill_code(scf_parse_t* parse, scf_vector_t* functions, scf_vector_t* global_vars, scf_string_t* code)
+{
+       int ret = _add_debug_file_names(parse);
+       if (ret < 0)
+               return ret;
+
+       assert(parse->debug->file_names->size > 0);
+
+       scf_string_t* file_name = parse->debug->file_names->data[0];
+       const char*   path      = file_name->data;
+
+       ADD_SECTION_SYMBOL(SCF_SHNDX_TEXT,   ".text");
+       ADD_SECTION_SYMBOL(SCF_SHNDX_RODATA, ".rodata");
+       ADD_SECTION_SYMBOL(SCF_SHNDX_DATA,   ".data");
+
+       scf_dwarf_info_entry_t*  cu = NULL;
+       scf_dwarf_line_result_t* r  = NULL;
+       scf_dwarf_line_result_t* r2 = NULL;
+
+       r = calloc(1, sizeof(scf_dwarf_line_result_t));
+       if (!r)
+               return -ENOMEM;
+
+       r->file_name = scf_string_cstr(path);
+       if (!r->file_name) {
+               free(r);
+               return -ENOMEM;
+       }
+       r->address = 0;
+       r->line    = 1;
+       r->is_stmt = 1;
+
+       if (scf_vector_add(parse->debug->lines, r) < 0) {
+               scf_string_free(r->file_name);
+               free(r);
+               return -ENOMEM;
+       }
+       r = NULL;
+
+       int64_t offset = scf_parse_fill_code2(parse, functions, global_vars, code, &cu);
+       if (offset < 0)
+               return offset;
+
        if (cu)
                DEBUG_UPDATE_HIGH_PC(cu, offset);
 
@@ -2337,8 +2339,8 @@ int scf_parse_compile(scf_parse_t* parse, const char* out, const char* arch, int
                free(r);
                return -ENOMEM;
        }
+       r = NULL;
 
-#if 1
        scf_dwarf_abbrev_declaration_t* abbrev0 = NULL;
 
        abbrev0 = scf_dwarf_abbrev_declaration_alloc();
@@ -2350,99 +2352,99 @@ int scf_parse_compile(scf_parse_t* parse, const char* out, const char* arch, int
                scf_dwarf_abbrev_declaration_free(abbrev0);
                return -ENOMEM;
        }
-#endif
 
-       cs.name         = ".text";
-       cs.sh_type      = SHT_PROGBITS;
-       cs.sh_flags     = SHF_ALLOC | SHF_EXECINSTR;
-       cs.sh_addralign = 1;
-       cs.data         = code->data;
-       cs.data_len     = code->len;
-       cs.index        = SCF_SHNDX_TEXT;
+       return 0;
+}
 
-       ret = scf_elf_add_section(elf, &cs);
-       if (ret < 0) {
-               scf_loge("\n");
-               goto error;
-       }
+int scf_parse_compile(scf_parse_t* parse, const char* out, const char* arch, int _3ac)
+{
+       scf_block_t* b = parse->ast->root_block;
+       if (!b)
+               return -EINVAL;
 
-       ret = _scf_parse_add_ds(parse, elf, global_vars);
+       int ret = 0;
+
+       scf_vector_t*  functions   = NULL;
+       scf_vector_t*  global_vars = NULL;
+       scf_string_t*  code        = NULL;
+
+       functions = scf_vector_alloc();
+       if (!functions)
+               return -ENOMEM;
+
+       ret = scf_node_search_bfs((scf_node_t*)b, NULL, functions, -1, _find_function);
        if (ret < 0) {
-               scf_loge("\n");
-               goto error;
+               scf_vector_free(functions);
+               return ret;
        }
 
-       ret = scf_dwarf_debug_encode(parse->debug);
+       scf_logi("all functions: %d\n", functions->size);
+
+       ret = scf_parse_compile_functions(parse, functions);
        if (ret < 0) {
-               scf_loge("\n");
-               goto error;
+               scf_vector_free(functions);
+               return ret;
        }
 
-       ret = _add_debug_sections(parse, elf);
+       if (_3ac)
+               return 0;
+
+       ret = scf_parse_native_functions(parse, functions, arch);
        if (ret < 0) {
-               scf_loge("\n");
-               goto error;
+               scf_vector_free(functions);
+               return ret;
        }
 
-       qsort(parse->symtab->data, parse->symtab->size, sizeof(void*), _sym_cmp);
+       if (!strcmp(arch, "eda")) {
+               ret = scf_eda_write_cpk(parse, out, functions, NULL);
 
-       ret = _scf_parse_add_data_relas(parse, elf);
-       if (ret < 0) {
-               scf_loge("\n");
-               goto error;
+               scf_vector_free(functions);
+               return ret;
        }
 
-       ret = _scf_parse_add_text_relas(parse, elf, functions);
+       global_vars = scf_vector_alloc();
+       if (!global_vars) {
+               ret = -ENOMEM;
+               goto global_vars_error;
+       }
+
+       ret = scf_node_search_bfs((scf_node_t*)b, NULL, global_vars, -1, _find_global_var);
        if (ret < 0) {
                scf_loge("\n");
-               goto error;
+               goto code_error;
        }
 
-       if (parse->debug->line_relas->size > 0) {
-               ret = _add_debug_relas(parse->debug->line_relas, parse, elf, SCF_SHNDX_DEBUG_LINE, ".rela.debug_line");
-               if (ret < 0) {
-                       scf_loge("\n");
-                       return ret;
-               }
-       }
+       scf_logd("all global_vars: %d\n", global_vars->size);
 
-       if (parse->debug->info_relas->size > 0) {
-               ret = _add_debug_relas(parse->debug->info_relas, parse, elf, SCF_SHNDX_DEBUG_INFO, ".rela.debug_info");
-               if (ret < 0) {
-                       scf_loge("\n");
-                       return ret;
-               }
-       }
+       parse->debug->arch = (char*)arch;
 
-       for (i = 0; i < parse->symtab->size; i++) {
-               scf_elf_sym_t* sym = parse->symtab->data[i];
+       code = scf_string_alloc();
+       if (!code) {
+               ret = -ENOMEM;
+               goto code_error;
+       }
 
-               ret = scf_elf_add_sym(elf, sym, ".symtab");
-               if (ret < 0) {
-                       scf_loge("\n");
-                       goto error;
-               }
+       ret = scf_parse_fill_code(parse, functions, global_vars, code);
+       if (ret < 0) {
+               scf_loge("\n");
+               goto error;
        }
 
-       ret = scf_elf_write_rel(elf);
+       ret = scf_parse_write_elf(parse, functions, global_vars, code, arch, out);
        if (ret < 0) {
                scf_loge("\n");
                goto error;
        }
+
        ret = 0;
 
        scf_logi("ok\n\n");
 
 error:
-       scf_elf_close(elf);
-open_elf_error:
        scf_string_free(code);
 code_error:
        scf_vector_free(global_vars);
 global_vars_error:
-       scf_native_close(native);
-open_native_error:
        scf_vector_free(functions);
        return ret;
 }
-