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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [opcodes/] [i370-dis.c] - Blame information for rev 1779

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

Line No. Rev Author Line
1 106 markom
 
2
/* i370-dis.c -- Disassemble Instruction 370 (ESA/390) instructions
3
   Copyright 1994, 2000 Free Software Foundation, Inc.
4
   PowerPC version written by Ian Lance Taylor, Cygnus Support
5
   Rewritten for i370 ESA/390 support by Linas Vepstas <linas@linas.org>
6
 
7
This file is part of GDB, GAS, and the GNU binutils.
8
 
9
GDB, GAS, and the GNU binutils are free software; you can redistribute
10
them and/or modify them under the terms of the GNU General Public
11
License as published by the Free Software Foundation; either version
12
2, or (at your option) any later version.
13
 
14
GDB, GAS, and the GNU binutils are distributed in the hope that they
15
will be useful, but WITHOUT ANY WARRANTY; without even the implied
16
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17
the GNU General Public License for more details.
18
 
19
You should have received a copy of the GNU General Public License
20
along with this file; see the file COPYING.  If not, write to the Free
21
Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22
 
23
#include <stdio.h>
24
#include "ansidecl.h"
25
#include "sysdep.h"
26
#include "dis-asm.h"
27
#include "opcode/i370.h"
28
 
29
/* This file provides several disassembler functions, all of which use
30
   the disassembler interface defined in dis-asm.h.
31
*/
32
 
33
int
34
print_insn_i370 (memaddr, info)
35
     bfd_vma memaddr;
36
     struct disassemble_info *info;
37
{
38
  bfd_byte buffer[8];
39
  int status;
40
  i370_insn_t insn;
41
  const struct i370_opcode *opcode;
42
  const struct i370_opcode *opcode_end;
43
 
44
  status = (*info->read_memory_func) (memaddr, buffer, 6, info);
45
  if (status != 0)
46
    {
47
      (*info->memory_error_func) (status, memaddr, info);
48
      return -1;
49
    }
50
 
51
  /* Cast the bytes into the insn (in a host-endian indep way) */
52
  insn.i[0] = (buffer[0] << 24) & 0xff000000;
53
  insn.i[0] |= (buffer[1] << 16) & 0xff0000;
54
  insn.i[0] |= (buffer[2] << 8) & 0xff00;
55
  insn.i[0] |= buffer[3]  & 0xff;
56
  insn.i[1] = (buffer[4] << 24) & 0xff000000;
57
  insn.i[1] |= (buffer[5] << 16) & 0xff0000;
58
 
59
  /* Find the first match in the opcode table.  We could speed this up
60
     a bit by doing a binary search on the major opcode.  */
61
  opcode_end = i370_opcodes + i370_num_opcodes;
62
  for (opcode = i370_opcodes; opcode < opcode_end; opcode++)
63
    {
64
      const unsigned char *opindex;
65
      const struct i370_operand *operand;
66
      i370_insn_t masked;
67
      int invalid;
68
 
69
      /* Mask off operands, and look for a match ... */
70
      masked = insn;
71
      if (2 == opcode->len)
72
        {
73
          masked.i[0] >>= 16;
74
          masked.i[0] &= 0xffff;
75
        }
76
      masked.i[0] &= opcode->mask.i[0];
77
      if (masked.i[0] != opcode->opcode.i[0]) continue;
78
 
79
      if (6 == opcode->len)
80
        {
81
          masked.i[1] &= opcode->mask.i[1];
82
          if (masked.i[1] != opcode->opcode.i[1]) continue;
83
        }
84
 
85
      /* Found a match.  adjust a tad */
86
      if (2 == opcode->len)
87
        {
88
          insn.i[0] >>= 16;
89
          insn.i[0] &= 0xffff;
90
        }
91
 
92
      /* Make two passes over the operands.  First see if any of them
93
         have extraction functions, and, if they do, make sure the
94
         instruction is valid.  */
95
      invalid = 0;
96
      for (opindex = opcode->operands; *opindex != 0; opindex++)
97
        {
98
          operand = i370_operands + *opindex;
99
          if (operand->extract)
100
            (*operand->extract) (insn, &invalid);
101
        }
102
      if (invalid) continue;
103
 
104
      /* The instruction is valid.  */
105
      (*info->fprintf_func) (info->stream, "%s", opcode->name);
106
      if (opcode->operands[0] != 0)
107
        (*info->fprintf_func) (info->stream, "\t");
108
 
109
      /* Now extract and print the operands.  */
110
      for (opindex = opcode->operands; *opindex != 0; opindex++)
111
        {
112
          long value;
113
 
114
          operand = i370_operands + *opindex;
115
 
116
          /* Extract the value from the instruction.  */
117
          if (operand->extract)
118
            value = (*operand->extract) (insn, (int *) NULL);
119
          else
120
            {
121
              value = (insn.i[0] >> operand->shift) & ((1 << operand->bits) - 1);
122
            }
123
 
124
          /* Print the operand as directed by the flags.  */
125
          if ((operand->flags & I370_OPERAND_OPTIONAL) != 0)
126
            {
127
              if (value)
128
                (*info->fprintf_func) (info->stream, "(r%ld)", value);
129
            }
130
          else if ((operand->flags & I370_OPERAND_SBASE) != 0)
131
            {
132
              (*info->fprintf_func) (info->stream, "(r%ld)", value);
133
            }
134
          else if ((operand->flags & I370_OPERAND_INDEX) != 0)
135
            {
136
              if (value)
137
                (*info->fprintf_func) (info->stream, "(r%ld,", value);
138
              else
139
                (*info->fprintf_func) (info->stream, "(,");
140
            }
141
          else if ((operand->flags & I370_OPERAND_LENGTH) != 0)
142
            {
143
              (*info->fprintf_func) (info->stream, "(%ld,", value);
144
            }
145
          else if ((operand->flags & I370_OPERAND_BASE) != 0)
146
            (*info->fprintf_func) (info->stream, "r%ld)", value);
147
          else if ((operand->flags & I370_OPERAND_GPR) != 0)
148
            (*info->fprintf_func) (info->stream, "r%ld,", value);
149
          else if ((operand->flags & I370_OPERAND_FPR) != 0)
150
            (*info->fprintf_func) (info->stream, "f%ld,", value);
151
          else if ((operand->flags & I370_OPERAND_RELATIVE) != 0)
152
            (*info->fprintf_func) (info->stream, "%ld", value);
153
          else
154
            (*info->fprintf_func) (info->stream, " %ld, ", value);
155
 
156
        }
157
 
158
      return opcode->len;
159
 
160
    }
161
 
162
 
163
  /* We could not find a match.  */
164
  (*info->fprintf_func) (info->stream, ".short 0x%02x%02x", buffer[0], buffer[1]);
165
 
166
  return 2;
167
}

powered by: WebSVN 2.1.0

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