@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("}")
@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:
yield "-"
yield f"{mask}"
yield ");"
- yield f"flags = {flags};"
+ yield f"operand->flags = {flags};"
self.emit("break;")
def address_handler(span):
#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
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;