2 * Copyright (C) 2006-2010 Michael Buesch <mb@bu3sch.de>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
25 struct bin_instruction {
27 unsigned int operands[3];
38 struct bin_instruction *bin;
40 const char *operands[5];
43 unsigned int labeladdr;
44 struct statement *labelref;
51 struct list_head list;
54 struct disassembler_context {
55 /* The architecture of the input file. */
58 struct bin_instruction *code;
61 struct list_head stmt_list;
67 const char *infile_name;
68 const char *outfile_name;
71 static const char * gen_raw_code(unsigned int operand)
76 snprintf(ret, 6, "@%X", operand);
81 static const char * disasm_mem_operand(unsigned int operand)
86 snprintf(ret, 9, "[0x%X]", operand);
91 static const char * disasm_indirect_mem_operand(unsigned int operand)
94 unsigned int offset, reg;
96 switch (cmdargs.arch) {
98 offset = (operand & 0x3F);
99 reg = ((operand >> 6) & 0x7);
102 offset = (operand & 0x7F);
103 reg = ((operand >> 7) & 0x7);
106 fprintf(stderr, "Internal error: disasm_indirect_mem_operand invalid arch\n");
110 snprintf(ret, 12, "[0x%02X,off%u]", offset, reg);
115 static const char * disasm_imm_operand(unsigned int operand)
118 unsigned int signmask;
121 switch (cmdargs.arch) {
127 signmask = (1 << 10);
131 fprintf(stderr, "Internal error: disasm_imm_operand invalid arch\n");
138 if (operand & signmask)
139 operand = (operand | (~mask & 0xFFFF));
140 snprintf(ret, 7, "0x%X", operand);
145 static const char * disasm_spr_operand(unsigned int operand)
150 switch (cmdargs.arch) {
158 fprintf(stderr, "Internal error: disasm_spr_operand invalid arch\n");
163 snprintf(ret, 8, "spr%X", (operand & mask));
168 static const char * disasm_gpr_operand(unsigned int operand)
173 switch (cmdargs.arch) {
181 fprintf(stderr, "Internal error: disasm_gpr_operand invalid arch\n");
186 snprintf(ret, 5, "r%u", (operand & mask));
191 static void disasm_std_operand(struct statement *stmt,
196 unsigned int operand = stmt->u.insn.bin->operands[oper_idx];
201 switch (cmdargs.arch) {
203 if (!(operand & 0x800)) {
204 stmt->u.insn.operands[out_idx] = disasm_mem_operand(operand);
206 } else if ((operand & 0xC00) == 0xC00) {
207 stmt->u.insn.operands[out_idx] = disasm_imm_operand(operand);
209 } else if ((operand & 0xFC0) == 0xBC0) {
210 stmt->u.insn.operands[out_idx] = disasm_gpr_operand(operand);
212 } else if ((operand & 0xE00) == 0x800) {
213 stmt->u.insn.operands[out_idx] = disasm_spr_operand(operand);
215 } else if ((operand & 0xE00) == 0xA00) {
216 stmt->u.insn.operands[out_idx] = disasm_indirect_mem_operand(operand);
221 if (!(operand & 0x1000)) {
222 stmt->u.insn.operands[out_idx] = disasm_mem_operand(operand);
224 } else if ((operand & 0x1800) == 0x1800) {
225 stmt->u.insn.operands[out_idx] = disasm_imm_operand(operand);
227 } else if ((operand & 0x1F80) == 0x1780) {
228 stmt->u.insn.operands[out_idx] = disasm_gpr_operand(operand);
230 } else if ((operand & 0x1C00) == 0x1000) {
231 stmt->u.insn.operands[out_idx] = disasm_spr_operand(operand);
233 } else if ((operand & 0x1C00) == 0x1400) {
234 stmt->u.insn.operands[out_idx] = disasm_indirect_mem_operand(operand);
239 fprintf(stderr, "Internal error: disasm_std_operand invalid arch\n");
243 stmt->u.insn.operands[out_idx] = gen_raw_code(operand);
246 static void disasm_opcode_raw(struct disassembler_context *ctx,
247 struct statement *stmt)
249 stmt->u.insn.name = gen_raw_code(stmt->u.insn.bin->opcode);
250 disasm_std_operand(stmt, 0, 0, 1);
251 disasm_std_operand(stmt, 1, 1, 1);
252 disasm_std_operand(stmt, 2, 2, 1);
255 static void disasm_constant_opcodes(struct disassembler_context *ctx,
256 struct statement *stmt)
258 struct bin_instruction *bin = stmt->u.insn.bin;
260 switch (bin->opcode) {
262 stmt->u.insn.name = "add";
263 disasm_std_operand(stmt, 0, 0, 0);
264 disasm_std_operand(stmt, 1, 1, 0);
265 disasm_std_operand(stmt, 2, 2, 0);
268 stmt->u.insn.name = "add.";
269 disasm_std_operand(stmt, 0, 0, 0);
270 disasm_std_operand(stmt, 1, 1, 0);
271 disasm_std_operand(stmt, 2, 2, 0);
274 stmt->u.insn.name = "addc";
275 disasm_std_operand(stmt, 0, 0, 0);
276 disasm_std_operand(stmt, 1, 1, 0);
277 disasm_std_operand(stmt, 2, 2, 0);
280 stmt->u.insn.name = "addc.";
281 disasm_std_operand(stmt, 0, 0, 0);
282 disasm_std_operand(stmt, 1, 1, 0);
283 disasm_std_operand(stmt, 2, 2, 0);
286 stmt->u.insn.name = "sub";
287 disasm_std_operand(stmt, 0, 0, 0);
288 disasm_std_operand(stmt, 1, 1, 0);
289 disasm_std_operand(stmt, 2, 2, 0);
292 stmt->u.insn.name = "sub.";
293 disasm_std_operand(stmt, 0, 0, 0);
294 disasm_std_operand(stmt, 1, 1, 0);
295 disasm_std_operand(stmt, 2, 2, 0);
298 stmt->u.insn.name = "subc";
299 disasm_std_operand(stmt, 0, 0, 0);
300 disasm_std_operand(stmt, 1, 1, 0);
301 disasm_std_operand(stmt, 2, 2, 0);
304 stmt->u.insn.name = "subc.";
305 disasm_std_operand(stmt, 0, 0, 0);
306 disasm_std_operand(stmt, 1, 1, 0);
307 disasm_std_operand(stmt, 2, 2, 0);
310 stmt->u.insn.name = "sra";
311 disasm_std_operand(stmt, 0, 0, 0);
312 disasm_std_operand(stmt, 1, 1, 0);
313 disasm_std_operand(stmt, 2, 2, 0);
316 stmt->u.insn.name = "or";
317 disasm_std_operand(stmt, 0, 0, 0);
318 disasm_std_operand(stmt, 1, 1, 0);
319 disasm_std_operand(stmt, 2, 2, 0);
322 stmt->u.insn.name = "and";
323 disasm_std_operand(stmt, 0, 0, 0);
324 disasm_std_operand(stmt, 1, 1, 0);
325 disasm_std_operand(stmt, 2, 2, 0);
328 stmt->u.insn.name = "xor";
329 disasm_std_operand(stmt, 0, 0, 0);
330 disasm_std_operand(stmt, 1, 1, 0);
331 disasm_std_operand(stmt, 2, 2, 0);
334 stmt->u.insn.name = "sr";
335 disasm_std_operand(stmt, 0, 0, 0);
336 disasm_std_operand(stmt, 1, 1, 0);
337 disasm_std_operand(stmt, 2, 2, 0);
340 stmt->u.insn.name = "sl";
341 disasm_std_operand(stmt, 0, 0, 0);
342 disasm_std_operand(stmt, 1, 1, 0);
343 disasm_std_operand(stmt, 2, 2, 0);
346 stmt->u.insn.name = "rl";
347 disasm_std_operand(stmt, 0, 0, 0);
348 disasm_std_operand(stmt, 1, 1, 0);
349 disasm_std_operand(stmt, 2, 2, 0);
352 stmt->u.insn.name = "rr";
353 disasm_std_operand(stmt, 0, 0, 0);
354 disasm_std_operand(stmt, 1, 1, 0);
355 disasm_std_operand(stmt, 2, 2, 0);
358 stmt->u.insn.name = "nand";
359 disasm_std_operand(stmt, 0, 0, 0);
360 disasm_std_operand(stmt, 1, 1, 0);
361 disasm_std_operand(stmt, 2, 2, 0);
364 stmt->u.insn.name = "jand";
365 stmt->u.insn.is_labelref = 2;
366 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
367 disasm_std_operand(stmt, 0, 0, 0);
368 disasm_std_operand(stmt, 1, 1, 0);
371 stmt->u.insn.name = "jnand";
372 stmt->u.insn.is_labelref = 2;
373 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
374 disasm_std_operand(stmt, 0, 0, 0);
375 disasm_std_operand(stmt, 1, 1, 0);
378 stmt->u.insn.name = "js";
379 stmt->u.insn.is_labelref = 2;
380 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
381 disasm_std_operand(stmt, 0, 0, 0);
382 disasm_std_operand(stmt, 1, 1, 0);
385 stmt->u.insn.name = "jns";
386 stmt->u.insn.is_labelref = 2;
387 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
388 disasm_std_operand(stmt, 0, 0, 0);
389 disasm_std_operand(stmt, 1, 1, 0);
392 stmt->u.insn.name = "je";
393 stmt->u.insn.is_labelref = 2;
394 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
395 disasm_std_operand(stmt, 0, 0, 0);
396 disasm_std_operand(stmt, 1, 1, 0);
399 stmt->u.insn.name = "jne";
400 stmt->u.insn.is_labelref = 2;
401 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
402 disasm_std_operand(stmt, 0, 0, 0);
403 disasm_std_operand(stmt, 1, 1, 0);
406 stmt->u.insn.name = "jls";
407 stmt->u.insn.is_labelref = 2;
408 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
409 disasm_std_operand(stmt, 0, 0, 0);
410 disasm_std_operand(stmt, 1, 1, 0);
413 stmt->u.insn.name = "jges";
414 stmt->u.insn.is_labelref = 2;
415 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
416 disasm_std_operand(stmt, 0, 0, 0);
417 disasm_std_operand(stmt, 1, 1, 0);
420 stmt->u.insn.name = "jgs";
421 stmt->u.insn.is_labelref = 2;
422 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
423 disasm_std_operand(stmt, 0, 0, 0);
424 disasm_std_operand(stmt, 1, 1, 0);
427 stmt->u.insn.name = "jles";
428 stmt->u.insn.is_labelref = 2;
429 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
430 disasm_std_operand(stmt, 0, 0, 0);
431 disasm_std_operand(stmt, 1, 1, 0);
434 stmt->u.insn.name = "jl";
435 stmt->u.insn.is_labelref = 2;
436 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
437 disasm_std_operand(stmt, 0, 0, 0);
438 disasm_std_operand(stmt, 1, 1, 0);
441 stmt->u.insn.name = "jge";
442 stmt->u.insn.is_labelref = 2;
443 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
444 disasm_std_operand(stmt, 0, 0, 0);
445 disasm_std_operand(stmt, 1, 1, 0);
448 stmt->u.insn.name = "jg";
449 stmt->u.insn.is_labelref = 2;
450 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
451 disasm_std_operand(stmt, 0, 0, 0);
452 disasm_std_operand(stmt, 1, 1, 0);
455 stmt->u.insn.name = "jle";
456 stmt->u.insn.is_labelref = 2;
457 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
458 disasm_std_operand(stmt, 0, 0, 0);
459 disasm_std_operand(stmt, 1, 1, 0);
464 switch (cmdargs.arch) {
466 stmt->u.insn.name = "call";
467 stmt->u.insn.is_labelref = 1;
468 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
470 snprintf(str, 4, "lr%u", stmt->u.insn.bin->operands[0]);
471 stmt->u.insn.operands[0] = str;
474 //FIXME: This opcode is different on r15. Decode raw for now.
475 disasm_opcode_raw(ctx, stmt);
483 stmt->u.insn.name = "ret";
485 snprintf(str, 4, "lr%u", stmt->u.insn.bin->operands[0]);
486 stmt->u.insn.operands[0] = str;
488 snprintf(str, 4, "lr%u", stmt->u.insn.bin->operands[2]);
489 stmt->u.insn.operands[2] = str;
492 //TODO also implement it in the assembler
495 if (cmdargs.arch != 15) {
496 fprintf(stderr, "Error: arch 15 call instruction found in arch %d binary\n",
500 stmt->u.insn.name = "call";
501 stmt->u.insn.is_labelref = 0;
502 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
503 if (stmt->u.insn.bin->operands[0] != 0x1780 ||
504 stmt->u.insn.bin->operands[1] != 0x1780) {
505 fprintf(stderr, "r15 call: Invalid first or second argument\n");
510 if (cmdargs.arch != 15) {
511 fprintf(stderr, "Error: arch 15 ret instruction found in arch %d binary\n",
515 stmt->u.insn.name = "ret";
520 unsigned int flags, mask;
522 switch (cmdargs.arch) {
530 fprintf(stderr, "Internal error: TKIP invalid arch\n");
534 flags = stmt->u.insn.bin->operands[1];
535 switch (flags & mask) {
537 stmt->u.insn.name = "tkiph";
540 stmt->u.insn.name = "tkiphs";
543 stmt->u.insn.name = "tkipl";
546 stmt->u.insn.name = "tkipls";
549 fprintf(stderr, "Invalid TKIP flags %X\n",
553 disasm_std_operand(stmt, 0, 0, 0);
554 disasm_std_operand(stmt, 2, 2, 0);
560 stmt->u.insn.name = "nap";
561 switch (cmdargs.arch) {
569 fprintf(stderr, "Internal error: NAP invalid arch\n");
572 if (stmt->u.insn.bin->operands[0] != mask) {
573 fprintf(stderr, "NAP: invalid first argument 0x%04X\n",
574 stmt->u.insn.bin->operands[0]);
576 if (stmt->u.insn.bin->operands[1] != mask) {
577 fprintf(stderr, "NAP: invalid second argument 0x%04X\n",
578 stmt->u.insn.bin->operands[1]);
580 if (stmt->u.insn.bin->operands[2] != 0) {
581 fprintf(stderr, "NAP: invalid third argument 0x%04X\n",
582 stmt->u.insn.bin->operands[2]);
587 disasm_opcode_raw(ctx, stmt);
592 static void disasm_opcodes(struct disassembler_context *ctx)
594 struct bin_instruction *bin;
596 struct statement *stmt;
599 for (i = 0; i < ctx->nr_insns; i++) {
600 bin = &(ctx->code[i]);
602 stmt = xmalloc(sizeof(struct statement));
603 stmt->type = STMT_INSN;
604 INIT_LIST_HEAD(&stmt->list);
605 stmt->u.insn.bin = bin;
606 stmt->u.insn.is_labelref = -1;
608 switch (bin->opcode & 0xF00) {
610 stmt->u.insn.name = "srx";
613 snprintf(str, 3, "%d", (bin->opcode & 0x0F0) >> 4);
614 stmt->u.insn.operands[0] = str;
616 snprintf(str, 3, "%d", (bin->opcode & 0x00F));
617 stmt->u.insn.operands[1] = str;
619 disasm_std_operand(stmt, 0, 2, 0);
620 disasm_std_operand(stmt, 1, 3, 0);
621 disasm_std_operand(stmt, 2, 4, 0);
624 stmt->u.insn.name = "orx";
627 snprintf(str, 3, "%d", (bin->opcode & 0x0F0) >> 4);
628 stmt->u.insn.operands[0] = str;
630 snprintf(str, 3, "%d", (bin->opcode & 0x00F));
631 stmt->u.insn.operands[1] = str;
633 disasm_std_operand(stmt, 0, 2, 0);
634 disasm_std_operand(stmt, 1, 3, 0);
635 disasm_std_operand(stmt, 2, 4, 0);
638 stmt->u.insn.name = "jzx";
641 snprintf(str, 3, "%d", (bin->opcode & 0x0F0) >> 4);
642 stmt->u.insn.operands[0] = str;
644 snprintf(str, 3, "%d", (bin->opcode & 0x00F));
645 stmt->u.insn.operands[1] = str;
647 disasm_std_operand(stmt, 0, 2, 0);
648 disasm_std_operand(stmt, 1, 3, 0);
649 stmt->u.insn.is_labelref = 4;
650 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
653 stmt->u.insn.name = "jnzx";
656 snprintf(str, 3, "%d", (bin->opcode & 0x0F0) >> 4);
657 stmt->u.insn.operands[0] = str;
659 snprintf(str, 3, "%d", (bin->opcode & 0x00F));
660 stmt->u.insn.operands[1] = str;
662 disasm_std_operand(stmt, 0, 2, 0);
663 disasm_std_operand(stmt, 1, 3, 0);
664 stmt->u.insn.is_labelref = 4;
665 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
668 stmt->u.insn.name = "jnext";
671 snprintf(str, 5, "0x%02X", (bin->opcode & 0x0FF));
672 stmt->u.insn.operands[0] = str;
674 /* We don't disassemble the first and second operand, as
675 * that always is a dummy r0 operand.
676 * disasm_std_operand(stmt, 0, 1, 0);
677 * disasm_std_operand(stmt, 1, 2, 0);
678 * stmt->u.insn.is_labelref = 3;
680 stmt->u.insn.is_labelref = 1;
681 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
684 stmt->u.insn.name = "jext";
687 snprintf(str, 5, "0x%02X", (bin->opcode & 0x0FF));
688 stmt->u.insn.operands[0] = str;
690 /* We don't disassemble the first and second operand, as
691 * that always is a dummy r0 operand.
692 * disasm_std_operand(stmt, 0, 1, 0);
693 * disasm_std_operand(stmt, 1, 2, 0);
694 * stmt->u.insn.is_labelref = 3;
696 stmt->u.insn.is_labelref = 1;
697 stmt->u.insn.labeladdr = stmt->u.insn.bin->operands[2];
700 disasm_constant_opcodes(ctx, stmt);
704 list_add_tail(&stmt->list, &ctx->stmt_list);
708 static struct statement * get_label_at(struct disassembler_context *ctx,
711 unsigned int addrcnt = 0;
712 struct statement *stmt, *ret, *prev;
714 list_for_each_entry(stmt, &ctx->stmt_list, list) {
715 if (stmt->type != STMT_INSN)
717 if (addrcnt == addr) {
718 prev = list_entry(stmt->list.prev, struct statement, list);
719 if (prev->type == STMT_LABEL)
721 ret = xmalloc(sizeof(struct statement));
722 INIT_LIST_HEAD(&ret->list);
723 ret->type = STMT_LABEL;
724 list_add(&ret->list, &prev->list);
734 static void resolve_labels(struct disassembler_context *ctx)
736 struct statement *stmt;
737 struct statement *label;
739 unsigned int labeladdr;
740 unsigned int namecnt = 0;
742 /* Resolve label references */
743 list_for_each_entry_safe(stmt, n, &ctx->stmt_list, list) {
744 if (stmt->type != STMT_INSN)
746 if (stmt->u.insn.is_labelref == -1)
748 labeladdr = stmt->u.insn.labeladdr;
749 label = get_label_at(ctx, labeladdr);
751 fprintf(stderr, "Labeladdress %X out of bounds\n",
755 stmt->u.insn.labelref = label;
758 /* Name the labels */
759 list_for_each_entry(stmt, &ctx->stmt_list, list) {
760 if (stmt->type != STMT_LABEL)
762 stmt->u.label.name = xmalloc(20);
763 snprintf(stmt->u.label.name, 20, "L%u", namecnt);
768 static void emit_asm(struct disassembler_context *ctx)
770 struct statement *stmt;
773 unsigned int addr = 0;
775 err = open_output_file();
779 fprintf(outfile, "%%arch %u\n", ctx->arch);
780 fprintf(outfile, "%%start entry\n\n");
781 fprintf(outfile, "entry:\n");
782 list_for_each_entry(stmt, &ctx->stmt_list, list) {
783 switch (stmt->type) {
785 if (cmdargs.print_addresses)
786 fprintf(outfile, "/* %03X */", addr);
787 fprintf(outfile, "\t%s", stmt->u.insn.name);
789 for (i = 0; i < ARRAY_SIZE(stmt->u.insn.operands); i++) {
790 if (!stmt->u.insn.operands[i] &&
791 stmt->u.insn.is_labelref != i)
794 fprintf(outfile, "\t");
796 fprintf(outfile, ", ");
798 if (stmt->u.insn.is_labelref == i) {
799 fprintf(outfile, "%s",
800 stmt->u.insn.labelref->u.label.name);
802 fprintf(outfile, "%s",
803 stmt->u.insn.operands[i]);
806 fprintf(outfile, "\n");
810 fprintf(outfile, "%s:\n", stmt->u.label.name);
818 static int read_input(struct disassembler_context *ctx)
820 size_t size = 0, pos = 0;
822 struct bin_instruction *code = NULL;
823 unsigned char tmp[sizeof(uint64_t)];
825 struct fw_header hdr;
828 err = open_input_file();
832 switch (cmdargs.informat) {
838 ret = fread(&hdr, 1, sizeof(hdr), infile);
839 if (ret != sizeof(hdr)) {
840 fprintf(stderr, "Corrupt input file (not fwcutter output)\n");
843 if (hdr.type != FW_TYPE_UCODE) {
844 fprintf(stderr, "Corrupt input file. Not a microcode image.\n");
847 if (hdr.ver != FW_HDR_VER) {
848 fprintf(stderr, "Invalid input file header version.\n");
857 code = xrealloc(code, size * sizeof(struct bin_instruction));
859 ret = fread(tmp, 1, sizeof(uint64_t), infile);
862 if (ret != sizeof(uint64_t)) {
863 fprintf(stderr, "Corrupt input file (not 8 byte aligned)\n");
867 switch (cmdargs.informat) {
871 codeword |= ((uint64_t)tmp[0]) << 56;
872 codeword |= ((uint64_t)tmp[1]) << 48;
873 codeword |= ((uint64_t)tmp[2]) << 40;
874 codeword |= ((uint64_t)tmp[3]) << 32;
875 codeword |= ((uint64_t)tmp[4]) << 24;
876 codeword |= ((uint64_t)tmp[5]) << 16;
877 codeword |= ((uint64_t)tmp[6]) << 8;
878 codeword |= ((uint64_t)tmp[7]);
879 codeword = ((codeword & (uint64_t)0xFFFFFFFF00000000ULL) >> 32) |
880 ((codeword & (uint64_t)0x00000000FFFFFFFFULL) << 32);
884 codeword |= ((uint64_t)tmp[7]) << 56;
885 codeword |= ((uint64_t)tmp[6]) << 48;
886 codeword |= ((uint64_t)tmp[5]) << 40;
887 codeword |= ((uint64_t)tmp[4]) << 32;
888 codeword |= ((uint64_t)tmp[3]) << 24;
889 codeword |= ((uint64_t)tmp[2]) << 16;
890 codeword |= ((uint64_t)tmp[1]) << 8;
891 codeword |= ((uint64_t)tmp[0]);
895 switch (cmdargs.arch) {
897 if (codeword >> 48) {
898 fprintf(stderr, "Instruction format error at 0x%X (upper not clear). "
899 "Wrong input format or architecture?\n", (unsigned int)pos);
902 code[pos].opcode = (codeword >> 36) & 0xFFF;
903 code[pos].operands[2] = codeword & 0xFFF;
904 code[pos].operands[1] = (codeword >> 12) & 0xFFF;
905 code[pos].operands[0] = (codeword >> 24) & 0xFFF;
908 if (codeword >> 51) {
909 fprintf(stderr, "Instruction format error at 0x%X (upper not clear). "
910 "Wrong input format or architecture?\n", (unsigned int)pos);
913 code[pos].opcode = (codeword >> 39) & 0xFFF;
914 code[pos].operands[2] = codeword & 0x1FFF;
915 code[pos].operands[1] = (codeword >> 13) & 0x1FFF;
916 code[pos].operands[0] = (codeword >> 26) & 0x1FFF;
919 fprintf(stderr, "Internal error: read_input unknown arch %u\n",
942 static void disassemble(void)
944 struct disassembler_context ctx;
947 memset(&ctx, 0, sizeof(ctx));
948 INIT_LIST_HEAD(&ctx.stmt_list);
949 ctx.arch = cmdargs.arch;
951 err = read_input(&ctx);
954 disasm_opcodes(&ctx);
955 resolve_labels(&ctx);
959 int main(int argc, char **argv)
963 err = parse_args(argc, argv);
973 /* Lazyman simply leaks all allocated memory. */