/* -- dis.c */ #undef CGEN_PRINT_INSN #define CGEN_PRINT_INSN my_print_insn static int my_print_insn (pc, info, buf, buflen) bfd_vma pc; disassemble_info *info; char *buf; int buflen; { /* 32 bit insn? */ if ((pc & 3) == 0 && (buf[0] & 0x80) != 0) return print_insn (pc, info, buf, buflen); /* Print the first insn. */ if ((pc & 3) == 0) { if (print_insn (pc, info, buf, 16) == 0) (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); buf += 2; } if (buf[0] & 0x80) { /* Parallel. */ (*info->fprintf_func) (info->stream, " || "); buf[0] &= 0x7f; } else (*info->fprintf_func) (info->stream, " -> "); /* The "& 3" is to ensure the branch address is computed correctly [if it is a branch]. */ if (print_insn (pc & ~ (bfd_vma) 3, info, buf, 16) == 0) (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); return (pc & 3) ? 2 : 4; } /* -- */ /* Main entry point for operand extraction. This function is basically just a big switch statement. Earlier versions used tables to look up the function to use, but - if the table contains both assembler and disassembler functions then the disassembler contains much of the assembler and vice-versa, - there's a lot of inlining possibilities as things grow, - using a switch statement avoids the function call overhead. This function could be moved into `print_insn_normal', but keeping it separate makes clear the interface between `print_insn_normal' and each of the handlers. */ CGEN_INLINE int m32r_cgen_extract_operand (opindex, buf_ctrl, insn_value, fields) int opindex; void *buf_ctrl; cgen_insn_t insn_value; CGEN_FIELDS *fields; { int length; switch (opindex) { case M32R_OPERAND_SR : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_r2); break; case M32R_OPERAND_DR : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_r1); break; case M32R_OPERAND_SRC1 : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_r1); break; case M32R_OPERAND_SRC2 : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_r2); break; case M32R_OPERAND_SCR : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_r2); break; case M32R_OPERAND_DCR : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_r1); break; case M32R_OPERAND_SIMM8 : length = extract_normal (NULL /*FIXME*/, insn_value, 0, 8, 8, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_simm8); break; case M32R_OPERAND_SIMM16 : length = extract_normal (NULL /*FIXME*/, insn_value, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_simm16); break; case M32R_OPERAND_UIMM4 : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_uimm4); break; case M32R_OPERAND_UIMM5 : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_uimm5); break; case M32R_OPERAND_UIMM16 : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_uimm16); break; case M32R_OPERAND_ACC_S : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_acc_s); break; case M32R_OPERAND_ACC : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_acc); break; case M32R_OPERAND_HI16 : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_hi16); break; case M32R_OPERAND_SLO16 : length = extract_normal (NULL /*FIXME*/, insn_value, 0, 16, 16, 0, CGEN_FIELDS_BITSIZE (fields), &fields->f_simm16); break; case M32R_OPERAND_ULO16 : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_uimm16); break; case M32R_OPERAND_UIMM24 : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_uimm24); break; case M32R_OPERAND_DISP8 : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_disp8); break; case M32R_OPERAND_DISP16 : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_disp16); break; case M32R_OPERAND_DISP24 : length = extract_normal (NULL /*FIXME*/, insn_value, 0|(1<f_disp24); break; default : fprintf (stderr, "Unrecognized field %d while decoding insn.\n", opindex); abort (); } return length; } /* Main entry point for printing operands. This function is basically just a big switch statement. Earlier versions used tables to look up the function to use, but - if the table contains both assembler and disassembler functions then the disassembler contains much of the assembler and vice-versa, - there's a lot of inlining possibilities as things grow, - using a switch statement avoids the function call overhead. This function could be moved into `print_insn_normal', but keeping it separate makes clear the interface between `print_insn_normal' and each of the handlers. */ CGEN_INLINE void m32r_cgen_print_operand (opindex, info, fields, attrs, pc, length) int opindex; disassemble_info *info; CGEN_FIELDS *fields; void const * attrs; bfd_vma pc; int length; { switch (opindex) { case M32R_OPERAND_SR : print_keyword (info, & m32r_cgen_opval_h_gr, fields->f_r2, 0|(1<f_r1, 0|(1<f_r1, 0|(1<f_r2, 0|(1<f_r2, 0|(1<f_r1, 0|(1<f_simm8, 0, pc, length); break; case M32R_OPERAND_SIMM16 : print_normal (info, fields->f_simm16, 0, pc, length); break; case M32R_OPERAND_UIMM4 : print_normal (info, fields->f_uimm4, 0|(1<f_uimm5, 0|(1<f_uimm16, 0|(1<f_acc_s, 0|(1<f_acc, 0|(1<f_hi16, 0|(1<f_simm16, 0, pc, length); break; case M32R_OPERAND_ULO16 : print_normal (info, fields->f_uimm16, 0|(1<f_uimm24, 0|(1<f_disp8, 0|(1<f_disp16, 0|(1<f_disp24, 0|(1<