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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [gdb-5.0/] [opcodes/] [alpha-dis.c] - Blame information for rev 1778

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

Line No. Rev Author Line
1 106 markom
/* 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.
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 "ansidecl.h"
25
#include "sysdep.h"
26
#include "dis-asm.h"
27
#include "opcode/alpha.h"
28
 
29
/* OSF register names.  */
30
 
31
static const char * const osf_regnames[64] =
32
{
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"
41
};
42
 
43
/* VMS register names.  */
44
 
45
static const char * const vms_regnames[64] =
46
{
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"
55
};
56
 
57
/* Disassemble Alpha instructions.  */
58
 
59
int
60
print_insn_alpha (memaddr, info)
61
     bfd_vma memaddr;
62
     struct disassemble_info *info;
63
{
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;
69
  int need_comma;
70
 
71
  /* Initialize the majorop table the first time through */
72
  if (!opcode_index[0])
73
    {
74
      opcode = alpha_opcodes;
75
      opcode_end = opcode + alpha_num_opcodes;
76
 
77
      for (op = 0; op < AXP_NOPS; ++op)
78
        {
79
          opcode_index[op] = opcode;
80
          while (opcode < opcode_end && op == AXP_OP (opcode->opcode))
81
            ++opcode;
82
        }
83
      opcode_index[op] = opcode;
84
    }
85
 
86
  if (info->flavour == bfd_target_evax_flavour)
87
    regnames = vms_regnames;
88
  else
89
    regnames = osf_regnames;
90
 
91
  isa_mask = AXP_OPCODE_NOPAL;
92
  switch (info->mach)
93
    {
94
    case bfd_mach_alpha_ev4:
95
      isa_mask |= AXP_OPCODE_EV4;
96
      break;
97
    case bfd_mach_alpha_ev5:
98
      isa_mask |= AXP_OPCODE_EV5;
99
      break;
100
    case bfd_mach_alpha_ev6:
101
      isa_mask |= AXP_OPCODE_EV6;
102
      break;
103
    }
104
 
105
  /* Read the insn into a host word */
106
  {
107
    bfd_byte buffer[4];
108
    int status = (*info->read_memory_func) (memaddr, buffer, 4, info);
109
    if (status != 0)
110
      {
111
        (*info->memory_error_func) (status, memaddr, info);
112
        return -1;
113
      }
114
    insn = bfd_getl32 (buffer);
115
  }
116
 
117
  /* Get the major opcode of the instruction.  */
118
  op = AXP_OP (insn);
119
 
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)
123
    {
124
      if ((insn & opcode->mask) != opcode->opcode)
125
        continue;
126
 
127
      if (!(opcode->flags & isa_mask))
128
        continue;
129
 
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.  */
133
      {
134
        int invalid = 0;
135
        for (opindex = opcode->operands; *opindex != 0; opindex++)
136
          {
137
            const struct alpha_operand *operand = alpha_operands + *opindex;
138
            if (operand->extract)
139
              (*operand->extract) (insn, &invalid);
140
          }
141
        if (invalid)
142
          continue;
143
      }
144
 
145
      /* The instruction is valid.  */
146
      goto found;
147
    }
148
 
149
  /* No instruction found */
150
  (*info->fprintf_func) (info->stream, ".long %#08x", insn);
151
 
152
  return 4;
153
 
154
found:
155
  (*info->fprintf_func) (info->stream, "%s", opcode->name);
156
  if (opcode->operands[0] != 0)
157
    (*info->fprintf_func) (info->stream, "\t");
158
 
159
  /* Now extract and print the operands.  */
160
  need_comma = 0;
161
  for (opindex = opcode->operands; *opindex != 0; opindex++)
162
    {
163
      const struct alpha_operand *operand = alpha_operands + *opindex;
164
      int value;
165
 
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)
170
        continue;
171
 
172
      /* Extract the value from the instruction.  */
173
      if (operand->extract)
174
        value = (*operand->extract) (insn, (int *) NULL);
175
      else
176
        {
177
          value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
178
          if (operand->flags & AXP_OPERAND_SIGNED)
179
            {
180
              int signbit = 1 << (operand->bits - 1);
181
              value = (value ^ signbit) - signbit;
182
            }
183
        }
184
 
185
      if (need_comma &&
186
          ((operand->flags & (AXP_OPERAND_PARENS|AXP_OPERAND_COMMA))
187
           != AXP_OPERAND_PARENS))
188
        {
189
          (*info->fprintf_func) (info->stream, ",");
190
        }
191
      if (operand->flags & AXP_OPERAND_PARENS)
192
        (*info->fprintf_func) (info->stream, "(");
193
 
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);
203
      else
204
        (*info->fprintf_func) (info->stream, "%#x", value);
205
 
206
      if (operand->flags & AXP_OPERAND_PARENS)
207
        (*info->fprintf_func) (info->stream, ")");
208
      need_comma = 1;
209
    }
210
 
211
  return 4;
212
}

powered by: WebSVN 2.1.0

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