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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [opcodes/] [alpha-dis.c] - Blame information for rev 579

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

Line No. Rev Author Line
1 578 markom
/* alpha-dis.c -- Disassemble Alpha AXP instructions
2
   Copyright 1996, 1998, 1999, 2000 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
{
32
  "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
33
  "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp",
34
  "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9",
35
  "t10", "t11", "ra", "t12", "at", "gp", "sp", "zero",
36
  "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
37
  "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
38
  "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
39
  "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
40
};
41
 
42
/* VMS register names.  */
43
 
44
static const char * const vms_regnames[64] =
45
{
46
  "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
47
  "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
48
  "R16", "R17", "R18", "R19", "R20", "R21", "R22", "R23",
49
  "R24", "AI", "RA", "PV", "AT", "FP", "SP", "RZ",
50
  "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7",
51
  "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15",
52
  "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23",
53
  "F24", "F25", "F26", "F27", "F28", "F29", "F30", "FZ"
54
};
55
 
56
/* Disassemble Alpha instructions.  */
57
 
58
int
59
print_insn_alpha (memaddr, info)
60
     bfd_vma memaddr;
61
     struct disassemble_info *info;
62
{
63
  static const struct alpha_opcode *opcode_index[AXP_NOPS+1];
64
  const char * const * regnames;
65
  const struct alpha_opcode *opcode, *opcode_end;
66
  const unsigned char *opindex;
67
  unsigned insn, op, isa_mask;
68
  int need_comma;
69
 
70
  /* Initialize the majorop table the first time through */
71
  if (!opcode_index[0])
72
    {
73
      opcode = alpha_opcodes;
74
      opcode_end = opcode + alpha_num_opcodes;
75
 
76
      for (op = 0; op < AXP_NOPS; ++op)
77
        {
78
          opcode_index[op] = opcode;
79
          while (opcode < opcode_end && op == AXP_OP (opcode->opcode))
80
            ++opcode;
81
        }
82
      opcode_index[op] = opcode;
83
    }
84
 
85
  if (info->flavour == bfd_target_evax_flavour)
86
    regnames = vms_regnames;
87
  else
88
    regnames = osf_regnames;
89
 
90
  isa_mask = AXP_OPCODE_NOPAL;
91
  switch (info->mach)
92
    {
93
    case bfd_mach_alpha_ev4:
94
      isa_mask |= AXP_OPCODE_EV4;
95
      break;
96
    case bfd_mach_alpha_ev5:
97
      isa_mask |= AXP_OPCODE_EV5;
98
      break;
99
    case bfd_mach_alpha_ev6:
100
      isa_mask |= AXP_OPCODE_EV6;
101
      break;
102
    }
103
 
104
  /* Read the insn into a host word */
105
  {
106
    bfd_byte buffer[4];
107
    int status = (*info->read_memory_func) (memaddr, buffer, 4, info);
108
    if (status != 0)
109
      {
110
        (*info->memory_error_func) (status, memaddr, info);
111
        return -1;
112
      }
113
    insn = bfd_getl32 (buffer);
114
  }
115
 
116
  /* Get the major opcode of the instruction.  */
117
  op = AXP_OP (insn);
118
 
119
  /* Find the first match in the opcode table.  */
120
  opcode_end = opcode_index[op+1];
121
  for (opcode = opcode_index[op]; opcode < opcode_end; ++opcode)
122
    {
123
      if ((insn & opcode->mask) != opcode->opcode)
124
        continue;
125
 
126
      if (!(opcode->flags & isa_mask))
127
        continue;
128
 
129
      /* Make two passes over the operands.  First see if any of them
130
         have extraction functions, and, if they do, make sure the
131
         instruction is valid.  */
132
      {
133
        int invalid = 0;
134
        for (opindex = opcode->operands; *opindex != 0; opindex++)
135
          {
136
            const struct alpha_operand *operand = alpha_operands + *opindex;
137
            if (operand->extract)
138
              (*operand->extract) (insn, &invalid);
139
          }
140
        if (invalid)
141
          continue;
142
      }
143
 
144
      /* The instruction is valid.  */
145
      goto found;
146
    }
147
 
148
  /* No instruction found */
149
  (*info->fprintf_func) (info->stream, ".long %#08x", insn);
150
 
151
  return 4;
152
 
153
found:
154
  (*info->fprintf_func) (info->stream, "%s", opcode->name);
155
  if (opcode->operands[0] != 0)
156
    (*info->fprintf_func) (info->stream, "\t");
157
 
158
  /* Now extract and print the operands.  */
159
  need_comma = 0;
160
  for (opindex = opcode->operands; *opindex != 0; opindex++)
161
    {
162
      const struct alpha_operand *operand = alpha_operands + *opindex;
163
      int value;
164
 
165
      /* Operands that are marked FAKE are simply ignored.  We
166
         already made sure that the extract function considered
167
         the instruction to be valid.  */
168
      if ((operand->flags & AXP_OPERAND_FAKE) != 0)
169
        continue;
170
 
171
      /* Extract the value from the instruction.  */
172
      if (operand->extract)
173
        value = (*operand->extract) (insn, (int *) NULL);
174
      else
175
        {
176
          value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
177
          if (operand->flags & AXP_OPERAND_SIGNED)
178
            {
179
              int signbit = 1 << (operand->bits - 1);
180
              value = (value ^ signbit) - signbit;
181
            }
182
        }
183
 
184
      if (need_comma &&
185
          ((operand->flags & (AXP_OPERAND_PARENS|AXP_OPERAND_COMMA))
186
           != AXP_OPERAND_PARENS))
187
        {
188
          (*info->fprintf_func) (info->stream, ",");
189
        }
190
      if (operand->flags & AXP_OPERAND_PARENS)
191
        (*info->fprintf_func) (info->stream, "(");
192
 
193
      /* Print the operand as directed by the flags.  */
194
      if (operand->flags & AXP_OPERAND_IR)
195
        (*info->fprintf_func) (info->stream, "%s", regnames[value]);
196
      else if (operand->flags & AXP_OPERAND_FPR)
197
        (*info->fprintf_func) (info->stream, "%s", regnames[value+32]);
198
      else if (operand->flags & AXP_OPERAND_RELATIVE)
199
        (*info->print_address_func) (memaddr + 4 + value, info);
200
      else if (operand->flags & AXP_OPERAND_SIGNED)
201
        (*info->fprintf_func) (info->stream, "%d", value);
202
      else
203
        (*info->fprintf_func) (info->stream, "%#x", value);
204
 
205
      if (operand->flags & AXP_OPERAND_PARENS)
206
        (*info->fprintf_func) (info->stream, ")");
207
      need_comma = 1;
208
    }
209
 
210
  return 4;
211
}

powered by: WebSVN 2.1.0

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