xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/common/config/riscv/riscv-common.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* Common hooks for RISC-V.
2    Copyright (C) 1989-2014 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10 
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "common/common-target.h"
25 #include "common/common-target-def.h"
26 #include "opts.h"
27 #include "flags.h"
28 #include "errors.h"
29 
30 /* Parse a RISC-V ISA string into an option mask.  */
31 
32 static void
33 riscv_parse_arch_string (const char *isa, int *flags)
34 {
35   const char *p = isa;
36 
37   if (strncmp (p, "RV32", 4) == 0)
38     *flags |= MASK_32BIT, p += 4;
39   else if (strncmp (p, "RV64", 4) == 0)
40     *flags &= ~MASK_32BIT, p += 4;
41 
42   if (*p++ != 'I')
43     {
44       error ("-march=%s: ISA strings must begin with I, RV32I, or RV64I", isa);
45       return;
46     }
47 
48   *flags &= ~MASK_MULDIV;
49   if (*p == 'M')
50     *flags |= MASK_MULDIV, p++;
51 
52   *flags &= ~MASK_ATOMIC;
53   if (*p == 'A')
54     *flags |= MASK_ATOMIC, p++;
55 
56   *flags |= MASK_SOFT_FLOAT_ABI;
57   if (*p == 'F')
58     *flags &= ~MASK_SOFT_FLOAT_ABI, p++;
59 
60   if (*p == 'D')
61     {
62       p++;
63       if (!TARGET_HARD_FLOAT)
64 	{
65 	  error ("-march=%s: the D extension requires the F extension", isa);
66 	  return;
67 	}
68     }
69   else if (TARGET_HARD_FLOAT)
70     {
71       error ("-march=%s: single-precision-only is not yet supported", isa);
72       return;
73     }
74 
75   if (*p)
76     {
77       error ("-march=%s: unsupported ISA substring %s", isa, p);
78       return;
79     }
80 }
81 
82 static int
83 riscv_flags_from_arch_string (const char *isa)
84 {
85   int flags = 0;
86   riscv_parse_arch_string (isa, &flags);
87   return flags;
88 }
89 
90 /* Implement TARGET_HANDLE_OPTION.  */
91 
92 static bool
93 riscv_handle_option (struct gcc_options *opts,
94 		     struct gcc_options *opts_set ATTRIBUTE_UNUSED,
95 		     const struct cl_decoded_option *decoded,
96 		     location_t loc ATTRIBUTE_UNUSED)
97 {
98   switch (decoded->opt_index)
99     {
100     case OPT_march_:
101       riscv_parse_arch_string (decoded->arg, &opts->x_target_flags);
102       return true;
103 
104     default:
105       return true;
106     }
107 }
108 
109 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
110 static const struct default_options riscv_option_optimization_table[] =
111   {
112     { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 },
113     { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
114     { OPT_LEVELS_NONE, 0, NULL, 0 }
115   };
116 
117 #undef TARGET_OPTION_OPTIMIZATION_TABLE
118 #define TARGET_OPTION_OPTIMIZATION_TABLE riscv_option_optimization_table
119 
120 #undef TARGET_DEFAULT_TARGET_FLAGS
121 #define TARGET_DEFAULT_TARGET_FLAGS				\
122   (TARGET_DEFAULT						\
123    | riscv_flags_from_arch_string (RISCV_ARCH_STRING_DEFAULT)	\
124    | (TARGET_64BIT_DEFAULT ? 0 : MASK_32BIT))
125 
126 #undef TARGET_HANDLE_OPTION
127 #define TARGET_HANDLE_OPTION riscv_handle_option
128 
129 struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
130