00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023 #include "sysdep.h"
00024 #include "dis-asm.h"
00025 #include "opcode/i370.h"
00026
00027
00028
00029
00030
00031 int
00032 print_insn_i370 (bfd_vma memaddr, struct disassemble_info *info)
00033 {
00034 bfd_byte buffer[8];
00035 int status;
00036 i370_insn_t insn;
00037 const struct i370_opcode *opcode;
00038 const struct i370_opcode *opcode_end;
00039
00040 status = (*info->read_memory_func) (memaddr, buffer, 6, info);
00041 if (status != 0)
00042 {
00043 (*info->memory_error_func) (status, memaddr, info);
00044 return -1;
00045 }
00046
00047
00048 insn.i[0] = (buffer[0] << 24) & 0xff000000;
00049 insn.i[0] |= (buffer[1] << 16) & 0xff0000;
00050 insn.i[0] |= (buffer[2] << 8) & 0xff00;
00051 insn.i[0] |= buffer[3] & 0xff;
00052 insn.i[1] = (buffer[4] << 24) & 0xff000000;
00053 insn.i[1] |= (buffer[5] << 16) & 0xff0000;
00054
00055
00056
00057 opcode_end = i370_opcodes + i370_num_opcodes;
00058 for (opcode = i370_opcodes; opcode < opcode_end; opcode++)
00059 {
00060 const unsigned char *opindex;
00061 const struct i370_operand *operand;
00062 i370_insn_t masked;
00063 int invalid;
00064
00065
00066 masked = insn;
00067 if (2 == opcode->len)
00068 {
00069 masked.i[0] >>= 16;
00070 masked.i[0] &= 0xffff;
00071 }
00072 masked.i[0] &= opcode->mask.i[0];
00073 if (masked.i[0] != opcode->opcode.i[0]) continue;
00074
00075 if (6 == opcode->len)
00076 {
00077 masked.i[1] &= opcode->mask.i[1];
00078 if (masked.i[1] != opcode->opcode.i[1]) continue;
00079 }
00080
00081
00082 if (2 == opcode->len)
00083 {
00084 insn.i[0] >>= 16;
00085 insn.i[0] &= 0xffff;
00086 }
00087
00088
00089
00090
00091 invalid = 0;
00092 for (opindex = opcode->operands; *opindex != 0; opindex++)
00093 {
00094 operand = i370_operands + *opindex;
00095 if (operand->extract)
00096 (*operand->extract) (insn, &invalid);
00097 }
00098 if (invalid) continue;
00099
00100
00101 (*info->fprintf_func) (info->stream, "%s", opcode->name);
00102 if (opcode->operands[0] != 0)
00103 (*info->fprintf_func) (info->stream, "\t");
00104
00105
00106 for (opindex = opcode->operands; *opindex != 0; opindex++)
00107 {
00108 long value;
00109
00110 operand = i370_operands + *opindex;
00111
00112
00113 if (operand->extract)
00114 value = (*operand->extract) (insn, (int *) NULL);
00115 else
00116 {
00117 value = (insn.i[0] >> operand->shift) & ((1 << operand->bits) - 1);
00118 }
00119
00120
00121 if ((operand->flags & I370_OPERAND_OPTIONAL) != 0)
00122 {
00123 if (value)
00124 (*info->fprintf_func) (info->stream, "(r%ld)", value);
00125 }
00126 else if ((operand->flags & I370_OPERAND_SBASE) != 0)
00127 {
00128 (*info->fprintf_func) (info->stream, "(r%ld)", value);
00129 }
00130 else if ((operand->flags & I370_OPERAND_INDEX) != 0)
00131 {
00132 if (value)
00133 (*info->fprintf_func) (info->stream, "(r%ld,", value);
00134 else
00135 (*info->fprintf_func) (info->stream, "(,");
00136 }
00137 else if ((operand->flags & I370_OPERAND_LENGTH) != 0)
00138 {
00139 (*info->fprintf_func) (info->stream, "(%ld,", value);
00140 }
00141 else if ((operand->flags & I370_OPERAND_BASE) != 0)
00142 (*info->fprintf_func) (info->stream, "r%ld)", value);
00143 else if ((operand->flags & I370_OPERAND_GPR) != 0)
00144 (*info->fprintf_func) (info->stream, "r%ld,", value);
00145 else if ((operand->flags & I370_OPERAND_FPR) != 0)
00146 (*info->fprintf_func) (info->stream, "f%ld,", value);
00147 else if ((operand->flags & I370_OPERAND_RELATIVE) != 0)
00148 (*info->fprintf_func) (info->stream, "%ld", value);
00149 else
00150 (*info->fprintf_func) (info->stream, " %ld, ", value);
00151
00152 }
00153
00154 return opcode->len;
00155
00156 }
00157
00158
00159
00160 (*info->fprintf_func) (info->stream, ".short 0x%02x%02x", buffer[0], buffer[1]);
00161
00162 return 2;
00163 }