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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
/* Morpho Technologies mRISC opcode support, for GNU Binutils.  -*- C -*-
2
   Copyright 2001, 2007, 2008, 2009 Free Software Foundation, Inc.
3
 
4
   Contributed by Red Hat Inc; developed under contract from
5
   Morpho Technologies.
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
 
25
/* Each section is delimited with start and end markers.
26
 
27
   -opc.h additions use: "-- opc.h"
28
   -opc.c additions use: "-- opc.c"
29
   -asm.c additions use: "-- asm.c"
30
   -dis.c additions use: "-- dis.c"
31
   -ibd.h additions use: "-- ibd.h"  */
32
 
33
/* -- opc.h */
34
 
35
/* Check applicability of instructions against machines.  */
36
#define CGEN_VALIDATE_INSN_SUPPORTED
37
 
38
/* Allows reason codes to be output when assembler errors occur.  */
39
#define CGEN_VERBOSE_ASSEMBLER_ERRORS
40
 
41
/* Override disassembly hashing - there are variable bits in the top
42
   byte of these instructions.  */
43
#define CGEN_DIS_HASH_SIZE 8
44
#define CGEN_DIS_HASH(buf, value) (((* (unsigned char *) (buf)) >> 5) % CGEN_DIS_HASH_SIZE)
45
 
46
#define CGEN_ASM_HASH_SIZE 127
47
#define CGEN_ASM_HASH(insn) mt_asm_hash (insn)
48
 
49
extern unsigned int mt_asm_hash (const char *);
50
 
51
extern int mt_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
52
 
53
 
54
/* -- opc.c */
55
#include "safe-ctype.h"
56
 
57
/* Special check to ensure that instruction exists for given machine.  */
58
 
59
int
60
mt_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
61
{
62
  int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
63
 
64
  /* No mach attribute?  Assume it's supported for all machs.  */
65
  if (machs == 0)
66
    return 1;
67
 
68
  return ((machs & cd->machs) != 0);
69
}
70
 
71
/* A better hash function for instruction mnemonics.  */
72
 
73
unsigned int
74
mt_asm_hash (const char* insn)
75
{
76
  unsigned int hash;
77
  const char* m = insn;
78
 
79
  for (hash = 0; *m && ! ISSPACE (*m); m++)
80
    hash = (hash * 23) ^ (0x1F & TOLOWER (*m));
81
 
82
  /* printf ("%s %d\n", insn, (hash % CGEN_ASM_HASH_SIZE)); */
83
 
84
  return hash % CGEN_ASM_HASH_SIZE;
85
}
86
 
87
 
88
/* -- asm.c */
89
/* Range checking for signed numbers.  Returns 0 if acceptable
90
   and 1 if the value is out of bounds for a signed quantity.  */
91
 
92
static int
93
signed_out_of_bounds (long val)
94
{
95
  if ((val < -32768) || (val > 32767))
96
    return 1;
97
  return 0;
98
}
99
 
100
static const char *
101
parse_loopsize (CGEN_CPU_DESC cd,
102
                const char **strp,
103
                int opindex,
104
                void *arg)
105
{
106
  signed long * valuep = (signed long *) arg;
107
  const char *errmsg;
108
  bfd_reloc_code_real_type code = BFD_RELOC_NONE;
109
  enum cgen_parse_operand_result result_type;
110
  bfd_vma value;
111
 
112
  /* Is it a control transfer instructions?  */
113
  if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_LOOPSIZE)
114
    {
115
      code = BFD_RELOC_MT_PCINSN8;
116
      errmsg = cgen_parse_address (cd, strp, opindex, code,
117
                                   & result_type, & value);
118
      *valuep = value;
119
      return errmsg;
120
    }
121
 
122
  abort ();
123
}
124
 
125
static const char *
126
parse_imm16 (CGEN_CPU_DESC cd,
127
             const char **strp,
128
             int opindex,
129
             void *arg)
130
{
131
  signed long * valuep = (signed long *) arg;
132
  const char *errmsg;
133
  enum cgen_parse_operand_result result_type;
134
  bfd_reloc_code_real_type code = BFD_RELOC_NONE;
135
  bfd_vma value;
136
 
137
  /* Is it a control transfer instructions?  */
138
  if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16O)
139
    {
140
      code = BFD_RELOC_16_PCREL;
141
      errmsg = cgen_parse_address (cd, strp, opindex, code,
142
                                   & result_type, & value);
143
      if (errmsg == NULL)
144
        {
145
          if (signed_out_of_bounds (value))
146
            errmsg = _("Operand out of range. Must be between -32768 and 32767.");
147
        }
148
      *valuep = value;
149
      return errmsg;
150
    }
151
 
152
  /* If it's not a control transfer instruction, then
153
     we have to check for %OP relocating operators.  */
154
  if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16L)
155
    ;
156
  else if (strncmp (*strp, "%hi16", 5) == 0)
157
    {
158
      *strp += 5;
159
      code = BFD_RELOC_HI16;
160
    }
161
  else if (strncmp (*strp, "%lo16", 5) == 0)
162
    {
163
      *strp += 5;
164
      code = BFD_RELOC_LO16;
165
    }
166
 
167
  /* If we found a %OP relocating operator, then parse it as an address.
168
     If not, we need to parse it as an integer, either signed or unsigned
169
     depending on which operand type we have.  */
170
  if (code != BFD_RELOC_NONE)
171
    {
172
       /* %OP relocating operator found.  */
173
       errmsg = cgen_parse_address (cd, strp, opindex, code,
174
                                   & result_type, & value);
175
       if (errmsg == NULL)
176
         {
177
           switch (result_type)
178
             {
179
             case (CGEN_PARSE_OPERAND_RESULT_NUMBER):
180
               if (code == BFD_RELOC_HI16)
181
                 value = (value >> 16) & 0xFFFF;
182
               else if (code == BFD_RELOC_LO16)
183
                 value = value  & 0xFFFF;
184
               else
185
                 errmsg = _("Biiiig Trouble in parse_imm16!");
186
               break;
187
 
188
             case (CGEN_PARSE_OPERAND_RESULT_QUEUED):
189
               /* No special processing for this case.  */
190
               break;
191
 
192
             default:
193
               errmsg = _("The percent-operator's operand is not a symbol");
194
               break;
195
             }
196
         }
197
       *valuep = value;
198
    }
199
  else
200
    {
201
      /* Parse hex values like 0xffff as unsigned, and sign extend
202
         them manually.  */
203
      int parse_signed = (opindex == (CGEN_OPERAND_TYPE)MT_OPERAND_IMM16);
204
 
205
      if ((*strp)[0] == '0'
206
          && ((*strp)[1] == 'x' || (*strp)[1] == 'X'))
207
        parse_signed = 0;
208
 
209
      /* No relocating operator.  Parse as an number.  */
210
      if (parse_signed)
211
        {
212
          /* Parse as as signed integer.  */
213
 
214
          errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
215
 
216
          if (errmsg == NULL)
217
            {
218
#if 0
219
              /* Manual range checking is needed for the signed case.  */
220
              if (*valuep & 0x8000)
221
                value = 0xffff0000 | *valuep;
222
              else
223
                value = *valuep;
224
 
225
              if (signed_out_of_bounds (value))
226
                errmsg = _("Operand out of range. Must be between -32768 and 32767.");
227
              /* Truncate to 16 bits. This is necessary
228
                 because cgen will have sign extended *valuep.  */
229
              *valuep &= 0xFFFF;
230
#endif
231
            }
232
        }
233
      else
234
        {
235
          /* MT_OPERAND_IMM16Z.  Parse as an unsigned integer.  */
236
          errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, (unsigned long *) valuep);
237
 
238
          if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16
239
              && *valuep >= 0x8000
240
              && *valuep <= 0xffff)
241
            *valuep -= 0x10000;
242
        }
243
    }
244
 
245
  return errmsg;
246
}
247
 
248
 
249
static const char *
250
parse_dup (CGEN_CPU_DESC cd,
251
           const char **strp,
252
           int opindex,
253
           unsigned long *valuep)
254
{
255
  const char *errmsg = NULL;
256
 
257
  if (strncmp (*strp, "dup", 3) == 0 || strncmp (*strp, "DUP", 3) == 0)
258
    {
259
      *strp += 3;
260
      *valuep = 1;
261
    }
262
  else if (strncmp (*strp, "xx", 2) == 0 || strncmp (*strp, "XX", 2) == 0)
263
    {
264
      *strp += 2;
265
      *valuep = 0;
266
    }
267
  else
268
    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
269
 
270
  return errmsg;
271
}
272
 
273
 
274
static const char *
275
parse_ball (CGEN_CPU_DESC cd,
276
            const char **strp,
277
            int opindex,
278
            unsigned long *valuep)
279
{
280
  const char *errmsg = NULL;
281
 
282
  if (strncmp (*strp, "all", 3) == 0 || strncmp (*strp, "ALL", 3) == 0)
283
    {
284
      *strp += 3;
285
      *valuep = 1;
286
    }
287
  else if (strncmp (*strp, "one", 3) == 0 || strncmp (*strp, "ONE", 3) == 0)
288
    {
289
      *strp += 3;
290
      *valuep = 0;
291
    }
292
  else
293
    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
294
 
295
  return errmsg;
296
}
297
 
298
static const char *
299
parse_xmode (CGEN_CPU_DESC cd,
300
             const char **strp,
301
             int opindex,
302
             unsigned long *valuep)
303
{
304
  const char *errmsg = NULL;
305
 
306
  if (strncmp (*strp, "pm", 2) == 0 || strncmp (*strp, "PM", 2) == 0)
307
    {
308
      *strp += 2;
309
      *valuep = 1;
310
    }
311
  else if (strncmp (*strp, "xm", 2) == 0 || strncmp (*strp, "XM", 2) == 0)
312
    {
313
      *strp += 2;
314
      *valuep = 0;
315
    }
316
  else
317
    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
318
 
319
  return errmsg;
320
}
321
 
322
static const char *
323
parse_rc (CGEN_CPU_DESC cd,
324
          const char **strp,
325
          int opindex,
326
          unsigned long *valuep)
327
{
328
  const char *errmsg = NULL;
329
 
330
  if (strncmp (*strp, "r", 1) == 0 || strncmp (*strp, "R", 1) == 0)
331
    {
332
      *strp += 1;
333
      *valuep = 1;
334
    }
335
  else if (strncmp (*strp, "c", 1) == 0 || strncmp (*strp, "C", 1) == 0)
336
    {
337
      *strp += 1;
338
      *valuep = 0;
339
    }
340
  else
341
    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
342
 
343
  return errmsg;
344
}
345
 
346
static const char *
347
parse_cbrb (CGEN_CPU_DESC cd,
348
            const char **strp,
349
            int opindex,
350
            unsigned long *valuep)
351
{
352
  const char *errmsg = NULL;
353
 
354
  if (strncmp (*strp, "rb", 2) == 0 || strncmp (*strp, "RB", 2) == 0)
355
    {
356
      *strp += 2;
357
      *valuep = 1;
358
    }
359
  else if (strncmp (*strp, "cb", 2) == 0 || strncmp (*strp, "CB", 2) == 0)
360
    {
361
      *strp += 2;
362
      *valuep = 0;
363
    }
364
  else
365
    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
366
 
367
  return errmsg;
368
}
369
 
370
static const char *
371
parse_rbbc (CGEN_CPU_DESC cd,
372
            const char **strp,
373
            int opindex,
374
            unsigned long *valuep)
375
{
376
  const char *errmsg = NULL;
377
 
378
  if (strncmp (*strp, "rt", 2) == 0 || strncmp (*strp, "RT", 2) == 0)
379
    {
380
      *strp += 2;
381
      *valuep = 0;
382
    }
383
  else if (strncmp (*strp, "br1", 3) == 0 || strncmp (*strp, "BR1", 3) == 0)
384
    {
385
      *strp += 3;
386
      *valuep = 1;
387
    }
388
  else if (strncmp (*strp, "br2", 3) == 0 || strncmp (*strp, "BR2", 3) == 0)
389
    {
390
      *strp += 3;
391
      *valuep = 2;
392
    }
393
  else if (strncmp (*strp, "cs", 2) == 0 || strncmp (*strp, "CS", 2) == 0)
394
    {
395
      *strp += 2;
396
      *valuep = 3;
397
    }
398
  else
399
    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
400
 
401
  return errmsg;
402
}
403
 
404
static const char *
405
parse_type (CGEN_CPU_DESC cd,
406
            const char **strp,
407
            int opindex,
408
            unsigned long *valuep)
409
{
410
  const char *errmsg = NULL;
411
 
412
  if (strncmp (*strp, "odd", 3) == 0 || strncmp (*strp, "ODD", 3) == 0)
413
    {
414
      *strp += 3;
415
      *valuep = 0;
416
    }
417
  else if (strncmp (*strp, "even", 4) == 0 || strncmp (*strp, "EVEN", 4) == 0)
418
    {
419
      *strp += 4;
420
      *valuep = 1;
421
    }
422
  else if (strncmp (*strp, "oe", 2) == 0 || strncmp (*strp, "OE", 2) == 0)
423
    {
424
      *strp += 2;
425
      *valuep = 2;
426
    }
427
  else
428
    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
429
 
430
 if ((errmsg == NULL) && (*valuep == 3))
431
    errmsg = _("invalid operand.  type may have values 0,1,2 only.");
432
 
433
  return errmsg;
434
}
435
 
436
/* -- dis.c */
437
static void print_dollarhex (CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int);
438
static void print_pcrel (CGEN_CPU_DESC, PTR, long, unsigned, bfd_vma, int);
439
 
440
static void
441
print_dollarhex (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
442
                 void * dis_info,
443
                 long value,
444
                 unsigned int attrs ATTRIBUTE_UNUSED,
445
                 bfd_vma pc ATTRIBUTE_UNUSED,
446
                 int length ATTRIBUTE_UNUSED)
447
{
448
  disassemble_info *info = (disassemble_info *) dis_info;
449
 
450
  info->fprintf_func (info->stream, "$%lx", value);
451
 
452
  if (0)
453
    print_normal (cd, dis_info, value, attrs, pc, length);
454
}
455
 
456
static void
457
print_pcrel (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
458
             void * dis_info,
459
             long value,
460
             unsigned int attrs ATTRIBUTE_UNUSED,
461
             bfd_vma pc ATTRIBUTE_UNUSED,
462
             int length ATTRIBUTE_UNUSED)
463
{
464
  print_address (cd, dis_info, value + pc, attrs, pc, length);
465
}
466
 
467
/* -- */
468
 
469
 
470
 
471
 
472
 

powered by: WebSVN 2.1.0

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