1 /* alpha-dis.c -- Disassemble Alpha AXP instructions
2 Copyright 1996, 1999 Free Software Foundation, Inc.
3 Contributed by Richard Henderson <rth@tamu.edu>,
4 patterned after the PPC opcode handling written by Ian Lance Taylor.
6 This file is part of GDB, GAS, and the GNU binutils.
8 GDB, GAS, and the GNU binutils are free software; you can redistribute
9 them and/or modify them under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either version
11 2, or (at your option) any later version.
13 GDB, GAS, and the GNU binutils are distributed in the hope that they
14 will be useful, but WITHOUT ANY WARRANTY; without even the implied
15 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16 the GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this file; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 #include "opcode/alpha.h"
29 /* OSF register names. */
31 static const char * const osf_regnames
[64] =
33 "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
34 "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp",
35 "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9",
36 "t10", "t11", "ra", "t12", "at", "gp", "sp", "zero",
37 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
38 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
39 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
40 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
43 /* VMS register names. */
45 static const char * const vms_regnames
[64] =
47 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
48 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
49 "R16", "R17", "R18", "R19", "R20", "R21", "R22", "R23",
50 "R24", "AI", "RA", "PV", "AT", "FP", "SP", "RZ",
51 "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7",
52 "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15",
53 "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23",
54 "F24", "F25", "F26", "F27", "F28", "F29", "F30", "FZ"
57 /* Disassemble Alpha instructions. */
60 print_insn_alpha (memaddr
, info
)
62 struct disassemble_info
*info
;
64 static const struct alpha_opcode
*opcode_index
[AXP_NOPS
+1];
65 const char * const * regnames
;
66 const struct alpha_opcode
*opcode
, *opcode_end
;
67 const unsigned char *opindex
;
68 unsigned insn
, op
, isa_mask
;
71 /* Initialize the majorop table the first time through */
74 opcode
= alpha_opcodes
;
75 opcode_end
= opcode
+ alpha_num_opcodes
;
77 for (op
= 0; op
< AXP_NOPS
; ++op
)
79 opcode_index
[op
] = opcode
;
80 while (opcode
< opcode_end
&& op
== AXP_OP (opcode
->opcode
))
83 opcode_index
[op
] = opcode
;
86 if (info
->flavour
== bfd_target_evax_flavour
)
87 regnames
= vms_regnames
;
89 regnames
= osf_regnames
;
91 isa_mask
= AXP_OPCODE_NOPAL
;
94 case bfd_mach_alpha_ev4
:
95 isa_mask
|= AXP_OPCODE_EV4
;
97 case bfd_mach_alpha_ev5
:
98 isa_mask
|= AXP_OPCODE_EV5
;
100 case bfd_mach_alpha_ev6
:
101 isa_mask
|= AXP_OPCODE_EV6
;
105 /* Read the insn into a host word */
108 int status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
111 (*info
->memory_error_func
) (status
, memaddr
, info
);
114 insn
= bfd_getl32 (buffer
);
117 /* Get the major opcode of the instruction. */
120 /* Find the first match in the opcode table. */
121 opcode_end
= opcode_index
[op
+1];
122 for (opcode
= opcode_index
[op
]; opcode
< opcode_end
; ++opcode
)
124 if ((insn
& opcode
->mask
) != opcode
->opcode
)
127 if (!(opcode
->flags
& isa_mask
))
130 /* Make two passes over the operands. First see if any of them
131 have extraction functions, and, if they do, make sure the
132 instruction is valid. */
135 for (opindex
= opcode
->operands
; *opindex
!= 0; opindex
++)
137 const struct alpha_operand
*operand
= alpha_operands
+ *opindex
;
138 if (operand
->extract
)
139 (*operand
->extract
) (insn
, &invalid
);
145 /* The instruction is valid. */
149 /* No instruction found */
150 (*info
->fprintf_func
) (info
->stream
, ".long %#08x", insn
);
155 (*info
->fprintf_func
) (info
->stream
, "%s", opcode
->name
);
156 if (opcode
->operands
[0] != 0)
157 (*info
->fprintf_func
) (info
->stream
, "\t");
159 /* Now extract and print the operands. */
161 for (opindex
= opcode
->operands
; *opindex
!= 0; opindex
++)
163 const struct alpha_operand
*operand
= alpha_operands
+ *opindex
;
166 /* Operands that are marked FAKE are simply ignored. We
167 already made sure that the extract function considered
168 the instruction to be valid. */
169 if ((operand
->flags
& AXP_OPERAND_FAKE
) != 0)
172 /* Extract the value from the instruction. */
173 if (operand
->extract
)
174 value
= (*operand
->extract
) (insn
, (int *) NULL
);
177 value
= (insn
>> operand
->shift
) & ((1 << operand
->bits
) - 1);
178 if (operand
->flags
& AXP_OPERAND_SIGNED
)
180 int signbit
= 1 << (operand
->bits
- 1);
181 value
= (value
^ signbit
) - signbit
;
186 ((operand
->flags
& (AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
))
187 != AXP_OPERAND_PARENS
))
189 (*info
->fprintf_func
) (info
->stream
, ",");
191 if (operand
->flags
& AXP_OPERAND_PARENS
)
192 (*info
->fprintf_func
) (info
->stream
, "(");
194 /* Print the operand as directed by the flags. */
195 if (operand
->flags
& AXP_OPERAND_IR
)
196 (*info
->fprintf_func
) (info
->stream
, "%s", regnames
[value
]);
197 else if (operand
->flags
& AXP_OPERAND_FPR
)
198 (*info
->fprintf_func
) (info
->stream
, "%s", regnames
[value
+32]);
199 else if (operand
->flags
& AXP_OPERAND_RELATIVE
)
200 (*info
->print_address_func
) (memaddr
+ 4 + value
, info
);
201 else if (operand
->flags
& AXP_OPERAND_SIGNED
)
202 (*info
->fprintf_func
) (info
->stream
, "%d", value
);
204 (*info
->fprintf_func
) (info
->stream
, "%#x", value
);
206 if (operand
->flags
& AXP_OPERAND_PARENS
)
207 (*info
->fprintf_func
) (info
->stream
, ")");
This page took 0.033491 seconds and 4 git commands to generate.