00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <stdio.h>
00029 #include "sysdep.h"
00030 #include "dis-asm.h"
00031 #include "opcode/alpha.h"
00032
00033
00034
00035 static const char * const osf_regnames[64] = {
00036 "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
00037 "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp",
00038 "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9",
00039 "t10", "t11", "ra", "t12", "at", "gp", "sp", "zero",
00040 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
00041 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
00042 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
00043 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
00044 };
00045
00046
00047
00048 static const char * const vms_regnames[64] = {
00049 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
00050 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
00051 "R16", "R17", "R18", "R19", "R20", "R21", "R22", "R23",
00052 "R24", "AI", "RA", "PV", "AT", "FP", "SP", "RZ",
00053 "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7",
00054 "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15",
00055 "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23",
00056 "F24", "F25", "F26", "F27", "F28", "F29", "F30", "FZ"
00057 };
00058
00059
00060
00061 int
00062 print_insn_alpha (memaddr, info)
00063 bfd_vma memaddr;
00064 struct disassemble_info *info;
00065 {
00066 static const struct alpha_opcode *opcode_index[AXP_NOPS+1];
00067 const char * const * regnames;
00068 const struct alpha_opcode *opcode, *opcode_end;
00069 const unsigned char *opindex;
00070 unsigned insn, op, isa_mask;
00071 int need_comma;
00072
00073
00074 if (!opcode_index[0])
00075 {
00076 opcode = alpha_opcodes;
00077 opcode_end = opcode + alpha_num_opcodes;
00078
00079 for (op = 0; op < AXP_NOPS; ++op)
00080 {
00081 opcode_index[op] = opcode;
00082 while (opcode < opcode_end && op == AXP_OP (opcode->opcode))
00083 ++opcode;
00084 }
00085 opcode_index[op] = opcode;
00086 }
00087
00088 if (info->flavour == bfd_target_evax_flavour)
00089 regnames = vms_regnames;
00090 else
00091 regnames = osf_regnames;
00092
00093 isa_mask = AXP_OPCODE_NOPAL;
00094 switch (info->mach)
00095 {
00096 case bfd_mach_alpha_ev4:
00097 isa_mask |= AXP_OPCODE_EV4;
00098 break;
00099 case bfd_mach_alpha_ev5:
00100 isa_mask |= AXP_OPCODE_EV5;
00101 break;
00102 case bfd_mach_alpha_ev6:
00103 isa_mask |= AXP_OPCODE_EV6;
00104 break;
00105 }
00106
00107
00108 {
00109 bfd_byte buffer[4];
00110 int status = (*info->read_memory_func) (memaddr, buffer, 4, info);
00111 if (status != 0)
00112 {
00113 (*info->memory_error_func) (status, memaddr, info);
00114 return -1;
00115 }
00116 insn = bfd_getl32 (buffer);
00117 }
00118
00119
00120 op = AXP_OP (insn);
00121
00122
00123 opcode_end = opcode_index[op + 1];
00124 for (opcode = opcode_index[op]; opcode < opcode_end; ++opcode)
00125 {
00126 if ((insn ^ opcode->opcode) & opcode->mask)
00127 continue;
00128
00129 if (!(opcode->flags & isa_mask))
00130 continue;
00131
00132
00133
00134
00135 {
00136 int invalid = 0;
00137 for (opindex = opcode->operands; *opindex != 0; opindex++)
00138 {
00139 const struct alpha_operand *operand = alpha_operands + *opindex;
00140 if (operand->extract)
00141 (*operand->extract) (insn, &invalid);
00142 }
00143 if (invalid)
00144 continue;
00145 }
00146
00147
00148 goto found;
00149 }
00150
00151
00152 (*info->fprintf_func) (info->stream, ".long %#08x", insn);
00153
00154 return 4;
00155
00156 found:
00157 (*info->fprintf_func) (info->stream, "%s", opcode->name);
00158 if (opcode->operands[0] != 0)
00159 (*info->fprintf_func) (info->stream, "\t");
00160
00161
00162 need_comma = 0;
00163 for (opindex = opcode->operands; *opindex != 0; opindex++)
00164 {
00165 const struct alpha_operand *operand = alpha_operands + *opindex;
00166 int value;
00167
00168
00169
00170
00171 if ((operand->flags & AXP_OPERAND_FAKE) != 0)
00172 continue;
00173
00174
00175 if (operand->extract)
00176 value = (*operand->extract) (insn, (int *) NULL);
00177 else
00178 {
00179 value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
00180 if (operand->flags & AXP_OPERAND_SIGNED)
00181 {
00182 int signbit = 1 << (operand->bits - 1);
00183 value = (value ^ signbit) - signbit;
00184 }
00185 }
00186
00187 if (need_comma &&
00188 ((operand->flags & (AXP_OPERAND_PARENS | AXP_OPERAND_COMMA))
00189 != AXP_OPERAND_PARENS))
00190 {
00191 (*info->fprintf_func) (info->stream, ",");
00192 }
00193 if (operand->flags & AXP_OPERAND_PARENS)
00194 (*info->fprintf_func) (info->stream, "(");
00195
00196
00197 if (operand->flags & AXP_OPERAND_IR)
00198 (*info->fprintf_func) (info->stream, "%s", regnames[value]);
00199 else if (operand->flags & AXP_OPERAND_FPR)
00200 (*info->fprintf_func) (info->stream, "%s", regnames[value + 32]);
00201 else if (operand->flags & AXP_OPERAND_RELATIVE)
00202 (*info->print_address_func) (memaddr + 4 + value, info);
00203 else if (operand->flags & AXP_OPERAND_SIGNED)
00204 (*info->fprintf_func) (info->stream, "%d", value);
00205 else
00206 (*info->fprintf_func) (info->stream, "%#x", value);
00207
00208 if (operand->flags & AXP_OPERAND_PARENS)
00209 (*info->fprintf_func) (info->stream, ")");
00210 need_comma = 1;
00211 }
00212
00213 return 4;
00214 }