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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [mep/] [mep-pragma.c] - Blame information for rev 433

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

Line No. Rev Author Line
1 282 jeremybenn
/* Definitions of Toshiba Media Processor
2
   Copyright (C) 2001, 2002, 2003, 2005, 2006, 2007, 2009 Free
3
   Software Foundation, Inc.  Contributed by Red Hat, Inc.
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify it under
8
the terms of the GNU General Public License as published by the Free
9
Software Foundation; either version 3, or (at your option) any later
10
version.
11
 
12
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13
WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.  */
20
 
21
#include <stdio.h>
22
#include "config.h"
23
#include "system.h"
24
#include "coretypes.h"
25
#include "tm.h"
26
#include "tree.h"
27
#include "rtl.h"
28
#include "toplev.h"
29
#include "c-pragma.h"
30
#include "cpplib.h"
31
#include "hard-reg-set.h"
32
#include "output.h"
33
#include "mep-protos.h"
34
#include "function.h"
35
#define MAX_RECOG_OPERANDS 10
36
#include "reload.h"
37
#include "target.h"
38
 
39
enum cw_which { CW_AVAILABLE, CW_CALL_SAVED };
40
 
41
static enum cpp_ttype
42
mep_pragma_lex (tree *valp)
43
{
44
  enum cpp_ttype t = pragma_lex (valp);
45
  if (t == CPP_EOF)
46
    t = CPP_PRAGMA_EOL;
47
  return t;
48
}
49
 
50
static void
51
mep_pragma_io_volatile (cpp_reader *reader ATTRIBUTE_UNUSED)
52
{
53
  /* On off.  */
54
  tree val;
55
  enum cpp_ttype type;
56
  const char * str;
57
 
58
  type = mep_pragma_lex (&val);
59
  if (type == CPP_NAME)
60
    {
61
      str = IDENTIFIER_POINTER (val);
62
 
63
      type = mep_pragma_lex (&val);
64
      if (type != CPP_PRAGMA_EOL)
65
        warning (0, "junk at end of #pragma io_volatile");
66
 
67
      if (strcmp (str, "on") == 0)
68
        {
69
          target_flags |= MASK_IO_VOLATILE;
70
          return;
71
        }
72
      if (strcmp (str, "off") == 0)
73
        {
74
          target_flags &= ~ MASK_IO_VOLATILE;
75
          return;
76
        }
77
    }
78
 
79
  error ("#pragma io_volatile takes only on or off");
80
}
81
 
82
static unsigned int
83
parse_cr_reg (const char * str)
84
{
85
  unsigned int regno;
86
 
87
  regno = decode_reg_name (str);
88
  if (regno >= FIRST_PSEUDO_REGISTER)
89
    return INVALID_REGNUM;
90
 
91
  /* Verify that the regno is in CR_REGS.  */
92
  if (! TEST_HARD_REG_BIT (reg_class_contents[CR_REGS], regno))
93
    return INVALID_REGNUM;
94
  return regno;
95
}
96
 
97
static bool
98
parse_cr_set (HARD_REG_SET * set)
99
{
100
  tree val;
101
  enum cpp_ttype type;
102
  unsigned int last_regno = INVALID_REGNUM;
103
  bool do_range = false;
104
 
105
  CLEAR_HARD_REG_SET (*set);
106
 
107
  while ((type = mep_pragma_lex (&val)) != CPP_PRAGMA_EOL)
108
    {
109
      if (type == CPP_COMMA)
110
        {
111
          last_regno = INVALID_REGNUM;
112
          do_range = false;
113
        }
114
      else if (type == CPP_ELLIPSIS)
115
        {
116
          if (last_regno == INVALID_REGNUM)
117
            {
118
              error ("invalid coprocessor register range");
119
              return false;
120
            }
121
          do_range = true;
122
        }
123
      else if (type == CPP_NAME || type == CPP_STRING)
124
        {
125
          const char *str;
126
          unsigned int regno, i;
127
 
128
          if (TREE_CODE (val) == IDENTIFIER_NODE)
129
            str = IDENTIFIER_POINTER (val);
130
          else if (TREE_CODE (val) == STRING_CST)
131
            str = TREE_STRING_POINTER (val);
132
          else
133
            gcc_unreachable ();
134
 
135
          regno = parse_cr_reg (str);
136
          if (regno == INVALID_REGNUM)
137
            {
138
              error ("invalid coprocessor register %qE", val);
139
              return false;
140
            }
141
 
142
          if (do_range)
143
            {
144
              if (last_regno > regno)
145
                i = regno, regno = last_regno;
146
              else
147
                i = last_regno;
148
              do_range = false;
149
            }
150
          else
151
            last_regno = i = regno;
152
 
153
          while (i <= regno)
154
            {
155
              SET_HARD_REG_BIT (*set, i);
156
              i++;
157
            }
158
        }
159
      else
160
        {
161
          error ("malformed coprocessor register");
162
          return false;
163
        }
164
    }
165
  return true;
166
}
167
 
168
static void
169
mep_pragma_coprocessor_which (enum cw_which cw_which)
170
{
171
  HARD_REG_SET set;
172
 
173
  /* Process the balance of the pragma and turn it into a hard reg set.  */
174
  if (! parse_cr_set (&set))
175
    return;
176
 
177
  /* Process the collected hard reg set.  */
178
  switch (cw_which)
179
    {
180
    case CW_AVAILABLE:
181
      {
182
        int i;
183
        for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
184
          if (TEST_HARD_REG_BIT (set, i))
185
            fixed_regs[i] = 0;
186
      }
187
      break;
188
 
189
    case CW_CALL_SAVED:
190
      {
191
        int i;
192
        for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
193
          if (TEST_HARD_REG_BIT (set, i))
194
            fixed_regs[i] = call_used_regs[i] = 0;
195
      }
196
      break;
197
 
198
    default:
199
      gcc_unreachable ();
200
    }
201
 
202
  /* Fix up register class hierarchy.  */
203
  save_register_info ();
204
  reinit_regs ();
205
 
206
  if (cfun == 0)
207
    {
208
      init_dummy_function_start ();
209
      init_caller_save ();
210
      expand_dummy_function_end ();
211
    }
212
  else
213
    {
214
      init_caller_save ();
215
    }
216
}
217
 
218
static void
219
mep_pragma_coprocessor_width (void)
220
{
221
  tree val;
222
  enum cpp_ttype type;
223
  HOST_WIDE_INT i;
224
 
225
  type = mep_pragma_lex (&val);
226
  switch (type)
227
    {
228
    case CPP_NUMBER:
229
      if (! host_integerp (val, 1))
230
        break;
231
      i = tree_low_cst (val, 1);
232
      /* This pragma no longer has any effect.  */
233
#if 0
234
      if (i == 32)
235
        target_flags &= ~MASK_64BIT_CR_REGS;
236
      else if (i == 64)
237
        target_flags |= MASK_64BIT_CR_REGS;
238
      else
239
        break;
240
      targetm.init_builtins ();
241
#else
242
      if (i != 32 && i != 64)
243
        break;
244
#endif
245
 
246
      type = mep_pragma_lex (&val);
247
      if (type != CPP_PRAGMA_EOL)
248
        warning (0, "junk at end of #pragma GCC coprocessor width");
249
      return;
250
 
251
    default:
252
      break;
253
    }
254
 
255
  error ("#pragma GCC coprocessor width takes only 32 or 64");
256
}
257
 
258
static void
259
mep_pragma_coprocessor_subclass (void)
260
{
261
  tree val;
262
  enum cpp_ttype type;
263
  HARD_REG_SET set;
264
  int class_letter;
265
  enum reg_class class;
266
 
267
  type = mep_pragma_lex (&val);
268
  if (type != CPP_CHAR)
269
    goto syntax_error;
270
  class_letter = tree_low_cst (val, 1);
271
  if (class_letter >= 'A' && class_letter <= 'D')
272
    class = class_letter - 'A' + USER0_REGS;
273
  else
274
    {
275
      error ("#pragma GCC coprocessor subclass letter must be in [ABCD]");
276
      return;
277
    }
278
  if (reg_class_size[class] > 0)
279
    {
280
      error ("#pragma GCC coprocessor subclass '%c' already defined",
281
             class_letter);
282
      return;
283
    }
284
 
285
  type = mep_pragma_lex (&val);
286
  if (type != CPP_EQ)
287
    goto syntax_error;
288
 
289
  if (! parse_cr_set (&set))
290
    return;
291
 
292
  /* Fix up register class hierarchy.  */
293
  COPY_HARD_REG_SET (reg_class_contents[class], set);
294
  init_regs ();
295
  return;
296
 
297
 syntax_error:
298
  error ("malformed #pragma GCC coprocessor subclass");
299
}
300
 
301
static void
302
mep_pragma_disinterrupt (cpp_reader *reader ATTRIBUTE_UNUSED)
303
{
304
  tree val;
305
  enum cpp_ttype type;
306
  int saw_one = 0;
307
 
308
  for (;;)
309
    {
310
      type = mep_pragma_lex (&val);
311
      if (type == CPP_COMMA)
312
        continue;
313
      if (type != CPP_NAME)
314
        break;
315
      mep_note_pragma_disinterrupt (IDENTIFIER_POINTER (val));
316
      saw_one = 1;
317
    }
318
  if (!saw_one || type != CPP_PRAGMA_EOL)
319
    {
320
      error ("malformed #pragma disinterrupt");
321
      return;
322
    }
323
}
324
 
325
static void
326
mep_pragma_coprocessor (cpp_reader *reader ATTRIBUTE_UNUSED)
327
{
328
  tree val;
329
  enum cpp_ttype type;
330
 
331
  type = mep_pragma_lex (&val);
332
  if (type != CPP_NAME)
333
    {
334
      error ("malformed #pragma GCC coprocessor");
335
      return;
336
    }
337
 
338
  if (!TARGET_COP)
339
    error ("coprocessor not enabled");
340
 
341
  if (strcmp (IDENTIFIER_POINTER (val), "available") == 0)
342
    mep_pragma_coprocessor_which (CW_AVAILABLE);
343
  else if (strcmp (IDENTIFIER_POINTER (val), "call_saved") == 0)
344
    mep_pragma_coprocessor_which (CW_CALL_SAVED);
345
  else if (strcmp (IDENTIFIER_POINTER (val), "width") == 0)
346
    mep_pragma_coprocessor_width ();
347
  else if (strcmp (IDENTIFIER_POINTER (val), "subclass") == 0)
348
    mep_pragma_coprocessor_subclass ();
349
  else
350
    error ("unknown #pragma GCC coprocessor %E", val);
351
}
352
 
353
static void
354
mep_pragma_call (cpp_reader *reader ATTRIBUTE_UNUSED)
355
{
356
  tree val;
357
  enum cpp_ttype type;
358
  int saw_one = 0;
359
 
360
  for (;;)
361
    {
362
      type = mep_pragma_lex (&val);
363
      if (type == CPP_COMMA)
364
        continue;
365
      if (type != CPP_NAME)
366
        break;
367
      mep_note_pragma_call (IDENTIFIER_POINTER (val));
368
      saw_one = 1;
369
    }
370
  if (!saw_one || type != CPP_PRAGMA_EOL)
371
    {
372
      error ("malformed #pragma call");
373
      return;
374
    }
375
}
376
 
377
void
378
mep_register_pragmas (void)
379
{
380
  c_register_pragma ("custom", "io_volatile", mep_pragma_io_volatile);
381
  c_register_pragma ("GCC", "coprocessor", mep_pragma_coprocessor);
382
  c_register_pragma (0, "disinterrupt", mep_pragma_disinterrupt);
383
  c_register_pragma (0, "call", mep_pragma_call);
384
}

powered by: WebSVN 2.1.0

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