add eda backend in scf native, to make a C code to digit electronic graph
authoryu.dongliang <18588496441@163.com>
Thu, 6 Jul 2023 13:06:34 +0000 (21:06 +0800)
committeryu.dongliang <18588496441@163.com>
Thu, 6 Jul 2023 13:06:34 +0000 (21:06 +0800)
18 files changed:
core/scf_ast.h
core/scf_core_types.h
core/scf_dag.h
core/scf_function.h
native/eda/Makefile [new file with mode: 0644]
native/eda/main.c [new file with mode: 0644]
native/eda/scf_eda.c [new file with mode: 0644]
native/eda/scf_eda.h [new file with mode: 0644]
native/eda/scf_eda.pb-c.c [new file with mode: 0644]
native/eda/scf_eda.pb-c.h [new file with mode: 0644]
native/eda/scf_eda.proto [new file with mode: 0644]
native/eda/scf_eda_inst.c [new file with mode: 0644]
native/eda/scf_eda_pb.c [new file with mode: 0644]
native/eda/scf_eda_pb.h [new file with mode: 0644]
native/scf_native.c
parse/Makefile
parse/main.c
parse/scf_parse.c

index 13ee8d8331c966cefd90e8eb5738675ad0c7fd9b..404c778b6b5a2ecb8edeecabe091639e1a54e71d 100644 (file)
@@ -46,6 +46,8 @@ struct scf_ast_s
 
        scf_vector_t*       global_consts;
        scf_vector_t*       global_relas;
+
+       ScfEboard*          board;
 };
 
 int scf_expr_calculate(scf_ast_t* ast, scf_expr_t* expr, scf_variable_t** pret);
index f698305e058cad155b0c0b2ed4b9c5a395cbd78e..6bcc398e533624991cdd5a382e2b68fe28dd4429 100644 (file)
@@ -23,6 +23,11 @@ typedef struct scf_regs_ops_s   scf_regs_ops_t;
 typedef struct scf_register_s   scf_register_t;
 typedef struct scf_OpCode_s     scf_OpCode_t;
 
+typedef struct _ScfEpin         ScfEpin;
+typedef struct _ScfEcomponent   ScfEcomponent;
+typedef struct _ScfEfunction    ScfEfunction;
+typedef struct _ScfEboard       ScfEboard;
+
 enum scf_core_types {
        SCF_OP_ADD      = 0,    // +
        SCF_OP_SUB,         // -
index a1e7779b03643a314fa9c0dfc4ee1dd6aa1955e7..ef69f22f1172808ba292d364e86d2bc4b9258c0c 100644 (file)
@@ -33,6 +33,9 @@ struct scf_dag_node_s {
        void*               rabi;
        void*               rabi2;
 
+       ScfEpin*            pins[256];
+       int                 n_pins;
+
        intptr_t            color;
 
        uint32_t            done   :1;
index 744d07e3e8a03dec61de04d83407e00a874e1ed5..a015500e3fb58d707edca329bdc049dd0eb301a8 100644 (file)
@@ -46,6 +46,8 @@ struct scf_function_s {
        scf_inst_ops_t*   iops;
        scf_regs_ops_t*   rops;
 
+       ScfEfunction*     ef;
+
        scf_3ac_code_t*   init_code;
        int               init_code_bytes;
 
diff --git a/native/eda/Makefile b/native/eda/Makefile
new file mode 100644 (file)
index 0000000..4875440
--- /dev/null
@@ -0,0 +1,15 @@
+CFILES += main.c
+CFILES += scf_eda.pb-c.c
+CFILES += scf_eda_pb.c
+
+CFLAGS += -g
+CFLAGS += -I./
+CFLAGS += -I../../util
+
+LDFLAGS += -lprotobuf-c
+
+all:
+       gcc $(CFLAGS) $(CFILES) $(LDFLAGS)
+
+clean:
+       rm *.o
diff --git a/native/eda/main.c b/native/eda/main.c
new file mode 100644 (file)
index 0000000..14fc571
--- /dev/null
@@ -0,0 +1,111 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#include"scf_eda_pb.h"
+#include"scf_def.h"
+
+
+int main()
+{
+       ScfEcomponent* r      = scf_ecomponent__alloc(SCF_EDA_None);
+       ScfEcomponent* d0     = scf_ecomponent__alloc(SCF_EDA_None);
+       ScfEcomponent* d1     = scf_ecomponent__alloc(SCF_EDA_None);
+
+       ScfEpin*       rp0    = scf_epin__alloc();
+       ScfEpin*       rp1    = scf_epin__alloc();
+
+       ScfEpin*       d0p0   = scf_epin__alloc();
+       ScfEpin*       d0p1   = scf_epin__alloc();
+
+       ScfEpin*       d1p0   = scf_epin__alloc();
+       ScfEpin*       d1p1   = scf_epin__alloc();
+
+       ScfEpin*       rps[]  = {rp0,  rp1};
+       ScfEpin*       d0ps[] = {d0p0, d0p1};
+       ScfEpin*       d1ps[] = {d1p0, d1p1};
+
+       int64_t c[] = {1, 2};
+       int64_t b[] = {0, 2};
+       int64_t a[] = {0, 1};
+
+       scf_epin__add_component(rp1, 1, SCF_EDA_Diode_NEG);
+       scf_epin__add_component(rp1, 2, SCF_EDA_Diode_NEG);
+
+       scf_epin__add_component(d0p1, 0, 0);
+       scf_epin__add_component(d0p1, 2, SCF_EDA_Diode_NEG);
+
+       scf_epin__add_component(d1p1, 0, 0);
+       scf_epin__add_component(d1p1, 1, SCF_EDA_Diode_NEG);
+
+       r->id      = 0;
+       r->type    = SCF_EDA_Resistor;
+       scf_ecomponent__add_pin(r, rp0);
+       scf_ecomponent__add_pin(r, rp1);
+
+       d0->id     = 1;
+       d0->type   = SCF_EDA_Diode;
+       scf_ecomponent__add_pin(d0, d0p0);
+       scf_ecomponent__add_pin(d0, d0p1);
+
+       d1->id     = 2;
+       d1->type   = SCF_EDA_Diode;
+       scf_ecomponent__add_pin(d1, d1p0);
+       scf_ecomponent__add_pin(d1, d1p1);
+
+       ScfEfunction* f = scf_efunction__alloc("test");
+       scf_efunction__add_component(f, r);
+       scf_efunction__add_component(f, d0);
+       scf_efunction__add_component(f, d1);
+
+       ScfEboard* board = scf_eboard__alloc();
+       scf_eboard__add_function(board, f);
+
+       size_t rlen  = scf_ecomponent__get_packed_size(r);
+       size_t d0len = scf_ecomponent__get_packed_size(d0);
+       size_t d1len = scf_ecomponent__get_packed_size(d1);
+       size_t flen  = scf_efunction__get_packed_size(f);
+       size_t blen  = scf_eboard__get_packed_size(board);
+
+       printf("rlen: %ld, d0len: %ld, d1len: %ld, flen: %ld, blen: %ld\n", rlen, d0len, d1len, flen, blen);
+
+       uint8_t pb[1024];
+
+       scf_eboard__pack(board, pb);
+
+       ScfEboard* p = scf_eboard__unpack(NULL, blen, pb);
+
+       printf("p: %p\n", p);
+       size_t i;
+       size_t j;
+       size_t k;
+       size_t l;
+
+       for (i = 0; i < p->n_functions; i++) {
+               ScfEfunction* pf = p->functions[i];
+
+               printf("f: %s\n", pf->name);
+
+               for (l = 0; l < pf->n_components; l++) {
+                       ScfEcomponent* pc = pf->components[l];
+
+                       printf("i: %ld, pc: %p, id: %ld, cid: %ld, n_pins: %ld\n", i, pc, pc->id, pc->type, pc->n_pins);
+
+                       for (j = 0; j < pc->n_pins; j++) {
+                               ScfEpin* pp = pc->pins[j];
+
+                               printf("j: %ld, pp: %p, n_tos: %ld\n", j, pp, pp->n_tos);
+
+                               for (k = 0; k + 1 < pp->n_tos; k += 2) {
+                                       printf("k: %ld, cid: %ld, pid: %ld\n", k, pp->tos[k], pp->tos[k + 1]);
+                               }
+                       }
+                       printf("\n");
+               }
+               printf("\n\n");
+       }
+
+       scf_eboard__free(board);
+
+       scf_eboard__free_unpacked(p, NULL);
+       return 0;
+}
diff --git a/native/eda/scf_eda.c b/native/eda/scf_eda.c
new file mode 100644 (file)
index 0000000..fec807a
--- /dev/null
@@ -0,0 +1,148 @@
+#include"scf_eda.h"
+#include"scf_basic_block.h"
+#include"scf_3ac.h"
+
+int    scf_eda_open(scf_native_t* ctx, const char* arch)
+{
+       scf_eda_context_t* eda = calloc(1, sizeof(scf_eda_context_t));
+       if (!eda)
+               return -ENOMEM;
+
+       ctx->priv = eda;
+       return 0;
+}
+
+int scf_eda_close(scf_native_t* ctx)
+{
+       scf_eda_context_t* eda = ctx->priv;
+
+       if (eda) {
+               free(eda);
+               eda = NULL;
+       }
+       return 0;
+}
+
+static int _eda_make_insts_for_list(scf_native_t* ctx, scf_list_t* h, int bb_offset)
+{
+       scf_list_t* l;
+       int ret;
+
+       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);
+
+               eda_inst_handler_t* h = scf_eda_find_inst_handler(c->op->type);
+               if (!h) {
+                       scf_loge("3ac operator '%s' not supported\n", c->op->name);
+                       return -EINVAL;
+               }
+
+               ret = h->func(ctx, c);
+               if (ret < 0) {
+                       scf_3ac_code_print(c, NULL);
+                       scf_loge("3ac op '%s' make inst failed\n", c->op->name);
+                       return ret;
+               }
+
+               if (!c->instructions)
+                       continue;
+
+               scf_3ac_code_print(c, NULL);
+       }
+
+       return bb_offset;
+}
+
+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;
+
+       int i;
+       int j;
+       int ret = 0;
+
+       for (i  = 0; i < f->bb_groups->size; i++) {
+               bbg =        f->bb_groups->data[i];
+
+               for (j = 0; j < bbg->body->size; j++) {
+                       bb =        bbg->body->data[j];
+
+                       assert(!bb->native_flag);
+
+                       scf_loge("************ bb: %d\n", bb->index);
+                       ret = _eda_make_insts_for_list(ctx, &bb->code_list_head, 0);
+                       if (ret < 0)
+                               return ret;
+                       bb->native_flag = 1;
+                       scf_loge("************ bb: %d\n", bb->index);
+               }
+       }
+
+       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];
+
+                       assert(!bb->native_flag);
+
+                       ret = _eda_make_insts_for_list(ctx, &bb->code_list_head, 0);
+                       if (ret < 0)
+                               return ret;
+                       bb->native_flag = 1;
+               }
+       }
+
+       return 0;
+}
+
+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;
+
+       eda->f = f;
+
+       assert(!f->ef);
+
+       f->ef = scf_efunction__alloc(f->node.w->text->data);
+       if (!f->ef)
+               return -ENOMEM;
+
+       EDA_INST_ADD_COMPONENT(f, B, SCF_EDA_Battery);
+
+       int ret = _scf_eda_select_inst(ctx);
+       if (ret < 0)
+               return ret;
+
+       for (l = scf_list_head(&f->dag_list_head); l != scf_list_sentinel(&f->dag_list_head); l = scf_list_next(l)) {
+
+               dn = scf_list_data(l, scf_dag_node_t, list);
+
+               if (dn->var && dn->var->arg_flag) {
+
+                       int i;
+                       for (i = 0; i < dn->n_pins; i++)
+                               dn->pins[i]->flags |= SCF_EDA_PIN_IN;
+               }
+       }
+
+       return 0;
+}
+
+scf_native_ops_t       native_ops_eda = {
+       .name            = "eda",
+
+       .open            = scf_eda_open,
+       .close           = scf_eda_close,
+
+       .select_inst     = scf_eda_select_inst,
+};
+
diff --git a/native/eda/scf_eda.h b/native/eda/scf_eda.h
new file mode 100644 (file)
index 0000000..de9561e
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef SCF_EDA_H
+#define SCF_EDA_H
+
+#include"scf_native.h"
+#include"scf_eda_pb.h"
+
+#define EDA_INST_ADD_COMPONENT(_f, _c, _type) \
+       do { \
+               _c = scf_ecomponent__alloc(_type); \
+               if (!_c) \
+                       return -ENOMEM; \
+               \
+               (_c)->id = (_f)->ef->n_components; \
+               \
+               int ret = scf_efunction__add_component((_f)->ef, _c); \
+               if (ret < 0) { \
+                       scf_ecomponent__free(_c); \
+                       _c = NULL; \
+                       return ret; \
+               } \
+       } while (0)
+
+
+#define EDA_PIN_ADD_COMPONENT(_pin, _cid, _pid) \
+       do { \
+               int ret = scf_epin__add_component((_pin), (_cid), (_pid)); \
+               if (ret < 0) \
+                       return ret; \
+               \
+       } while (0)
+
+typedef struct {
+
+       scf_function_t*     f;
+
+} scf_eda_context_t;
+
+typedef struct {
+       int     type;
+       int             (*func)(scf_native_t* ctx, scf_3ac_code_t* c);
+} eda_inst_handler_t;
+
+eda_inst_handler_t* scf_eda_find_inst_handler(const int op_type);
+
+int scf_eda_open  (scf_native_t* ctx, const char* arch);
+int scf_eda_close (scf_native_t* ctx);
+int scf_eda_select(scf_native_t* ctx);
+
+static inline int eda_variable_size(scf_variable_t* v)
+{
+       if (v->nb_dimentions + v->nb_pointers > 0)
+               return 64;
+
+       if (v->type >= SCF_STRUCT)
+               return 64;
+
+       if (SCF_VAR_BIT == v->type)
+               return 1;
+
+       return v->size << 3;
+}
+
+#endif
diff --git a/native/eda/scf_eda.pb-c.c b/native/eda/scf_eda.pb-c.c
new file mode 100644 (file)
index 0000000..190f5b8
--- /dev/null
@@ -0,0 +1,609 @@
+/* Generated by the protocol buffer compiler.  DO NOT EDIT! */
+/* Generated from: scf_eda.proto */
+
+/* Do not generate deprecated warnings for self */
+#ifndef PROTOBUF_C__NO_DEPRECATED
+#define PROTOBUF_C__NO_DEPRECATED
+#endif
+
+#include "scf_eda.pb-c.h"
+void   scf_eline__init
+                     (ScfEline         *message)
+{
+  static ScfEline init_value = SCF_ELINE__INIT;
+  *message = init_value;
+}
+size_t scf_eline__get_packed_size
+                     (const ScfEline *message)
+{
+  assert(message->base.descriptor == &scf_eline__descriptor);
+  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
+}
+size_t scf_eline__pack
+                     (const ScfEline *message,
+                      uint8_t       *out)
+{
+  assert(message->base.descriptor == &scf_eline__descriptor);
+  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
+}
+size_t scf_eline__pack_to_buffer
+                     (const ScfEline *message,
+                      ProtobufCBuffer *buffer)
+{
+  assert(message->base.descriptor == &scf_eline__descriptor);
+  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
+}
+ScfEline *
+       scf_eline__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data)
+{
+  return (ScfEline *)
+     protobuf_c_message_unpack (&scf_eline__descriptor,
+                                allocator, len, data);
+}
+void   scf_eline__free_unpacked
+                     (ScfEline *message,
+                      ProtobufCAllocator *allocator)
+{
+  assert(message->base.descriptor == &scf_eline__descriptor);
+  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
+}
+void   scf_epin__init
+                     (ScfEpin         *message)
+{
+  static ScfEpin init_value = SCF_EPIN__INIT;
+  *message = init_value;
+}
+size_t scf_epin__get_packed_size
+                     (const ScfEpin *message)
+{
+  assert(message->base.descriptor == &scf_epin__descriptor);
+  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
+}
+size_t scf_epin__pack
+                     (const ScfEpin *message,
+                      uint8_t       *out)
+{
+  assert(message->base.descriptor == &scf_epin__descriptor);
+  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
+}
+size_t scf_epin__pack_to_buffer
+                     (const ScfEpin *message,
+                      ProtobufCBuffer *buffer)
+{
+  assert(message->base.descriptor == &scf_epin__descriptor);
+  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
+}
+ScfEpin *
+       scf_epin__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data)
+{
+  return (ScfEpin *)
+     protobuf_c_message_unpack (&scf_epin__descriptor,
+                                allocator, len, data);
+}
+void   scf_epin__free_unpacked
+                     (ScfEpin *message,
+                      ProtobufCAllocator *allocator)
+{
+  assert(message->base.descriptor == &scf_epin__descriptor);
+  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
+}
+void   scf_ecomponent__init
+                     (ScfEcomponent         *message)
+{
+  static ScfEcomponent init_value = SCF_ECOMPONENT__INIT;
+  *message = init_value;
+}
+size_t scf_ecomponent__get_packed_size
+                     (const ScfEcomponent *message)
+{
+  assert(message->base.descriptor == &scf_ecomponent__descriptor);
+  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
+}
+size_t scf_ecomponent__pack
+                     (const ScfEcomponent *message,
+                      uint8_t       *out)
+{
+  assert(message->base.descriptor == &scf_ecomponent__descriptor);
+  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
+}
+size_t scf_ecomponent__pack_to_buffer
+                     (const ScfEcomponent *message,
+                      ProtobufCBuffer *buffer)
+{
+  assert(message->base.descriptor == &scf_ecomponent__descriptor);
+  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
+}
+ScfEcomponent *
+       scf_ecomponent__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data)
+{
+  return (ScfEcomponent *)
+     protobuf_c_message_unpack (&scf_ecomponent__descriptor,
+                                allocator, len, data);
+}
+void   scf_ecomponent__free_unpacked
+                     (ScfEcomponent *message,
+                      ProtobufCAllocator *allocator)
+{
+  assert(message->base.descriptor == &scf_ecomponent__descriptor);
+  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
+}
+void   scf_efunction__init
+                     (ScfEfunction         *message)
+{
+  static ScfEfunction init_value = SCF_EFUNCTION__INIT;
+  *message = init_value;
+}
+size_t scf_efunction__get_packed_size
+                     (const ScfEfunction *message)
+{
+  assert(message->base.descriptor == &scf_efunction__descriptor);
+  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
+}
+size_t scf_efunction__pack
+                     (const ScfEfunction *message,
+                      uint8_t       *out)
+{
+  assert(message->base.descriptor == &scf_efunction__descriptor);
+  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
+}
+size_t scf_efunction__pack_to_buffer
+                     (const ScfEfunction *message,
+                      ProtobufCBuffer *buffer)
+{
+  assert(message->base.descriptor == &scf_efunction__descriptor);
+  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
+}
+ScfEfunction *
+       scf_efunction__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data)
+{
+  return (ScfEfunction *)
+     protobuf_c_message_unpack (&scf_efunction__descriptor,
+                                allocator, len, data);
+}
+void   scf_efunction__free_unpacked
+                     (ScfEfunction *message,
+                      ProtobufCAllocator *allocator)
+{
+  assert(message->base.descriptor == &scf_efunction__descriptor);
+  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
+}
+void   scf_eboard__init
+                     (ScfEboard         *message)
+{
+  static ScfEboard init_value = SCF_EBOARD__INIT;
+  *message = init_value;
+}
+size_t scf_eboard__get_packed_size
+                     (const ScfEboard *message)
+{
+  assert(message->base.descriptor == &scf_eboard__descriptor);
+  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
+}
+size_t scf_eboard__pack
+                     (const ScfEboard *message,
+                      uint8_t       *out)
+{
+  assert(message->base.descriptor == &scf_eboard__descriptor);
+  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
+}
+size_t scf_eboard__pack_to_buffer
+                     (const ScfEboard *message,
+                      ProtobufCBuffer *buffer)
+{
+  assert(message->base.descriptor == &scf_eboard__descriptor);
+  return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
+}
+ScfEboard *
+       scf_eboard__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data)
+{
+  return (ScfEboard *)
+     protobuf_c_message_unpack (&scf_eboard__descriptor,
+                                allocator, len, data);
+}
+void   scf_eboard__free_unpacked
+                     (ScfEboard *message,
+                      ProtobufCAllocator *allocator)
+{
+  assert(message->base.descriptor == &scf_eboard__descriptor);
+  protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
+}
+static const ProtobufCFieldDescriptor scf_eline__field_descriptors[4] =
+{
+  {
+    "x0",
+    1,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_UINT32,
+    0,   /* quantifier_offset */
+    offsetof(ScfEline, x0),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "y0",
+    2,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_UINT32,
+    0,   /* quantifier_offset */
+    offsetof(ScfEline, y0),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "x1",
+    3,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_UINT32,
+    0,   /* quantifier_offset */
+    offsetof(ScfEline, x1),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "y1",
+    4,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_UINT32,
+    0,   /* quantifier_offset */
+    offsetof(ScfEline, y1),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+};
+static const unsigned scf_eline__field_indices_by_name[] = {
+  0,   /* field[0] = x0 */
+  2,   /* field[2] = x1 */
+  1,   /* field[1] = y0 */
+  3,   /* field[3] = y1 */
+};
+static const ProtobufCIntRange scf_eline__number_ranges[1 + 1] =
+{
+  { 1, 0 },
+  { 0, 4 }
+};
+const ProtobufCMessageDescriptor scf_eline__descriptor =
+{
+  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
+  "scf_eline",
+  "ScfEline",
+  "ScfEline",
+  "",
+  sizeof(ScfEline),
+  4,
+  scf_eline__field_descriptors,
+  scf_eline__field_indices_by_name,
+  1,  scf_eline__number_ranges,
+  (ProtobufCMessageInit) scf_eline__init,
+  NULL,NULL,NULL    /* reserved[123] */
+};
+static const ProtobufCFieldDescriptor scf_epin__field_descriptors[6] =
+{
+  {
+    "tos",
+    1,
+    PROTOBUF_C_LABEL_REPEATED,
+    PROTOBUF_C_TYPE_UINT64,
+    offsetof(ScfEpin, n_tos),
+    offsetof(ScfEpin, tos),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "id",
+    2,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_UINT64,
+    0,   /* quantifier_offset */
+    offsetof(ScfEpin, id),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "flags",
+    3,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_UINT64,
+    0,   /* quantifier_offset */
+    offsetof(ScfEpin, flags),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "x",
+    4,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_UINT32,
+    0,   /* quantifier_offset */
+    offsetof(ScfEpin, x),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "y",
+    5,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_UINT32,
+    0,   /* quantifier_offset */
+    offsetof(ScfEpin, y),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "lines",
+    6,
+    PROTOBUF_C_LABEL_REPEATED,
+    PROTOBUF_C_TYPE_MESSAGE,
+    offsetof(ScfEpin, n_lines),
+    offsetof(ScfEpin, lines),
+    &scf_eline__descriptor,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+};
+static const unsigned scf_epin__field_indices_by_name[] = {
+  2,   /* field[2] = flags */
+  1,   /* field[1] = id */
+  5,   /* field[5] = lines */
+  0,   /* field[0] = tos */
+  3,   /* field[3] = x */
+  4,   /* field[4] = y */
+};
+static const ProtobufCIntRange scf_epin__number_ranges[1 + 1] =
+{
+  { 1, 0 },
+  { 0, 6 }
+};
+const ProtobufCMessageDescriptor scf_epin__descriptor =
+{
+  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
+  "scf_epin",
+  "ScfEpin",
+  "ScfEpin",
+  "",
+  sizeof(ScfEpin),
+  6,
+  scf_epin__field_descriptors,
+  scf_epin__field_indices_by_name,
+  1,  scf_epin__number_ranges,
+  (ProtobufCMessageInit) scf_epin__init,
+  NULL,NULL,NULL    /* reserved[123] */
+};
+static const ProtobufCFieldDescriptor scf_ecomponent__field_descriptors[7] =
+{
+  {
+    "id",
+    1,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_UINT64,
+    0,   /* quantifier_offset */
+    offsetof(ScfEcomponent, id),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "type",
+    2,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_UINT64,
+    0,   /* quantifier_offset */
+    offsetof(ScfEcomponent, type),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "pins",
+    3,
+    PROTOBUF_C_LABEL_REPEATED,
+    PROTOBUF_C_TYPE_MESSAGE,
+    offsetof(ScfEcomponent, n_pins),
+    offsetof(ScfEcomponent, pins),
+    &scf_epin__descriptor,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "x",
+    4,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_UINT32,
+    0,   /* quantifier_offset */
+    offsetof(ScfEcomponent, x),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "y",
+    5,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_UINT32,
+    0,   /* quantifier_offset */
+    offsetof(ScfEcomponent, y),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "w",
+    6,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_UINT32,
+    0,   /* quantifier_offset */
+    offsetof(ScfEcomponent, w),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "h",
+    7,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_UINT32,
+    0,   /* quantifier_offset */
+    offsetof(ScfEcomponent, h),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+};
+static const unsigned scf_ecomponent__field_indices_by_name[] = {
+  6,   /* field[6] = h */
+  0,   /* field[0] = id */
+  2,   /* field[2] = pins */
+  1,   /* field[1] = type */
+  5,   /* field[5] = w */
+  3,   /* field[3] = x */
+  4,   /* field[4] = y */
+};
+static const ProtobufCIntRange scf_ecomponent__number_ranges[1 + 1] =
+{
+  { 1, 0 },
+  { 0, 7 }
+};
+const ProtobufCMessageDescriptor scf_ecomponent__descriptor =
+{
+  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
+  "scf_ecomponent",
+  "ScfEcomponent",
+  "ScfEcomponent",
+  "",
+  sizeof(ScfEcomponent),
+  7,
+  scf_ecomponent__field_descriptors,
+  scf_ecomponent__field_indices_by_name,
+  1,  scf_ecomponent__number_ranges,
+  (ProtobufCMessageInit) scf_ecomponent__init,
+  NULL,NULL,NULL    /* reserved[123] */
+};
+static const ProtobufCFieldDescriptor scf_efunction__field_descriptors[2] =
+{
+  {
+    "name",
+    1,
+    PROTOBUF_C_LABEL_REQUIRED,
+    PROTOBUF_C_TYPE_STRING,
+    0,   /* quantifier_offset */
+    offsetof(ScfEfunction, name),
+    NULL,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+  {
+    "components",
+    2,
+    PROTOBUF_C_LABEL_REPEATED,
+    PROTOBUF_C_TYPE_MESSAGE,
+    offsetof(ScfEfunction, n_components),
+    offsetof(ScfEfunction, components),
+    &scf_ecomponent__descriptor,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+};
+static const unsigned scf_efunction__field_indices_by_name[] = {
+  1,   /* field[1] = components */
+  0,   /* field[0] = name */
+};
+static const ProtobufCIntRange scf_efunction__number_ranges[1 + 1] =
+{
+  { 1, 0 },
+  { 0, 2 }
+};
+const ProtobufCMessageDescriptor scf_efunction__descriptor =
+{
+  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
+  "scf_efunction",
+  "ScfEfunction",
+  "ScfEfunction",
+  "",
+  sizeof(ScfEfunction),
+  2,
+  scf_efunction__field_descriptors,
+  scf_efunction__field_indices_by_name,
+  1,  scf_efunction__number_ranges,
+  (ProtobufCMessageInit) scf_efunction__init,
+  NULL,NULL,NULL    /* reserved[123] */
+};
+static const ProtobufCFieldDescriptor scf_eboard__field_descriptors[1] =
+{
+  {
+    "functions",
+    1,
+    PROTOBUF_C_LABEL_REPEATED,
+    PROTOBUF_C_TYPE_MESSAGE,
+    offsetof(ScfEboard, n_functions),
+    offsetof(ScfEboard, functions),
+    &scf_efunction__descriptor,
+    NULL,
+    0,             /* flags */
+    0,NULL,NULL    /* reserved1,reserved2, etc */
+  },
+};
+static const unsigned scf_eboard__field_indices_by_name[] = {
+  0,   /* field[0] = functions */
+};
+static const ProtobufCIntRange scf_eboard__number_ranges[1 + 1] =
+{
+  { 1, 0 },
+  { 0, 1 }
+};
+const ProtobufCMessageDescriptor scf_eboard__descriptor =
+{
+  PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
+  "scf_eboard",
+  "ScfEboard",
+  "ScfEboard",
+  "",
+  sizeof(ScfEboard),
+  1,
+  scf_eboard__field_descriptors,
+  scf_eboard__field_indices_by_name,
+  1,  scf_eboard__number_ranges,
+  (ProtobufCMessageInit) scf_eboard__init,
+  NULL,NULL,NULL    /* reserved[123] */
+};
diff --git a/native/eda/scf_eda.pb-c.h b/native/eda/scf_eda.pb-c.h
new file mode 100644 (file)
index 0000000..53b065e
--- /dev/null
@@ -0,0 +1,227 @@
+/* Generated by the protocol buffer compiler.  DO NOT EDIT! */
+/* Generated from: scf_eda.proto */
+
+#ifndef PROTOBUF_C_scf_5feda_2eproto__INCLUDED
+#define PROTOBUF_C_scf_5feda_2eproto__INCLUDED
+
+#include <protobuf-c/protobuf-c.h>
+
+PROTOBUF_C__BEGIN_DECLS
+
+#if PROTOBUF_C_VERSION_NUMBER < 1000000
+# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers.
+#elif 1002001 < PROTOBUF_C_MIN_COMPILER_VERSION
+# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c.
+#endif
+
+
+typedef struct _ScfEline ScfEline;
+typedef struct _ScfEpin ScfEpin;
+typedef struct _ScfEcomponent ScfEcomponent;
+typedef struct _ScfEfunction ScfEfunction;
+typedef struct _ScfEboard ScfEboard;
+
+
+/* --- enums --- */
+
+
+/* --- messages --- */
+
+struct  _ScfEline
+{
+  ProtobufCMessage base;
+  uint32_t x0;
+  uint32_t y0;
+  uint32_t x1;
+  uint32_t y1;
+};
+#define SCF_ELINE__INIT \
+ { PROTOBUF_C_MESSAGE_INIT (&scf_eline__descriptor) \
+    , 0, 0, 0, 0 }
+
+
+struct  _ScfEpin
+{
+  ProtobufCMessage base;
+  size_t n_tos;
+  uint64_t *tos;
+  uint64_t id;
+  uint64_t flags;
+  uint32_t x;
+  uint32_t y;
+  size_t n_lines;
+  ScfEline **lines;
+};
+#define SCF_EPIN__INIT \
+ { PROTOBUF_C_MESSAGE_INIT (&scf_epin__descriptor) \
+    , 0,NULL, 0, 0, 0, 0, 0,NULL }
+
+
+struct  _ScfEcomponent
+{
+  ProtobufCMessage base;
+  uint64_t id;
+  uint64_t type;
+  size_t n_pins;
+  ScfEpin **pins;
+  uint32_t x;
+  uint32_t y;
+  uint32_t w;
+  uint32_t h;
+};
+#define SCF_ECOMPONENT__INIT \
+ { PROTOBUF_C_MESSAGE_INIT (&scf_ecomponent__descriptor) \
+    , 0, 0, 0,NULL, 0, 0, 0, 0 }
+
+
+struct  _ScfEfunction
+{
+  ProtobufCMessage base;
+  char *name;
+  size_t n_components;
+  ScfEcomponent **components;
+};
+#define SCF_EFUNCTION__INIT \
+ { PROTOBUF_C_MESSAGE_INIT (&scf_efunction__descriptor) \
+    , NULL, 0,NULL }
+
+
+struct  _ScfEboard
+{
+  ProtobufCMessage base;
+  size_t n_functions;
+  ScfEfunction **functions;
+};
+#define SCF_EBOARD__INIT \
+ { PROTOBUF_C_MESSAGE_INIT (&scf_eboard__descriptor) \
+    , 0,NULL }
+
+
+/* ScfEline methods */
+void   scf_eline__init
+                     (ScfEline         *message);
+size_t scf_eline__get_packed_size
+                     (const ScfEline   *message);
+size_t scf_eline__pack
+                     (const ScfEline   *message,
+                      uint8_t             *out);
+size_t scf_eline__pack_to_buffer
+                     (const ScfEline   *message,
+                      ProtobufCBuffer     *buffer);
+ScfEline *
+       scf_eline__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data);
+void   scf_eline__free_unpacked
+                     (ScfEline *message,
+                      ProtobufCAllocator *allocator);
+/* ScfEpin methods */
+void   scf_epin__init
+                     (ScfEpin         *message);
+size_t scf_epin__get_packed_size
+                     (const ScfEpin   *message);
+size_t scf_epin__pack
+                     (const ScfEpin   *message,
+                      uint8_t             *out);
+size_t scf_epin__pack_to_buffer
+                     (const ScfEpin   *message,
+                      ProtobufCBuffer     *buffer);
+ScfEpin *
+       scf_epin__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data);
+void   scf_epin__free_unpacked
+                     (ScfEpin *message,
+                      ProtobufCAllocator *allocator);
+/* ScfEcomponent methods */
+void   scf_ecomponent__init
+                     (ScfEcomponent         *message);
+size_t scf_ecomponent__get_packed_size
+                     (const ScfEcomponent   *message);
+size_t scf_ecomponent__pack
+                     (const ScfEcomponent   *message,
+                      uint8_t             *out);
+size_t scf_ecomponent__pack_to_buffer
+                     (const ScfEcomponent   *message,
+                      ProtobufCBuffer     *buffer);
+ScfEcomponent *
+       scf_ecomponent__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data);
+void   scf_ecomponent__free_unpacked
+                     (ScfEcomponent *message,
+                      ProtobufCAllocator *allocator);
+/* ScfEfunction methods */
+void   scf_efunction__init
+                     (ScfEfunction         *message);
+size_t scf_efunction__get_packed_size
+                     (const ScfEfunction   *message);
+size_t scf_efunction__pack
+                     (const ScfEfunction   *message,
+                      uint8_t             *out);
+size_t scf_efunction__pack_to_buffer
+                     (const ScfEfunction   *message,
+                      ProtobufCBuffer     *buffer);
+ScfEfunction *
+       scf_efunction__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data);
+void   scf_efunction__free_unpacked
+                     (ScfEfunction *message,
+                      ProtobufCAllocator *allocator);
+/* ScfEboard methods */
+void   scf_eboard__init
+                     (ScfEboard         *message);
+size_t scf_eboard__get_packed_size
+                     (const ScfEboard   *message);
+size_t scf_eboard__pack
+                     (const ScfEboard   *message,
+                      uint8_t             *out);
+size_t scf_eboard__pack_to_buffer
+                     (const ScfEboard   *message,
+                      ProtobufCBuffer     *buffer);
+ScfEboard *
+       scf_eboard__unpack
+                     (ProtobufCAllocator  *allocator,
+                      size_t               len,
+                      const uint8_t       *data);
+void   scf_eboard__free_unpacked
+                     (ScfEboard *message,
+                      ProtobufCAllocator *allocator);
+/* --- per-message closures --- */
+
+typedef void (*ScfEline_Closure)
+                 (const ScfEline *message,
+                  void *closure_data);
+typedef void (*ScfEpin_Closure)
+                 (const ScfEpin *message,
+                  void *closure_data);
+typedef void (*ScfEcomponent_Closure)
+                 (const ScfEcomponent *message,
+                  void *closure_data);
+typedef void (*ScfEfunction_Closure)
+                 (const ScfEfunction *message,
+                  void *closure_data);
+typedef void (*ScfEboard_Closure)
+                 (const ScfEboard *message,
+                  void *closure_data);
+
+/* --- services --- */
+
+
+/* --- descriptors --- */
+
+extern const ProtobufCMessageDescriptor scf_eline__descriptor;
+extern const ProtobufCMessageDescriptor scf_epin__descriptor;
+extern const ProtobufCMessageDescriptor scf_ecomponent__descriptor;
+extern const ProtobufCMessageDescriptor scf_efunction__descriptor;
+extern const ProtobufCMessageDescriptor scf_eboard__descriptor;
+
+PROTOBUF_C__END_DECLS
+
+
+#endif  /* PROTOBUF_C_scf_5feda_2eproto__INCLUDED */
diff --git a/native/eda/scf_eda.proto b/native/eda/scf_eda.proto
new file mode 100644 (file)
index 0000000..78e95fb
--- /dev/null
@@ -0,0 +1,43 @@
+syntax="proto2";
+
+message scf_eline
+{
+       required uint32 x0    = 1;
+       required uint32 y0    = 2;
+       required uint32 x1    = 3;
+       required uint32 y1    = 4;
+}
+
+message scf_epin
+{
+       repeated uint64    tos   = 1;
+       required uint64    id    = 2;
+       required uint64    flags = 3;
+
+       required uint32    x     = 4;
+       required uint32    y     = 5;
+       repeated scf_eline lines = 6;
+}
+
+message scf_ecomponent
+{
+       required uint64    id   = 1;
+       required uint64    type = 2;
+       repeated scf_epin  pins = 3;
+
+       required uint32    x    = 4;
+       required uint32    y    = 5;
+       required uint32    w    = 6;
+       required uint32    h    = 7;
+}
+
+message scf_efunction
+{
+       required string         name       = 1;
+       repeated scf_ecomponent components = 2;
+}
+
+message scf_eboard
+{
+       repeated scf_efunction functions = 1;
+}
diff --git a/native/eda/scf_eda_inst.c b/native/eda/scf_eda_inst.c
new file mode 100644 (file)
index 0000000..bf7b376
--- /dev/null
@@ -0,0 +1,625 @@
+#include"scf_eda.h"
+
+#define EDA_INST_OP2_CHECK() \
+       if (!c->dsts || c->dsts->size != 1) \
+               return -EINVAL; \
+       \
+       if (!c->srcs || c->srcs->size != 1) \
+               return -EINVAL; \
+       \
+       scf_eda_context_t* eda  = ctx->priv; \
+       scf_function_t*    f    = eda->f; \
+       \
+       scf_3ac_operand_t* dst  = c->dsts->data[0]; \
+       scf_3ac_operand_t* src  = c->srcs->data[0]; \
+       \
+       if (!src || !src->dag_node) \
+               return -EINVAL; \
+       \
+       if (!dst || !dst->dag_node) \
+               return -EINVAL; \
+       \
+       if (src->dag_node->var->size != dst->dag_node->var->size) {\
+               scf_loge("size: %d, %d\n", src->dag_node->var->size, dst->dag_node->var->size); \
+               return -EINVAL; \
+       }
+
+#define EDA_INST_OP3_CHECK() \
+       if (!c->dsts || c->dsts->size != 1) \
+               return -EINVAL; \
+       \
+       if (!c->srcs || c->srcs->size != 2) \
+               return -EINVAL; \
+       \
+       scf_eda_context_t* eda  = ctx->priv; \
+       scf_function_t*    f    = eda->f; \
+       \
+       scf_3ac_operand_t* dst  = c->dsts->data[0]; \
+       scf_3ac_operand_t* src0 = c->srcs->data[0]; \
+       scf_3ac_operand_t* src1 = c->srcs->data[1]; \
+       \
+       if (!src0 || !src0->dag_node) \
+               return -EINVAL; \
+       \
+       if (!src1 || !src1->dag_node) \
+               return -EINVAL; \
+       \
+       if (!dst || !dst->dag_node) \
+               return -EINVAL; \
+       \
+       if (src0->dag_node->var->size != src1->dag_node->var->size) {\
+               scf_loge("size: %d, %d\n", src0->dag_node->var->size, src1->dag_node->var->size); \
+               return -EINVAL; \
+       }
+
+#define EDA_INST_IN_CHECK(_in, _N) \
+       do { \
+               int i; \
+               if (!(_in)->var->arg_flag) { \
+                       if ((_in)->n_pins != _N) \
+                               return -EINVAL; \
+                       \
+                       for (i = 0; i < N; i++) { \
+                               if (!(_in)->pins[i]) \
+                                       return -EINVAL; \
+                       } \
+               } \
+       } while (0)
+
+static int _eda_inst_bit_not_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;
+
+       ScfEcomponent*  T   = NULL;
+       ScfEcomponent*  R   = NULL;
+       ScfEcomponent*  B   = f->ef->components[0];
+
+       int i;
+       int N = eda_variable_size(in->var);
+
+       EDA_INST_IN_CHECK(in, N);
+
+       in ->n_pins = N;
+       out->n_pins = N;
+
+       for (i = 0; i < N; i++) {
+
+               EDA_INST_ADD_COMPONENT(f, T, SCF_EDA_Transistor);
+               EDA_INST_ADD_COMPONENT(f, R, SCF_EDA_Resistor);
+
+               in->pins[i] = T->pins[SCF_EDA_Transistor_B];
+
+               EDA_PIN_ADD_COMPONENT(T->pins[SCF_EDA_Transistor_C], R->id, 1);
+               EDA_PIN_ADD_COMPONENT(T->pins[SCF_EDA_Transistor_E], B->id, SCF_EDA_Battery_NEG);
+
+               EDA_PIN_ADD_COMPONENT(R->pins[0], B->id, SCF_EDA_Battery_POS);
+               EDA_PIN_ADD_COMPONENT(R->pins[1], T->id, SCF_EDA_Transistor_C);
+
+               out->pins[i] = T->pins[SCF_EDA_Transistor_C];
+       }
+
+       return 0;
+}
+
+static int _eda_inst_bit_and_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       EDA_INST_OP3_CHECK()
+
+       scf_dag_node_t* in0 = src0->dag_node;
+       scf_dag_node_t* in1 = src1->dag_node;
+       scf_dag_node_t* out = dst ->dag_node;
+
+       ScfEcomponent*  D0  = NULL;
+       ScfEcomponent*  D1  = NULL;
+       ScfEcomponent*  R   = NULL;
+       ScfEcomponent*  B   = f->ef->components[0];
+
+       int i;
+       int N = eda_variable_size(in0->var);
+
+       EDA_INST_IN_CHECK(in0, N);
+       EDA_INST_IN_CHECK(in1, N);
+
+       in0->n_pins = N;
+       in1->n_pins = N;
+       out->n_pins = N;
+
+       for (i = 0; i < N; i++) {
+
+               EDA_INST_ADD_COMPONENT(f, D0, SCF_EDA_Diode);
+               EDA_INST_ADD_COMPONENT(f, D1, SCF_EDA_Diode);
+               EDA_INST_ADD_COMPONENT(f, R,  SCF_EDA_Resistor);
+
+               in0->pins[i] = D0->pins[SCF_EDA_Diode_NEG];
+               in1->pins[i] = D1->pins[SCF_EDA_Diode_NEG];
+
+               EDA_PIN_ADD_COMPONENT(D0->pins[SCF_EDA_Diode_POS], D1->id, SCF_EDA_Diode_POS);
+               EDA_PIN_ADD_COMPONENT(D0->pins[SCF_EDA_Diode_POS], R ->id, 1);
+
+               EDA_PIN_ADD_COMPONENT(D1->pins[SCF_EDA_Diode_POS], D0->id, SCF_EDA_Diode_POS);
+               EDA_PIN_ADD_COMPONENT(D1->pins[SCF_EDA_Diode_POS], R ->id, 1);
+
+               EDA_PIN_ADD_COMPONENT(R->pins[1], D0->id, SCF_EDA_Diode_POS);
+               EDA_PIN_ADD_COMPONENT(R->pins[1], D1->id, SCF_EDA_Diode_POS);
+               EDA_PIN_ADD_COMPONENT(R->pins[0], B ->id, SCF_EDA_Battery_POS);
+
+               out->pins[i] = R ->pins[1];
+       }
+
+       return 0;
+}
+
+static int _eda_inst_bit_or_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       EDA_INST_OP3_CHECK()
+
+       scf_dag_node_t* in0 = src0->dag_node;
+       scf_dag_node_t* in1 = src1->dag_node;
+       scf_dag_node_t* out = dst ->dag_node;
+
+       ScfEcomponent*  D0  = NULL;
+       ScfEcomponent*  D1  = NULL;
+       ScfEcomponent*  R   = NULL;
+       ScfEcomponent*  B   = f->ef->components[0];
+
+       int i;
+       int N = eda_variable_size(in0->var);
+
+       EDA_INST_IN_CHECK(in0, N);
+       EDA_INST_IN_CHECK(in1, N);
+
+       in0->n_pins = N;
+       in1->n_pins = N;
+       out->n_pins = N;
+
+       for (i = 0; i < N; i++) {
+
+               EDA_INST_ADD_COMPONENT(f, D0, SCF_EDA_Diode);
+               EDA_INST_ADD_COMPONENT(f, D1, SCF_EDA_Diode);
+               EDA_INST_ADD_COMPONENT(f, R,  SCF_EDA_Resistor);
+
+               in0->pins[i] = D0->pins[SCF_EDA_Diode_POS];
+               in1->pins[i] = D1->pins[SCF_EDA_Diode_POS];
+
+               EDA_PIN_ADD_COMPONENT(D0->pins[SCF_EDA_Diode_NEG], D1->id, SCF_EDA_Diode_NEG);
+               EDA_PIN_ADD_COMPONENT(D0->pins[SCF_EDA_Diode_NEG], R ->id, 0);
+
+               EDA_PIN_ADD_COMPONENT(D1->pins[SCF_EDA_Diode_NEG], D0->id, SCF_EDA_Diode_NEG);
+               EDA_PIN_ADD_COMPONENT(D1->pins[SCF_EDA_Diode_NEG], R ->id, 0);
+
+               EDA_PIN_ADD_COMPONENT(R->pins[0], D0->id, SCF_EDA_Diode_NEG);
+               EDA_PIN_ADD_COMPONENT(R->pins[0], D1->id, SCF_EDA_Diode_NEG);
+               EDA_PIN_ADD_COMPONENT(R->pins[1], B ->id, SCF_EDA_Battery_NEG);
+
+               out->pins[i] = R ->pins[0];
+       }
+
+       return 0;
+}
+
+static int _eda_inst_inc_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_inc_post_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_dec_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_dec_post_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_assign_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       if (!c->srcs || c->srcs->size != 4)
+               return -EINVAL;
+
+       scf_eda_context_t*  eda    = ctx->priv;
+       scf_function_t*     f      = eda->f;
+
+       scf_3ac_operand_t*  base   = c->srcs->data[0];
+       scf_3ac_operand_t*  index  = c->srcs->data[1];
+       scf_3ac_operand_t*  scale  = c->srcs->data[2];
+       scf_3ac_operand_t*  src    = c->srcs->data[3];
+
+       if (!base || !base->dag_node)
+               return -EINVAL;
+
+       if (!index || !index->dag_node)
+               return -EINVAL;
+
+       if (!scale || !scale->dag_node)
+               return -EINVAL;
+
+       if (!src || !src->dag_node)
+               return -EINVAL;
+
+       return -EINVAL;
+}
+
+static int _eda_inst_and_assign_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       if (!c->srcs || c->srcs->size != 4)
+               return -EINVAL;
+
+       scf_eda_context_t*  eda    = ctx->priv;
+       scf_function_t*     f      = eda->f;
+
+       scf_3ac_operand_t*  base   = c->srcs->data[0];
+       scf_3ac_operand_t*  index  = c->srcs->data[1];
+       scf_3ac_operand_t*  scale  = c->srcs->data[2];
+       scf_3ac_operand_t*  src    = c->srcs->data[3];
+
+       if (!base || !base->dag_node)
+               return -EINVAL;
+
+       if (!index || !index->dag_node)
+               return -EINVAL;
+
+       if (!scale || !scale->dag_node)
+               return -EINVAL;
+
+       if (!src || !src->dag_node)
+               return -EINVAL;
+
+       return -EINVAL;
+}
+
+static int _eda_inst_or_assign_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       if (!c->srcs || c->srcs->size != 4)
+               return -EINVAL;
+
+       scf_eda_context_t*  eda    = ctx->priv;
+       scf_function_t*     f      = eda->f;
+
+       scf_3ac_operand_t*  base   = c->srcs->data[0];
+       scf_3ac_operand_t*  index  = c->srcs->data[1];
+       scf_3ac_operand_t*  scale  = c->srcs->data[2];
+       scf_3ac_operand_t*  src    = c->srcs->data[3];
+
+       if (!base || !base->dag_node)
+               return -EINVAL;
+
+       if (!index || !index->dag_node)
+               return -EINVAL;
+
+       if (!scale || !scale->dag_node)
+               return -EINVAL;
+
+       if (!src || !src->dag_node)
+               return -EINVAL;
+
+       return -EINVAL;
+}
+
+static int _eda_inst_array_index_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       if (!c->dsts || c->dsts->size != 1)
+               return -EINVAL;
+
+       if (!c->srcs || c->srcs->size != 3)
+               return -EINVAL;
+
+       scf_eda_context_t*  eda    = ctx->priv;
+       scf_function_t*     f      = eda->f;
+
+       scf_3ac_operand_t*  dst    = c->dsts->data[0];
+       scf_3ac_operand_t*  base   = c->srcs->data[0];
+       scf_3ac_operand_t*  index  = c->srcs->data[1];
+       scf_3ac_operand_t*  scale  = c->srcs->data[2];
+
+       if (!base || !base->dag_node)
+               return -EINVAL;
+
+       if (!index || !index->dag_node)
+               return -EINVAL;
+
+       if (!scale || !scale->dag_node)
+               return -EINVAL;
+
+       if (!c->instructions) {
+               c->instructions = scf_vector_alloc();
+               if (!c->instructions)
+                       return -ENOMEM;
+       }
+
+       scf_variable_t*     vd  = dst  ->dag_node->var;
+       scf_variable_t*     vb  = base ->dag_node->var;
+       scf_variable_t*     vi  = index->dag_node->var;
+       scf_variable_t*     vs  = scale->dag_node->var;
+
+       return -EINVAL;
+}
+
+static int _eda_inst_teq_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_logic_not_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_cmp_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_setz_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_setnz_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_setgt_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_setge_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_setlt_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_setle_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_eq_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_ne_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_gt_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_ge_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_lt_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_le_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_cast_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       if (!c->dsts || c->dsts->size != 1)
+               return -EINVAL;
+
+       if (!c->srcs || c->srcs->size != 1)
+               return -EINVAL;
+
+       scf_eda_context_t* eda = ctx->priv;
+       scf_function_t*    f   = eda->f;
+       scf_3ac_operand_t* src = c->srcs->data[0];
+       scf_3ac_operand_t* dst = c->dsts->data[0];
+
+       if (!src || !src->dag_node)
+               return -EINVAL;
+
+       if (!dst || !dst->dag_node)
+               return -EINVAL;
+
+       if (0 == dst->dag_node->color)
+               return -EINVAL;
+
+       return -EINVAL;
+}
+
+static int _eda_inst_return_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       if (!c->srcs || c->srcs->size < 1)
+               return -EINVAL;
+
+       scf_eda_context_t*  eda  = ctx->priv;
+       scf_function_t*     f    = eda->f;
+       scf_3ac_operand_t*  src  = NULL;
+       scf_dag_node_t*     out  = NULL;
+
+       int i;
+       int j;
+
+       for (i  = 0; i < c->srcs->size; i++) {
+               src =        c->srcs->data[i];
+
+               out = src->dag_node;
+
+               if (out->n_pins <= 0) {
+                       scf_loge("\n");
+                       return -EINVAL;
+               }
+
+               for (j  = 0; j < out->n_pins; j++)
+                       out->pins[j]->flags |= SCF_EDA_PIN_OUT;
+       }
+
+       return 0;
+}
+
+static int _eda_inst_nop_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return 0;
+}
+
+static int _eda_inst_end_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return 0;
+}
+
+static int _eda_inst_goto_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_jz_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_jnz_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_jgt_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_jge_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_jlt_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_jle_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return -EINVAL;
+}
+
+static int _eda_inst_load_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return 0;
+}
+
+static int _eda_inst_reload_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return 0;
+}
+
+static int _eda_inst_save_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return 0;
+}
+
+static int _eda_inst_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return 0;
+}
+
+static int _eda_inst_and_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return 0;
+}
+
+static int _eda_inst_or_assign_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       return 0;
+}
+
+static eda_inst_handler_t eda_inst_handlers[] =
+{
+       {SCF_OP_ARRAY_INDEX,    _eda_inst_array_index_handler},
+
+       {SCF_OP_TYPE_CAST,      _eda_inst_cast_handler},
+       {SCF_OP_LOGIC_NOT,              _eda_inst_logic_not_handler},
+       {SCF_OP_BIT_NOT,        _eda_inst_bit_not_handler},
+
+       {SCF_OP_INC,            _eda_inst_inc_handler},
+       {SCF_OP_DEC,            _eda_inst_dec_handler},
+
+       {SCF_OP_INC_POST,       _eda_inst_inc_post_handler},
+       {SCF_OP_DEC_POST,       _eda_inst_dec_post_handler},
+
+       {SCF_OP_BIT_AND,        _eda_inst_bit_and_handler},
+       {SCF_OP_BIT_OR,         _eda_inst_bit_or_handler},
+
+       {SCF_OP_3AC_TEQ,        _eda_inst_teq_handler},
+       {SCF_OP_3AC_CMP,        _eda_inst_cmp_handler},
+
+       {SCF_OP_3AC_SETZ,       _eda_inst_setz_handler},
+       {SCF_OP_3AC_SETNZ,      _eda_inst_setnz_handler},
+       {SCF_OP_3AC_SETGT,      _eda_inst_setgt_handler},
+       {SCF_OP_3AC_SETGE,      _eda_inst_setge_handler},
+       {SCF_OP_3AC_SETLT,      _eda_inst_setlt_handler},
+       {SCF_OP_3AC_SETLE,      _eda_inst_setle_handler},
+
+       {SCF_OP_EQ,                     _eda_inst_eq_handler},
+       {SCF_OP_NE,                     _eda_inst_ne_handler},
+       {SCF_OP_GT,                     _eda_inst_gt_handler},
+       {SCF_OP_GE,             _eda_inst_ge_handler},
+       {SCF_OP_LT,             _eda_inst_lt_handler},
+       {SCF_OP_LE,             _eda_inst_le_handler},
+
+       {SCF_OP_ASSIGN,                 _eda_inst_assign_handler},
+
+       {SCF_OP_AND_ASSIGN,     _eda_inst_and_assign_handler},
+       {SCF_OP_OR_ASSIGN,      _eda_inst_or_assign_handler},
+
+       {SCF_OP_RETURN,                 _eda_inst_return_handler},
+       {SCF_OP_GOTO,                   _eda_inst_goto_handler},
+
+       {SCF_OP_3AC_JZ,                 _eda_inst_jz_handler},
+       {SCF_OP_3AC_JNZ,                _eda_inst_jnz_handler},
+       {SCF_OP_3AC_JGT,                _eda_inst_jgt_handler},
+       {SCF_OP_3AC_JGE,                _eda_inst_jge_handler},
+       {SCF_OP_3AC_JLT,                _eda_inst_jlt_handler},
+       {SCF_OP_3AC_JLE,                _eda_inst_jle_handler},
+
+       {SCF_OP_3AC_NOP,                _eda_inst_nop_handler},
+       {SCF_OP_3AC_END,                _eda_inst_end_handler},
+
+       {SCF_OP_3AC_SAVE,       _eda_inst_save_handler},
+       {SCF_OP_3AC_LOAD,       _eda_inst_load_handler},
+
+       {SCF_OP_3AC_RESAVE,     _eda_inst_save_handler},
+       {SCF_OP_3AC_RELOAD,     _eda_inst_reload_handler},
+
+       {SCF_OP_3AC_ASSIGN_ARRAY_INDEX,     _eda_inst_assign_array_index_handler},
+       {SCF_OP_3AC_AND_ASSIGN_ARRAY_INDEX, _eda_inst_and_assign_array_index_handler},
+       {SCF_OP_3AC_OR_ASSIGN_ARRAY_INDEX,  _eda_inst_or_assign_array_index_handler},
+};
+
+eda_inst_handler_t* scf_eda_find_inst_handler(const int op_type)
+{
+       int i;
+       for (i = 0; i < sizeof(eda_inst_handlers) / sizeof(eda_inst_handlers[0]); i++) {
+
+               eda_inst_handler_t* h = &(eda_inst_handlers[i]);
+
+               if (op_type == h->type)
+                       return h;
+       }
+       return NULL;
+}
diff --git a/native/eda/scf_eda_pb.c b/native/eda/scf_eda_pb.c
new file mode 100644 (file)
index 0000000..2791ce3
--- /dev/null
@@ -0,0 +1,407 @@
+#include "scf_eda_pb.h"
+#include "scf_def.h"
+
+static int component_pins[SCF_EDA_Components_NB] =
+{
+       0, // None
+       SCF_EDA_Battery_NB, // SCF_EDA_Battery
+
+       2, // SCF_EDA_Resistor
+       2, // SCF_EDA_Capacitor
+       2, // SCF_EDA_Inductor
+
+       SCF_EDA_Diode_NB,
+       SCF_EDA_Transistor_NB,
+};
+
+ScfEline* scf_eline__alloc()
+{
+       ScfEline* l = malloc(sizeof(ScfEline));
+       if (!l)
+               return NULL;
+
+       scf_eline__init(l);
+       return l;
+}
+
+void scf_eline__free(ScfEline* l)
+{
+       if (l)
+               free(l);
+}
+
+ScfEpin* scf_epin__alloc()
+{
+       ScfEpin* pin = malloc(sizeof(ScfEpin));
+       if (!pin)
+               return NULL;
+
+       scf_epin__init(pin);
+       return pin;
+}
+
+int scf_epin__add_component(ScfEpin* pin, uint64_t cid, uint64_t pid)
+{
+       if (!pin)
+               return -EINVAL;
+
+       for (size_t i = 0; i + 1 < pin->n_tos; i += 2) {
+
+               if (pin->tos[i] == cid && pin->tos[i + 1] == pid)
+                       return 0;
+       }
+
+       uint64_t* p = realloc(pin->tos, sizeof(uint64_t) * (pin->n_tos + 2));
+       if (!p)
+               return -ENOMEM;
+
+       pin->tos = p;
+       pin->tos[pin->n_tos++] = cid;
+       pin->tos[pin->n_tos++] = pid;
+       return 0;
+}
+
+int scf_epin__del_component(ScfEpin* pin, uint64_t cid, uint64_t pid)
+{
+       if (!pin)
+               return -EINVAL;
+
+       uint64_t* p;
+       size_t    i;
+       size_t    j;
+
+       for (i = 0; i + 1 < pin->n_tos; i += 2) {
+
+               if (pin->tos[i] == cid && pin->tos[i + 1] == pid) {
+
+                       for (j = i + 2;  j  < pin->n_tos; j++)
+                               pin->tos[j - 2] = pin->tos[j];
+
+                       pin->n_tos -= 2;
+
+                       p = realloc(pin->tos, sizeof(uint64_t) * pin->n_tos);
+                       if (p)
+                               pin->tos = p;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+int scf_epin__add_line(ScfEpin* pin, ScfEline* l)
+{
+       if (!pin || !l)
+               return -EINVAL;
+
+       for (size_t i = 0; i < pin->n_lines; i++) {
+
+               if (pin->lines[i]->x0 == l->x0
+                && pin->lines[i]->y0 == l->y0
+                && pin->lines[i]->x1 == l->x1
+                && pin->lines[i]->y1 == l->y1)
+                       return 0;
+       }
+
+       void* p = realloc(pin->lines, sizeof(ScfEline*) * (pin->n_lines + 1));
+       if (!p)
+               return -ENOMEM;
+
+       pin->lines = p;
+       pin->lines[pin->n_lines++] = l;
+       return 0;
+}
+
+int scf_epin__del_line(ScfEpin* pin, ScfEline* l)
+{
+       if (!pin || !l)
+               return -EINVAL;
+
+       void*  p;
+       size_t i;
+       size_t j;
+       size_t n = pin->n_lines;
+
+       for (i = 0; i < pin->n_lines; ) {
+
+               if (pin->lines[i]->x0 == l->x0
+                && pin->lines[i]->y0 == l->y0
+                && pin->lines[i]->x1 == l->x1
+                && pin->lines[i]->y1 == l->y1) {
+
+                       for (j = i + 1;  j    < pin->n_lines; j++)
+                               pin->lines[j - 1] = pin->lines[j];
+
+                       pin->n_lines--;
+               } else
+                       i++;
+       }
+
+       if (pin->n_lines < n) {
+               p = realloc(pin->lines, sizeof(ScfEline*) * pin->n_lines);
+               if (p)
+                       pin->lines = p;
+       }
+
+       return 0;
+}
+
+void scf_epin__free(ScfEpin* pin)
+{
+       if (pin) {
+               scf_logd("pin: %p\n", pin);
+
+               if (pin->lines) {
+                       size_t i;
+
+                       for (i = 0; i < pin->n_lines; i++)
+                               scf_eline__free(pin->lines[i]);
+
+                       free(pin->lines);
+               }
+
+               if (pin->tos)
+                       free(pin->tos);
+               free(pin);
+       }
+}
+
+ScfEcomponent* scf_ecomponent__alloc(uint64_t type)
+{
+       if (type >= SCF_EDA_Components_NB)
+               return NULL;
+
+       ScfEcomponent* c = malloc(sizeof(ScfEcomponent));
+       if (!c)
+               return NULL;
+
+       scf_ecomponent__init(c);
+
+       c->type = type;
+
+       int i;
+       for (i = 0; i < component_pins[type]; i++) {
+
+               ScfEpin* pin = scf_epin__alloc();
+               if (!pin) {
+                       scf_ecomponent__free(c);
+                       return NULL;
+               }
+
+               pin->id = i;
+
+               if (scf_ecomponent__add_pin(c, pin) < 0) {
+                       scf_ecomponent__free(c);
+                       scf_epin__free(pin);
+                       return NULL;
+               }
+       }
+
+       return c;
+}
+
+int scf_ecomponent__add_pin(ScfEcomponent* c, ScfEpin* pin)
+{
+       if (!c || !pin)
+               return -EINVAL;
+
+       void* p = realloc(c->pins, sizeof(ScfEpin*) * (c->n_pins + 1));
+       if (!p)
+               return -ENOMEM;
+
+       c->pins = p;
+       c->pins[c->n_pins++] = pin;
+       return 0;
+}
+
+int scf_ecomponent__del_pin(ScfEcomponent* c, ScfEpin* pin)
+{
+       if (!c)
+               return -EINVAL;
+
+       size_t   i;
+       size_t   j;
+       void*    p;
+
+       for (i = 0; i < c->n_pins; i++) {
+
+               if (c->pins[i] == pin) {
+
+                       for (j = i + 1; j  < c->n_pins; j++)
+                               c->pins[j - 1] = c->pins[j];
+
+                       c->n_pins--;
+
+                       p = realloc(c->pins, sizeof(ScfEpin*) * c->n_pins);
+                       if (p)
+                               c->pins = p;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+void scf_ecomponent__free(ScfEcomponent* c)
+{
+       if (c) {
+               scf_logd("c: %ld\n", c->id);
+
+               if (c->pins) {
+                       size_t i;
+
+                       for (i = 0; i < c->n_pins; i++)
+                               scf_epin__free(c->pins[i]);
+
+                       free(c->pins);
+               }
+
+               free(c);
+       }
+}
+
+ScfEfunction*  scf_efunction__alloc(const char* name)
+{
+       ScfEfunction* f = malloc(sizeof(ScfEfunction));
+       if (!f)
+               return NULL;
+
+       scf_efunction__init(f);
+
+       f->name = strdup(name);
+       if (!f->name) {
+               free(f);
+               return NULL;
+       }
+
+       return f;
+}
+
+int scf_efunction__add_component(ScfEfunction* f, ScfEcomponent* c)
+{
+       if (!f || !c)
+               return -EINVAL;
+
+       void* p = realloc(f->components, sizeof(ScfEcomponent*) * (f->n_components + 1));
+       if (!p)
+               return -ENOMEM;
+
+       f->components = p;
+       f->components[f->n_components++] = c;
+       return 0;
+}
+
+int scf_efunction__del_component(ScfEfunction* f, ScfEcomponent* c)
+{
+       if (!f)
+               return -EINVAL;
+
+       size_t   i;
+       size_t   j;
+       void*    p;
+
+       for (i = 0; i < f->n_components; i++) {
+
+               if (f->components[i] == c) {
+
+                       for (j = i + 1;  j < f->n_components; j++)
+                               f->components[j - 1] = f->components[j];
+
+                       f->n_components--;
+
+                       p = realloc(f->components, sizeof(ScfEfunction*) * f->n_components);
+                       if (p)
+                               f->components = p;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+void scf_efunction__free(ScfEfunction* f)
+{
+       if (f) {
+               scf_logd("f: %s\n", f->name);
+
+               if (f->components) {
+                       size_t i;
+
+                       for (i = 0; i < f->n_components; i++)
+                               scf_ecomponent__free(f->components[i]);
+
+                       free(f->components);
+               }
+
+               free(f->name);
+               free(f);
+       }
+}
+
+ScfEboard* scf_eboard__alloc()
+{
+       ScfEboard* b = malloc(sizeof(ScfEboard));
+       if (!b)
+               return NULL;
+
+       scf_eboard__init(b);
+       return b;
+}
+
+int scf_eboard__add_function(ScfEboard* b, ScfEfunction* f)
+{
+       if (!b || !f)
+               return -EINVAL;
+
+       void* p = realloc(b->functions, sizeof(ScfEfunction*) * (b->n_functions + 1));
+       if (!p)
+               return -ENOMEM;
+
+       b->functions = p;
+       b->functions[b->n_functions++] = f;
+       return 0;
+}
+
+int scf_eboard__del_function(ScfEboard* b, ScfEfunction* f)
+{
+       if (!b)
+               return -EINVAL;
+
+       size_t   i;
+       size_t   j;
+       void*    p;
+
+       for (i = 0; i < b->n_functions; i++) {
+
+               if (b->functions[i] == f) {
+
+                       for (j = i + 1;  j < b->n_functions; j++)
+                               b->functions[j - 1] = b->functions[j];
+
+                       b->n_functions--;
+
+                       p = realloc(b->functions, sizeof(ScfEfunction*) * b->n_functions);
+                       if (p)
+                               b->functions = p;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+void scf_eboard__free(ScfEboard* b)
+{
+       if (b) {
+               if (b->functions) {
+                       size_t i;
+
+                       for (i = 0; i < b->n_functions; i++)
+                               scf_efunction__free(b->functions[i]);
+
+                       free(b->functions);
+               }
+
+               free(b);
+       }
+}
diff --git a/native/eda/scf_eda_pb.h b/native/eda/scf_eda_pb.h
new file mode 100644 (file)
index 0000000..739e566
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef SCF_EDA_PB_H
+#define SCF_EDA_PB_H
+
+#include "scf_eda.pb-c.h"
+
+enum {
+       SCF_EDA_None,
+       SCF_EDA_Battery,
+
+       SCF_EDA_Resistor,
+       SCF_EDA_Capacitor,
+       SCF_EDA_Inductor,
+
+       SCF_EDA_Diode,
+       SCF_EDA_Transistor,
+
+       SCF_EDA_Components_NB,
+};
+
+#define SCF_EDA_PIN_NONE  0
+#define SCF_EDA_PIN_IN    1
+#define SCF_EDA_PIN_OUT   2
+
+enum {
+       SCF_EDA_Battery_NEG,
+       SCF_EDA_Battery_POS,
+       SCF_EDA_Battery_NB,
+};
+
+enum {
+       SCF_EDA_Diode_NEG,
+       SCF_EDA_Diode_POS,
+       SCF_EDA_Diode_NB,
+};
+
+enum {
+       SCF_EDA_Transistor_B,
+       SCF_EDA_Transistor_C,
+       SCF_EDA_Transistor_E,
+       SCF_EDA_Transistor_NB,
+};
+
+ScfEline*      scf_eline__alloc();
+void           scf_eline__free (ScfEline* l);
+
+ScfEpin*       scf_epin__alloc();
+int            scf_epin__add_component(ScfEpin* pin, uint64_t cid, uint64_t pid);
+int            scf_epin__del_component(ScfEpin* pin, uint64_t cid, uint64_t pid);
+int            scf_epin__add_line     (ScfEpin* pin, ScfEline* l);
+int            scf_epin__del_line     (ScfEpin* pin, ScfEline* l);
+void           scf_epin__free         (ScfEpin* pin);
+
+ScfEcomponent* scf_ecomponent__alloc(uint64_t type);
+int            scf_ecomponent__add_pin(ScfEcomponent* c, ScfEpin* pin);
+int            scf_ecomponent__del_pin(ScfEcomponent* c, ScfEpin* pin);
+void           scf_ecomponent__free   (ScfEcomponent* c);
+
+ScfEfunction*  scf_efunction__alloc        (const   char* name);
+int            scf_efunction__add_component(ScfEfunction* f, ScfEcomponent* c);
+int            scf_efunction__del_component(ScfEfunction* f, ScfEcomponent* c);
+void           scf_efunction__free         (ScfEfunction* f);
+
+ScfEboard*     scf_eboard__alloc();
+int            scf_eboard__add_function(ScfEboard* b, ScfEfunction* f);
+int            scf_eboard__del_function(ScfEboard* b, ScfEfunction* f);
+void           scf_eboard__free        (ScfEboard* b);
+
+#endif
index b0eac6c4b07ab9b3ce0408e780d62be948d2dd4f..14b3e81e9c447bb29ed6e7a69f5d9d7d973a131a 100644 (file)
@@ -2,6 +2,7 @@
 
 extern scf_native_ops_t native_ops_x64;
 extern scf_native_ops_t native_ops_risc;
+extern scf_native_ops_t native_ops_eda;
 
 void scf_instruction_print(scf_instruction_t* inst)
 {
@@ -50,6 +51,9 @@ int scf_native_open(scf_native_t** pctx, const char* name)
 
        if (!strcmp(name, "x64"))
                ctx->ops = &native_ops_x64;
+
+       else if (!strcmp(name, "eda"))
+               ctx->ops = &native_ops_eda;
        else
                ctx->ops = &native_ops_risc;
 
index 51efbdbb0ea159be6018db3ba8d19fcca8472682..7091925a8b9078c96b4ce889143fb6555bb716e1 100644 (file)
@@ -42,6 +42,11 @@ CFILES += ../native/risc/scf_arm64.c
 CFILES += ../native/risc/scf_arm32.c
 CFILES += ../native/risc/scf_naja.c
 
+CFILES += ../native/eda/scf_eda.c
+CFILES += ../native/eda/scf_eda_inst.c
+CFILES += ../native/eda/scf_eda_pb.c
+CFILES += ../native/eda/scf_eda.pb-c.c
+
 CFILES += ../elf/scf_elf.c
 CFILES += ../elf/scf_elf_link.c
 CFILES += ../elf/scf_elf_native.c
@@ -167,8 +172,10 @@ CFLAGS += -I../vm
 CFLAGS += -I../native
 CFLAGS += -I../native/x64
 CFLAGS += -I../native/risc
+CFLAGS += -I../native/eda
 
 LDFLAGS += -ldl
+LDFLAGS += -lprotobuf-c
 
 all:
        gcc $(CFLAGS) $(CFILES) $(LDFLAGS) -o scf
index 0eae6c392bebc9d009ae56c824cfd00b125b4044..073045b2c46a76725935a8ec5a27c087eb55d733 100644 (file)
@@ -42,7 +42,7 @@ void usage(char* path)
 {
        fprintf(stderr, "Usage: %s [-c] [-a arch] [-o out] src0 [src1]\n\n", path);
        fprintf(stderr, "-c: only compile, not link\n");
-       fprintf(stderr, "-a: select cpu arch (x64 or arm64), default is x64\n");
+       fprintf(stderr, "-a: select cpu arch (x64, arm64, naja, or eda), default is x64\n");
 }
 
 int main(int argc, char* argv[])
index 73432b2c3c9c67876e77105d57c389c72b386a73..eb07ab98c423433f46aa731df317f612cf543934 100644 (file)
@@ -7,6 +7,7 @@
 #include"scf_optimizer.h"
 #include"scf_elf.h"
 #include"scf_leb128.h"
+#include"scf_eda.h"
 
 #define ADD_SECTION_SYMBOL(sh_index, sh_name) \
        do { \
@@ -2059,6 +2060,57 @@ static int _add_debug_file_names(scf_parse_t* parse)
        return 0;
 }
 
+int scf_eda_write_pb(scf_parse_t* parse, const char* out, scf_vector_t* functions, scf_vector_t* global_vars)
+{
+       scf_function_t* f;
+       ScfEboard*      b;
+
+       b = scf_eboard__alloc();
+       if (!b)
+               return -ENOMEM;
+
+       int i;
+       for (i = 0; i < functions->size; i++) {
+               f  =        functions->data[i];
+
+               if (!f->node.define_flag)
+                       continue;
+
+               if (!f->ef)
+                       continue;
+
+               int ret = scf_eboard__add_function(b, f->ef);
+               f->ef   = NULL;
+
+               if (ret < 0) {
+                       scf_eboard__free(b);
+                       return ret;
+               }
+       }
+
+       size_t len = scf_eboard__get_packed_size(b);
+
+       scf_loge("len: %ld\n", len);
+
+       uint8_t* buf = malloc(len);
+       if (!buf) {
+               scf_eboard__free(b);
+               return -ENOMEM;
+       }
+
+       scf_eboard__pack(b, buf);
+       scf_eboard__free(b);
+       b = NULL;
+
+       FILE* fp = fopen(out, "wb");
+       if (!fp)
+               return -EINVAL;
+
+       fwrite(buf, len, 1, fp);
+       fclose(fp);
+       return 0;
+}
+
 int scf_parse_compile(scf_parse_t* parse, const char* out, const char* arch)
 {
        scf_block_t* b = parse->ast->root_block;
@@ -2069,65 +2121,66 @@ int scf_parse_compile(scf_parse_t* parse, const char* out, const char* arch)
 
        scf_vector_t*      functions   = NULL;
        scf_vector_t*      global_vars = NULL;
-       scf_elf_context_t* elf         = NULL;
        scf_native_t*      native      = NULL;
        scf_string_t*      code        = NULL;
 
-       scf_elf_section_t  cs = {0};
+       scf_elf_context_t* elf         = NULL;
+       scf_elf_section_t  cs          = {0};
 
        functions = scf_vector_alloc();
        if (!functions)
                return -ENOMEM;
 
-       global_vars = scf_vector_alloc();
-       if (!global_vars) {
-               ret = -ENOMEM;
-               goto global_vars_error;
-       }
-
-       code = scf_string_alloc();
-       if (!code) {
-               ret = -ENOMEM;
-               goto code_error;
+       ret = scf_node_search_bfs((scf_node_t*)b, NULL, functions, -1, _find_function);
+       if (ret < 0) {
+               scf_loge("\n");
+               goto open_native_error;
        }
 
-       parse->debug->arch = (char*)arch;
+       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;
        }
-#if 1
-       ret = scf_elf_open(&elf, arch, out, "wb");
-       if (ret < 0) {
-               scf_loge("open elf file failed\n");
-               goto open_elf_error;
-       }
-#endif
-       ret = scf_node_search_bfs((scf_node_t*)b, NULL, functions, -1, _find_function);
+
+       ret = scf_parse_compile_functions(parse, native, functions);
        if (ret < 0) {
                scf_loge("\n");
-               goto error;
+               goto open_native_error;
+       }
+
+       if (!strcmp(arch, "eda"))
+               return scf_eda_write_pb(parse, out, functions, NULL);
+
+       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;
        }
 
-       scf_logi("all functions: %d\n",   functions->size);
        scf_logi("all global_vars: %d\n", global_vars->size);
 
-       int64_t tv0 = gettime();
-       ret = scf_parse_compile_functions(parse, native, functions);
+       parse->debug->arch = (char*)arch;
+
+       code = scf_string_alloc();
+       if (!code) {
+               ret = -ENOMEM;
+               goto code_error;
+       }
+
+       ret = scf_elf_open(&elf, arch, out, "wb");
        if (ret < 0) {
-               scf_loge("\n");
-               goto error;
+               scf_loge("open elf file failed\n");
+               goto open_elf_error;
        }
-       int64_t tv1 = gettime();
-       scf_logw("tv1 - tv0: %ld\n", tv1 - tv0);
 
        ret = _add_debug_file_names(parse);
        if (ret < 0) {
@@ -2359,19 +2412,17 @@ int scf_parse_compile(scf_parse_t* parse, const char* out, const char* arch)
        }
        ret = 0;
 
-       int64_t tv2 = gettime();
-       scf_logw("tv2 - tv1: %ld\n", tv2 - tv1);
        scf_logi("ok\n\n");
 
 error:
        scf_elf_close(elf);
 open_elf_error:
-       scf_native_close(native);
-open_native_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;
 }