libopid: refactor operands disassembly
authorDmitry Selyutin <ghostmansd@gmail.com>
Mon, 11 Sep 2023 18:42:21 +0000 (21:42 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Wed, 13 Sep 2023 17:26:19 +0000 (20:26 +0300)
src/libopid/Makefile
src/libopid/codegen.py
src/libopid/opid-dis.c

index d7b5768a9dedee992d7bba90556b0439cd5e8df3..b18611bcc729525a667f584ad774762a29ec45f5 100644 (file)
@@ -1,7 +1,7 @@
 CC?=gcc
 AR?=ar
 CPPFLAGS?=-I.
-CFLAGS?=-O3 -Werror -Wall -Wextra
+CFLAGS?=-O0 -g -Werror -Wall -Wextra
 PYTHON?=python3
 
 
index 2712e51b77e591b588d678e95cab196116d0414f..7f30bb52a8817ac19dba38ce2096681cf08bf370 100644 (file)
@@ -246,22 +246,20 @@ class DisGenSource(Source):
     @contextlib.contextmanager
     def dispatch_operands(self, node):
         self.emit("static inline enum opid_state")
-        self.emit("opid_disassemble_operand(struct opid_ctx *ctx, uint32_t insn, size_t id) {")
+        self.emit("opid_disassemble_operand(uint32_t insn,")
         with self:
-            self.emit("uint32_t value;")
-            self.emit("uint32_t flags;")
-            self.emit("")
-            self.emit(f"switch (ctx->record->operands[id]) {{")
+            with self:
+                self.emit("size_t category,")
+                self.emit("struct opid_operand *operand) {")
+        with self:
+            self.emit(f"switch (category) {{")
             yield node
             self.emit("default:")
             with self:
-                self.emit("return (enum opid_state)((size_t)OPID_ERROR_OPERAND_0 + id);")
+                self.emit("return OPID_ERROR_OPERAND_0;")
             self.emit("}")
         self.emit("")
         with self:
-            self.emit("ctx->operands[id].value = value;")
-            self.emit("ctx->operands[id].flags = flags;")
-            self.emit("")
             self.emit("return OPID_SUCCESS;")
         self.emit("}")
 
@@ -269,24 +267,24 @@ class DisGenSource(Source):
     @contextlib.contextmanager
     def dispatch_operand(self, node, *, path, pathcls):
         def generic_handler(span, flags="UINT32_C(0)"):
-            yield f"value = ("
+            yield f"operand->value = ("
             with self:
                 yield from fetch(span)
             yield f");"
-            yield f"flags = {flags};"
+            yield f"operand->flags = {flags};"
             self.emit("break;")
 
         def nonzero_handler(span):
-            yield f"value = (UINT32_C(1) + ("
+            yield f"operand->value = (UINT32_C(1) + ("
             with self:
                 yield from fetch(span)
             yield f"));"
-            yield f"flags = OPID_OPERAND_NONZERO;"
+            yield f"operand->flags = OPID_OPERAND_NONZERO;"
             self.emit("break;")
 
         def signed_handler(span, flags="OPID_OPERAND_SIGNED"):
             mask = f"(UINT32_C(1) << (UINT32_C({len(span)}) - 1))"
-            yield "value = ("
+            yield "operand->value = ("
             with self:
                 yield "("
                 with self:
@@ -300,7 +298,7 @@ class DisGenSource(Source):
                 yield "-"
                 yield f"{mask}"
             yield ");"
-            yield f"flags = {flags};"
+            yield f"operand->flags = {flags};"
             self.emit("break;")
 
         def address_handler(span):
index c628eabbed0cc837ba51e5cb53e2c97d6574fff2..81f1d9eab71cdbe784ee17da411ec0194ea36595 100644 (file)
@@ -3,6 +3,11 @@
 
 #include "opid.h"
 
+static inline enum opid_state
+opid_disassemble_operand(uint32_t insn,
+        size_t category,
+        struct opid_operand *operand);
+
 #include "opid-dis-gen.c"
 
 static inline enum opid_state
@@ -10,9 +15,14 @@ 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)
+        state = opid_disassemble_operand(insn,
+            ctx->record->operands[id],
+            &ctx->operands[id]);
+        if (state != OPID_SUCCESS) {
+            if (state == OPID_ERROR_OPERAND_0)
+                state = (enum opid_state)((size_t)state + id);
             return state;
+        }
     }
 
     return OPID_SUCCESS;