libopid: decouple static code
authorDmitry Selyutin <ghostmansd@gmail.com>
Sun, 10 Sep 2023 19:41:40 +0000 (22:41 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Wed, 13 Sep 2023 17:26:19 +0000 (20:26 +0300)
src/libopid/.gitignore
src/libopid/Makefile
src/libopid/codegen.py
src/libopid/opid-dis.c [new file with mode: 0644]
src/libopid/opid-opc.c [new file with mode: 0644]

index 5c09e3066fdf413fc6cb7e6f266ddefa67e7fcc4..4c881193125f5b5f6b6c2a7e7b8d8aab436b93a6 100644 (file)
@@ -2,4 +2,4 @@
 *.a
 *.so
 *.o
-opid-dis
+opid-check
index fa56684643f9897e5fe5ed976de55e7b0a9dc2b4..4ff00f26be58ed2f1e6521b9f65c614a66758815 100644 (file)
@@ -14,8 +14,8 @@ SRCS:=\
        opid-check.c \
 
 OBJS:=\
-       opid-dis-gen.o \
-       opid-opc-gen.o \
+       opid-dis.o \
+       opid-opc.o \
        opid-check.o \
 
 
@@ -44,6 +44,10 @@ check: opid-check.py opid-check
        python3 opid-check.py
 
 
+opid-opc.c: opid-opc-gen.c
+opid-dis.c: opid-dis-gen.c
+
+
 opid-check: opid-check.o libopid.a
        $(CC) $(CPPFLAGS) $(CFLAGS) -fPIC $< -o $@ -L. -l:libopid.a
 
index 349b2e572bb114a781462e4e6fe60e5162c1159c..525c2e8d09eecc9cdc46c2932b409ab6797dc0b1 100644 (file)
@@ -208,6 +208,21 @@ class Source(Codegen):
         with self: yield node
         self.emit("},")
 
+    @mdis.dispatcher.Hook(Cache)
+    @contextlib.contextmanager
+    def dispatch_cache(self, node):
+        self.emit("/*")
+        self.emit(" * Autogenerated by libresoc codegen script")
+        self.emit(" * DO NOT EDIT: all changes will be lost")
+        self.emit(" */")
+        self.emit("")
+        self.emit("#include <stddef.h>")
+        self.emit("#include <stdint.h>")
+        self.emit("")
+        self.emit("#include \"opid.h\"")
+        self.emit("")
+        yield node
+
 
 class Record(Struct):
     static_operands: StaticOperands
@@ -249,23 +264,6 @@ class DisGenSource(Source):
             self.emit("")
             self.emit("return OPID_SUCCESS;")
         self.emit("}")
-        self.emit("")
-
-        self.emit("static inline enum opid_state")
-        self.emit("opid_disassemble_operands(struct opid_ctx *ctx, uint32_t insn) {")
-        with self:
-            self.emit(f"for (size_t id = 0; ((id != OPID_OPERANDS) && ctx->record->operands[id]); ++id) {{")
-            with self:
-                self.emit("enum opid_state state;")
-                self.emit("")
-                self.emit("state = opid_disassemble_operand(ctx, insn, id);")
-                self.emit("if (state != OPID_SUCCESS)")
-                with self:
-                    self.emit("return state;")
-            self.emit("}")
-            self.emit("")
-            self.emit("return OPID_SUCCESS;")
-        self.emit("}")
 
     @mdis.dispatcher.Hook(DynamicOperand)
     @contextlib.contextmanager
@@ -351,33 +349,6 @@ class DisGenSource(Source):
             self.emit("")
             yield node
 
-    @mdis.dispatcher.Hook(Cache)
-    @contextlib.contextmanager
-    def dispatch_cache(self, node):
-        self.emit("/*")
-        self.emit(" * Autogenerated by libresoc codegen script")
-        self.emit(" * DO NOT EDIT: all changes will be lost")
-        self.emit(" */")
-        self.emit("")
-        self.emit("#include <stdbool.h>")
-        self.emit("#include <stddef.h>")
-        self.emit("#include <stdint.h>")
-        self.emit("")
-        self.emit("#include \"opid.h\"")
-        self.emit("")
-        yield node
-        self.emit("enum opid_state")
-        self.emit("opid_disassemble(struct opid_ctx *ctx, uint32_t insn) {")
-        with self:
-            self.emit("ctx->record = opid_lookup_insn(insn);")
-            self.emit("")
-            self.emit("if (ctx->record == NULL)")
-            with self:
-                self.emit("return OPID_ERROR_LOOKUP;")
-            self.emit("")
-            self.emit("return opid_disassemble_operands(ctx, insn);")
-        self.emit("}")
-
 
 class OpcGenSource(Source):
     class Walker(Walker):
@@ -454,7 +425,6 @@ class OpcGenSource(Source):
                 tail = tails[index]
                 self.emit(f"[0x{index:02x}] = {{{head}, {tail}}},")
         self.emit("};")
-        self.emit("")
         yield node
 
     @mdis.dispatcher.Hook(Records)
@@ -465,43 +435,6 @@ class OpcGenSource(Source):
         self.emit("};")
         self.emit("")
 
-    @mdis.dispatcher.Hook(Cache)
-    @contextlib.contextmanager
-    def dispatch_cache(self, node):
-        self.emit("/*")
-        self.emit(" * Autogenerated by libresoc codegen script")
-        self.emit(" * DO NOT EDIT: all changes will be lost")
-        self.emit(" */")
-        self.emit("")
-        self.emit("#include <stddef.h>")
-        self.emit("#include <stdint.h>")
-        self.emit("")
-        self.emit("#include \"opid.h\"")
-        self.emit("")
-        yield node
-        self.emit("struct opid_record const *")
-        self.emit("opid_lookup_insn(uint32_t insn) {")
-        with self:
-            self.emit("uint32_t PO = (")
-            with self:
-                for line in fetch(range(6)):
-                    self.emit(line)
-            self.emit(");")
-            self.emit("struct opid_record const *iter = &opid_records[opid_opcode_hash[PO][0]];")
-            self.emit("struct opid_record const *tail = &opid_records[opid_opcode_hash[PO][1]];")
-            self.emit("")
-            self.emit("for (; iter != tail; ++iter) {")
-            with self:
-                self.emit("struct opid_opcode const *opcode = &iter->opcode;")
-                self.emit("")
-                self.emit("if ((opcode->value & opcode->mask) == (insn & opcode->mask))")
-                with self:
-                    self.emit("return iter;")
-            self.emit("}")
-            self.emit("")
-            self.emit("return NULL;")
-        self.emit("}")
-
 
 def main():
     table = {mode:{} for mode in Mode}
diff --git a/src/libopid/opid-dis.c b/src/libopid/opid-dis.c
new file mode 100644 (file)
index 0000000..c628eab
--- /dev/null
@@ -0,0 +1,29 @@
+#include <stddef.h>
+#include <stdint.h>
+
+#include "opid.h"
+
+#include "opid-dis-gen.c"
+
+static inline enum opid_state
+opid_disassemble_operands(struct opid_ctx *ctx, uint32_t insn) {
+    for (size_t id = 0; ((id != OPID_OPERANDS) && ctx->record->operands[id]); ++id) {
+        enum opid_state state;
+
+        state = opid_disassemble_operand(ctx, insn, id);
+        if (state != OPID_SUCCESS)
+            return state;
+    }
+
+    return OPID_SUCCESS;
+}
+
+enum opid_state
+opid_disassemble(struct opid_ctx *ctx, uint32_t insn) {
+    ctx->record = opid_lookup_insn(insn);
+
+    if (ctx->record == NULL)
+        return OPID_ERROR_LOOKUP;
+
+    return opid_disassemble_operands(ctx, insn);
+}
diff --git a/src/libopid/opid-opc.c b/src/libopid/opid-opc.c
new file mode 100644 (file)
index 0000000..2a387f7
--- /dev/null
@@ -0,0 +1,33 @@
+#include <stddef.h>
+#include <stdint.h>
+
+#include "opid.h"
+
+static struct opid_record const opid_records[];
+static uint16_t const opid_opcode_hash[64][2];
+
+#include "opid-opc-gen.c"
+
+struct opid_record const *
+opid_lookup_insn(uint32_t insn) {
+    uint32_t PO = (
+        /* 0  */ (((insn >> UINT32_C(31)) & UINT32_C(1)) << UINT32_C(5)) |
+        /* 1  */ (((insn >> UINT32_C(30)) & UINT32_C(1)) << UINT32_C(4)) |
+        /* 2  */ (((insn >> UINT32_C(29)) & UINT32_C(1)) << UINT32_C(3)) |
+        /* 3  */ (((insn >> UINT32_C(28)) & UINT32_C(1)) << UINT32_C(2)) |
+        /* 4  */ (((insn >> UINT32_C(27)) & UINT32_C(1)) << UINT32_C(1)) |
+        /* 5  */ (((insn >> UINT32_C(26)) & UINT32_C(1)) << UINT32_C(0)) |
+        UINT32_C(0)
+    );
+    struct opid_record const *iter = &opid_records[opid_opcode_hash[PO][0]];
+    struct opid_record const *tail = &opid_records[opid_opcode_hash[PO][1]];
+
+    for (; iter != tail; ++iter) {
+        struct opid_opcode const *opcode = &iter->opcode;
+
+        if ((opcode->value & opcode->mask) == (insn & opcode->mask))
+            return iter;
+    }
+
+    return NULL;
+}