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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [cpu/] [iq2000.opc] - Blame information for rev 818

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
/* IQ2000 opcode support.  -*- C -*-
2
 
3
   Copyright 2000, 2001, 2002, 2005, 2007, 2009 Free Software Foundation, Inc.
4
 
5
   Contributed by Red Hat Inc; developed under contract from Fujitsu.
6
 
7
   This file is part of the GNU Binutils.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   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 program; if not, write to the Free Software
21
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22
   MA 02110-1301, USA.  */
23
 
24
/* This file is an addendum to iq2000.cpu.  Heavy use of C code isn't
25
   appropriate in .cpu files, so it resides here.  This especially applies
26
   to assembly/disassembly where parsing/printing can be quite involved.
27
   Such things aren't really part of the specification of the cpu, per se,
28
   so .cpu files provide the general framework and .opc files handle the
29
   nitty-gritty details as necessary.
30
 
31
   Each section is delimited with start and end markers.
32
 
33
   -opc.h additions use: "-- opc.h"
34
   -opc.c additions use: "-- opc.c"
35
   -asm.c additions use: "-- asm.c"
36
   -dis.c additions use: "-- dis.c"
37
   -ibd.h additions use: "-- ibd.h".  */
38
 
39
/* -- opc.h */
40
 
41
/* Allows reason codes to be output when assembler errors occur.  */
42
#define CGEN_VERBOSE_ASSEMBLER_ERRORS
43
 
44
/* Override disassembly hashing - there are variable bits in the top
45
   byte of these instructions.  */
46
#define CGEN_DIS_HASH_SIZE 8
47
#define CGEN_DIS_HASH(buf,value) (((* (unsigned char*) (buf)) >> 6) % CGEN_DIS_HASH_SIZE)
48
 
49
/* following activates check beyond hashing since some iq2000 and iq10
50
   instructions have same mnemonics but different functionality. */
51
#define CGEN_VALIDATE_INSN_SUPPORTED
52
 
53
extern int iq2000_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
54
 
55
/* -- asm.c */
56
 
57
#include "safe-ctype.h"
58
 
59
static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");
60
 
61
/* Special check to ensure that instruction exists for given machine.  */
62
 
63
int
64
iq2000_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
65
{
66
  int machs = cd->machs;
67
 
68
  return (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH) & machs) != 0;
69
}
70
 
71
static int
72
iq2000_cgen_isa_register (const char **strp)
73
{
74
  int len;
75
  int ch1, ch2;
76
 
77
  if (**strp == 'r' || **strp == 'R')
78
    {
79
      len = strlen (*strp);
80
      if (len == 2)
81
        {
82
          ch1 = (*strp)[1];
83
          if ('0' <= ch1 && ch1 <= '9')
84
            return 1;
85
        }
86
      else if (len == 3)
87
        {
88
          ch1 = (*strp)[1];
89
          ch2 = (*strp)[2];
90
          if (('1' <= ch1 && ch1 <= '2') && ('0' <= ch2 && ch2 <= '9'))
91
            return 1;
92
          if ('3' == ch1 && (ch2 == '0' || ch2 == '1'))
93
            return 1;
94
        }
95
    }
96
  if (**strp == '%'
97
      && TOLOWER ((*strp)[1]) != 'l'
98
      && TOLOWER ((*strp)[1]) != 'h')
99
    return 1;
100
  return 0;
101
}
102
 
103
/* Handle negated literal.  */
104
 
105
static const char *
106
parse_mimm (CGEN_CPU_DESC cd,
107
            const char **strp,
108
            int opindex,
109
            unsigned long *valuep)
110
{
111
  const char *errmsg;
112
 
113
  /* Verify this isn't a register.  */
114
  if (iq2000_cgen_isa_register (strp))
115
    errmsg = _("immediate value cannot be register");
116
  else
117
    {
118
      long value;
119
 
120
      errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
121
      if (errmsg == NULL)
122
        {
123
          long x = (-value) & 0xFFFF0000;
124
 
125
          if (x != 0 && x != (long) 0xFFFF0000)
126
            errmsg = _("immediate value out of range");
127
          else
128
            *valuep = (-value & 0xFFFF);
129
        }
130
    }
131
  return errmsg;
132
}
133
 
134
/* Handle signed/unsigned literal.  */
135
 
136
static const char *
137
parse_imm (CGEN_CPU_DESC cd,
138
           const char **strp,
139
           int opindex,
140
           unsigned long *valuep)
141
{
142
  const char *errmsg;
143
 
144
  if (iq2000_cgen_isa_register (strp))
145
    errmsg = _("immediate value cannot be register");
146
  else
147
    {
148
      long value;
149
 
150
      errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
151
      if (errmsg == NULL)
152
        {
153
          long x = value & 0xFFFF0000;
154
 
155
          if (x != 0 && x != (long) 0xFFFF0000)
156
            errmsg = _("immediate value out of range");
157
          else
158
            *valuep = (value & 0xFFFF);
159
        }
160
    }
161
  return errmsg;
162
}
163
 
164
/* Handle iq10 21-bit jmp offset.  */
165
 
166
static const char *
167
parse_jtargq10 (CGEN_CPU_DESC cd,
168
                const char **strp,
169
                int opindex,
170
                int reloc ATTRIBUTE_UNUSED,
171
                enum cgen_parse_operand_result *type_addr ATTRIBUTE_UNUSED,
172
                bfd_vma *valuep)
173
{
174
  const char *errmsg;
175
  bfd_vma value;
176
  enum cgen_parse_operand_result result_type = CGEN_PARSE_OPERAND_RESULT_NUMBER;
177
 
178
  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IQ2000_OFFSET_21,
179
                               & result_type, & value);
180
  if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
181
    {
182
      /* Check value is within 23-bits
183
         (remembering that 2-bit shift right will occur).  */
184
      if (value > 0x7fffff)
185
        return _("21-bit offset out of range");
186
    }
187
  *valuep = (value & 0x7FFFFF);
188
  return errmsg;
189
}
190
 
191
/* Handle high().  */
192
 
193
static const char *
194
parse_hi16 (CGEN_CPU_DESC cd,
195
            const char **strp,
196
            int opindex,
197
            unsigned long *valuep)
198
{
199
  if (strncasecmp (*strp, "%hi(", 4) == 0)
200
    {
201
      enum cgen_parse_operand_result result_type;
202
      bfd_vma value;
203
      const char *errmsg;
204
 
205
      *strp += 4;
206
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
207
                                   & result_type, & value);
208
      if (**strp != ')')
209
        return MISSING_CLOSING_PARENTHESIS;
210
 
211
      ++*strp;
212
      if (errmsg == NULL
213
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
214
        {
215
          /* If value has top-bit of %lo on, then it will
216
             sign-propagate and so we compensate by adding
217
             1 to the resultant %hi value.  */
218
          if (value & 0x8000)
219
            value += 0x10000;
220
          value >>= 16;
221
          value &= 0xffff;
222
        }
223
      *valuep = value;
224
 
225
      return errmsg;
226
    }
227
 
228
  /* We add %uhi in case a user just wants the high 16-bits or is using
229
     an insn like ori for %lo which does not sign-propagate.  */
230
  if (strncasecmp (*strp, "%uhi(", 5) == 0)
231
    {
232
      enum cgen_parse_operand_result result_type;
233
      bfd_vma value;
234
      const char *errmsg;
235
 
236
      *strp += 5;
237
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IQ2000_UHI16,
238
                                   & result_type, & value);
239
      if (**strp != ')')
240
        return MISSING_CLOSING_PARENTHESIS;
241
 
242
      ++*strp;
243
      if (errmsg == NULL
244
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
245
        value >>= 16;
246
 
247
      value &= 0xffff;
248
      *valuep = value;
249
 
250
      return errmsg;
251
    }
252
 
253
  return parse_imm (cd, strp, opindex, valuep);
254
}
255
 
256
/* Handle %lo in a signed context.
257
   The signedness of the value doesn't matter to %lo(), but this also
258
   handles the case where %lo() isn't present.  */
259
 
260
static const char *
261
parse_lo16 (CGEN_CPU_DESC cd,
262
            const char **strp,
263
            int opindex,
264
            unsigned long *valuep)
265
{
266
  if (strncasecmp (*strp, "%lo(", 4) == 0)
267
    {
268
      const char *errmsg;
269
      enum cgen_parse_operand_result result_type;
270
      bfd_vma value;
271
 
272
      *strp += 4;
273
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
274
                                   & result_type, & value);
275
      if (**strp != ')')
276
        return MISSING_CLOSING_PARENTHESIS;
277
      ++*strp;
278
      if (errmsg == NULL
279
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
280
        value &= 0xffff;
281
      *valuep = value;
282
      return errmsg;
283
    }
284
 
285
  return parse_imm (cd, strp, opindex, valuep);
286
}
287
 
288
/* Handle %lo in a negated signed context.
289
   The signedness of the value doesn't matter to %lo(), but this also
290
   handles the case where %lo() isn't present.  */
291
 
292
static const char *
293
parse_mlo16 (CGEN_CPU_DESC cd,
294
             const char **strp,
295
             int opindex,
296
             unsigned long *valuep)
297
{
298
  if (strncasecmp (*strp, "%lo(", 4) == 0)
299
    {
300
      const char *errmsg;
301
      enum cgen_parse_operand_result result_type;
302
      bfd_vma value;
303
 
304
      *strp += 4;
305
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
306
                                   & result_type, & value);
307
      if (**strp != ')')
308
        return MISSING_CLOSING_PARENTHESIS;
309
      ++*strp;
310
      if (errmsg == NULL
311
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
312
        value = (-value) & 0xffff;
313
      *valuep = value;
314
      return errmsg;
315
    }
316
 
317
  return parse_mimm (cd, strp, opindex, valuep);
318
}
319
 
320
/* -- */

powered by: WebSVN 2.1.0

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