OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [opcodes/] [alpha-dis.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* alpha-dis.c -- Disassemble Alpha AXP instructions
2
   Copyright 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
   Contributed by Richard Henderson <rth@tamu.edu>,
4
   patterned after the PPC opcode handling written by Ian Lance Taylor.
5
 
6
This file is part of GDB, GAS, and the GNU binutils.
7
 
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.
12
 
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.
17
 
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
21
02111-1307, USA.  */
22
 
23
#include <stdio.h>
24
#include "sysdep.h"
25
#include "dis-asm.h"
26
#include "opcode/alpha.h"
27
 
28
/* OSF register names.  */
29
 
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"
39
};
40
 
41
/* VMS register names.  */
42
 
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"
52
};
53
 
54
/* Disassemble Alpha instructions.  */
55
 
56
int
57
print_insn_alpha (memaddr, info)
58
     bfd_vma memaddr;
59
     struct disassemble_info *info;
60
{
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;
66
  int need_comma;
67
 
68
  /* Initialize the majorop table the first time through */
69
  if (!opcode_index[0])
70
    {
71
      opcode = alpha_opcodes;
72
      opcode_end = opcode + alpha_num_opcodes;
73
 
74
      for (op = 0; op < AXP_NOPS; ++op)
75
        {
76
          opcode_index[op] = opcode;
77
          while (opcode < opcode_end && op == AXP_OP (opcode->opcode))
78
            ++opcode;
79
        }
80
      opcode_index[op] = opcode;
81
    }
82
 
83
  if (info->flavour == bfd_target_evax_flavour)
84
    regnames = vms_regnames;
85
  else
86
    regnames = osf_regnames;
87
 
88
  isa_mask = AXP_OPCODE_NOPAL;
89
  switch (info->mach)
90
    {
91
    case bfd_mach_alpha_ev4:
92
      isa_mask |= AXP_OPCODE_EV4;
93
      break;
94
    case bfd_mach_alpha_ev5:
95
      isa_mask |= AXP_OPCODE_EV5;
96
      break;
97
    case bfd_mach_alpha_ev6:
98
      isa_mask |= AXP_OPCODE_EV6;
99
      break;
100
    }
101
 
102
  /* Read the insn into a host word */
103
  {
104
    bfd_byte buffer[4];
105
    int status = (*info->read_memory_func) (memaddr, buffer, 4, info);
106
    if (status != 0)
107
      {
108
        (*info->memory_error_func) (status, memaddr, info);
109
        return -1;
110
      }
111
    insn = bfd_getl32 (buffer);
112
  }
113
 
114
  /* Get the major opcode of the instruction.  */
115
  op = AXP_OP (insn);
116
 
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)
120
    {
121
      if ((insn ^ opcode->opcode) & opcode->mask)
122
        continue;
123
 
124
      if (!(opcode->flags & isa_mask))
125
        continue;
126
 
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.  */
130
      {
131
        int invalid = 0;
132
        for (opindex = opcode->operands; *opindex != 0; opindex++)
133
          {
134
            const struct alpha_operand *operand = alpha_operands + *opindex;
135
            if (operand->extract)
136
              (*operand->extract) (insn, &invalid);
137
          }
138
        if (invalid)
139
          continue;
140
      }
141
 
142
      /* The instruction is valid.  */
143
      goto found;
144
    }
145
 
146
  /* No instruction found */
147
  (*info->fprintf_func) (info->stream, ".long %#08x", insn);
148
 
149
  return 4;
150
 
151
found:
152
  (*info->fprintf_func) (info->stream, "%s", opcode->name);
153
  if (opcode->operands[0] != 0)
154
    (*info->fprintf_func) (info->stream, "\t");
155
 
156
  /* Now extract and print the operands.  */
157
  need_comma = 0;
158
  for (opindex = opcode->operands; *opindex != 0; opindex++)
159
    {
160
      const struct alpha_operand *operand = alpha_operands + *opindex;
161
      int value;
162
 
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)
167
        continue;
168
 
169
      /* Extract the value from the instruction.  */
170
      if (operand->extract)
171
        value = (*operand->extract) (insn, (int *) NULL);
172
      else
173
        {
174
          value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
175
          if (operand->flags & AXP_OPERAND_SIGNED)
176
            {
177
              int signbit = 1 << (operand->bits - 1);
178
              value = (value ^ signbit) - signbit;
179
            }
180
        }
181
 
182
      if (need_comma &&
183
          ((operand->flags & (AXP_OPERAND_PARENS | AXP_OPERAND_COMMA))
184
           != AXP_OPERAND_PARENS))
185
        {
186
          (*info->fprintf_func) (info->stream, ",");
187
        }
188
      if (operand->flags & AXP_OPERAND_PARENS)
189
        (*info->fprintf_func) (info->stream, "(");
190
 
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);
200
      else
201
        (*info->fprintf_func) (info->stream, "%#x", value);
202
 
203
      if (operand->flags & AXP_OPERAND_PARENS)
204
        (*info->fprintf_func) (info->stream, ")");
205
      need_comma = 1;
206
    }
207
 
208
  return 4;
209
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.