Home | History | Annotate | Line # | Download | only in m32c
      1  1.1  mrg /* M32C Pragma support
      2  1.1  mrg    Copyright (C) 2004-2022 Free Software Foundation, Inc.
      3  1.1  mrg    Contributed by Red Hat, Inc.
      4  1.1  mrg 
      5  1.1  mrg    This file is part of GCC.
      6  1.1  mrg 
      7  1.1  mrg    GCC is free software; you can redistribute it and/or modify
      8  1.1  mrg    it under the terms of the GNU General Public License as published by
      9  1.1  mrg    the Free Software Foundation; either version 3, or (at your option)
     10  1.1  mrg    any later version.
     11  1.1  mrg 
     12  1.1  mrg    GCC is distributed in the hope that it will be useful,
     13  1.1  mrg    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  mrg    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  mrg    GNU General Public License for more details.
     16  1.1  mrg 
     17  1.1  mrg    You should have received a copy of the GNU General Public License
     18  1.1  mrg    along with GCC; see the file COPYING3.  If not see
     19  1.1  mrg    <http://www.gnu.org/licenses/>.  */
     20  1.1  mrg 
     21  1.1  mrg #define IN_TARGET_CODE 1
     22  1.1  mrg 
     23  1.1  mrg #include "config.h"
     24  1.1  mrg #include "system.h"
     25  1.1  mrg #include "coretypes.h"
     26  1.1  mrg #include "tm.h"
     27  1.1  mrg #include "c-family/c-common.h"
     28  1.1  mrg #include "c-family/c-pragma.h"
     29  1.1  mrg #include "m32c-protos.h"
     30  1.1  mrg 
     31  1.1  mrg /* Implements the "GCC memregs" pragma.  This pragma takes only an
     32  1.1  mrg    integer, and is semantically identical to the -memregs= command
     33  1.1  mrg    line option.  The only catch is, the programmer should only use
     34  1.1  mrg    this pragma at the beginning of the file (preferably, in some
     35  1.1  mrg    project-wide header) to avoid ABI changes related to changing the
     36  1.1  mrg    list of available "registers".  */
     37  1.1  mrg static void
     38  1.1  mrg m32c_pragma_memregs (cpp_reader * reader ATTRIBUTE_UNUSED)
     39  1.1  mrg {
     40  1.1  mrg   /* on off */
     41  1.1  mrg   tree val;
     42  1.1  mrg   enum cpp_ttype type;
     43  1.1  mrg   HOST_WIDE_INT i;
     44  1.1  mrg 
     45  1.1  mrg   type = pragma_lex (&val);
     46  1.1  mrg   if (type == CPP_NUMBER)
     47  1.1  mrg     {
     48  1.1  mrg       if (tree_fits_uhwi_p (val))
     49  1.1  mrg 	{
     50  1.1  mrg 	  i = tree_to_uhwi (val);
     51  1.1  mrg 
     52  1.1  mrg 	  type = pragma_lex (&val);
     53  1.1  mrg 	  if (type != CPP_EOF)
     54  1.1  mrg 	    warning (0, "junk at end of %<#pragma GCC memregs%> [0-16]");
     55  1.1  mrg 
     56  1.1  mrg 	  if (i >= 0 && i <= 16)
     57  1.1  mrg 	    {
     58  1.1  mrg 	      if (!ok_to_change_target_memregs)
     59  1.1  mrg 		{
     60  1.1  mrg 		  warning (0,
     61  1.1  mrg 			   "%<#pragma GCC memregs%> must precede any function declarations");
     62  1.1  mrg 		  return;
     63  1.1  mrg 		}
     64  1.1  mrg 	      target_memregs = i;
     65  1.1  mrg 	      m32c_conditional_register_usage ();
     66  1.1  mrg 	    }
     67  1.1  mrg 	  else
     68  1.1  mrg 	    {
     69  1.1  mrg 	      warning (0, "%<#pragma GCC memregs%> takes a number [0-16]");
     70  1.1  mrg 	    }
     71  1.1  mrg 
     72  1.1  mrg 	  return;
     73  1.1  mrg 	}
     74  1.1  mrg     }
     75  1.1  mrg 
     76  1.1  mrg   error ("%<#pragma GCC memregs%> takes a number [0-16]");
     77  1.1  mrg }
     78  1.1  mrg 
     79  1.1  mrg /* Implements the "pragma ADDRESS" pragma.  This pragma takes a
     80  1.1  mrg    variable name and an address, and arranges for that variable to be
     81  1.1  mrg    "at" that address.  The variable is also made volatile.  */
     82  1.1  mrg static void
     83  1.1  mrg m32c_pragma_address (cpp_reader * reader ATTRIBUTE_UNUSED)
     84  1.1  mrg {
     85  1.1  mrg   /* on off */
     86  1.1  mrg   tree var, addr;
     87  1.1  mrg   enum cpp_ttype type;
     88  1.1  mrg 
     89  1.1  mrg   type = pragma_lex (&var);
     90  1.1  mrg   if (type == CPP_NAME)
     91  1.1  mrg     {
     92  1.1  mrg       type = pragma_lex (&addr);
     93  1.1  mrg       if (type == CPP_NUMBER)
     94  1.1  mrg 	{
     95  1.1  mrg 	  if (var != error_mark_node)
     96  1.1  mrg 	    {
     97  1.1  mrg 	      unsigned uaddr = tree_to_uhwi (addr);
     98  1.1  mrg 	      m32c_note_pragma_address (IDENTIFIER_POINTER (var), uaddr);
     99  1.1  mrg 	    }
    100  1.1  mrg 
    101  1.1  mrg 	  type = pragma_lex (&var);
    102  1.1  mrg 	  if (type != CPP_EOF)
    103  1.1  mrg 	    {
    104  1.1  mrg 	      error ("junk at end of %<#pragma ADDRESS%>");
    105  1.1  mrg 	    }
    106  1.1  mrg 	  return;
    107  1.1  mrg 	}
    108  1.1  mrg     }
    109  1.1  mrg   error ("malformed %<#pragma ADDRESS%> variable address");
    110  1.1  mrg }
    111  1.1  mrg 
    112  1.1  mrg /* Implements REGISTER_TARGET_PRAGMAS.  */
    113  1.1  mrg void
    114  1.1  mrg m32c_register_pragmas (void)
    115  1.1  mrg {
    116  1.1  mrg   c_register_pragma ("GCC", "memregs", m32c_pragma_memregs);
    117  1.1  mrg   c_register_pragma (NULL, "ADDRESS", m32c_pragma_address);
    118  1.1  mrg   c_register_pragma (NULL, "address", m32c_pragma_address);
    119  1.1  mrg 
    120  1.1  mrg   /* R8C and M16C have 16-bit pointers in a 20-bit address zpace.
    121  1.1  mrg      M32C has 24-bit pointers in a 24-bit address space, so does not
    122  1.1  mrg      need far pointers, but we accept the qualifier anyway, as a
    123  1.1  mrg      no-op.  */
    124  1.1  mrg   if (TARGET_A16)
    125  1.1  mrg     c_register_addr_space ("__far", ADDR_SPACE_FAR);
    126  1.1  mrg   else
    127  1.1  mrg     c_register_addr_space ("__far", ADDR_SPACE_GENERIC);
    128  1.1  mrg }
    129