static PyObject *build_insn(m68k_insn_t *insn, Py_ssize_t sz) { PyObject *pyinsn, *operands, *op; int i; if (insn->opcode == M68K_OP_INVALID) Py_RETURN_NONE; if (!(operands = PyList_New(insn->opcount))) return NULL; for (i=0; i<insn->opcount; i++) { if (!(op = build_operand(insn->op + i))) { Py_XDECREF(operands); return NULL; } if (PyList_SetItem(operands, i, op) < 0) { Py_XDECREF(operands); return NULL; } } if (!(op = build_opcode(insn))) { Py_XDECREF(operands); return NULL; } pyinsn = Py_BuildValue("(OsOi)", op, sz_to_str(insn), operands, sz); Py_XDECREF(op); Py_XDECREF(operands); return pyinsn; }
unsigned long itbl_assemble (char *name, char *s) { unsigned long opcode; struct itbl_entry *e = NULL; struct itbl_field *f; char *n; int processor; if (!name || !*name) return 0; /* error! must have an opcode name/expr */ /* find entry in list of instructions for all processors */ for (processor = 0; processor < e_nprocs; processor++) { e = find_entry_byname (processor, e_insn, name); if (e) break; } if (!e) return 0; /* opcode not in table; invalid instruction */ opcode = build_opcode (e); /* parse opcode's args (if any) */ for (f = e->fields; f; f = f->next) /* for each arg, ... */ { struct itbl_entry *r; unsigned long value; if (!s || !*s) return 0; /* error - not enough operands */ n = itbl_get_field (&s); /* n should be in form $n or 0xhhh (are symbol names valid?? */ switch (f->type) { case e_dreg: case e_creg: case e_greg: /* Accept either a string name * or '$' followed by the register number */ if (*n == '$') { n++; value = strtol (n, 0, 10); /* FIXME! could have "0l"... then what?? */ if (value == 0 && *n != '0') return 0; /* error; invalid operand */ } else { r = find_entry_byname (e->processor, f->type, n); if (r) value = r->value; else return 0; /* error; invalid operand */ } break; case e_addr: /* use assembler's symbol table to find symbol */ /* FIXME!! Do we need this? if so, what about relocs?? my_getExpression (&imm_expr, s); return 0; /-* error; invalid operand *-/ break; */ /* If not a symbol, fall thru to IMMED */ case e_immed: if (*n == '0' && *(n + 1) == 'x') /* hex begins 0x... */ { n += 2; value = strtol (n, 0, 16); /* FIXME! could have "0xl"... then what?? */ } else { value = strtol (n, 0, 10); /* FIXME! could have "0l"... then what?? */ if (value == 0 && *n != '0') return 0; /* error; invalid operand */ } break; default: return 0; /* error; invalid field spec */ } opcode |= apply_range (value, f->range); } if (s && *s) return 0; /* error - too many operands */ return opcode; /* done! */ }