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
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
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):
tail = tails[index]
self.emit(f"[0x{index:02x}] = {{{head}, {tail}}},")
self.emit("};")
- self.emit("")
yield node
@mdis.dispatcher.Hook(Records)
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}
--- /dev/null
+#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);
+}
--- /dev/null
+#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;
+}