1 /* alpha-dis.c -- Disassemble Alpha AXP instructions
2 Copyright (C) 1996-2015 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 libopcodes.
8 This library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 It is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 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, 51 Franklin Street - Fifth Floor, Boston, MA
26 #include "opcode/alpha.h"
28 /* OSF register names. */
30 static const char * const osf_regnames
[64] = {
31 "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
32 "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp",
33 "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9",
34 "t10", "t11", "ra", "t12", "at", "gp", "sp", "zero",
35 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
36 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
37 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
38 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
41 /* VMS register names. */
43 static const char * const vms_regnames
[64] = {
44 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
45 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
46 "R16", "R17", "R18", "R19", "R20", "R21", "R22", "R23",
47 "R24", "AI", "RA", "PV", "AT", "FP", "SP", "RZ",
48 "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7",
49 "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15",
50 "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23",
51 "F24", "F25", "F26", "F27", "F28", "F29", "F30", "FZ"
54 /* Disassemble Alpha instructions. */
57 print_insn_alpha (memaddr
, info
)
59 struct disassemble_info
*info
;
61 static const struct alpha_opcode
*opcode_index
[AXP_NOPS
+1];
62 const char * const * regnames
;
63 const struct alpha_opcode
*opcode
, *opcode_end
;
64 const unsigned char *opindex
;
65 unsigned insn
, op
, isa_mask
;
68 /* Initialize the majorop table the first time through */
71 opcode
= alpha_opcodes
;
72 opcode_end
= opcode
+ alpha_num_opcodes
;
74 for (op
= 0; op
< AXP_NOPS
; ++op
)
76 opcode_index
[op
] = opcode
;
77 while (opcode
< opcode_end
&& op
== AXP_OP (opcode
->opcode
))
80 opcode_index
[op
] = opcode
;
83 if (info
->flavour
== bfd_target_evax_flavour
)
84 regnames
= vms_regnames
;
86 regnames
= osf_regnames
;
88 isa_mask
= AXP_OPCODE_NOPAL
;
91 case bfd_mach_alpha_ev4
:
92 isa_mask
|= AXP_OPCODE_EV4
;
94 case bfd_mach_alpha_ev5
:
95 isa_mask
|= AXP_OPCODE_EV5
;
97 case bfd_mach_alpha_ev6
:
98 isa_mask
|= AXP_OPCODE_EV6
;
102 /* Read the insn into a host word */
105 int status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
108 (*info
->memory_error_func
) (status
, memaddr
, info
);
111 insn
= bfd_getl32 (buffer
);
114 /* Get the major opcode of the instruction. */
117 /* Find the first match in the opcode table. */
118 opcode_end
= opcode_index
[op
+ 1];
119 for (opcode
= opcode_index
[op
]; opcode
< opcode_end
; ++opcode
)
121 if ((insn
^ opcode
->opcode
) & opcode
->mask
)
124 if (!(opcode
->flags
& isa_mask
))
127 /* Make two passes over the operands. First see if any of them
128 have extraction functions, and, if they do, make sure the
129 instruction is valid. */
132 for (opindex
= opcode
->operands
; *opindex
!= 0; opindex
++)
134 const struct alpha_operand
*operand
= alpha_operands
+ *opindex
;
135 if (operand
->extract
)
136 (*operand
->extract
) (insn
, &invalid
);
142 /* The instruction is valid. */
146 /* No instruction found */
147 (*info
->fprintf_func
) (info
->stream
, ".long %#08x", insn
);
152 (*info
->fprintf_func
) (info
->stream
, "%s", opcode
->name
);
153 if (opcode
->operands
[0] != 0)
154 (*info
->fprintf_func
) (info
->stream
, "\t");
156 /* Now extract and print the operands. */
158 for (opindex
= opcode
->operands
; *opindex
!= 0; opindex
++)
160 const struct alpha_operand
*operand
= alpha_operands
+ *opindex
;
163 /* Operands that are marked FAKE are simply ignored. We
164 already made sure that the extract function considered
165 the instruction to be valid. */
166 if ((operand
->flags
& AXP_OPERAND_FAKE
) != 0)
169 /* Extract the value from the instruction. */
170 if (operand
->extract
)
171 value
= (*operand
->extract
) (insn
, (int *) NULL
);
174 value
= (insn
>> operand
->shift
) & ((1 << operand
->bits
) - 1);
175 if (operand
->flags
& AXP_OPERAND_SIGNED
)
177 int signbit
= 1 << (operand
->bits
- 1);
178 value
= (value
^ signbit
) - signbit
;
183 ((operand
->flags
& (AXP_OPERAND_PARENS
| AXP_OPERAND_COMMA
))
184 != AXP_OPERAND_PARENS
))
186 (*info
->fprintf_func
) (info
->stream
, ",");
188 if (operand
->flags
& AXP_OPERAND_PARENS
)
189 (*info
->fprintf_func
) (info
->stream
, "(");
191 /* Print the operand as directed by the flags. */
192 if (operand
->flags
& AXP_OPERAND_IR
)
193 (*info
->fprintf_func
) (info
->stream
, "%s", regnames
[value
]);
194 else if (operand
->flags
& AXP_OPERAND_FPR
)
195 (*info
->fprintf_func
) (info
->stream
, "%s", regnames
[value
+ 32]);
196 else if (operand
->flags
& AXP_OPERAND_RELATIVE
)
197 (*info
->print_address_func
) (memaddr
+ 4 + value
, info
);
198 else if (operand
->flags
& AXP_OPERAND_SIGNED
)
199 (*info
->fprintf_func
) (info
->stream
, "%d", value
);
201 (*info
->fprintf_func
) (info
->stream
, "%#x", value
);
203 if (operand
->flags
& AXP_OPERAND_PARENS
)
204 (*info
->fprintf_func
) (info
->stream
, ")");
This page took 0.035829 seconds and 4 git commands to generate.