comparison gcc/config/nios2/nios2.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* Target machine subroutines for Altera Nios II. 1 /* Target machine subroutines for Altera Nios II.
2 Copyright (C) 2012-2017 Free Software Foundation, Inc. 2 Copyright (C) 2012-2018 Free Software Foundation, Inc.
3 Contributed by Jonah Graham (jgraham@altera.com), 3 Contributed by Jonah Graham (jgraham@altera.com),
4 Will Reece (wreece@altera.com), and Jeff DaSilva (jdasilva@altera.com). 4 Will Reece (wreece@altera.com), and Jeff DaSilva (jdasilva@altera.com).
5 Contributed by Mentor Graphics, Inc. 5 Contributed by Mentor Graphics, Inc.
6 6
7 This file is part of GCC. 7 This file is part of GCC.
17 License for more details. 17 License for more details.
18 18
19 You should have received a copy of the GNU General Public License 19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see 20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */ 21 <http://www.gnu.org/licenses/>. */
22
23 #define IN_TARGET_CODE 1
22 24
23 #include "config.h" 25 #include "config.h"
24 #include "system.h" 26 #include "system.h"
25 #include "coretypes.h" 27 #include "coretypes.h"
26 #include "backend.h" 28 #include "backend.h"
1112 1114
1113 /* Set OFFSET to the offset from the stack pointer. */ 1115 /* Set OFFSET to the offset from the stack pointer. */
1114 switch (from) 1116 switch (from)
1115 { 1117 {
1116 case FRAME_POINTER_REGNUM: 1118 case FRAME_POINTER_REGNUM:
1117 offset = cfun->machine->args_size; 1119 /* This is the high end of the local variable storage, not the
1120 hard frame pointer. */
1121 offset = cfun->machine->args_size + cfun->machine->var_size;
1118 break; 1122 break;
1119 1123
1120 case ARG_POINTER_REGNUM: 1124 case ARG_POINTER_REGNUM:
1121 offset = cfun->machine->total_size; 1125 offset = cfun->machine->total_size;
1122 offset -= crtl->args.pretend_args_size; 1126 offset -= crtl->args.pretend_args_size;
1324 static void 1328 static void
1325 nios2_handle_custom_fpu_insn_option (int fpu_insn_index) 1329 nios2_handle_custom_fpu_insn_option (int fpu_insn_index)
1326 { 1330 {
1327 int param = N2FPU_N (fpu_insn_index); 1331 int param = N2FPU_N (fpu_insn_index);
1328 1332
1329 if (0 <= param && param <= 255) 1333 if (param >= 0 && param <= 255)
1330 nios2_register_custom_code (param, CCS_FPU, fpu_insn_index); 1334 nios2_register_custom_code (param, CCS_FPU, fpu_insn_index);
1331 1335
1332 /* Valid values are 0-255, but also allow -1 so that the 1336 /* Valid values are 0-255, but also allow -1 so that the
1333 -mno-custom-<opt> switches work. */ 1337 -mno-custom-<opt> switches work. */
1334 else if (param != -1) 1338 else if (param != -1)
2005 } 2009 }
2006 2010
2007 2011
2008 /* Addressing modes and constants. */ 2012 /* Addressing modes and constants. */
2009 2013
2010 /* Symbolic constants are split into high/lo_sum pairs during the 2014 /* Symbol references and other 32-bit constants are split into
2011 split1 pass. After that, they are not considered legitimate addresses. 2015 high/lo_sum pairs during the split1 pass. After that, they are not
2016 considered legitimate addresses.
2012 This function returns true if in a pre-split context where these 2017 This function returns true if in a pre-split context where these
2013 constants are allowed. */ 2018 constants are allowed. */
2014 static bool 2019 static bool
2015 nios2_symbolic_constant_allowed (void) 2020 nios2_large_constant_allowed (void)
2016 { 2021 {
2017 /* The reload_completed check is for the benefit of 2022 /* The reload_completed check is for the benefit of
2018 nios2_asm_output_mi_thunk and perhaps other places that try to 2023 nios2_asm_output_mi_thunk and perhaps other places that try to
2019 emulate a post-reload pass. */ 2024 emulate a post-reload pass. */
2020 return !(cfun->curr_properties & PROP_rtl_split_insns) && !reload_completed; 2025 return !(cfun->curr_properties & PROP_rtl_split_insns) && !reload_completed;
2042 } 2047 }
2043 return false; 2048 return false;
2044 } 2049 }
2045 2050
2046 /* Return true if X is an expression of the form 2051 /* Return true if X is an expression of the form
2047 (PLUS reg symbolic_constant). */ 2052 (PLUS reg large_constant). */
2048 static bool 2053 static bool
2049 nios2_plus_symbolic_constant_p (rtx x) 2054 nios2_plus_large_constant_p (rtx x)
2050 { 2055 {
2051 return (GET_CODE (x) == PLUS 2056 return (GET_CODE (x) == PLUS
2052 && REG_P (XEXP (x, 0)) 2057 && REG_P (XEXP (x, 0))
2053 && nios2_symbolic_constant_p (XEXP (x, 1))); 2058 && nios2_large_constant_p (XEXP (x, 1)));
2054 } 2059 }
2055 2060
2056 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */ 2061 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
2057 static bool 2062 static bool
2058 nios2_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x) 2063 nios2_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
2118 base = SUBREG_REG (base); 2123 base = SUBREG_REG (base);
2119 return (REG_P (base) 2124 return (REG_P (base)
2120 && nios2_regno_ok_for_base_p (REGNO (base), strict_p) 2125 && nios2_regno_ok_for_base_p (REGNO (base), strict_p)
2121 && (offset == NULL_RTX 2126 && (offset == NULL_RTX
2122 || nios2_valid_addr_offset_p (offset) 2127 || nios2_valid_addr_offset_p (offset)
2123 || (nios2_symbolic_constant_allowed () 2128 || (nios2_large_constant_allowed ()
2124 && nios2_symbolic_constant_p (offset)) 2129 && nios2_symbolic_constant_p (offset))
2125 || nios2_unspec_reloc_p (offset))); 2130 || nios2_unspec_reloc_p (offset)));
2126 } 2131 }
2127 2132
2128 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */ 2133 /* Implement TARGET_LEGITIMATE_ADDRESS_P. */
2142 if (gprel_constant_p (operand) || r0rel_constant_p (operand)) 2147 if (gprel_constant_p (operand) || r0rel_constant_p (operand))
2143 return true; 2148 return true;
2144 2149
2145 /* Else, fall through. */ 2150 /* Else, fall through. */
2146 case LABEL_REF: 2151 case LABEL_REF:
2147 if (nios2_symbolic_constant_allowed () 2152 if (nios2_large_constant_allowed ()
2148 && nios2_symbolic_constant_p (operand)) 2153 && nios2_symbolic_constant_p (operand))
2149 return true; 2154 return true;
2150 2155 return false;
2151 /* Else, fall through. */ 2156
2152 case CONST_INT: 2157 case CONST_INT:
2158 if (r0rel_constant_p (operand))
2159 return true;
2160 return nios2_large_constant_allowed ();
2161
2153 case CONST_DOUBLE: 2162 case CONST_DOUBLE:
2154 return false; 2163 return false;
2155 2164
2156 /* Register indirect. */ 2165 /* Register indirect. */
2157 case REG: 2166 case REG:
2209 nios2_address_cost (rtx address, 2218 nios2_address_cost (rtx address,
2210 machine_mode mode ATTRIBUTE_UNUSED, 2219 machine_mode mode ATTRIBUTE_UNUSED,
2211 addr_space_t as ATTRIBUTE_UNUSED, 2220 addr_space_t as ATTRIBUTE_UNUSED,
2212 bool speed ATTRIBUTE_UNUSED) 2221 bool speed ATTRIBUTE_UNUSED)
2213 { 2222 {
2214 if (nios2_plus_symbolic_constant_p (address)) 2223 if (nios2_plus_large_constant_p (address))
2215 return COSTS_N_INSNS (1); 2224 return COSTS_N_INSNS (1);
2216 if (nios2_symbolic_constant_p (address)) 2225 if (nios2_large_constant_p (address))
2217 { 2226 {
2218 if (GET_CODE (address) == CONST) 2227 if (GET_CODE (address) == CONST)
2219 return COSTS_N_INSNS (1); 2228 return COSTS_N_INSNS (1);
2220 else 2229 else
2221 return COSTS_N_INSNS (0); 2230 return COSTS_N_INSNS (0);
2222 } 2231 }
2223 return COSTS_N_INSNS (0); 2232 return COSTS_N_INSNS (0);
2224 } 2233 }
2225 2234
2226 /* Return true if X is a MEM whose address expression involves a symbolic 2235 /* Return true if X is a MEM whose address expression involves a large (32-bit)
2227 constant. */ 2236 constant. */
2228 bool 2237 bool
2229 nios2_symbolic_memory_operand_p (rtx x) 2238 nios2_large_constant_memory_operand_p (rtx x)
2230 { 2239 {
2231 rtx addr; 2240 rtx addr;
2232 2241
2233 if (GET_CODE (x) != MEM) 2242 if (GET_CODE (x) != MEM)
2234 return false; 2243 return false;
2235 addr = XEXP (x, 0); 2244 addr = XEXP (x, 0);
2236 2245
2237 return (nios2_symbolic_constant_p (addr) 2246 return (nios2_large_constant_p (addr)
2238 || nios2_plus_symbolic_constant_p (addr)); 2247 || nios2_plus_large_constant_p (addr));
2239 } 2248 }
2240 2249
2241 2250
2242 /* Return true if X is something that needs to be split into a 2251 /* Return true if X is something that needs to be split into a
2243 high/lo_sum pair. */ 2252 high/lo_sum pair. */
2244 bool 2253 bool
2245 nios2_large_constant_p (rtx x) 2254 nios2_large_constant_p (rtx x)
2246 { 2255 {
2247 return (nios2_symbolic_constant_p (x) 2256 return (nios2_symbolic_constant_p (x)
2248 || nios2_large_unspec_reloc_p (x)); 2257 || nios2_large_unspec_reloc_p (x)
2258 || (CONST_INT_P (x) && !SMALL_INT (INTVAL (x))));
2249 } 2259 }
2250 2260
2251 /* Given an RTX X that satisfies nios2_large_constant_p, split it into 2261 /* Given an RTX X that satisfies nios2_large_constant_p, split it into
2252 high and lo_sum parts using TEMP as a scratch register. Emit the high 2262 high and lo_sum parts using TEMP as a scratch register. Emit the high
2253 instruction and return the lo_sum expression. */ 2263 instruction and return the lo_sum expression.
2264 Also handle special cases involving constant integers. */
2254 rtx 2265 rtx
2255 nios2_split_large_constant (rtx x, rtx temp) 2266 nios2_split_large_constant (rtx x, rtx temp)
2256 { 2267 {
2268 if (CONST_INT_P (x))
2269 {
2270 HOST_WIDE_INT val = INTVAL (x);
2271 if (SMALL_INT (val))
2272 return x;
2273 else if (SMALL_INT_UNSIGNED (val) || UPPER16_INT (val))
2274 {
2275 emit_move_insn (temp, x);
2276 return temp;
2277 }
2278 else
2279 {
2280 HOST_WIDE_INT high = (val + 0x8000) & ~0xffff;
2281 HOST_WIDE_INT low = val - high;
2282 emit_move_insn (temp, gen_int_mode (high, Pmode));
2283 return gen_rtx_PLUS (Pmode, temp, gen_int_mode (low, Pmode));
2284 }
2285 }
2286
2257 emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (Pmode, copy_rtx (x)))); 2287 emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (Pmode, copy_rtx (x))));
2258 return gen_rtx_LO_SUM (Pmode, temp, copy_rtx (x)); 2288 return gen_rtx_LO_SUM (Pmode, temp, copy_rtx (x));
2259 } 2289 }
2260 2290
2261 /* Split an RTX of the form 2291 /* Split an RTX of the form
2274 emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (Pmode, copy_rtx (op1)))); 2304 emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (Pmode, copy_rtx (op1))));
2275 emit_insn (gen_rtx_SET (temp, gen_rtx_PLUS (Pmode, op0, temp))); 2305 emit_insn (gen_rtx_SET (temp, gen_rtx_PLUS (Pmode, op0, temp)));
2276 return gen_rtx_LO_SUM (Pmode, temp, copy_rtx (op1)); 2306 return gen_rtx_LO_SUM (Pmode, temp, copy_rtx (op1));
2277 } 2307 }
2278 2308
2279 /* Given a MEM OP with an address that includes a splittable symbol, 2309 /* Given a MEM OP with an address that includes a splittable symbol or
2280 emit some instructions to do the split and return a new MEM. */ 2310 other large constant, emit some instructions to do the split and
2311 return a new MEM. */
2281 rtx 2312 rtx
2282 nios2_split_symbolic_memory_operand (rtx op) 2313 nios2_split_large_constant_memory_operand (rtx op)
2283 { 2314 {
2284 rtx addr = XEXP (op, 0); 2315 rtx addr = XEXP (op, 0);
2285 2316
2286 if (nios2_symbolic_constant_p (addr)) 2317 if (nios2_large_constant_p (addr))
2287 addr = nios2_split_large_constant (addr, gen_reg_rtx (Pmode)); 2318 addr = nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
2288 else if (nios2_plus_symbolic_constant_p (addr)) 2319 else if (nios2_plus_large_constant_p (addr))
2289 addr = nios2_split_plus_large_constant (XEXP (addr, 0), XEXP (addr, 1)); 2320 addr = nios2_split_plus_large_constant (XEXP (addr, 0), XEXP (addr, 1));
2290 else 2321 else
2291 gcc_unreachable (); 2322 gcc_unreachable ();
2292 return replace_equiv_address (op, addr, false); 2323 return replace_equiv_address (op, addr, false);
2293 } 2324 }
2529 2560
2530 if (nios2_tls_symbol_p (base)) 2561 if (nios2_tls_symbol_p (base))
2531 base = nios2_legitimize_tls_address (base); 2562 base = nios2_legitimize_tls_address (base);
2532 else if (flag_pic) 2563 else if (flag_pic)
2533 base = nios2_load_pic_address (base, UNSPEC_PIC_SYM, NULL_RTX); 2564 base = nios2_load_pic_address (base, UNSPEC_PIC_SYM, NULL_RTX);
2534 else if (!nios2_symbolic_constant_allowed () 2565 else if (!nios2_large_constant_allowed ()
2535 && nios2_symbolic_constant_p (addr)) 2566 && nios2_symbolic_constant_p (addr))
2536 return nios2_split_large_constant (addr, gen_reg_rtx (Pmode)); 2567 return nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
2568 else if (CONST_INT_P (addr))
2569 {
2570 HOST_WIDE_INT val = INTVAL (addr);
2571 if (SMALL_INT (val))
2572 /* Use r0-relative addressing. */
2573 return addr;
2574 else if (!nios2_large_constant_allowed ())
2575 /* Split into high/lo pair. */
2576 return nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
2577 }
2537 else 2578 else
2538 return addr; 2579 return addr;
2539 2580
2540 if (offset != const0_rtx) 2581 if (offset != const0_rtx)
2541 { 2582 {
2575 return gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), copy_rtx (op1)); 2616 return gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), copy_rtx (op1));
2576 2617
2577 /* We may need to split symbolic constants now. */ 2618 /* We may need to split symbolic constants now. */
2578 else if (nios2_symbolic_constant_p (op1)) 2619 else if (nios2_symbolic_constant_p (op1))
2579 { 2620 {
2580 if (nios2_symbolic_constant_allowed ()) 2621 if (nios2_large_constant_allowed ())
2581 return gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), copy_rtx (op1)); 2622 return gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), copy_rtx (op1));
2582 else 2623 else
2583 return nios2_split_plus_large_constant (op0, op1); 2624 return nios2_split_plus_large_constant (op0, op1);
2584 } 2625 }
2585 2626
2685 else if (nios2_large_constant_p (from)) 2726 else if (nios2_large_constant_p (from))
2686 /* This case covers either a regular symbol reference or an UNSPEC 2727 /* This case covers either a regular symbol reference or an UNSPEC
2687 representing a 32-bit offset. We split the former 2728 representing a 32-bit offset. We split the former
2688 only conditionally and the latter always. */ 2729 only conditionally and the latter always. */
2689 { 2730 {
2690 if (!nios2_symbolic_constant_allowed () 2731 if (!nios2_large_constant_allowed ()
2691 || nios2_large_unspec_reloc_p (from)) 2732 || nios2_large_unspec_reloc_p (from))
2692 { 2733 {
2693 rtx lo = nios2_split_large_constant (from, to); 2734 rtx lo = nios2_split_large_constant (from, to);
2694 emit_insn (gen_rtx_SET (to, lo)); 2735 emit_insn (gen_rtx_SET (to, lo));
2695 set_unique_reg_note (get_last_insn (), REG_EQUAL, 2736 set_unique_reg_note (get_last_insn (), REG_EQUAL,
3038 && nios2_symbol_ref_in_r0rel_data_p (op)) 3079 && nios2_symbol_ref_in_r0rel_data_p (op))
3039 return true; 3080 return true;
3040 else if (GET_CODE (op) == CONST 3081 else if (GET_CODE (op) == CONST
3041 && GET_CODE (XEXP (op, 0)) == PLUS) 3082 && GET_CODE (XEXP (op, 0)) == PLUS)
3042 return r0rel_constant_p (XEXP (XEXP (op, 0), 0)); 3083 return r0rel_constant_p (XEXP (XEXP (op, 0), 0));
3084 else if (GET_CODE (op) == CONST_INT
3085 && SMALL_INT (INTVAL (op)))
3086 return true;
3043 3087
3044 return false; 3088 return false;
3045 } 3089 }
3046 3090
3047 /* Return the name string for a supported unspec reloc offset. */ 3091 /* Return the name string for a supported unspec reloc offset. */
3108 fprintf (file, ")(%s)", reg_names[GP_REGNO]); 3152 fprintf (file, ")(%s)", reg_names[GP_REGNO]);
3109 return; 3153 return;
3110 } 3154 }
3111 else if (r0rel_constant_p (op)) 3155 else if (r0rel_constant_p (op))
3112 { 3156 {
3113 fprintf (file, "%%lo("); 3157 if (CONST_INT_P (op))
3114 output_addr_const (file, op); 3158 {
3115 fprintf (file, ")(r0)"); 3159 output_addr_const (file, op);
3116 return; 3160 fprintf (file, "(r0)");
3117 } 3161 return;
3162 }
3163 else
3164 {
3165 fprintf (file, "%%lo(");
3166 output_addr_const (file, op);
3167 fprintf (file, ")(r0)");
3168 return;
3169 }
3170 }
3118 break; 3171 break;
3119 3172
3120 case PLUS: 3173 case PLUS:
3121 { 3174 {
3122 rtx op0 = XEXP (op, 0); 3175 rtx op0 = XEXP (op, 0);
5076 stw.n, ldwsp.n, or stwsp.n instruction. */ 5129 stw.n, ldwsp.n, or stwsp.n instruction. */
5077 static bool 5130 static bool
5078 can_use_cdx_ldstw (int regno, int basereg, int offset) 5131 can_use_cdx_ldstw (int regno, int basereg, int offset)
5079 { 5132 {
5080 if (CDX_REG_P (regno) && CDX_REG_P (basereg) 5133 if (CDX_REG_P (regno) && CDX_REG_P (basereg)
5081 && (offset & 0x3) == 0 && 0 <= offset && offset < 0x40) 5134 && (offset & 0x3) == 0 && offset >= 0 && offset < 0x40)
5082 return true; 5135 return true;
5083 else if (basereg == SP_REGNO 5136 else if (basereg == SP_REGNO
5084 && offset >= 0 && offset < 0x80 && (offset & 0x3) == 0) 5137 && offset >= 0 && offset < 0x80 && (offset & 0x3) == 0)
5085 return true; 5138 return true;
5086 return false; 5139 return false;
5348 nios2_label_align (rtx label) 5401 nios2_label_align (rtx label)
5349 { 5402 {
5350 int n = CODE_LABEL_NUMBER (label); 5403 int n = CODE_LABEL_NUMBER (label);
5351 5404
5352 if (label_align && n >= min_labelno && n <= max_labelno) 5405 if (label_align && n >= min_labelno && n <= max_labelno)
5353 return MAX (label_align[n - min_labelno], align_labels_log); 5406 return MAX (label_align[n - min_labelno], align_labels.levels[0].log);
5354 return align_labels_log; 5407 return align_labels.levels[0].log;
5355 } 5408 }
5356 5409
5357 /* Implement ADJUST_REG_ALLOC_ORDER. We use the default ordering 5410 /* Implement ADJUST_REG_ALLOC_ORDER. We use the default ordering
5358 for R1 and non-CDX R2 code; for CDX we tweak thing to prefer 5411 for R1 and non-CDX R2 code; for CDX we tweak thing to prefer
5359 the registers that can be used as operands to instructions that 5412 the registers that can be used as operands to instructions that
5517 #define TARGET_MACHINE_DEPENDENT_REORG nios2_reorg 5570 #define TARGET_MACHINE_DEPENDENT_REORG nios2_reorg
5518 5571
5519 #undef TARGET_CONSTANT_ALIGNMENT 5572 #undef TARGET_CONSTANT_ALIGNMENT
5520 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings 5573 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
5521 5574
5575 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
5576 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
5577
5522 struct gcc_target targetm = TARGET_INITIALIZER; 5578 struct gcc_target targetm = TARGET_INITIALIZER;
5523 5579
5524 #include "gt-nios2.h" 5580 #include "gt-nios2.h"