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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_58/] [or1ksim/] [cpu/] [or32/] [generate.c] - Blame information for rev 1342

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

Line No. Rev Author Line
1 709 markom
/* generate.c -- generates file execgen.c from instruction set
2
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
3 1342 nogj
   Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
4 709 markom
 
5
This file is part of OpenRISC 1000 Architectural Simulator.
6
 
7
This program 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 2 of the License, or
10
(at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
 
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <string.h>
24
#include <stdarg.h>
25
#include <ctype.h>
26
 
27
#include "config.h"
28
#include "opcode/or32.h"
29
#include "abstract.h"
30
 
31 1342 nogj
static char *in_file;
32
static char *out_file;
33
static unsigned long op[MAX_OPERANDS];
34 709 markom
 
35 1342 nogj
/* Whether this instruction stores something in register */
36
static int write_to_reg;
37 709 markom
 
38 1342 nogj
static int out_lines = 0;
39 709 markom
 
40 1342 nogj
void debug(int level, const char *format, ...)
41 709 markom
{
42 1308 phoenix
#if DEBUG
43 709 markom
  char *p;
44
  va_list ap;
45
 
46
  if ((p = malloc(1000)) == NULL)
47
    return;
48
  va_start(ap, format);
49
  (void) vsnprintf(p, 1000, format, ap);
50
  va_end(ap);
51
  printf("%s\n", p);
52
  fflush(stdout);
53
  free(p);
54
#endif
55
}
56
 
57 1342 nogj
static int shift_fprintf(int level, FILE *f, const char *fmt, ...)
58
{
59
  va_list ap;
60
  int i;
61 713 markom
 
62 1342 nogj
  va_start(ap, fmt);
63
  for(i = 0; i < level; i++)
64
    fprintf(f, "  ");
65 712 markom
 
66 1342 nogj
  i = vfprintf(f, fmt, ap);
67
  va_end(ap);
68
 
69
  out_lines++;
70
  return i + (level * 2);
71 712 markom
}
72
 
73 713 markom
/* Generates a execute sequence for one instruction */
74 709 markom
int output_function (FILE *fo, const char *func_name, int level)
75
{
76
  FILE *fi;
77 1342 nogj
  int olevel;
78
  int line_num = 0;
79
 
80
  if ((fi = fopen (in_file, "rt")) == NULL) {
81
    printf("could not open file\n");
82
    return 1;
83
  }
84
 
85 709 markom
  while (!feof (fi)) {
86
    char line[10000], *str = line;
87
    fgets (str, sizeof (line), fi);
88 1342 nogj
    line[sizeof (line) - 1] = 0;
89
    line_num++;
90 709 markom
    if (strncmp (str, "INSTRUCTION (", 13) == 0) {
91
      char *s;
92
      str += 13;
93
      while (isspace (*str)) str++;
94
      s = str;
95
      while (*s && *s != ')') s++;
96
      *s = 0;
97
      while (isspace(*(s - 1))) s--;
98
      *s = 0;
99
      if (strcmp (str, func_name) == 0) {
100 712 markom
        olevel = 1;
101 709 markom
        str += strlen (str) + 1;
102
        while (isspace (*str)) str++;
103
        s = str;
104
        while (*s && *s != '\n' && *s != '\r') s++;
105
        *s = 0;
106
        while (isspace(*(s - 1))) s--;
107
        *s = 0;
108 1342 nogj
        /*shift_fprintf (level, fo, "#line %i \"%s\"\n", line_num, in_file);*/
109
        shift_fprintf (level, fo, "%s", str);
110
        shift_fprintf (level, fo, "   /* \"%s\" */\n", func_name);
111 709 markom
        do {
112 712 markom
          fgets (line, sizeof (line), fi);
113
          line[sizeof(line) - 1] = 0;
114
          for (str = line; *str; str++) {
115 1342 nogj
            if (*str == '{') olevel++;
116
            else if (*str == '}') olevel--;
117 712 markom
          }
118 1342 nogj
          shift_fprintf (level, fo, "%s", line);
119 709 markom
        } while (olevel);
120 1342 nogj
        fclose(fi);
121
        /*shift_fprintf (level, fo, "#line %i \"%s\"\n", out_lines, out_file);*/
122 709 markom
        return 0;
123
      }
124
    }
125
  }
126 1342 nogj
  shift_fprintf (level, fo, "%s ();\n", func_name);
127 1244 hpanther
 
128
  fclose(fi);
129 709 markom
  return 0;
130
}
131
 
132
/* Parses and puts operands into op[] structure.
133
   Replacement for eval_operands routine. */
134
 
135 1342 nogj
static int
136 709 markom
gen_eval_operands (FILE *fo, int insn_index, int level)
137
{
138
  struct insn_op_struct *opd = op_start[insn_index];
139 1342 nogj
  int i;
140
  int num_ops;
141
  int nbits = 0;
142
  int set_param = 0;
143 709 markom
  int dis = 0;
144 1342 nogj
  int sbit;
145 709 markom
 
146 1342 nogj
  write_to_reg = 0;
147
 
148
  shift_fprintf (level, fo, "unsigned long ");
149
 
150
  /* Count number of operands */
151
  for (i = 0, num_ops = 0;; i++) {
152
    if (!(opd[i].type & OPTYPE_OP))
153
      continue;
154
    if (opd[i].type & OPTYPE_DIS)
155
      continue;
156
    if (num_ops)
157
      fprintf(fo, ", ");
158
    fprintf(fo, "%c", 'a' + num_ops);
159
    num_ops++;
160
    if (opd[i].type & OPTYPE_LAST)
161
      break;
162
  }
163
 
164
  fprintf (fo, ";\n");
165
 
166
  shift_fprintf (level, fo, "/* Number of operands: %i */\n", num_ops);
167
 
168
  i = 0;
169
  num_ops = 0;
170
  do {
171
/*
172
    printf("opd[%i].type<last> = %c\n", i, opd->type & OPTYPE_LAST ? '1' : '0');    printf("opd[%i].type<op> = %c\n", i, opd->type & OPTYPE_OP ? '1' : '0');
173
    printf("opd[%i].type<reg> = %c\n", i, opd->type & OPTYPE_REG ? '1' : '0');
174
    printf("opd[%i].type<sig> = %c\n", i, opd->type & OPTYPE_SIG ? '1' : '0');
175
    printf("opd[%i].type<dis> = %c\n", i, opd->type & OPTYPE_DIS ? '1' : '0');
176
    printf("opd[%i].type<shr> = %i\n", i, opd->type & OPTYPE_SHR);
177
    printf("opd[%i].type<sbit> = %i\n", i, (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR);
178
    printf("opd[%i].data = %i\n", i, opd->data);
179
*/
180
 
181
    if (!nbits)
182
      shift_fprintf (level, fo, "%c = (insn >> %i) & 0x%x;\n", 'a' + num_ops,
183
                     opd->type & OPTYPE_SHR, (1 << opd->data) - 1);
184
    else
185
      shift_fprintf (level, fo, "%c |= ((insn >> %i) & 0x%x) << %i;\n",
186
                     'a' + num_ops, opd->type & OPTYPE_SHR,
187
                     (1 << opd->data) - 1, nbits);
188
 
189
    nbits += opd->data;
190
 
191
    if (opd->type & OPTYPE_DIS) {
192
      sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
193 709 markom
      if (opd->type & OPTYPE_SIG)
194 1342 nogj
        shift_fprintf (level, fo, "if(%c & 0x%08x) %c |= 0x%x;\n",
195
                       'a' + num_ops, 1 << sbit, 'a' + num_ops,
196
                       0xffffffff << sbit);
197 709 markom
      opd++;
198 1342 nogj
      shift_fprintf (level, fo, "(signed)%c += (signed)reg[(insn >> %i) & 0x%x];\n",
199
                     'a' + num_ops, opd->type & OPTYPE_SHR,
200
                     (1 << opd->data) - 1);
201
      dis = 1;
202 709 markom
    }
203 1342 nogj
 
204
    if (opd->type & OPTYPE_OP) {
205
      sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
206
      if (opd->type & OPTYPE_SIG)
207
        shift_fprintf (level, fo, "if(%c & 0x%08x) %c |= 0x%x;\n",
208
                       'a' + num_ops, 1 << sbit, 'a' + num_ops,
209
                       0xffffffff << sbit);
210
      if ((opd->type & OPTYPE_REG) && !dis) {
211
        if(!i) {
212
          shift_fprintf (level, fo, "#define SET_PARAM0(val) reg[a] = val\n");
213
          set_param = 1;
214
        }
215
        shift_fprintf (level, fo, "#define PARAM%i reg[%c]\n", num_ops,
216
                      'a' + num_ops);
217
        if(opd->type & OPTYPE_DST)
218
          write_to_reg = 1;
219
      } else {
220
        shift_fprintf (level, fo, "#define PARAM%i %c\n", num_ops,
221
                       'a' + num_ops);
222
      }
223
 
224
      op[num_ops] = opd->type;
225
      if(dis)
226
        op[num_ops] |= OPTYPE_DIS;
227
      num_ops++;
228
      nbits = 0;
229
      dis = 0;
230
    }
231
 
232
    if ((opd->type & OPTYPE_LAST))
233
      break;
234
    opd++;
235
    i++;
236
  } while (1);
237
 
238
  output_function (fo, or32_opcodes[insn_index].function_name, level);
239
 
240
  if (set_param)
241
    shift_fprintf (level, fo, "#undef SET_PARAM\n");
242
 
243
  for (i = 0; i < num_ops; i++)
244
    shift_fprintf (level, fo, "#undef PARAM%i\n", i);
245
 
246
  return num_ops;
247 709 markom
}
248
 
249 713 markom
/* Generates decode and execute for one instruction instance */
250 1342 nogj
static int output_call (FILE *fo, int index, int level)
251 709 markom
{
252 712 markom
  int i;
253 1342 nogj
  int num_op;
254
 
255
  /*printf ("%i:%s\n", index, insn_name (index));*/
256
 
257
  shift_fprintf (level++, fo, "{\n");
258
 
259 717 markom
  if (index >= 0)
260 1342 nogj
    num_op = gen_eval_operands (fo, index, level);
261 717 markom
  else
262
    num_op = 0;
263 1342 nogj
 
264 709 markom
  if (index < 0) output_function (fo, "l_invalid", level);
265 1342 nogj
 
266 713 markom
  fprintf (fo, "\n");
267 717 markom
 
268 1342 nogj
  shift_fprintf (level++, fo, "if (do_stats) {\n");
269
  shift_fprintf (level, fo, "num_op = %i;\n", num_op);
270
 
271
  if (num_op) shift_fprintf (level, fo, "op = &current->op[0];\n");
272
  shift_fprintf (level, fo, "current->insn_index = %i;   /* \"%s\" */\n", index,
273
                 insn_name (index));
274
 
275 717 markom
  for (i = 0; i < num_op; i++) {
276 1342 nogj
    shift_fprintf (level, fo, "op[%i] = %c;\n", i, 'a' + i);
277
    shift_fprintf (level, fo, "op[%i + MAX_OPERANDS] = 0x%08x;\n", i, op[i]);
278 717 markom
  }
279 1342 nogj
  shift_fprintf (level, fo, "analysis(current);\n");
280
  shift_fprintf (--level, fo, "}\n");
281
  if (write_to_reg)
282
    shift_fprintf (level, fo, "reg[0] = 0; /* Repair in case we changed it */\n");
283
  shift_fprintf (--level, fo, "}\n");
284 709 markom
  return 0;
285
}
286
 
287 713 markom
/* Generates .c file header */
288 1342 nogj
static int generate_header (FILE *fo)
289 709 markom
{
290
  fprintf (fo, "/* This file was automatically generated by generate (see cpu/or32/generate.c) */\n\n");
291 712 markom
  fprintf (fo, "static inline void decode_execute (struct iqueue_entry *current)\n{\n");
292 709 markom
  fprintf (fo, "  unsigned long insn = current->insn;\n");
293 1342 nogj
  out_lines = 5;
294 709 markom
  return 0;
295
}
296
 
297 713 markom
/* Generates .c file footer */
298 1342 nogj
static int generate_footer (FILE *fo)
299 709 markom
{
300
  fprintf (fo, "}\n");
301
  return 0;
302
}
303
 
304
/* Decodes all instructions and generates code for that.  This function
305
   is similar to insn_decode, except it decodes all instructions. */
306
static int generate_body (FILE *fo, unsigned long *a, unsigned long cur_mask, int level)
307
{
308 1342 nogj
  unsigned long shift = *a;
309
  unsigned long mask;
310 709 markom
  int i;
311 1342 nogj
  int prev_inv = 0;
312
 
313 709 markom
  if (!(*a & LEAF_FLAG)) {
314 1342 nogj
    shift = *a++;
315
    mask = *a++;
316
    shift_fprintf (level, fo, "switch((insn >> %i) & 0x%x) {\n", shift,
317
                   mask);
318 709 markom
    for (i = 0; i <= mask; i++, a++) {
319
      if (!*a) {
320 1342 nogj
        shift_fprintf (level, fo, "case 0x%x:\n", i);
321
        prev_inv = 1;
322 709 markom
      } else {
323 1342 nogj
        if(prev_inv) {
324
          shift_fprintf (++level, fo, "/* Invalid instruction(s) */\n");
325
          shift_fprintf (level--, fo, "break;\n");
326 709 markom
        }
327 1342 nogj
        shift_fprintf (level, fo, "case 0x%x:\n", i);
328
        generate_body (fo, automata + *a, cur_mask | (mask << shift), ++level);
329
        shift_fprintf (level--, fo, "break;\n");
330
        prev_inv = 0;
331 709 markom
      }
332
    }
333 1342 nogj
    if (prev_inv) {
334
      shift_fprintf (++level, fo, "/* Invalid instruction(s) */\n");
335
      shift_fprintf (level--, fo, "break;\n");
336 709 markom
    }
337 1342 nogj
    shift_fprintf (level, fo, "}\n");
338 709 markom
  } else {
339
    i = *a & ~LEAF_FLAG;
340 1342 nogj
 
341 709 markom
    /* Final check - do we have direct match?
342
       (based on or32_opcodes this should be the only possibility,
343
       but in case of invalid/missing instruction we must perform a check)  */
344
 
345
    if (ti[i].insn_mask != cur_mask) {
346 1342 nogj
      shift_fprintf (level, fo, "/* Not unique: real mask %08lx and current mask %08lx differ - do final check */\n", ti[i].insn_mask, cur_mask);
347
      shift_fprintf (level++, fo, "if((insn & 0x%x) == 0x%x) {\n",
348
                     ti[i].insn_mask, ti[i].insn);
349 709 markom
    }
350 1342 nogj
    shift_fprintf (level, fo, "/* Instruction: %s */\n", or32_opcodes[i].name);
351
 
352
    output_call (fo, i, level);
353
 
354
    if (ti[i].insn_mask != cur_mask) {
355
      shift_fprintf (--level, fo, "} else {\n");
356
      shift_fprintf (++level, fo, "/* Invalid insn */\n");
357
      output_call (fo, -1, level);
358
      shift_fprintf (--level, fo, "}\n");
359
    }
360 709 markom
  }
361
  return 0;
362
}
363
 
364
/* Main function; it takes two parameters:
365
   input_file(possibly insnset.c) output_file(possibly execgen.c)*/
366
int main (int argc, char *argv[])
367
{
368
  FILE *fo;
369
 
370
  if (argc != 3) {
371
    fprintf (stderr, "USAGE: generate input_file(possibly insnset.c) output_file(possibly execgen.c)\n");
372
    exit (-1);
373
  }
374
 
375
  in_file = argv[1];
376 1342 nogj
  out_file = argv[2];
377 709 markom
  if (!(fo = fopen (argv[2], "wt+"))) {
378
    fprintf (stderr, "Cannot create '%s'.\n", argv[2]);
379
    exit (1);
380
  }
381
 
382
  build_automata ();
383 1342 nogj
  if (generate_header (fo)) {
384
    fprintf (stderr, "generate_header\n");
385
    return 1;
386
  }
387
 
388
  if (generate_body (fo, automata, 0, 1)) {
389
    fprintf (stderr, "generate_body\n");
390
    return 1;
391
  }
392
 
393
  if (generate_footer (fo)) {
394
    fprintf (stderr, "generate_footer\n");
395
    return 1;
396
  }
397
 
398 709 markom
  fclose (fo);
399
  destruct_automata ();
400
  return 0;
401
}
402 713 markom
 

powered by: WebSVN 2.1.0

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