From 23459a642c9feb99b7a9a970fda28aaa5b510d6f Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Sun, 10 Sep 2023 22:41:40 +0300 Subject: [PATCH] libopid: decouple static code --- src/libopid/.gitignore | 2 +- src/libopid/Makefile | 8 +++- src/libopid/codegen.py | 97 +++++++----------------------------------- src/libopid/opid-dis.c | 29 +++++++++++++ src/libopid/opid-opc.c | 33 ++++++++++++++ 5 files changed, 84 insertions(+), 85 deletions(-) create mode 100644 src/libopid/opid-dis.c create mode 100644 src/libopid/opid-opc.c diff --git a/src/libopid/.gitignore b/src/libopid/.gitignore index 5c09e306..4c881193 100644 --- a/src/libopid/.gitignore +++ b/src/libopid/.gitignore @@ -2,4 +2,4 @@ *.a *.so *.o -opid-dis +opid-check diff --git a/src/libopid/Makefile b/src/libopid/Makefile index fa566846..4ff00f26 100644 --- a/src/libopid/Makefile +++ b/src/libopid/Makefile @@ -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 diff --git a/src/libopid/codegen.py b/src/libopid/codegen.py index 349b2e57..525c2e8d 100644 --- a/src/libopid/codegen.py +++ b/src/libopid/codegen.py @@ -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 ") + self.emit("#include ") + 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 ") - self.emit("#include ") - self.emit("#include ") - 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 ") - self.emit("#include ") - 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 index 00000000..c628eabb --- /dev/null +++ b/src/libopid/opid-dis.c @@ -0,0 +1,29 @@ +#include +#include + +#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 index 00000000..2a387f72 --- /dev/null +++ b/src/libopid/opid-opc.c @@ -0,0 +1,33 @@ +#include +#include + +#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; +} -- 2.30.2