OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [gdb-6.8/] [pre-binutils-2.20.1-sync/] [opcodes/] [s390-mkopc.c] - Blame information for rev 457

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

Line No. Rev Author Line
1 24 jeremybenn
/* s390-mkopc.c -- Generates opcode table out of s390-opc.txt
2
   Copyright 2000, 2001, 2003, 2007 Free Software Foundation, Inc.
3
   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
4
 
5
   This file is part of the GNU opcodes library.
6
 
7
   This library is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
 
12
   It is distributed in the hope that it will be useful, but WITHOUT
13
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15
   License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this file; see the file COPYING.  If not, write to the
19
   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
 
26
/* Taken from opcodes/s390.h */
27
enum s390_opcode_mode_val
28
  {
29
    S390_OPCODE_ESA = 0,
30
    S390_OPCODE_ZARCH
31
  };
32
 
33
enum s390_opcode_cpu_val
34
  {
35
    S390_OPCODE_G5 = 0,
36
    S390_OPCODE_G6,
37
    S390_OPCODE_Z900,
38
    S390_OPCODE_Z990,
39
    S390_OPCODE_Z9_109,
40
    S390_OPCODE_Z9_EC
41
  };
42
 
43
struct op_struct
44
  {
45
    char  opcode[16];
46
    char  mnemonic[16];
47
    char  format[16];
48
    int   mode_bits;
49
    int   min_cpu;
50
 
51
    unsigned long long sort_value;
52
    int   no_nibbles;
53
  };
54
 
55
struct op_struct *op_array;
56
int max_ops;
57
int no_ops;
58
 
59
static void
60
createTable (void)
61
{
62
  max_ops = 256;
63
  op_array = malloc (max_ops * sizeof (struct op_struct));
64
  no_ops = 0;
65
}
66
 
67
/* `insertOpcode': insert an op_struct into sorted opcode array.  */
68
 
69
static void
70
insertOpcode (char *opcode, char *mnemonic, char *format,
71
              int min_cpu, int mode_bits)
72
{
73
  char *str;
74
  unsigned long long sort_value;
75
  int no_nibbles;
76
  int ix, k;
77
 
78
  while (no_ops >= max_ops)
79
    {
80
      max_ops = max_ops * 2;
81
      op_array = realloc (op_array, max_ops * sizeof (struct op_struct));
82
    }
83
 
84
  sort_value = 0;
85
  str = opcode;
86
  for (ix = 0; ix < 16; ix++)
87
    {
88
      if (*str >= '0' && *str <= '9')
89
        sort_value = (sort_value << 4) + (*str - '0');
90
      else if (*str >= 'a' && *str <= 'f')
91
        sort_value = (sort_value << 4) + (*str - 'a' + 10);
92
      else if (*str >= 'A' && *str <= 'F')
93
        sort_value = (sort_value << 4) + (*str - 'A' + 10);
94
      else if (*str == '?')
95
        sort_value <<= 4;
96
      else
97
        break;
98
      str ++;
99
    }
100
  sort_value <<= 4*(16 - ix);
101
  sort_value += (min_cpu << 8) + mode_bits;
102
  no_nibbles = ix;
103
  for (ix = 0; ix < no_ops; ix++)
104
    if (sort_value > op_array[ix].sort_value)
105
      break;
106
  for (k = no_ops; k > ix; k--)
107
    op_array[k] = op_array[k-1];
108
  strcpy(op_array[ix].opcode, opcode);
109
  strcpy(op_array[ix].mnemonic, mnemonic);
110
  strcpy(op_array[ix].format, format);
111
  op_array[ix].sort_value = sort_value;
112
  op_array[ix].no_nibbles = no_nibbles;
113
  op_array[ix].min_cpu = min_cpu;
114
  op_array[ix].mode_bits = mode_bits;
115
  no_ops++;
116
}
117
 
118
struct s390_cond_ext_format
119
{
120
  char nibble;
121
  char extension[4];
122
};
123
 
124
#define NUM_COND_EXTENSIONS 20
125
 
126
const struct s390_cond_ext_format s390_cond_extensions[NUM_COND_EXTENSIONS] =
127
  {
128
    { '1', "o" },    /* jump on overflow / if ones */
129
    { '2', "h" },    /* jump on A high */
130
    { '2', "p" },    /* jump on plus */
131
    { '3', "nle" },  /* jump on not low or equal */
132
    { '4', "l" },    /* jump on A low */
133
    { '4', "m" },    /* jump on minus / if mixed */
134
    { '5', "nhe" },  /* jump on not high or equal */
135
    { '6', "lh" },   /* jump on low or high */
136
    { '7', "ne" },   /* jump on A not equal B */
137
    { '7', "nz" },   /* jump on not zero / if not zeros */
138
    { '8', "e" },    /* jump on A equal B */
139
    { '8', "z" },    /* jump on zero / if zeros */
140
    { '9', "nlh" },  /* jump on not low or high */
141
    { 'a', "he" },   /* jump on high or equal */
142
    { 'b', "nl" },   /* jump on A not low */
143
    { 'b', "nm" },   /* jump on not minus / if not mixed */
144
    { 'c', "le" },   /* jump on low or equal */
145
    { 'd', "nh" },   /* jump on A not high */
146
    { 'd', "np" },   /* jump on not plus */
147
    { 'e', "no" },   /* jump on not overflow / if not ones */
148
  };
149
 
150
/* As with insertOpcode instructions are added to the sorted opcode
151
   array.  Additionally mnemonics containing the '*<number>' tag are
152
   expanded to the set of conditional instructions described by
153
   s390_cond_extensions with the '*<number>' tag replaced by the
154
   respective mnemonic extensions.  */
155
 
156
static void
157
expandConditionalJump (char *opcode, char *mnemonic, char *format,
158
                       int min_cpu, int mode_bits)
159
{
160
  char prefix[5];
161
  char suffix[5];
162
  char number[5];
163
  int mask_start, i = 0, star_found = 0, reading_number = 0;
164
  int number_p = 0, suffix_p = 0, prefix_p = 0;
165
 
166
  while (mnemonic[i] != '\0')
167
    {
168
      switch (mnemonic[i])
169
        {
170
        case '*':
171
          if (star_found)
172
            goto malformed_mnemonic;
173
 
174
          star_found = 1;
175
          reading_number = 1;
176
          break;
177
 
178
        case '0': case '1': case '2': case '3': case '4':
179
        case '5': case '6': case '7': case '8': case '9':
180
          if (!star_found || !reading_number)
181
            goto malformed_mnemonic;
182
 
183
          number[number_p++] = mnemonic[i];
184
          break;
185
 
186
        default:
187
          if (reading_number)
188
            {
189
              if (!number_p)
190
                goto malformed_mnemonic;
191
              else
192
                reading_number = 0;
193
            }
194
 
195
          if (star_found)
196
            suffix[suffix_p++] = mnemonic[i];
197
          else
198
            prefix[prefix_p++] = mnemonic[i];
199
        }
200
      i++;
201
    }
202
 
203
  prefix[prefix_p] = '\0';
204
  suffix[suffix_p] = '\0';
205
  number[number_p] = '\0';
206
 
207
  if (sscanf (number, "%d", &mask_start) != 1)
208
    goto malformed_mnemonic;
209
 
210
  if (mask_start & 3)
211
    {
212
      fprintf (stderr, "Conditional mask not at nibble boundary in: %s\n",
213
               mnemonic);
214
      return;
215
    }
216
 
217
  mask_start >>= 2;
218
 
219
  for (i = 0; i < NUM_COND_EXTENSIONS; i++)
220
    {
221
      char new_mnemonic[15];
222
 
223
      strcpy (new_mnemonic, prefix);
224
      strcat (new_mnemonic, s390_cond_extensions[i].extension);
225
      strcat (new_mnemonic, suffix);
226
      opcode[mask_start] = s390_cond_extensions[i].nibble;
227
      insertOpcode (opcode, new_mnemonic, format, min_cpu, mode_bits);
228
    }
229
  return;
230
 
231
 malformed_mnemonic:
232
  fprintf (stderr, "Malformed mnemonic: %s\n", mnemonic);
233
}
234
 
235
static char file_header[] =
236
  "/* The opcode table. This file was generated by s390-mkopc.\n\n"
237
  "   The format of the opcode table is:\n\n"
238
  "   NAME           OPCODE     MASK    OPERANDS\n\n"
239
  "   Name is the name of the instruction.\n"
240
  "   OPCODE is the instruction opcode.\n"
241
  "   MASK is the opcode mask; this is used to tell the disassembler\n"
242
  "     which bits in the actual opcode must match OPCODE.\n"
243
  "   OPERANDS is the list of operands.\n\n"
244
  "   The disassembler reads the table in order and prints the first\n"
245
  "   instruction which matches.  */\n\n"
246
  "const struct s390_opcode s390_opcodes[] =\n  {\n";
247
 
248
/* `dumpTable': write opcode table.  */
249
 
250
static void
251
dumpTable (void)
252
{
253
  char *str;
254
  int  ix;
255
 
256
  /*  Write hash table entries (slots).  */
257
  printf (file_header);
258
 
259
  for (ix = 0; ix < no_ops; ix++)
260
    {
261
      printf ("  { \"%s\", ", op_array[ix].mnemonic);
262
      for (str = op_array[ix].opcode; *str != 0; str++)
263
        if (*str == '?')
264
          *str = '0';
265
      printf ("OP%i(0x%sLL), ",
266
              op_array[ix].no_nibbles*4, op_array[ix].opcode);
267
      printf ("MASK_%s, INSTR_%s, ",
268
              op_array[ix].format, op_array[ix].format);
269
      printf ("%i, ", op_array[ix].mode_bits);
270
      printf ("%i}", op_array[ix].min_cpu);
271
      if (ix < no_ops-1)
272
        printf (",\n");
273
      else
274
        printf ("\n");
275
    }
276
  printf ("};\n\n");
277
  printf ("const int s390_num_opcodes =\n");
278
  printf ("  sizeof (s390_opcodes) / sizeof (s390_opcodes[0]);\n\n");
279
}
280
 
281
int
282
main (void)
283
{
284
  char currentLine[256];
285
 
286
  createTable ();
287
 
288
  /*  Read opcode descriptions from `stdin'.  For each mnemonic,
289
      make an entry into the opcode table.  */
290
  while (fgets (currentLine, sizeof (currentLine), stdin) != NULL)
291
    {
292
      char  opcode[16];
293
      char  mnemonic[16];
294
      char  format[16];
295
      char  description[64];
296
      char  cpu_string[16];
297
      char  modes_string[16];
298
      int   min_cpu;
299
      int   mode_bits;
300
      char  *str;
301
 
302
      if (currentLine[0] == '#')
303
        continue;
304
      memset (opcode, 0, 8);
305
      if (sscanf (currentLine, "%15s %15s %15s \"%[^\"]\" %15s %15s",
306
                  opcode, mnemonic, format, description,
307
                  cpu_string, modes_string) == 6)
308
        {
309
          if (strcmp (cpu_string, "g5") == 0)
310
            min_cpu = S390_OPCODE_G5;
311
          else if (strcmp (cpu_string, "g6") == 0)
312
            min_cpu = S390_OPCODE_G6;
313
          else if (strcmp (cpu_string, "z900") == 0)
314
            min_cpu = S390_OPCODE_Z900;
315
          else if (strcmp (cpu_string, "z990") == 0)
316
            min_cpu = S390_OPCODE_Z990;
317
          else if (strcmp (cpu_string, "z9-109") == 0)
318
            min_cpu = S390_OPCODE_Z9_109;
319
          else if (strcmp (cpu_string, "z9-ec") == 0)
320
            min_cpu = S390_OPCODE_Z9_EC;
321
          else {
322
            fprintf (stderr, "Couldn't parse cpu string %s\n", cpu_string);
323
            exit (1);
324
          }
325
 
326
          str = modes_string;
327
          mode_bits = 0;
328
          do {
329
            if (strncmp (str, "esa", 3) == 0
330
                && (str[3] == 0 || str[3] == ',')) {
331
              mode_bits |= 1 << S390_OPCODE_ESA;
332
              str += 3;
333
            } else if (strncmp (str, "zarch", 5) == 0
334
                       && (str[5] == 0 || str[5] == ',')) {
335
              mode_bits |= 1 << S390_OPCODE_ZARCH;
336
              str += 5;
337
            } else {
338
              fprintf (stderr, "Couldn't parse modes string %s\n",
339
                       modes_string);
340
              exit (1);
341
            }
342
            if (*str == ',')
343
              str++;
344
          } while (*str != 0);
345
 
346
          if (!strchr (mnemonic, '*'))
347
            insertOpcode (opcode, mnemonic, format, min_cpu, mode_bits);
348
          else
349
            expandConditionalJump (opcode, mnemonic, format,
350
                                   min_cpu, mode_bits);
351
        }
352
      else
353
        fprintf (stderr, "Couldn't scan line %s\n", currentLine);
354
    }
355
 
356
  dumpTable ();
357
  return 0;
358
}

powered by: WebSVN 2.1.0

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