From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- gcc/config/mep/mep-pragma.c | 404 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 404 insertions(+) create mode 100644 gcc/config/mep/mep-pragma.c (limited to 'gcc/config/mep/mep-pragma.c') diff --git a/gcc/config/mep/mep-pragma.c b/gcc/config/mep/mep-pragma.c new file mode 100644 index 000000000..d9457ed6c --- /dev/null +++ b/gcc/config/mep/mep-pragma.c @@ -0,0 +1,404 @@ +/* Definitions of Toshiba Media Processor + Copyright (C) 2001, 2002, 2003, 2005, 2006, 2007, 2009, 2010 Free + Software Foundation, Inc. Contributed by Red Hat, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "tree.h" +#include "diagnostic-core.h" +#include "c-family/c-pragma.h" +#include "cpplib.h" +#include "hard-reg-set.h" +#include "output.h" +#include "mep-protos.h" +#include "function.h" +#define MAX_RECOG_OPERANDS 10 +#include "reload.h" +#include "target.h" + +enum cw_which { CW_AVAILABLE, CW_CALL_SAVED }; + +/* This is normally provided by rtl.h but we can't include that file + here. It's safe to copy the definition here because we're only + using it internally; the value isn't passed to functions outside + this file. */ +#ifndef INVALID_REGNUM +#define INVALID_REGNUM (~(unsigned int) 0) +#endif + +static enum cpp_ttype +mep_pragma_lex (tree *valp) +{ + enum cpp_ttype t = pragma_lex (valp); + if (t == CPP_EOF) + t = CPP_PRAGMA_EOL; + return t; +} + +static void +mep_pragma_io_volatile (cpp_reader *reader ATTRIBUTE_UNUSED) +{ + /* On off. */ + tree val; + enum cpp_ttype type; + const char * str; + + type = mep_pragma_lex (&val); + if (type == CPP_NAME) + { + str = IDENTIFIER_POINTER (val); + + type = mep_pragma_lex (&val); + if (type != CPP_PRAGMA_EOL) + warning (0, "junk at end of #pragma io_volatile"); + + if (strcmp (str, "on") == 0) + { + target_flags |= MASK_IO_VOLATILE; + return; + } + if (strcmp (str, "off") == 0) + { + target_flags &= ~ MASK_IO_VOLATILE; + return; + } + } + + error ("#pragma io_volatile takes only on or off"); +} + +static unsigned int +parse_cr_reg (const char * str) +{ + unsigned int regno; + + regno = decode_reg_name (str); + if (regno >= FIRST_PSEUDO_REGISTER) + return INVALID_REGNUM; + + /* Verify that the regno is in CR_REGS. */ + if (! TEST_HARD_REG_BIT (reg_class_contents[CR_REGS], regno)) + return INVALID_REGNUM; + return regno; +} + +static bool +parse_cr_set (HARD_REG_SET * set) +{ + tree val; + enum cpp_ttype type; + unsigned int last_regno = INVALID_REGNUM; + bool do_range = false; + + CLEAR_HARD_REG_SET (*set); + + while ((type = mep_pragma_lex (&val)) != CPP_PRAGMA_EOL) + { + if (type == CPP_COMMA) + { + last_regno = INVALID_REGNUM; + do_range = false; + } + else if (type == CPP_ELLIPSIS) + { + if (last_regno == INVALID_REGNUM) + { + error ("invalid coprocessor register range"); + return false; + } + do_range = true; + } + else if (type == CPP_NAME || type == CPP_STRING) + { + const char *str; + unsigned int regno, i; + + if (TREE_CODE (val) == IDENTIFIER_NODE) + str = IDENTIFIER_POINTER (val); + else if (TREE_CODE (val) == STRING_CST) + str = TREE_STRING_POINTER (val); + else + gcc_unreachable (); + + regno = parse_cr_reg (str); + if (regno == INVALID_REGNUM) + { + error ("invalid coprocessor register %qE", val); + return false; + } + + if (do_range) + { + if (last_regno > regno) + i = regno, regno = last_regno; + else + i = last_regno; + do_range = false; + } + else + last_regno = i = regno; + + while (i <= regno) + { + SET_HARD_REG_BIT (*set, i); + i++; + } + } + else + { + error ("malformed coprocessor register"); + return false; + } + } + return true; +} + +static void +mep_pragma_coprocessor_which (enum cw_which cw_which) +{ + HARD_REG_SET set; + + /* Process the balance of the pragma and turn it into a hard reg set. */ + if (! parse_cr_set (&set)) + return; + + /* Process the collected hard reg set. */ + switch (cw_which) + { + case CW_AVAILABLE: + { + int i; + for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) + if (TEST_HARD_REG_BIT (set, i)) + fixed_regs[i] = 0; + } + break; + + case CW_CALL_SAVED: + { + int i; + for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) + if (TEST_HARD_REG_BIT (set, i)) + fixed_regs[i] = call_used_regs[i] = 0; + } + break; + + default: + gcc_unreachable (); + } + + /* Fix up register class hierarchy. */ + mep_save_register_info (); + mep_reinit_regs (); + + if (cfun == 0) + { + init_dummy_function_start (); + init_caller_save (); + expand_dummy_function_end (); + } + else + { + init_caller_save (); + } +} + +static void +mep_pragma_coprocessor_width (void) +{ + tree val; + enum cpp_ttype type; + HOST_WIDE_INT i; + + type = mep_pragma_lex (&val); + switch (type) + { + case CPP_NUMBER: + if (! host_integerp (val, 1)) + break; + i = tree_low_cst (val, 1); + /* This pragma no longer has any effect. */ +#if 0 + if (i == 32) + target_flags &= ~MASK_64BIT_CR_REGS; + else if (i == 64) + target_flags |= MASK_64BIT_CR_REGS; + else + break; + targetm.init_builtins (); +#else + if (i != 32 && i != 64) + break; +#endif + + type = mep_pragma_lex (&val); + if (type != CPP_PRAGMA_EOL) + warning (0, "junk at end of #pragma GCC coprocessor width"); + return; + + default: + break; + } + + error ("#pragma GCC coprocessor width takes only 32 or 64"); +} + +static void +mep_pragma_coprocessor_subclass (void) +{ + tree val; + enum cpp_ttype type; + HARD_REG_SET set; + int class_letter; + enum reg_class rclass; + + type = mep_pragma_lex (&val); + if (type != CPP_CHAR) + goto syntax_error; + class_letter = tree_low_cst (val, 1); + if (class_letter >= 'A' && class_letter <= 'D') + switch (class_letter) + { + case 'A': + rclass = USER0_REGS; + break; + case 'B': + rclass = USER1_REGS; + break; + case 'C': + rclass = USER2_REGS; + break; + case 'D': + rclass = USER3_REGS; + break; + } + else + { + error ("#pragma GCC coprocessor subclass letter must be in [ABCD]"); + return; + } + if (reg_class_size[rclass] > 0) + { + error ("#pragma GCC coprocessor subclass '%c' already defined", + class_letter); + return; + } + + type = mep_pragma_lex (&val); + if (type != CPP_EQ) + goto syntax_error; + + if (! parse_cr_set (&set)) + return; + + /* Fix up register class hierarchy. */ + COPY_HARD_REG_SET (reg_class_contents[rclass], set); + mep_init_regs (); + return; + + syntax_error: + error ("malformed #pragma GCC coprocessor subclass"); +} + +static void +mep_pragma_disinterrupt (cpp_reader *reader ATTRIBUTE_UNUSED) +{ + tree val; + enum cpp_ttype type; + int saw_one = 0; + + for (;;) + { + type = mep_pragma_lex (&val); + if (type == CPP_COMMA) + continue; + if (type != CPP_NAME) + break; + mep_note_pragma_disinterrupt (IDENTIFIER_POINTER (val)); + saw_one = 1; + } + if (!saw_one || type != CPP_PRAGMA_EOL) + { + error ("malformed #pragma disinterrupt"); + return; + } +} + +static void +mep_pragma_coprocessor (cpp_reader *reader ATTRIBUTE_UNUSED) +{ + tree val; + enum cpp_ttype type; + + type = mep_pragma_lex (&val); + if (type != CPP_NAME) + { + error ("malformed #pragma GCC coprocessor"); + return; + } + + if (!TARGET_COP) + error ("coprocessor not enabled"); + + if (strcmp (IDENTIFIER_POINTER (val), "available") == 0) + mep_pragma_coprocessor_which (CW_AVAILABLE); + else if (strcmp (IDENTIFIER_POINTER (val), "call_saved") == 0) + mep_pragma_coprocessor_which (CW_CALL_SAVED); + else if (strcmp (IDENTIFIER_POINTER (val), "width") == 0) + mep_pragma_coprocessor_width (); + else if (strcmp (IDENTIFIER_POINTER (val), "subclass") == 0) + mep_pragma_coprocessor_subclass (); + else + error ("unknown #pragma GCC coprocessor %E", val); +} + +static void +mep_pragma_call (cpp_reader *reader ATTRIBUTE_UNUSED) +{ + tree val; + enum cpp_ttype type; + int saw_one = 0; + + for (;;) + { + type = mep_pragma_lex (&val); + if (type == CPP_COMMA) + continue; + if (type != CPP_NAME) + break; + mep_note_pragma_call (IDENTIFIER_POINTER (val)); + saw_one = 1; + } + if (!saw_one || type != CPP_PRAGMA_EOL) + { + error ("malformed #pragma call"); + return; + } +} + +void +mep_register_pragmas (void) +{ + c_register_pragma ("custom", "io_volatile", mep_pragma_io_volatile); + c_register_pragma ("GCC", "coprocessor", mep_pragma_coprocessor); + c_register_pragma (0, "disinterrupt", mep_pragma_disinterrupt); + c_register_pragma (0, "call", mep_pragma_call); +} -- cgit v1.2.3