1 1.1 mrg /* Target machine subroutines for Altera Nios II. 2 1.1 mrg Copyright (C) 2012-2022 Free Software Foundation, Inc. 3 1.1 mrg Contributed by Jonah Graham (jgraham (at) altera.com), 4 1.1 mrg Will Reece (wreece (at) altera.com), and Jeff DaSilva (jdasilva (at) altera.com). 5 1.1 mrg Contributed by Mentor Graphics, Inc. 6 1.1 mrg 7 1.1 mrg This file is part of GCC. 8 1.1 mrg 9 1.1 mrg GCC is free software; you can redistribute it and/or modify it 10 1.1 mrg under the terms of the GNU General Public License as published 11 1.1 mrg by the Free Software Foundation; either version 3, or (at your 12 1.1 mrg option) any later version. 13 1.1 mrg 14 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT 15 1.1 mrg ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 17 1.1 mrg License for more details. 18 1.1 mrg 19 1.1 mrg You should have received a copy of the GNU General Public License 20 1.1 mrg along with GCC; see the file COPYING3. If not see 21 1.1 mrg <http://www.gnu.org/licenses/>. */ 22 1.1 mrg 23 1.1 mrg #define IN_TARGET_CODE 1 24 1.1 mrg 25 1.1 mrg #include "config.h" 26 1.1 mrg #include "system.h" 27 1.1 mrg #include "coretypes.h" 28 1.1 mrg #include "backend.h" 29 1.1 mrg #include "target.h" 30 1.1 mrg #include "rtl.h" 31 1.1 mrg #include "tree.h" 32 1.1 mrg #include "stringpool.h" 33 1.1 mrg #include "attribs.h" 34 1.1 mrg #include "df.h" 35 1.1 mrg #include "memmodel.h" 36 1.1 mrg #include "tm_p.h" 37 1.1 mrg #include "optabs.h" 38 1.1 mrg #include "regs.h" 39 1.1 mrg #include "emit-rtl.h" 40 1.1 mrg #include "recog.h" 41 1.1 mrg #include "diagnostic-core.h" 42 1.1 mrg #include "output.h" 43 1.1 mrg #include "insn-attr.h" 44 1.1 mrg #include "flags.h" 45 1.1 mrg #include "explow.h" 46 1.1 mrg #include "calls.h" 47 1.1 mrg #include "varasm.h" 48 1.1 mrg #include "expr.h" 49 1.1 mrg #include "toplev.h" 50 1.1 mrg #include "langhooks.h" 51 1.1 mrg #include "stor-layout.h" 52 1.1 mrg #include "builtins.h" 53 1.1 mrg #include "tree-pass.h" 54 1.1 mrg #include "xregex.h" 55 1.1 mrg #include "opts.h" 56 1.1 mrg 57 1.1 mrg /* This file should be included last. */ 58 1.1 mrg #include "target-def.h" 59 1.1 mrg 60 1.1 mrg /* Forward function declarations. */ 61 1.1 mrg static bool nios2_symbolic_constant_p (rtx); 62 1.1 mrg static bool prologue_saved_reg_p (unsigned); 63 1.1 mrg static void nios2_load_pic_register (void); 64 1.1 mrg static void nios2_register_custom_code (unsigned int, enum nios2_ccs_code, int); 65 1.1 mrg static const char *nios2_unspec_reloc_name (int); 66 1.1 mrg static void nios2_register_builtin_fndecl (unsigned, tree); 67 1.1 mrg static rtx nios2_ldst_parallel (bool, bool, bool, rtx, int, 68 1.1 mrg unsigned HOST_WIDE_INT, bool); 69 1.1 mrg static int nios2_address_cost (rtx, machine_mode, addr_space_t, bool); 70 1.1 mrg 71 1.1 mrg /* Threshold for data being put into the small data/bss area, instead 72 1.1 mrg of the normal data area (references to the small data/bss area take 73 1.1 mrg 1 instruction, and use the global pointer, references to the normal 74 1.1 mrg data area takes 2 instructions). */ 75 1.1 mrg unsigned HOST_WIDE_INT nios2_section_threshold = NIOS2_DEFAULT_GVALUE; 76 1.1 mrg 77 1.1 mrg struct GTY (()) machine_function 78 1.1 mrg { 79 1.1 mrg /* Current frame information, to be filled in by nios2_compute_frame_layout 80 1.1 mrg with register save masks, and offsets for the current function. */ 81 1.1 mrg 82 1.1 mrg /* Mask of registers to save. */ 83 1.1 mrg unsigned int save_mask; 84 1.1 mrg /* Number of bytes that the entire frame takes up. */ 85 1.1 mrg int total_size; 86 1.1 mrg /* Number of bytes that variables take up. */ 87 1.1 mrg int var_size; 88 1.1 mrg /* Number of bytes that outgoing arguments take up. */ 89 1.1 mrg int args_size; 90 1.1 mrg /* Number of bytes needed to store registers in frame. */ 91 1.1 mrg int save_reg_size; 92 1.1 mrg /* Number of bytes used to store callee-saved registers. */ 93 1.1 mrg int callee_save_reg_size; 94 1.1 mrg /* Offset from new stack pointer to store registers. */ 95 1.1 mrg int save_regs_offset; 96 1.1 mrg /* Offset from save_regs_offset to store frame pointer register. */ 97 1.1 mrg int fp_save_offset; 98 1.1 mrg /* != 0 if function has a variable argument list. */ 99 1.1 mrg int uses_anonymous_args; 100 1.1 mrg /* != 0 if frame layout already calculated. */ 101 1.1 mrg int initialized; 102 1.1 mrg }; 103 1.1 mrg 104 1.1 mrg /* State to track the assignment of custom codes to FPU/custom builtins. */ 105 1.1 mrg static enum nios2_ccs_code custom_code_status[256]; 106 1.1 mrg static int custom_code_index[256]; 107 1.1 mrg /* Set to true if any conflicts (re-use of a code between 0-255) are found. */ 108 1.1 mrg static bool custom_code_conflict = false; 109 1.1 mrg 110 1.1 mrg /* State for command-line options. */ 111 1.1 mrg regex_t nios2_gprel_sec_regex; 112 1.1 mrg regex_t nios2_r0rel_sec_regex; 113 1.1 mrg 114 1.1 mrg 115 1.1 mrg /* Definition of builtin function types for nios2. */ 117 1.1 mrg 118 1.1 mrg #define N2_FTYPES \ 119 1.1 mrg N2_FTYPE(1, (SF)) \ 120 1.1 mrg N2_FTYPE(1, (VOID)) \ 121 1.1 mrg N2_FTYPE(2, (DF, DF)) \ 122 1.1 mrg N2_FTYPE(3, (DF, DF, DF)) \ 123 1.1 mrg N2_FTYPE(2, (DF, SF)) \ 124 1.1 mrg N2_FTYPE(2, (DF, SI)) \ 125 1.1 mrg N2_FTYPE(2, (DF, UI)) \ 126 1.1 mrg N2_FTYPE(2, (SF, DF)) \ 127 1.1 mrg N2_FTYPE(2, (SF, SF)) \ 128 1.1 mrg N2_FTYPE(3, (SF, SF, SF)) \ 129 1.1 mrg N2_FTYPE(2, (SF, SI)) \ 130 1.1 mrg N2_FTYPE(2, (SF, UI)) \ 131 1.1 mrg N2_FTYPE(2, (SI, CVPTR)) \ 132 1.1 mrg N2_FTYPE(2, (SI, DF)) \ 133 1.1 mrg N2_FTYPE(3, (SI, DF, DF)) \ 134 1.1 mrg N2_FTYPE(2, (SI, SF)) \ 135 1.1 mrg N2_FTYPE(3, (SI, SF, SF)) \ 136 1.1 mrg N2_FTYPE(2, (SI, SI)) \ 137 1.1 mrg N2_FTYPE(3, (SI, SI, SI)) \ 138 1.1 mrg N2_FTYPE(3, (SI, VPTR, SI)) \ 139 1.1 mrg N2_FTYPE(2, (UI, CVPTR)) \ 140 1.1 mrg N2_FTYPE(2, (UI, DF)) \ 141 1.1 mrg N2_FTYPE(2, (UI, SF)) \ 142 1.1 mrg N2_FTYPE(2, (VOID, DF)) \ 143 1.1 mrg N2_FTYPE(2, (VOID, SF)) \ 144 1.1 mrg N2_FTYPE(2, (VOID, SI)) \ 145 1.1 mrg N2_FTYPE(3, (VOID, SI, SI)) \ 146 1.1 mrg N2_FTYPE(2, (VOID, VPTR)) \ 147 1.1 mrg N2_FTYPE(3, (VOID, VPTR, SI)) 148 1.1 mrg 149 1.1 mrg #define N2_FTYPE_OP1(R) N2_FTYPE_ ## R ## _VOID 150 1.1 mrg #define N2_FTYPE_OP2(R, A1) N2_FTYPE_ ## R ## _ ## A1 151 1.1 mrg #define N2_FTYPE_OP3(R, A1, A2) N2_FTYPE_ ## R ## _ ## A1 ## _ ## A2 152 1.1 mrg 153 1.1 mrg /* Expand ftcode enumeration. */ 154 1.1 mrg enum nios2_ftcode { 155 1.1 mrg #define N2_FTYPE(N,ARGS) N2_FTYPE_OP ## N ARGS, 156 1.1 mrg N2_FTYPES 157 1.1 mrg #undef N2_FTYPE 158 1.1 mrg N2_FTYPE_MAX 159 1.1 mrg }; 160 1.1 mrg 161 1.1 mrg /* Return the tree function type, based on the ftcode. */ 162 1.1 mrg static tree 163 1.1 mrg nios2_ftype (enum nios2_ftcode ftcode) 164 1.1 mrg { 165 1.1 mrg static tree types[(int) N2_FTYPE_MAX]; 166 1.1 mrg 167 1.1 mrg tree N2_TYPE_SF = float_type_node; 168 1.1 mrg tree N2_TYPE_DF = double_type_node; 169 1.1 mrg tree N2_TYPE_SI = integer_type_node; 170 1.1 mrg tree N2_TYPE_UI = unsigned_type_node; 171 1.1 mrg tree N2_TYPE_VOID = void_type_node; 172 1.1 mrg 173 1.1 mrg static const_tree N2_TYPE_CVPTR, N2_TYPE_VPTR; 174 1.1 mrg if (!N2_TYPE_CVPTR) 175 1.1 mrg { 176 1.1 mrg /* const volatile void *. */ 177 1.1 mrg N2_TYPE_CVPTR 178 1.1 mrg = build_pointer_type (build_qualified_type (void_type_node, 179 1.1 mrg (TYPE_QUAL_CONST 180 1.1 mrg | TYPE_QUAL_VOLATILE))); 181 1.1 mrg /* volatile void *. */ 182 1.1 mrg N2_TYPE_VPTR 183 1.1 mrg = build_pointer_type (build_qualified_type (void_type_node, 184 1.1 mrg TYPE_QUAL_VOLATILE)); 185 1.1 mrg } 186 1.1 mrg if (types[(int) ftcode] == NULL_TREE) 187 1.1 mrg switch (ftcode) 188 1.1 mrg { 189 1.1 mrg #define N2_FTYPE_ARGS1(R) N2_TYPE_ ## R 190 1.1 mrg #define N2_FTYPE_ARGS2(R,A1) N2_TYPE_ ## R, N2_TYPE_ ## A1 191 1.1 mrg #define N2_FTYPE_ARGS3(R,A1,A2) N2_TYPE_ ## R, N2_TYPE_ ## A1, N2_TYPE_ ## A2 192 1.1 mrg #define N2_FTYPE(N,ARGS) \ 193 1.1 mrg case N2_FTYPE_OP ## N ARGS: \ 194 1.1 mrg types[(int) ftcode] \ 195 1.1 mrg = build_function_type_list (N2_FTYPE_ARGS ## N ARGS, NULL_TREE); \ 196 1.1 mrg break; 197 1.1 mrg N2_FTYPES 198 1.1 mrg #undef N2_FTYPE 199 1.1 mrg default: gcc_unreachable (); 200 1.1 mrg } 201 1.1 mrg return types[(int) ftcode]; 202 1.1 mrg } 203 1.1 mrg 204 1.1 mrg 205 1.1 mrg /* Definition of FPU instruction descriptions. */ 207 1.1 mrg 208 1.1 mrg struct nios2_fpu_insn_info 209 1.1 mrg { 210 1.1 mrg const char *name; 211 1.1 mrg int num_operands, *optvar; 212 1.1 mrg int opt, no_opt; 213 1.1 mrg #define N2F_DF 0x1 214 1.1 mrg #define N2F_DFREQ 0x2 215 1.1 mrg #define N2F_UNSAFE 0x4 216 1.1 mrg #define N2F_FINITE 0x8 217 1.1 mrg #define N2F_NO_ERRNO 0x10 218 1.1 mrg unsigned int flags; 219 1.1 mrg enum insn_code icode; 220 1.1 mrg enum nios2_ftcode ftcode; 221 1.1 mrg }; 222 1.1 mrg 223 1.1 mrg /* Base macro for defining FPU instructions. */ 224 1.1 mrg #define N2FPU_INSN_DEF_BASE(insn, nop, flags, icode, args) \ 225 1.1 mrg { #insn, nop, &nios2_custom_ ## insn, OPT_mcustom_##insn##_, \ 226 1.1 mrg OPT_mno_custom_##insn, flags, CODE_FOR_ ## icode, \ 227 1.1 mrg N2_FTYPE_OP ## nop args } 228 1.1 mrg 229 1.1 mrg /* Arithmetic and math functions; 2 or 3 operand FP operations. */ 230 1.1 mrg #define N2FPU_OP2(mode) (mode, mode) 231 1.1 mrg #define N2FPU_OP3(mode) (mode, mode, mode) 232 1.1 mrg #define N2FPU_INSN_DEF(code, icode, nop, flags, m, M) \ 233 1.1 mrg N2FPU_INSN_DEF_BASE (f ## code ## m, nop, flags, \ 234 1.1 mrg icode ## m ## f ## nop, N2FPU_OP ## nop (M ## F)) 235 1.1 mrg #define N2FPU_INSN_SF(code, nop, flags) \ 236 1.1 mrg N2FPU_INSN_DEF (code, code, nop, flags, s, S) 237 1.1 mrg #define N2FPU_INSN_DF(code, nop, flags) \ 238 1.1 mrg N2FPU_INSN_DEF (code, code, nop, flags | N2F_DF, d, D) 239 1.1 mrg 240 1.1 mrg /* Compare instructions, 3 operand FP operation with a SI result. */ 241 1.1 mrg #define N2FPU_CMP_DEF(code, flags, m, M) \ 242 1.1 mrg N2FPU_INSN_DEF_BASE (fcmp ## code ## m, 3, flags, \ 243 1.1 mrg nios2_s ## code ## m ## f, (SI, M ## F, M ## F)) 244 1.1 mrg #define N2FPU_CMP_SF(code) N2FPU_CMP_DEF (code, 0, s, S) 245 1.1 mrg #define N2FPU_CMP_DF(code) N2FPU_CMP_DEF (code, N2F_DF, d, D) 246 1.1 mrg 247 1.1 mrg /* The order of definition needs to be maintained consistent with 248 1.1 mrg enum n2fpu_code in nios2-opts.h. */ 249 1.1 mrg struct nios2_fpu_insn_info nios2_fpu_insn[] = 250 1.1 mrg { 251 1.1 mrg /* Single precision instructions. */ 252 1.1 mrg N2FPU_INSN_SF (add, 3, 0), 253 1.1 mrg N2FPU_INSN_SF (sub, 3, 0), 254 1.1 mrg N2FPU_INSN_SF (mul, 3, 0), 255 1.1 mrg N2FPU_INSN_SF (div, 3, 0), 256 1.1 mrg /* Due to textual difference between min/max and smin/smax. */ 257 1.1 mrg N2FPU_INSN_DEF (min, smin, 3, N2F_FINITE, s, S), 258 1.1 mrg N2FPU_INSN_DEF (max, smax, 3, N2F_FINITE, s, S), 259 1.1 mrg N2FPU_INSN_SF (neg, 2, 0), 260 1.1 mrg N2FPU_INSN_SF (abs, 2, 0), 261 1.1 mrg N2FPU_INSN_SF (sqrt, 2, 0), 262 1.1 mrg N2FPU_INSN_SF (sin, 2, N2F_UNSAFE), 263 1.1 mrg N2FPU_INSN_SF (cos, 2, N2F_UNSAFE), 264 1.1 mrg N2FPU_INSN_SF (tan, 2, N2F_UNSAFE), 265 1.1 mrg N2FPU_INSN_SF (atan, 2, N2F_UNSAFE), 266 1.1 mrg N2FPU_INSN_SF (exp, 2, N2F_UNSAFE), 267 1.1 mrg N2FPU_INSN_SF (log, 2, N2F_UNSAFE), 268 1.1 mrg /* Single precision compares. */ 269 1.1 mrg N2FPU_CMP_SF (eq), N2FPU_CMP_SF (ne), 270 1.1 mrg N2FPU_CMP_SF (lt), N2FPU_CMP_SF (le), 271 1.1 mrg N2FPU_CMP_SF (gt), N2FPU_CMP_SF (ge), 272 1.1 mrg 273 1.1 mrg /* Double precision instructions. */ 274 1.1 mrg N2FPU_INSN_DF (add, 3, 0), 275 1.1 mrg N2FPU_INSN_DF (sub, 3, 0), 276 1.1 mrg N2FPU_INSN_DF (mul, 3, 0), 277 1.1 mrg N2FPU_INSN_DF (div, 3, 0), 278 1.1 mrg /* Due to textual difference between min/max and smin/smax. */ 279 1.1 mrg N2FPU_INSN_DEF (min, smin, 3, N2F_FINITE, d, D), 280 1.1 mrg N2FPU_INSN_DEF (max, smax, 3, N2F_FINITE, d, D), 281 1.1 mrg N2FPU_INSN_DF (neg, 2, 0), 282 1.1 mrg N2FPU_INSN_DF (abs, 2, 0), 283 1.1 mrg N2FPU_INSN_DF (sqrt, 2, 0), 284 1.1 mrg N2FPU_INSN_DF (sin, 2, N2F_UNSAFE), 285 1.1 mrg N2FPU_INSN_DF (cos, 2, N2F_UNSAFE), 286 1.1 mrg N2FPU_INSN_DF (tan, 2, N2F_UNSAFE), 287 1.1 mrg N2FPU_INSN_DF (atan, 2, N2F_UNSAFE), 288 1.1 mrg N2FPU_INSN_DF (exp, 2, N2F_UNSAFE), 289 1.1 mrg N2FPU_INSN_DF (log, 2, N2F_UNSAFE), 290 1.1 mrg /* Double precision compares. */ 291 1.1 mrg N2FPU_CMP_DF (eq), N2FPU_CMP_DF (ne), 292 1.1 mrg N2FPU_CMP_DF (lt), N2FPU_CMP_DF (le), 293 1.1 mrg N2FPU_CMP_DF (gt), N2FPU_CMP_DF (ge), 294 1.1 mrg 295 1.1 mrg /* Conversion instructions. */ 296 1.1 mrg N2FPU_INSN_DEF_BASE (floatis, 2, 0, floatsisf2, (SF, SI)), 297 1.1 mrg N2FPU_INSN_DEF_BASE (floatus, 2, 0, floatunssisf2, (SF, UI)), 298 1.1 mrg N2FPU_INSN_DEF_BASE (floatid, 2, 0, floatsidf2, (DF, SI)), 299 1.1 mrg N2FPU_INSN_DEF_BASE (floatud, 2, 0, floatunssidf2, (DF, UI)), 300 1.1 mrg N2FPU_INSN_DEF_BASE (round, 2, N2F_NO_ERRNO, lroundsfsi2, (SI, SF)), 301 1.1 mrg N2FPU_INSN_DEF_BASE (fixsi, 2, 0, fix_truncsfsi2, (SI, SF)), 302 1.1 mrg N2FPU_INSN_DEF_BASE (fixsu, 2, 0, fixuns_truncsfsi2, (UI, SF)), 303 1.1 mrg N2FPU_INSN_DEF_BASE (fixdi, 2, 0, fix_truncdfsi2, (SI, DF)), 304 1.1 mrg N2FPU_INSN_DEF_BASE (fixdu, 2, 0, fixuns_truncdfsi2, (UI, DF)), 305 1.1 mrg N2FPU_INSN_DEF_BASE (fextsd, 2, 0, extendsfdf2, (DF, SF)), 306 1.1 mrg N2FPU_INSN_DEF_BASE (ftruncds, 2, 0, truncdfsf2, (SF, DF)), 307 1.1 mrg 308 1.1 mrg /* X, Y access instructions. */ 309 1.1 mrg N2FPU_INSN_DEF_BASE (fwrx, 2, N2F_DFREQ, nios2_fwrx, (VOID, DF)), 310 1.1 mrg N2FPU_INSN_DEF_BASE (fwry, 2, N2F_DFREQ, nios2_fwry, (VOID, SF)), 311 1.1 mrg N2FPU_INSN_DEF_BASE (frdxlo, 1, N2F_DFREQ, nios2_frdxlo, (SF)), 312 1.1 mrg N2FPU_INSN_DEF_BASE (frdxhi, 1, N2F_DFREQ, nios2_frdxhi, (SF)), 313 1.1 mrg N2FPU_INSN_DEF_BASE (frdy, 1, N2F_DFREQ, nios2_frdy, (SF)) 314 1.1 mrg }; 315 1.1 mrg 316 1.1 mrg /* Some macros for ease of access. */ 317 1.1 mrg #define N2FPU(code) nios2_fpu_insn[(int) code] 318 1.1 mrg #define N2FPU_ENABLED_P(code) (N2FPU_N(code) >= 0) 319 1.1 mrg #define N2FPU_N(code) (*N2FPU(code).optvar) 320 1.1 mrg #define N2FPU_NAME(code) (N2FPU(code).name) 321 1.1 mrg #define N2FPU_ICODE(code) (N2FPU(code).icode) 322 1.1 mrg #define N2FPU_FTCODE(code) (N2FPU(code).ftcode) 323 1.1 mrg #define N2FPU_FINITE_P(code) (N2FPU(code).flags & N2F_FINITE) 324 1.1 mrg #define N2FPU_UNSAFE_P(code) (N2FPU(code).flags & N2F_UNSAFE) 325 1.1 mrg #define N2FPU_NO_ERRNO_P(code) (N2FPU(code).flags & N2F_NO_ERRNO) 326 1.1 mrg #define N2FPU_DOUBLE_P(code) (N2FPU(code).flags & N2F_DF) 327 1.1 mrg #define N2FPU_DOUBLE_REQUIRED_P(code) (N2FPU(code).flags & N2F_DFREQ) 328 1.1 mrg 329 1.1 mrg /* Same as above, but for cases where using only the op part is shorter. */ 330 1.1 mrg #define N2FPU_OP(op) N2FPU(n2fpu_ ## op) 331 1.1 mrg #define N2FPU_OP_NAME(op) N2FPU_NAME(n2fpu_ ## op) 332 1.1 mrg #define N2FPU_OP_ENABLED_P(op) N2FPU_ENABLED_P(n2fpu_ ## op) 333 1.1 mrg 334 1.1 mrg /* Export the FPU insn enabled predicate to nios2.md. */ 335 1.1 mrg bool 336 1.1 mrg nios2_fpu_insn_enabled (enum n2fpu_code code) 337 1.1 mrg { 338 1.1 mrg return N2FPU_ENABLED_P (code); 339 1.1 mrg } 340 1.1 mrg 341 1.1 mrg /* Return true if COND comparison for mode MODE is enabled under current 342 1.1 mrg settings. */ 343 1.1 mrg 344 1.1 mrg static bool 345 1.1 mrg nios2_fpu_compare_enabled (enum rtx_code cond, machine_mode mode) 346 1.1 mrg { 347 1.1 mrg if (mode == SFmode) 348 1.1 mrg switch (cond) 349 1.1 mrg { 350 1.1 mrg case EQ: return N2FPU_OP_ENABLED_P (fcmpeqs); 351 1.1 mrg case NE: return N2FPU_OP_ENABLED_P (fcmpnes); 352 1.1 mrg case GT: return N2FPU_OP_ENABLED_P (fcmpgts); 353 1.1 mrg case GE: return N2FPU_OP_ENABLED_P (fcmpges); 354 1.1 mrg case LT: return N2FPU_OP_ENABLED_P (fcmplts); 355 1.1 mrg case LE: return N2FPU_OP_ENABLED_P (fcmples); 356 1.1 mrg default: break; 357 1.1 mrg } 358 1.1 mrg else if (mode == DFmode) 359 1.1 mrg switch (cond) 360 1.1 mrg { 361 1.1 mrg case EQ: return N2FPU_OP_ENABLED_P (fcmpeqd); 362 1.1 mrg case NE: return N2FPU_OP_ENABLED_P (fcmpned); 363 1.1 mrg case GT: return N2FPU_OP_ENABLED_P (fcmpgtd); 364 1.1 mrg case GE: return N2FPU_OP_ENABLED_P (fcmpged); 365 1.1 mrg case LT: return N2FPU_OP_ENABLED_P (fcmpltd); 366 1.1 mrg case LE: return N2FPU_OP_ENABLED_P (fcmpled); 367 1.1 mrg default: break; 368 1.1 mrg } 369 1.1 mrg return false; 370 1.1 mrg } 371 1.1 mrg 372 1.1 mrg /* Stack layout and calling conventions. */ 373 1.1 mrg 374 1.1 mrg #define NIOS2_STACK_ALIGN(LOC) \ 375 1.1 mrg (((LOC) + ((PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) - 1)) \ 376 1.1 mrg & ~((PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) - 1)) 377 1.1 mrg 378 1.1 mrg /* Return the bytes needed to compute the frame pointer from the current 379 1.1 mrg stack pointer. */ 380 1.1 mrg static int 381 1.1 mrg nios2_compute_frame_layout (void) 382 1.1 mrg { 383 1.1 mrg unsigned int regno; 384 1.1 mrg unsigned int save_mask = 0; 385 1.1 mrg int total_size; 386 1.1 mrg int var_size; 387 1.1 mrg int out_args_size; 388 1.1 mrg int save_reg_size; 389 1.1 mrg int callee_save_reg_size; 390 1.1 mrg 391 1.1 mrg if (cfun->machine->initialized) 392 1.1 mrg return cfun->machine->total_size; 393 1.1 mrg 394 1.1 mrg /* Calculate space needed for gp registers. */ 395 1.1 mrg save_reg_size = 0; 396 1.1 mrg for (regno = 0; regno <= LAST_GP_REG; regno++) 397 1.1 mrg if (prologue_saved_reg_p (regno)) 398 1.1 mrg { 399 1.1 mrg save_mask |= 1 << regno; 400 1.1 mrg save_reg_size += 4; 401 1.1 mrg } 402 1.1 mrg 403 1.1 mrg /* If we are saving any callee-save register, then assume 404 1.1 mrg push.n/pop.n should be used. Make sure RA is saved, and 405 1.1 mrg contiguous registers starting from r16-- are all saved. */ 406 1.1 mrg if (TARGET_HAS_CDX && save_reg_size != 0) 407 1.1 mrg { 408 1.1 mrg if ((save_mask & (1 << RA_REGNO)) == 0) 409 1.1 mrg { 410 1.1 mrg save_mask |= 1 << RA_REGNO; 411 1.1 mrg save_reg_size += 4; 412 1.1 mrg } 413 1.1 mrg 414 1.1 mrg for (regno = 23; regno >= 16; regno--) 415 1.1 mrg if ((save_mask & (1 << regno)) != 0) 416 1.1 mrg { 417 1.1 mrg /* Starting from highest numbered callee-saved 418 1.1 mrg register that is used, make sure all regs down 419 1.1 mrg to r16 is saved, to maintain contiguous range 420 1.1 mrg for push.n/pop.n. */ 421 1.1 mrg unsigned int i; 422 1.1 mrg for (i = regno - 1; i >= 16; i--) 423 1.1 mrg if ((save_mask & (1 << i)) == 0) 424 1.1 mrg { 425 1.1 mrg save_mask |= 1 << i; 426 1.1 mrg save_reg_size += 4; 427 1.1 mrg } 428 1.1 mrg break; 429 1.1 mrg } 430 1.1 mrg } 431 1.1 mrg 432 1.1 mrg callee_save_reg_size = save_reg_size; 433 1.1 mrg 434 1.1 mrg /* If we call eh_return, we need to save the EH data registers. */ 435 1.1 mrg if (crtl->calls_eh_return) 436 1.1 mrg { 437 1.1 mrg unsigned i; 438 1.1 mrg unsigned r; 439 1.1 mrg 440 1.1 mrg for (i = 0; (r = EH_RETURN_DATA_REGNO (i)) != INVALID_REGNUM; i++) 441 1.1 mrg if (!(save_mask & (1 << r))) 442 1.1 mrg { 443 1.1 mrg save_mask |= 1 << r; 444 1.1 mrg save_reg_size += 4; 445 1.1 mrg } 446 1.1 mrg } 447 1.1 mrg 448 1.1 mrg cfun->machine->fp_save_offset = 0; 449 1.1 mrg if (save_mask & (1 << HARD_FRAME_POINTER_REGNUM)) 450 1.1 mrg { 451 1.1 mrg int fp_save_offset = 0; 452 1.1 mrg for (regno = 0; regno < HARD_FRAME_POINTER_REGNUM; regno++) 453 1.1 mrg if (save_mask & (1 << regno)) 454 1.1 mrg fp_save_offset += 4; 455 1.1 mrg 456 1.1 mrg cfun->machine->fp_save_offset = fp_save_offset; 457 1.1 mrg } 458 1.1 mrg 459 1.1 mrg var_size = NIOS2_STACK_ALIGN (get_frame_size ()); 460 1.1 mrg out_args_size = NIOS2_STACK_ALIGN (crtl->outgoing_args_size); 461 1.1 mrg total_size = var_size + out_args_size; 462 1.1 mrg 463 1.1 mrg save_reg_size = NIOS2_STACK_ALIGN (save_reg_size); 464 1.1 mrg total_size += save_reg_size; 465 1.1 mrg total_size += NIOS2_STACK_ALIGN (crtl->args.pretend_args_size); 466 1.1 mrg 467 1.1 mrg /* Save other computed information. */ 468 1.1 mrg cfun->machine->save_mask = save_mask; 469 1.1 mrg cfun->machine->total_size = total_size; 470 1.1 mrg cfun->machine->var_size = var_size; 471 1.1 mrg cfun->machine->args_size = out_args_size; 472 1.1 mrg cfun->machine->save_reg_size = save_reg_size; 473 1.1 mrg cfun->machine->callee_save_reg_size = callee_save_reg_size; 474 1.1 mrg cfun->machine->initialized = reload_completed; 475 1.1 mrg cfun->machine->save_regs_offset = out_args_size + var_size; 476 1.1 mrg 477 1.1 mrg return total_size; 478 1.1 mrg } 479 1.1 mrg 480 1.1 mrg /* Generate save/restore of register REGNO at SP + OFFSET. Used by the 481 1.1 mrg prologue/epilogue expand routines. */ 482 1.1 mrg static void 483 1.1 mrg save_reg (int regno, unsigned offset) 484 1.1 mrg { 485 1.1 mrg rtx reg = gen_rtx_REG (SImode, regno); 486 1.1 mrg rtx addr = plus_constant (Pmode, stack_pointer_rtx, offset, false); 487 1.1 mrg rtx_insn *insn = emit_move_insn (gen_frame_mem (Pmode, addr), reg); 488 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 489 1.1 mrg } 490 1.1 mrg 491 1.1 mrg static void 492 1.1 mrg restore_reg (int regno, unsigned offset) 493 1.1 mrg { 494 1.1 mrg rtx reg = gen_rtx_REG (SImode, regno); 495 1.1 mrg rtx addr = plus_constant (Pmode, stack_pointer_rtx, offset, false); 496 1.1 mrg rtx_insn *insn = emit_move_insn (reg, gen_frame_mem (Pmode, addr)); 497 1.1 mrg /* Tag epilogue unwind note. */ 498 1.1 mrg add_reg_note (insn, REG_CFA_RESTORE, reg); 499 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 500 1.1 mrg } 501 1.1 mrg 502 1.1 mrg /* This routine tests for the base register update SET in load/store 503 1.1 mrg multiple RTL insns, used in pop_operation_p and ldstwm_operation_p. */ 504 1.1 mrg static bool 505 1.1 mrg base_reg_adjustment_p (rtx set, rtx *base_reg, rtx *offset) 506 1.1 mrg { 507 1.1 mrg if (GET_CODE (set) == SET 508 1.1 mrg && REG_P (SET_DEST (set)) 509 1.1 mrg && GET_CODE (SET_SRC (set)) == PLUS 510 1.1 mrg && REG_P (XEXP (SET_SRC (set), 0)) 511 1.1 mrg && rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0)) 512 1.1 mrg && CONST_INT_P (XEXP (SET_SRC (set), 1))) 513 1.1 mrg { 514 1.1 mrg *base_reg = XEXP (SET_SRC (set), 0); 515 1.1 mrg *offset = XEXP (SET_SRC (set), 1); 516 1.1 mrg return true; 517 1.1 mrg } 518 1.1 mrg return false; 519 1.1 mrg } 520 1.1 mrg 521 1.1 mrg /* Does the CFA note work for push/pop prologue/epilogue instructions. */ 522 1.1 mrg static void 523 1.1 mrg nios2_create_cfa_notes (rtx_insn *insn, bool epilogue_p) 524 1.1 mrg { 525 1.1 mrg int i = 0; 526 1.1 mrg rtx base_reg, offset, elt, pat = PATTERN (insn); 527 1.1 mrg if (epilogue_p) 528 1.1 mrg { 529 1.1 mrg elt = XVECEXP (pat, 0, 0); 530 1.1 mrg if (GET_CODE (elt) == RETURN) 531 1.1 mrg i++; 532 1.1 mrg elt = XVECEXP (pat, 0, i); 533 1.1 mrg if (base_reg_adjustment_p (elt, &base_reg, &offset)) 534 1.1 mrg { 535 1.1 mrg add_reg_note (insn, REG_CFA_ADJUST_CFA, copy_rtx (elt)); 536 1.1 mrg i++; 537 1.1 mrg } 538 1.1 mrg for (; i < XVECLEN (pat, 0); i++) 539 1.1 mrg { 540 1.1 mrg elt = SET_DEST (XVECEXP (pat, 0, i)); 541 1.1 mrg gcc_assert (REG_P (elt)); 542 1.1 mrg add_reg_note (insn, REG_CFA_RESTORE, elt); 543 1.1 mrg } 544 1.1 mrg } 545 1.1 mrg else 546 1.1 mrg { 547 1.1 mrg /* Tag each of the prologue sets. */ 548 1.1 mrg for (i = 0; i < XVECLEN (pat, 0); i++) 549 1.1 mrg RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1; 550 1.1 mrg } 551 1.1 mrg } 552 1.1 mrg 553 1.1 mrg /* Temp regno used inside prologue/epilogue. */ 554 1.1 mrg #define TEMP_REG_NUM 8 555 1.1 mrg 556 1.1 mrg /* Emit conditional trap for checking stack limit. SIZE is the number of 557 1.1 mrg additional bytes required. 558 1.1 mrg 559 1.1 mrg GDB prologue analysis depends on this generating a direct comparison 560 1.1 mrg to the SP register, so the adjustment to add SIZE needs to be done on 561 1.1 mrg the other operand to the comparison. Use TEMP_REG_NUM as a temporary, 562 1.1 mrg if necessary. */ 563 1.1 mrg static void 564 1.1 mrg nios2_emit_stack_limit_check (int size) 565 1.1 mrg { 566 1.1 mrg rtx sum = NULL_RTX; 567 1.1 mrg 568 1.1 mrg if (GET_CODE (stack_limit_rtx) == SYMBOL_REF) 569 1.1 mrg { 570 1.1 mrg /* This generates a %hiadj/%lo pair with the constant size 571 1.1 mrg add handled by the relocations. */ 572 1.1 mrg sum = gen_rtx_REG (Pmode, TEMP_REG_NUM); 573 1.1 mrg emit_move_insn (sum, plus_constant (Pmode, stack_limit_rtx, size)); 574 1.1 mrg } 575 1.1 mrg else if (!REG_P (stack_limit_rtx)) 576 1.1 mrg sorry ("Unknown form for stack limit expression"); 577 1.1 mrg else if (size == 0) 578 1.1 mrg sum = stack_limit_rtx; 579 1.1 mrg else if (SMALL_INT (size)) 580 1.1 mrg { 581 1.1 mrg sum = gen_rtx_REG (Pmode, TEMP_REG_NUM); 582 1.1 mrg emit_move_insn (sum, plus_constant (Pmode, stack_limit_rtx, size)); 583 1.1 mrg } 584 1.1 mrg else 585 1.1 mrg { 586 1.1 mrg sum = gen_rtx_REG (Pmode, TEMP_REG_NUM); 587 1.1 mrg emit_move_insn (sum, gen_int_mode (size, Pmode)); 588 1.1 mrg emit_insn (gen_add2_insn (sum, stack_limit_rtx)); 589 1.1 mrg } 590 1.1 mrg 591 1.1 mrg emit_insn (gen_ctrapsi4 (gen_rtx_LTU (VOIDmode, stack_pointer_rtx, sum), 592 1.1 mrg stack_pointer_rtx, sum, GEN_INT (3))); 593 1.1 mrg } 594 1.1 mrg 595 1.1 mrg static rtx_insn * 596 1.1 mrg nios2_emit_add_constant (rtx reg, HOST_WIDE_INT immed) 597 1.1 mrg { 598 1.1 mrg rtx_insn *insn; 599 1.1 mrg if (SMALL_INT (immed)) 600 1.1 mrg insn = emit_insn (gen_add2_insn (reg, gen_int_mode (immed, Pmode))); 601 1.1 mrg else 602 1.1 mrg { 603 1.1 mrg rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM); 604 1.1 mrg emit_move_insn (tmp, gen_int_mode (immed, Pmode)); 605 1.1 mrg insn = emit_insn (gen_add2_insn (reg, tmp)); 606 1.1 mrg } 607 1.1 mrg return insn; 608 1.1 mrg } 609 1.1 mrg 610 1.1 mrg static rtx_insn * 611 1.1 mrg nios2_adjust_stack (int sp_adjust, bool epilogue_p) 612 1.1 mrg { 613 1.1 mrg enum reg_note note_kind = REG_NOTE_MAX; 614 1.1 mrg rtx_insn *insn = NULL; 615 1.1 mrg if (sp_adjust) 616 1.1 mrg { 617 1.1 mrg if (SMALL_INT (sp_adjust)) 618 1.1 mrg insn = emit_insn (gen_add2_insn (stack_pointer_rtx, 619 1.1 mrg gen_int_mode (sp_adjust, Pmode))); 620 1.1 mrg else 621 1.1 mrg { 622 1.1 mrg rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM); 623 1.1 mrg emit_move_insn (tmp, gen_int_mode (sp_adjust, Pmode)); 624 1.1 mrg insn = emit_insn (gen_add2_insn (stack_pointer_rtx, tmp)); 625 1.1 mrg /* Attach a note indicating what happened. */ 626 1.1 mrg if (!epilogue_p) 627 1.1 mrg note_kind = REG_FRAME_RELATED_EXPR; 628 1.1 mrg } 629 1.1 mrg if (epilogue_p) 630 1.1 mrg note_kind = REG_CFA_ADJUST_CFA; 631 1.1 mrg if (note_kind != REG_NOTE_MAX) 632 1.1 mrg { 633 1.1 mrg rtx cfa_adj = gen_rtx_SET (stack_pointer_rtx, 634 1.1 mrg plus_constant (Pmode, stack_pointer_rtx, 635 1.1 mrg sp_adjust)); 636 1.1 mrg add_reg_note (insn, note_kind, cfa_adj); 637 1.1 mrg } 638 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 639 1.1 mrg } 640 1.1 mrg return insn; 641 1.1 mrg } 642 1.1 mrg 643 1.1 mrg void 644 1.1 mrg nios2_expand_prologue (void) 645 1.1 mrg { 646 1.1 mrg unsigned int regno; 647 1.1 mrg int total_frame_size, save_offset; 648 1.1 mrg int sp_offset; /* offset from base_reg to final stack value. */ 649 1.1 mrg int save_regs_base; /* offset from base_reg to register save area. */ 650 1.1 mrg rtx_insn *insn; 651 1.1 mrg 652 1.1 mrg total_frame_size = nios2_compute_frame_layout (); 653 1.1 mrg 654 1.1 mrg if (flag_stack_usage_info) 655 1.1 mrg current_function_static_stack_size = total_frame_size; 656 1.1 mrg 657 1.1 mrg /* When R2 CDX push.n/stwm is available, arrange for stack frame to be built 658 1.1 mrg using them. */ 659 1.1 mrg if (TARGET_HAS_CDX 660 1.1 mrg && (cfun->machine->save_reg_size != 0 661 1.1 mrg || cfun->machine->uses_anonymous_args)) 662 1.1 mrg { 663 1.1 mrg unsigned int regmask = cfun->machine->save_mask; 664 1.1 mrg unsigned int callee_save_regs = regmask & 0xffff0000; 665 1.1 mrg unsigned int caller_save_regs = regmask & 0x0000ffff; 666 1.1 mrg int push_immed = 0; 667 1.1 mrg int pretend_args_size = NIOS2_STACK_ALIGN (crtl->args.pretend_args_size); 668 1.1 mrg rtx stack_mem = 669 1.1 mrg gen_frame_mem (SImode, plus_constant (Pmode, stack_pointer_rtx, -4)); 670 1.1 mrg 671 1.1 mrg /* Check that there is room for the entire stack frame before doing 672 1.1 mrg any SP adjustments or pushes. */ 673 1.1 mrg if (crtl->limit_stack) 674 1.1 mrg nios2_emit_stack_limit_check (total_frame_size); 675 1.1 mrg 676 1.1 mrg if (pretend_args_size) 677 1.1 mrg { 678 1.1 mrg if (cfun->machine->uses_anonymous_args) 679 1.1 mrg { 680 1.1 mrg /* Emit a stwm to push copy of argument registers onto 681 1.1 mrg the stack for va_arg processing. */ 682 1.1 mrg unsigned int r, mask = 0, n = pretend_args_size / 4; 683 1.1 mrg for (r = LAST_ARG_REGNO - n + 1; r <= LAST_ARG_REGNO; r++) 684 1.1 mrg mask |= (1 << r); 685 1.1 mrg insn = emit_insn (nios2_ldst_parallel 686 1.1 mrg (false, false, false, stack_mem, 687 1.1 mrg -pretend_args_size, mask, false)); 688 1.1 mrg /* Tag first SP adjustment as frame-related. */ 689 1.1 mrg RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 0)) = 1; 690 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 691 1.1 mrg } 692 1.1 mrg else 693 1.1 mrg nios2_adjust_stack (-pretend_args_size, false); 694 1.1 mrg } 695 1.1 mrg if (callee_save_regs) 696 1.1 mrg { 697 1.1 mrg /* Emit a push.n to save registers and optionally allocate 698 1.1 mrg push_immed extra bytes on the stack. */ 699 1.1 mrg int sp_adjust; 700 1.1 mrg if (caller_save_regs) 701 1.1 mrg /* Can't allocate extra stack space yet. */ 702 1.1 mrg push_immed = 0; 703 1.1 mrg else if (cfun->machine->save_regs_offset <= 60) 704 1.1 mrg /* Stack adjustment fits entirely in the push.n. */ 705 1.1 mrg push_immed = cfun->machine->save_regs_offset; 706 1.1 mrg else if (frame_pointer_needed 707 1.1 mrg && cfun->machine->fp_save_offset == 0) 708 1.1 mrg /* Deferring the entire stack adjustment until later 709 1.1 mrg allows us to use a mov.n instead of a 32-bit addi 710 1.1 mrg instruction to set the frame pointer. */ 711 1.1 mrg push_immed = 0; 712 1.1 mrg else 713 1.1 mrg /* Splitting the stack adjustment between the push.n 714 1.1 mrg and an explicit adjustment makes it more likely that 715 1.1 mrg we can use spdeci.n for the explicit part. */ 716 1.1 mrg push_immed = 60; 717 1.1 mrg sp_adjust = -(cfun->machine->callee_save_reg_size + push_immed); 718 1.1 mrg insn = emit_insn (nios2_ldst_parallel (false, false, false, 719 1.1 mrg stack_mem, sp_adjust, 720 1.1 mrg callee_save_regs, false)); 721 1.1 mrg nios2_create_cfa_notes (insn, false); 722 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 723 1.1 mrg } 724 1.1 mrg 725 1.1 mrg if (caller_save_regs) 726 1.1 mrg { 727 1.1 mrg /* Emit a stwm to save the EH data regs, r4-r7. */ 728 1.1 mrg int caller_save_size = (cfun->machine->save_reg_size 729 1.1 mrg - cfun->machine->callee_save_reg_size); 730 1.1 mrg gcc_assert ((caller_save_regs & ~0xf0) == 0); 731 1.1 mrg insn = emit_insn (nios2_ldst_parallel 732 1.1 mrg (false, false, false, stack_mem, 733 1.1 mrg -caller_save_size, caller_save_regs, false)); 734 1.1 mrg nios2_create_cfa_notes (insn, false); 735 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 736 1.1 mrg } 737 1.1 mrg 738 1.1 mrg save_regs_base = push_immed; 739 1.1 mrg sp_offset = -(cfun->machine->save_regs_offset - push_immed); 740 1.1 mrg } 741 1.1 mrg /* The non-CDX cases decrement the stack pointer, to prepare for individual 742 1.1 mrg register saves to the stack. */ 743 1.1 mrg else if (!SMALL_INT (total_frame_size)) 744 1.1 mrg { 745 1.1 mrg /* We need an intermediary point, this will point at the spill block. */ 746 1.1 mrg nios2_adjust_stack (cfun->machine->save_regs_offset - total_frame_size, 747 1.1 mrg false); 748 1.1 mrg save_regs_base = 0; 749 1.1 mrg sp_offset = -cfun->machine->save_regs_offset; 750 1.1 mrg if (crtl->limit_stack) 751 1.1 mrg nios2_emit_stack_limit_check (cfun->machine->save_regs_offset); 752 1.1 mrg } 753 1.1 mrg else if (total_frame_size) 754 1.1 mrg { 755 1.1 mrg nios2_adjust_stack (-total_frame_size, false); 756 1.1 mrg save_regs_base = cfun->machine->save_regs_offset; 757 1.1 mrg sp_offset = 0; 758 1.1 mrg if (crtl->limit_stack) 759 1.1 mrg nios2_emit_stack_limit_check (0); 760 1.1 mrg } 761 1.1 mrg else 762 1.1 mrg save_regs_base = sp_offset = 0; 763 1.1 mrg 764 1.1 mrg /* Save the registers individually in the non-CDX case. */ 765 1.1 mrg if (!TARGET_HAS_CDX) 766 1.1 mrg { 767 1.1 mrg save_offset = save_regs_base + cfun->machine->save_reg_size; 768 1.1 mrg 769 1.1 mrg for (regno = LAST_GP_REG; regno > 0; regno--) 770 1.1 mrg if (cfun->machine->save_mask & (1 << regno)) 771 1.1 mrg { 772 1.1 mrg save_offset -= 4; 773 1.1 mrg save_reg (regno, save_offset); 774 1.1 mrg } 775 1.1 mrg } 776 1.1 mrg 777 1.1 mrg /* Set the hard frame pointer. */ 778 1.1 mrg if (frame_pointer_needed) 779 1.1 mrg { 780 1.1 mrg int fp_save_offset = save_regs_base + cfun->machine->fp_save_offset; 781 1.1 mrg insn = 782 1.1 mrg (fp_save_offset == 0 783 1.1 mrg ? emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx) 784 1.1 mrg : emit_insn (gen_add3_insn (hard_frame_pointer_rtx, 785 1.1 mrg stack_pointer_rtx, 786 1.1 mrg gen_int_mode (fp_save_offset, Pmode)))); 787 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 788 1.1 mrg } 789 1.1 mrg 790 1.1 mrg /* Allocate sp_offset more bytes in the stack frame. */ 791 1.1 mrg nios2_adjust_stack (sp_offset, false); 792 1.1 mrg 793 1.1 mrg /* Load the PIC register if needed. */ 794 1.1 mrg if (crtl->uses_pic_offset_table) 795 1.1 mrg nios2_load_pic_register (); 796 1.1 mrg 797 1.1 mrg /* If we are profiling, make sure no instructions are scheduled before 798 1.1 mrg the call to mcount. */ 799 1.1 mrg if (crtl->profile) 800 1.1 mrg emit_insn (gen_blockage ()); 801 1.1 mrg } 802 1.1 mrg 803 1.1 mrg void 804 1.1 mrg nios2_expand_epilogue (bool sibcall_p) 805 1.1 mrg { 806 1.1 mrg rtx_insn *insn; 807 1.1 mrg rtx cfa_adj; 808 1.1 mrg int total_frame_size; 809 1.1 mrg int sp_adjust, save_offset; 810 1.1 mrg unsigned int regno; 811 1.1 mrg 812 1.1 mrg if (!sibcall_p && nios2_can_use_return_insn ()) 813 1.1 mrg { 814 1.1 mrg emit_jump_insn (gen_return ()); 815 1.1 mrg return; 816 1.1 mrg } 817 1.1 mrg 818 1.1 mrg emit_insn (gen_blockage ()); 819 1.1 mrg 820 1.1 mrg total_frame_size = nios2_compute_frame_layout (); 821 1.1 mrg if (frame_pointer_needed) 822 1.1 mrg { 823 1.1 mrg /* Recover the stack pointer. */ 824 1.1 mrg insn = 825 1.1 mrg (cfun->machine->fp_save_offset == 0 826 1.1 mrg ? emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx) 827 1.1 mrg : emit_insn (gen_add3_insn 828 1.1 mrg (stack_pointer_rtx, hard_frame_pointer_rtx, 829 1.1 mrg gen_int_mode (-cfun->machine->fp_save_offset, Pmode)))); 830 1.1 mrg cfa_adj = plus_constant (Pmode, stack_pointer_rtx, 831 1.1 mrg (total_frame_size 832 1.1 mrg - cfun->machine->save_regs_offset)); 833 1.1 mrg add_reg_note (insn, REG_CFA_DEF_CFA, cfa_adj); 834 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 835 1.1 mrg 836 1.1 mrg save_offset = 0; 837 1.1 mrg sp_adjust = total_frame_size - cfun->machine->save_regs_offset; 838 1.1 mrg } 839 1.1 mrg else if (!SMALL_INT (total_frame_size)) 840 1.1 mrg { 841 1.1 mrg nios2_adjust_stack (cfun->machine->save_regs_offset, true); 842 1.1 mrg save_offset = 0; 843 1.1 mrg sp_adjust = total_frame_size - cfun->machine->save_regs_offset; 844 1.1 mrg } 845 1.1 mrg else 846 1.1 mrg { 847 1.1 mrg save_offset = cfun->machine->save_regs_offset; 848 1.1 mrg sp_adjust = total_frame_size; 849 1.1 mrg } 850 1.1 mrg 851 1.1 mrg if (!TARGET_HAS_CDX) 852 1.1 mrg { 853 1.1 mrg /* Generate individual register restores. */ 854 1.1 mrg save_offset += cfun->machine->save_reg_size; 855 1.1 mrg 856 1.1 mrg for (regno = LAST_GP_REG; regno > 0; regno--) 857 1.1 mrg if (cfun->machine->save_mask & (1 << regno)) 858 1.1 mrg { 859 1.1 mrg save_offset -= 4; 860 1.1 mrg restore_reg (regno, save_offset); 861 1.1 mrg } 862 1.1 mrg nios2_adjust_stack (sp_adjust, true); 863 1.1 mrg } 864 1.1 mrg else if (cfun->machine->save_reg_size == 0) 865 1.1 mrg { 866 1.1 mrg /* Nothing to restore, just recover the stack position. */ 867 1.1 mrg nios2_adjust_stack (sp_adjust, true); 868 1.1 mrg } 869 1.1 mrg else 870 1.1 mrg { 871 1.1 mrg /* Emit CDX pop.n/ldwm to restore registers and optionally return. */ 872 1.1 mrg unsigned int regmask = cfun->machine->save_mask; 873 1.1 mrg unsigned int callee_save_regs = regmask & 0xffff0000; 874 1.1 mrg unsigned int caller_save_regs = regmask & 0x0000ffff; 875 1.1 mrg int callee_save_size = cfun->machine->callee_save_reg_size; 876 1.1 mrg int caller_save_size = cfun->machine->save_reg_size - callee_save_size; 877 1.1 mrg int pretend_args_size = NIOS2_STACK_ALIGN (crtl->args.pretend_args_size); 878 1.1 mrg bool ret_p = (!pretend_args_size && !crtl->calls_eh_return 879 1.1 mrg && !sibcall_p); 880 1.1 mrg 881 1.1 mrg if (!ret_p || caller_save_size > 0) 882 1.1 mrg sp_adjust = save_offset; 883 1.1 mrg else 884 1.1 mrg sp_adjust = (save_offset > 60 ? save_offset - 60 : 0); 885 1.1 mrg 886 1.1 mrg save_offset -= sp_adjust; 887 1.1 mrg 888 1.1 mrg nios2_adjust_stack (sp_adjust, true); 889 1.1 mrg 890 1.1 mrg if (caller_save_regs) 891 1.1 mrg { 892 1.1 mrg /* Emit a ldwm to restore EH data regs. */ 893 1.1 mrg rtx stack_mem = gen_frame_mem (SImode, stack_pointer_rtx); 894 1.1 mrg insn = emit_insn (nios2_ldst_parallel 895 1.1 mrg (true, true, true, stack_mem, 896 1.1 mrg caller_save_size, caller_save_regs, false)); 897 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 898 1.1 mrg nios2_create_cfa_notes (insn, true); 899 1.1 mrg } 900 1.1 mrg 901 1.1 mrg if (callee_save_regs) 902 1.1 mrg { 903 1.1 mrg int sp_adjust = save_offset + callee_save_size; 904 1.1 mrg rtx stack_mem; 905 1.1 mrg if (ret_p) 906 1.1 mrg { 907 1.1 mrg /* Emit a pop.n to restore regs and return. */ 908 1.1 mrg stack_mem = 909 1.1 mrg gen_frame_mem (SImode, 910 1.1 mrg gen_rtx_PLUS (Pmode, stack_pointer_rtx, 911 1.1 mrg gen_int_mode (sp_adjust - 4, 912 1.1 mrg Pmode))); 913 1.1 mrg insn = 914 1.1 mrg emit_jump_insn (nios2_ldst_parallel (true, false, false, 915 1.1 mrg stack_mem, sp_adjust, 916 1.1 mrg callee_save_regs, ret_p)); 917 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 918 1.1 mrg /* No need to attach CFA notes since we cannot step over 919 1.1 mrg a return. */ 920 1.1 mrg return; 921 1.1 mrg } 922 1.1 mrg else 923 1.1 mrg { 924 1.1 mrg /* If no return, we have to use the ldwm form. */ 925 1.1 mrg stack_mem = gen_frame_mem (SImode, stack_pointer_rtx); 926 1.1 mrg insn = 927 1.1 mrg emit_insn (nios2_ldst_parallel (true, true, true, 928 1.1 mrg stack_mem, sp_adjust, 929 1.1 mrg callee_save_regs, ret_p)); 930 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 931 1.1 mrg nios2_create_cfa_notes (insn, true); 932 1.1 mrg } 933 1.1 mrg } 934 1.1 mrg 935 1.1 mrg if (pretend_args_size) 936 1.1 mrg nios2_adjust_stack (pretend_args_size, true); 937 1.1 mrg } 938 1.1 mrg 939 1.1 mrg /* Add in the __builtin_eh_return stack adjustment. */ 940 1.1 mrg if (crtl->calls_eh_return) 941 1.1 mrg emit_insn (gen_add2_insn (stack_pointer_rtx, EH_RETURN_STACKADJ_RTX)); 942 1.1 mrg 943 1.1 mrg if (!sibcall_p) 944 1.1 mrg emit_jump_insn (gen_simple_return ()); 945 1.1 mrg } 946 1.1 mrg 947 1.1 mrg bool 948 1.1 mrg nios2_expand_return (void) 949 1.1 mrg { 950 1.1 mrg /* If CDX is available, generate a pop.n instruction to do both 951 1.1 mrg the stack pop and return. */ 952 1.1 mrg if (TARGET_HAS_CDX) 953 1.1 mrg { 954 1.1 mrg int total_frame_size = nios2_compute_frame_layout (); 955 1.1 mrg int sp_adjust = (cfun->machine->save_regs_offset 956 1.1 mrg + cfun->machine->callee_save_reg_size); 957 1.1 mrg gcc_assert (sp_adjust == total_frame_size); 958 1.1 mrg if (sp_adjust != 0) 959 1.1 mrg { 960 1.1 mrg rtx mem = 961 1.1 mrg gen_frame_mem (SImode, 962 1.1 mrg plus_constant (Pmode, stack_pointer_rtx, 963 1.1 mrg sp_adjust - 4, false)); 964 1.1 mrg rtx_insn *insn = 965 1.1 mrg emit_jump_insn (nios2_ldst_parallel (true, false, false, 966 1.1 mrg mem, sp_adjust, 967 1.1 mrg cfun->machine->save_mask, 968 1.1 mrg true)); 969 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 970 1.1 mrg /* No need to create CFA notes since we can't step over 971 1.1 mrg a return. */ 972 1.1 mrg return true; 973 1.1 mrg } 974 1.1 mrg } 975 1.1 mrg return false; 976 1.1 mrg } 977 1.1 mrg 978 1.1 mrg /* Implement RETURN_ADDR_RTX. Note, we do not support moving 979 1.1 mrg back to a previous frame. */ 980 1.1 mrg rtx 981 1.1 mrg nios2_get_return_address (int count) 982 1.1 mrg { 983 1.1 mrg if (count != 0) 984 1.1 mrg return const0_rtx; 985 1.1 mrg 986 1.1 mrg return get_hard_reg_initial_val (Pmode, RA_REGNO); 987 1.1 mrg } 988 1.1 mrg 989 1.1 mrg /* Emit code to change the current function's return address to 990 1.1 mrg ADDRESS. SCRATCH is available as a scratch register, if needed. 991 1.1 mrg ADDRESS and SCRATCH are both word-mode GPRs. */ 992 1.1 mrg void 993 1.1 mrg nios2_set_return_address (rtx address, rtx scratch) 994 1.1 mrg { 995 1.1 mrg nios2_compute_frame_layout (); 996 1.1 mrg if (cfun->machine->save_mask & (1 << RA_REGNO)) 997 1.1 mrg { 998 1.1 mrg unsigned offset = cfun->machine->save_reg_size - 4; 999 1.1 mrg rtx base; 1000 1.1 mrg 1001 1.1 mrg if (frame_pointer_needed) 1002 1.1 mrg base = hard_frame_pointer_rtx; 1003 1.1 mrg else 1004 1.1 mrg { 1005 1.1 mrg base = stack_pointer_rtx; 1006 1.1 mrg offset += cfun->machine->save_regs_offset; 1007 1.1 mrg 1008 1.1 mrg if (!SMALL_INT (offset)) 1009 1.1 mrg { 1010 1.1 mrg emit_move_insn (scratch, gen_int_mode (offset, Pmode)); 1011 1.1 mrg emit_insn (gen_add2_insn (scratch, base)); 1012 1.1 mrg base = scratch; 1013 1.1 mrg offset = 0; 1014 1.1 mrg } 1015 1.1 mrg } 1016 1.1 mrg if (offset) 1017 1.1 mrg base = plus_constant (Pmode, base, offset); 1018 1.1 mrg emit_move_insn (gen_rtx_MEM (Pmode, base), address); 1019 1.1 mrg } 1020 1.1 mrg else 1021 1.1 mrg emit_move_insn (gen_rtx_REG (Pmode, RA_REGNO), address); 1022 1.1 mrg } 1023 1.1 mrg 1024 1.1 mrg /* Implement FUNCTION_PROFILER macro. */ 1025 1.1 mrg void 1026 1.1 mrg nios2_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED) 1027 1.1 mrg { 1028 1.1 mrg fprintf (file, "\tmov\tr8, ra\n"); 1029 1.1 mrg if (flag_pic == 1) 1030 1.1 mrg { 1031 1.1 mrg fprintf (file, "\tnextpc\tr2\n"); 1032 1.1 mrg fprintf (file, "\t1: movhi\tr3, %%hiadj(_gp_got - 1b)\n"); 1033 1.1 mrg fprintf (file, "\taddi\tr3, r3, %%lo(_gp_got - 1b)\n"); 1034 1.1 mrg fprintf (file, "\tadd\tr2, r2, r3\n"); 1035 1.1 mrg fprintf (file, "\tldw\tr2, %%call(_mcount)(r2)\n"); 1036 1.1 mrg fprintf (file, "\tcallr\tr2\n"); 1037 1.1 mrg } 1038 1.1 mrg else if (flag_pic == 2) 1039 1.1 mrg { 1040 1.1 mrg fprintf (file, "\tnextpc\tr2\n"); 1041 1.1 mrg fprintf (file, "\t1: movhi\tr3, %%hiadj(_gp_got - 1b)\n"); 1042 1.1 mrg fprintf (file, "\taddi\tr3, r3, %%lo(_gp_got - 1b)\n"); 1043 1.1 mrg fprintf (file, "\tadd\tr2, r2, r3\n"); 1044 1.1 mrg fprintf (file, "\tmovhi\tr3, %%call_hiadj(_mcount)\n"); 1045 1.1 mrg fprintf (file, "\taddi\tr3, r3, %%call_lo(_mcount)\n"); 1046 1.1 mrg fprintf (file, "\tadd\tr3, r2, r3\n"); 1047 1.1 mrg fprintf (file, "\tldw\tr2, 0(r3)\n"); 1048 1.1 mrg fprintf (file, "\tcallr\tr2\n"); 1049 1.1 mrg } 1050 1.1 mrg else 1051 1.1 mrg fprintf (file, "\tcall\t_mcount\n"); 1052 1.1 mrg fprintf (file, "\tmov\tra, r8\n"); 1053 1.1 mrg } 1054 1.1 mrg 1055 1.1 mrg /* Dump stack layout. */ 1056 1.1 mrg static void 1057 1.1 mrg nios2_dump_frame_layout (FILE *file) 1058 1.1 mrg { 1059 1.1 mrg fprintf (file, "\t%s Current Frame Info\n", ASM_COMMENT_START); 1060 1.1 mrg fprintf (file, "\t%s total_size = %d\n", ASM_COMMENT_START, 1061 1.1 mrg cfun->machine->total_size); 1062 1.1 mrg fprintf (file, "\t%s var_size = %d\n", ASM_COMMENT_START, 1063 1.1 mrg cfun->machine->var_size); 1064 1.1 mrg fprintf (file, "\t%s args_size = %d\n", ASM_COMMENT_START, 1065 1.1 mrg cfun->machine->args_size); 1066 1.1 mrg fprintf (file, "\t%s save_reg_size = %d\n", ASM_COMMENT_START, 1067 1.1 mrg cfun->machine->save_reg_size); 1068 1.1 mrg fprintf (file, "\t%s initialized = %d\n", ASM_COMMENT_START, 1069 1.1 mrg cfun->machine->initialized); 1070 1.1 mrg fprintf (file, "\t%s save_regs_offset = %d\n", ASM_COMMENT_START, 1071 1.1 mrg cfun->machine->save_regs_offset); 1072 1.1 mrg fprintf (file, "\t%s is_leaf = %d\n", ASM_COMMENT_START, 1073 1.1 mrg crtl->is_leaf); 1074 1.1 mrg fprintf (file, "\t%s frame_pointer_needed = %d\n", ASM_COMMENT_START, 1075 1.1 mrg frame_pointer_needed); 1076 1.1 mrg fprintf (file, "\t%s pretend_args_size = %d\n", ASM_COMMENT_START, 1077 1.1 mrg crtl->args.pretend_args_size); 1078 1.1 mrg } 1079 1.1 mrg 1080 1.1 mrg /* Return true if REGNO should be saved in the prologue. */ 1081 1.1 mrg static bool 1082 1.1 mrg prologue_saved_reg_p (unsigned regno) 1083 1.1 mrg { 1084 1.1 mrg gcc_assert (GP_REG_P (regno)); 1085 1.1 mrg 1086 1.1 mrg if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno)) 1087 1.1 mrg return true; 1088 1.1 mrg 1089 1.1 mrg if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) 1090 1.1 mrg return true; 1091 1.1 mrg 1092 1.1 mrg if (regno == PIC_OFFSET_TABLE_REGNUM && crtl->uses_pic_offset_table) 1093 1.1 mrg return true; 1094 1.1 mrg 1095 1.1 mrg if (regno == RA_REGNO && df_regs_ever_live_p (RA_REGNO)) 1096 1.1 mrg return true; 1097 1.1 mrg 1098 1.1 mrg return false; 1099 1.1 mrg } 1100 1.1 mrg 1101 1.1 mrg /* Implement TARGET_CAN_ELIMINATE. */ 1102 1.1 mrg static bool 1103 1.1 mrg nios2_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) 1104 1.1 mrg { 1105 1.1 mrg if (to == STACK_POINTER_REGNUM) 1106 1.1 mrg return !frame_pointer_needed; 1107 1.1 mrg return true; 1108 1.1 mrg } 1109 1.1 mrg 1110 1.1 mrg /* Implement INITIAL_ELIMINATION_OFFSET macro. */ 1111 1.1 mrg int 1112 1.1 mrg nios2_initial_elimination_offset (int from, int to) 1113 1.1 mrg { 1114 1.1 mrg int offset; 1115 1.1 mrg 1116 1.1 mrg nios2_compute_frame_layout (); 1117 1.1 mrg 1118 1.1 mrg /* Set OFFSET to the offset from the stack pointer. */ 1119 1.1 mrg switch (from) 1120 1.1 mrg { 1121 1.1 mrg case FRAME_POINTER_REGNUM: 1122 1.1 mrg /* This is the high end of the local variable storage, not the 1123 1.1 mrg hard frame pointer. */ 1124 1.1 mrg offset = cfun->machine->args_size + cfun->machine->var_size; 1125 1.1 mrg break; 1126 1.1 mrg 1127 1.1 mrg case ARG_POINTER_REGNUM: 1128 1.1 mrg offset = cfun->machine->total_size; 1129 1.1 mrg offset -= crtl->args.pretend_args_size; 1130 1.1 mrg break; 1131 1.1 mrg 1132 1.1 mrg default: 1133 1.1 mrg gcc_unreachable (); 1134 1.1 mrg } 1135 1.1 mrg 1136 1.1 mrg /* If we are asked for the frame pointer offset, then adjust OFFSET 1137 1.1 mrg by the offset from the frame pointer to the stack pointer. */ 1138 1.1 mrg if (to == HARD_FRAME_POINTER_REGNUM) 1139 1.1 mrg offset -= (cfun->machine->save_regs_offset 1140 1.1 mrg + cfun->machine->fp_save_offset); 1141 1.1 mrg 1142 1.1 mrg return offset; 1143 1.1 mrg } 1144 1.1 mrg 1145 1.1 mrg /* Return nonzero if this function is known to have a null epilogue. 1146 1.1 mrg This allows the optimizer to omit jumps to jumps if no stack 1147 1.1 mrg was created. */ 1148 1.1 mrg int 1149 1.1 mrg nios2_can_use_return_insn (void) 1150 1.1 mrg { 1151 1.1 mrg int total_frame_size; 1152 1.1 mrg 1153 1.1 mrg if (!reload_completed || crtl->profile) 1154 1.1 mrg return 0; 1155 1.1 mrg 1156 1.1 mrg total_frame_size = nios2_compute_frame_layout (); 1157 1.1 mrg 1158 1.1 mrg /* If CDX is available, check if we can return using a 1159 1.1 mrg single pop.n instruction. */ 1160 1.1 mrg if (TARGET_HAS_CDX 1161 1.1 mrg && !frame_pointer_needed 1162 1.1 mrg && cfun->machine->save_regs_offset <= 60 1163 1.1 mrg && (cfun->machine->save_mask & 0x80000000) != 0 1164 1.1 mrg && (cfun->machine->save_mask & 0xffff) == 0 1165 1.1 mrg && crtl->args.pretend_args_size == 0) 1166 1.1 mrg return true; 1167 1.1 mrg 1168 1.1 mrg return total_frame_size == 0; 1169 1.1 mrg } 1170 1.1 mrg 1171 1.1 mrg 1172 1.1 mrg /* Check and signal some warnings/errors on FPU insn options. */ 1174 1.1 mrg static void 1175 1.1 mrg nios2_custom_check_insns (void) 1176 1.1 mrg { 1177 1.1 mrg unsigned int i, j; 1178 1.1 mrg bool errors = false; 1179 1.1 mrg 1180 1.1 mrg for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++) 1181 1.1 mrg if (N2FPU_ENABLED_P (i) && N2FPU_DOUBLE_P (i)) 1182 1.1 mrg { 1183 1.1 mrg for (j = 0; j < ARRAY_SIZE (nios2_fpu_insn); j++) 1184 1.1 mrg if (N2FPU_DOUBLE_REQUIRED_P (j) && ! N2FPU_ENABLED_P (j)) 1185 1.1 mrg { 1186 1.1 mrg error ("switch %<-mcustom-%s%> is required for " 1187 1.1 mrg "double-precision floating-point", N2FPU_NAME (j)); 1188 1.1 mrg errors = true; 1189 1.1 mrg } 1190 1.1 mrg break; 1191 1.1 mrg } 1192 1.1 mrg 1193 1.1 mrg if (errors || custom_code_conflict) 1194 1.1 mrg fatal_error (input_location, 1195 1.1 mrg "conflicting use of %<-mcustom%> switches, " 1196 1.1 mrg "target attributes, " 1197 1.1 mrg "and/or %<__builtin_custom_%> functions"); 1198 1.1 mrg } 1199 1.1 mrg 1200 1.1 mrg static void 1201 1.1 mrg nios2_set_fpu_custom_code (enum n2fpu_code code, int n, bool override_p) 1202 1.1 mrg { 1203 1.1 mrg if (override_p || N2FPU_N (code) == -1) 1204 1.1 mrg N2FPU_N (code) = n; 1205 1.1 mrg nios2_register_custom_code (n, CCS_FPU, (int) code); 1206 1.1 mrg } 1207 1.1 mrg 1208 1.1 mrg /* Type to represent a standard FPU config. */ 1209 1.1 mrg struct nios2_fpu_config 1210 1.1 mrg { 1211 1.1 mrg const char *name; 1212 1.1 mrg bool set_sp_constants; 1213 1.1 mrg int code[n2fpu_code_num]; 1214 1.1 mrg }; 1215 1.1 mrg 1216 1.1 mrg #define NIOS2_FPU_CONFIG_NUM 4 1217 1.1 mrg static struct nios2_fpu_config custom_fpu_config[NIOS2_FPU_CONFIG_NUM]; 1218 1.1 mrg 1219 1.1 mrg static void 1220 1.1 mrg nios2_init_fpu_configs (void) 1221 1.1 mrg { 1222 1.1 mrg struct nios2_fpu_config* cfg; 1223 1.1 mrg int i = 0; 1224 1.1 mrg #define NEXT_FPU_CONFIG \ 1225 1.1 mrg do { \ 1226 1.1 mrg cfg = &custom_fpu_config[i++]; \ 1227 1.1 mrg memset (cfg, -1, sizeof (struct nios2_fpu_config));\ 1228 1.1 mrg } while (0) 1229 1.1 mrg 1230 1.1 mrg NEXT_FPU_CONFIG; 1231 1.1 mrg cfg->name = "60-1"; 1232 1.1 mrg cfg->set_sp_constants = true; 1233 1.1 mrg cfg->code[n2fpu_fmuls] = 252; 1234 1.1 mrg cfg->code[n2fpu_fadds] = 253; 1235 1.1 mrg cfg->code[n2fpu_fsubs] = 254; 1236 1.1 mrg 1237 1.1 mrg NEXT_FPU_CONFIG; 1238 1.1 mrg cfg->name = "60-2"; 1239 1.1 mrg cfg->set_sp_constants = true; 1240 1.1 mrg cfg->code[n2fpu_fmuls] = 252; 1241 1.1 mrg cfg->code[n2fpu_fadds] = 253; 1242 1.1 mrg cfg->code[n2fpu_fsubs] = 254; 1243 1.1 mrg cfg->code[n2fpu_fdivs] = 255; 1244 1.1 mrg 1245 1.1 mrg NEXT_FPU_CONFIG; 1246 1.1 mrg cfg->name = "72-3"; 1247 1.1 mrg cfg->set_sp_constants = true; 1248 1.1 mrg cfg->code[n2fpu_floatus] = 243; 1249 1.1 mrg cfg->code[n2fpu_fixsi] = 244; 1250 1.1 mrg cfg->code[n2fpu_floatis] = 245; 1251 1.1 mrg cfg->code[n2fpu_fcmpgts] = 246; 1252 1.1 mrg cfg->code[n2fpu_fcmples] = 249; 1253 1.1 mrg cfg->code[n2fpu_fcmpeqs] = 250; 1254 1.1 mrg cfg->code[n2fpu_fcmpnes] = 251; 1255 1.1 mrg cfg->code[n2fpu_fmuls] = 252; 1256 1.1 mrg cfg->code[n2fpu_fadds] = 253; 1257 1.1 mrg cfg->code[n2fpu_fsubs] = 254; 1258 1.1 mrg cfg->code[n2fpu_fdivs] = 255; 1259 1.1 mrg 1260 1.1 mrg NEXT_FPU_CONFIG; 1261 1.1 mrg cfg->name = "fph2"; 1262 1.1 mrg cfg->code[n2fpu_fabss] = 224; 1263 1.1 mrg cfg->code[n2fpu_fnegs] = 225; 1264 1.1 mrg cfg->code[n2fpu_fcmpnes] = 226; 1265 1.1 mrg cfg->code[n2fpu_fcmpeqs] = 227; 1266 1.1 mrg cfg->code[n2fpu_fcmpges] = 228; 1267 1.1 mrg cfg->code[n2fpu_fcmpgts] = 229; 1268 1.1 mrg cfg->code[n2fpu_fcmples] = 230; 1269 1.1 mrg cfg->code[n2fpu_fcmplts] = 231; 1270 1.1 mrg cfg->code[n2fpu_fmaxs] = 232; 1271 1.1 mrg cfg->code[n2fpu_fmins] = 233; 1272 1.1 mrg cfg->code[n2fpu_round] = 248; 1273 1.1 mrg cfg->code[n2fpu_fixsi] = 249; 1274 1.1 mrg cfg->code[n2fpu_floatis] = 250; 1275 1.1 mrg cfg->code[n2fpu_fsqrts] = 251; 1276 1.1 mrg cfg->code[n2fpu_fmuls] = 252; 1277 1.1 mrg cfg->code[n2fpu_fadds] = 253; 1278 1.1 mrg cfg->code[n2fpu_fsubs] = 254; 1279 1.1 mrg cfg->code[n2fpu_fdivs] = 255; 1280 1.1 mrg 1281 1.1 mrg #undef NEXT_FPU_CONFIG 1282 1.1 mrg gcc_assert (i == NIOS2_FPU_CONFIG_NUM); 1283 1.1 mrg } 1284 1.1 mrg 1285 1.1 mrg static struct nios2_fpu_config * 1286 1.1 mrg nios2_match_custom_fpu_cfg (const char *cfgname, const char *endp) 1287 1.1 mrg { 1288 1.1 mrg int i; 1289 1.1 mrg for (i = 0; i < NIOS2_FPU_CONFIG_NUM; i++) 1290 1.1 mrg { 1291 1.1 mrg bool match = !(endp != NULL 1292 1.1 mrg ? strncmp (custom_fpu_config[i].name, cfgname, 1293 1.1 mrg endp - cfgname) 1294 1.1 mrg : strcmp (custom_fpu_config[i].name, cfgname)); 1295 1.1 mrg if (match) 1296 1.1 mrg return &custom_fpu_config[i]; 1297 1.1 mrg } 1298 1.1 mrg return NULL; 1299 1.1 mrg } 1300 1.1 mrg 1301 1.1 mrg /* Use CFGNAME to lookup FPU config, ENDP if not NULL marks end of string. 1302 1.1 mrg OVERRIDE is true if loaded config codes should overwrite current state. */ 1303 1.1 mrg static void 1304 1.1 mrg nios2_handle_custom_fpu_cfg (const char *cfgname, const char *endp, 1305 1.1 mrg bool override) 1306 1.1 mrg { 1307 1.1 mrg struct nios2_fpu_config *cfg = nios2_match_custom_fpu_cfg (cfgname, endp); 1308 1.1 mrg if (cfg) 1309 1.1 mrg { 1310 1.1 mrg unsigned int i; 1311 1.1 mrg for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++) 1312 1.1 mrg if (cfg->code[i] >= 0) 1313 1.1 mrg nios2_set_fpu_custom_code ((enum n2fpu_code) i, cfg->code[i], 1314 1.1 mrg override); 1315 1.1 mrg if (cfg->set_sp_constants) 1316 1.1 mrg flag_single_precision_constant = 1; 1317 1.1 mrg } 1318 1.1 mrg else 1319 1.1 mrg warning (0, "ignoring unrecognized switch %<-mcustom-fpu-cfg%> " 1320 1.1 mrg "value %<%s%>", cfgname); 1321 1.1 mrg 1322 1.1 mrg /* Guard against errors in the standard configurations. */ 1323 1.1 mrg nios2_custom_check_insns (); 1324 1.1 mrg } 1325 1.1 mrg 1326 1.1 mrg /* Check individual FPU insn options, and register custom code. */ 1327 1.1 mrg static void 1328 1.1 mrg nios2_handle_custom_fpu_insn_option (int fpu_insn_index) 1329 1.1 mrg { 1330 1.1 mrg int param = N2FPU_N (fpu_insn_index); 1331 1.1 mrg 1332 1.1 mrg if (param >= 0 && param <= 255) 1333 1.1 mrg nios2_register_custom_code (param, CCS_FPU, fpu_insn_index); 1334 1.1 mrg 1335 1.1 mrg /* Valid values are 0-255, but also allow -1 so that the 1336 1.1 mrg -mno-custom-<opt> switches work. */ 1337 1.1 mrg else if (param != -1) 1338 1.1 mrg error ("switch %<-mcustom-%s%> value %d must be between 0 and 255", 1339 1.1 mrg N2FPU_NAME (fpu_insn_index), param); 1340 1.1 mrg } 1341 1.1 mrg 1342 1.1 mrg /* Allocate a chunk of memory for per-function machine-dependent data. */ 1343 1.1 mrg static struct machine_function * 1344 1.1 mrg nios2_init_machine_status (void) 1345 1.1 mrg { 1346 1.1 mrg return ggc_cleared_alloc<machine_function> (); 1347 1.1 mrg } 1348 1.1 mrg 1349 1.1 mrg /* Implement TARGET_OPTION_OVERRIDE. */ 1350 1.1 mrg static void 1351 1.1 mrg nios2_option_override (void) 1352 1.1 mrg { 1353 1.1 mrg unsigned int i; 1354 1.1 mrg 1355 1.1 mrg #ifdef SUBTARGET_OVERRIDE_OPTIONS 1356 1.1 mrg SUBTARGET_OVERRIDE_OPTIONS; 1357 1.1 mrg #endif 1358 1.1 mrg 1359 1.1 mrg /* Check for unsupported options. */ 1360 1.1 mrg if (flag_pic && !TARGET_LINUX_ABI) 1361 1.1 mrg sorry ("position-independent code requires the Linux ABI"); 1362 1.1 mrg if (flag_pic && stack_limit_rtx 1363 1.1 mrg && GET_CODE (stack_limit_rtx) == SYMBOL_REF) 1364 1.1 mrg sorry ("PIC support for %<-fstack-limit-symbol%>"); 1365 1.1 mrg 1366 1.1 mrg /* Function to allocate machine-dependent function status. */ 1367 1.1 mrg init_machine_status = &nios2_init_machine_status; 1368 1.1 mrg 1369 1.1 mrg nios2_section_threshold 1370 1.1 mrg = (OPTION_SET_P (g_switch_value) 1371 1.1 mrg ? g_switch_value : NIOS2_DEFAULT_GVALUE); 1372 1.1 mrg 1373 1.1 mrg if (nios2_gpopt_option == gpopt_unspecified) 1374 1.1 mrg { 1375 1.1 mrg /* Default to -mgpopt unless -fpic or -fPIC. */ 1376 1.1 mrg if (flag_pic) 1377 1.1 mrg nios2_gpopt_option = gpopt_none; 1378 1.1 mrg else 1379 1.1 mrg nios2_gpopt_option = gpopt_local; 1380 1.1 mrg } 1381 1.1 mrg 1382 1.1 mrg /* GP-relative and r0-relative addressing don't make sense for PIC. */ 1383 1.1 mrg if (flag_pic) 1384 1.1 mrg { 1385 1.1 mrg if (nios2_gpopt_option != gpopt_none) 1386 1.1 mrg error ("%<-mgpopt%> not supported with PIC"); 1387 1.1 mrg if (nios2_gprel_sec) 1388 1.1 mrg error ("%<-mgprel-sec=%> not supported with PIC"); 1389 1.1 mrg if (nios2_r0rel_sec) 1390 1.1 mrg error ("%<-mr0rel-sec=%> not supported with PIC"); 1391 1.1 mrg } 1392 1.1 mrg 1393 1.1 mrg /* Process -mgprel-sec= and -m0rel-sec=. */ 1394 1.1 mrg if (nios2_gprel_sec) 1395 1.1 mrg { 1396 1.1 mrg if (regcomp (&nios2_gprel_sec_regex, nios2_gprel_sec, 1397 1.1 mrg REG_EXTENDED | REG_NOSUB)) 1398 1.1 mrg error ("%<-mgprel-sec=%> argument is not a valid regular expression"); 1399 1.1 mrg } 1400 1.1 mrg if (nios2_r0rel_sec) 1401 1.1 mrg { 1402 1.1 mrg if (regcomp (&nios2_r0rel_sec_regex, nios2_r0rel_sec, 1403 1.1 mrg REG_EXTENDED | REG_NOSUB)) 1404 1.1 mrg error ("%<-mr0rel-sec=%> argument is not a valid regular expression"); 1405 1.1 mrg } 1406 1.1 mrg 1407 1.1 mrg /* If we don't have mul, we don't have mulx either! */ 1408 1.1 mrg if (!TARGET_HAS_MUL && TARGET_HAS_MULX) 1409 1.1 mrg target_flags &= ~MASK_HAS_MULX; 1410 1.1 mrg 1411 1.1 mrg /* Optional BMX and CDX instructions only make sense for R2. */ 1412 1.1 mrg if (!TARGET_ARCH_R2) 1413 1.1 mrg { 1414 1.1 mrg if (TARGET_HAS_BMX) 1415 1.1 mrg error ("BMX instructions are only supported with R2 architecture"); 1416 1.1 mrg if (TARGET_HAS_CDX) 1417 1.1 mrg error ("CDX instructions are only supported with R2 architecture"); 1418 1.1 mrg } 1419 1.1 mrg 1420 1.1 mrg /* R2 is little-endian only. */ 1421 1.1 mrg if (TARGET_ARCH_R2 && TARGET_BIG_ENDIAN) 1422 1.1 mrg error ("R2 architecture is little-endian only"); 1423 1.1 mrg 1424 1.1 mrg /* Initialize default FPU configurations. */ 1425 1.1 mrg nios2_init_fpu_configs (); 1426 1.1 mrg 1427 1.1 mrg /* Set up default handling for floating point custom instructions. 1428 1.1 mrg 1429 1.1 mrg Putting things in this order means that the -mcustom-fpu-cfg= 1430 1.1 mrg switch will always be overridden by individual -mcustom-fadds= 1431 1.1 mrg switches, regardless of the order in which they were specified 1432 1.1 mrg on the command line. 1433 1.1 mrg 1434 1.1 mrg This behavior of prioritization of individual -mcustom-<insn>= 1435 1.1 mrg options before the -mcustom-fpu-cfg= switch is maintained for 1436 1.1 mrg compatibility. */ 1437 1.1 mrg if (nios2_custom_fpu_cfg_string && *nios2_custom_fpu_cfg_string) 1438 1.1 mrg nios2_handle_custom_fpu_cfg (nios2_custom_fpu_cfg_string, NULL, false); 1439 1.1 mrg 1440 1.1 mrg /* Handle options for individual FPU insns. */ 1441 1.1 mrg for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++) 1442 1.1 mrg nios2_handle_custom_fpu_insn_option (i); 1443 1.1 mrg 1444 1.1 mrg nios2_custom_check_insns (); 1445 1.1 mrg 1446 1.1 mrg /* Save the initial options in case the user does function specific 1447 1.1 mrg options. */ 1448 1.1 mrg target_option_default_node = target_option_current_node 1449 1.1 mrg = build_target_option_node (&global_options, &global_options_set); 1450 1.1 mrg } 1451 1.1 mrg 1452 1.1 mrg 1453 1.1 mrg /* Return true if CST is a constant within range of movi/movui/movhi. */ 1455 1.1 mrg static bool 1456 1.1 mrg nios2_simple_const_p (const_rtx cst) 1457 1.1 mrg { 1458 1.1 mrg if (!CONST_INT_P (cst)) 1459 1.1 mrg return false; 1460 1.1 mrg HOST_WIDE_INT val = INTVAL (cst); 1461 1.1 mrg return SMALL_INT (val) || SMALL_INT_UNSIGNED (val) || UPPER16_INT (val); 1462 1.1 mrg } 1463 1.1 mrg 1464 1.1 mrg /* Compute a (partial) cost for rtx X. Return true if the complete 1465 1.1 mrg cost has been computed, and false if subexpressions should be 1466 1.1 mrg scanned. In either case, *TOTAL contains the cost result. */ 1467 1.1 mrg static bool 1468 1.1 mrg nios2_rtx_costs (rtx x, machine_mode mode, 1469 1.1 mrg int outer_code, 1470 1.1 mrg int opno, 1471 1.1 mrg int *total, bool speed) 1472 1.1 mrg { 1473 1.1 mrg int code = GET_CODE (x); 1474 1.1 mrg 1475 1.1 mrg switch (code) 1476 1.1 mrg { 1477 1.1 mrg case CONST_INT: 1478 1.1 mrg if (INTVAL (x) == 0 || nios2_simple_const_p (x)) 1479 1.1 mrg { 1480 1.1 mrg *total = COSTS_N_INSNS (0); 1481 1.1 mrg return true; 1482 1.1 mrg } 1483 1.1 mrg else 1484 1.1 mrg { 1485 1.1 mrg /* High + lo_sum. */ 1486 1.1 mrg *total = COSTS_N_INSNS (1); 1487 1.1 mrg return true; 1488 1.1 mrg } 1489 1.1 mrg 1490 1.1 mrg case LABEL_REF: 1491 1.1 mrg case SYMBOL_REF: 1492 1.1 mrg case CONST: 1493 1.1 mrg case CONST_DOUBLE: 1494 1.1 mrg if (gprel_constant_p (x) || r0rel_constant_p (x)) 1495 1.1 mrg { 1496 1.1 mrg *total = COSTS_N_INSNS (1); 1497 1.1 mrg return true; 1498 1.1 mrg } 1499 1.1 mrg else 1500 1.1 mrg { 1501 1.1 mrg /* High + lo_sum. */ 1502 1.1 mrg *total = COSTS_N_INSNS (1); 1503 1.1 mrg return true; 1504 1.1 mrg } 1505 1.1 mrg 1506 1.1 mrg case HIGH: 1507 1.1 mrg { 1508 1.1 mrg /* This is essentially a constant. */ 1509 1.1 mrg *total = COSTS_N_INSNS (0); 1510 1.1 mrg return true; 1511 1.1 mrg } 1512 1.1 mrg 1513 1.1 mrg case LO_SUM: 1514 1.1 mrg { 1515 1.1 mrg *total = COSTS_N_INSNS (0); 1516 1.1 mrg return true; 1517 1.1 mrg } 1518 1.1 mrg 1519 1.1 mrg case AND: 1520 1.1 mrg { 1521 1.1 mrg /* Recognize 'nor' insn pattern. */ 1522 1.1 mrg if (GET_CODE (XEXP (x, 0)) == NOT 1523 1.1 mrg && GET_CODE (XEXP (x, 1)) == NOT) 1524 1.1 mrg { 1525 1.1 mrg *total = COSTS_N_INSNS (1); 1526 1.1 mrg return true; 1527 1.1 mrg } 1528 1.1 mrg return false; 1529 1.1 mrg } 1530 1.1 mrg 1531 1.1 mrg /* For insns that have an execution latency (3 cycles), don't 1532 1.1 mrg penalize by the full amount since we can often schedule 1533 1.1 mrg to avoid it. */ 1534 1.1 mrg case MULT: 1535 1.1 mrg { 1536 1.1 mrg if (!TARGET_HAS_MUL) 1537 1.1 mrg *total = COSTS_N_INSNS (5); /* Guess? */ 1538 1.1 mrg else if (speed) 1539 1.1 mrg *total = COSTS_N_INSNS (2); /* Latency adjustment. */ 1540 1.1 mrg else 1541 1.1 mrg *total = COSTS_N_INSNS (1); 1542 1.1 mrg if (TARGET_HAS_MULX && GET_MODE (x) == DImode) 1543 1.1 mrg { 1544 1.1 mrg enum rtx_code c0 = GET_CODE (XEXP (x, 0)); 1545 1.1 mrg enum rtx_code c1 = GET_CODE (XEXP (x, 1)); 1546 1.1 mrg if ((c0 == SIGN_EXTEND && c1 == SIGN_EXTEND) 1547 1.1 mrg || (c0 == ZERO_EXTEND && c1 == ZERO_EXTEND)) 1548 1.1 mrg /* This is the <mul>sidi3 pattern, which expands into 4 insns, 1549 1.1 mrg 2 multiplies and 2 moves. */ 1550 1.1 mrg { 1551 1.1 mrg *total = *total * 2 + COSTS_N_INSNS (2); 1552 1.1 mrg return true; 1553 1.1 mrg } 1554 1.1 mrg } 1555 1.1 mrg return false; 1556 1.1 mrg } 1557 1.1 mrg 1558 1.1 mrg case DIV: 1559 1.1 mrg { 1560 1.1 mrg if (!TARGET_HAS_DIV) 1561 1.1 mrg *total = COSTS_N_INSNS (5); /* Guess? */ 1562 1.1 mrg else if (speed) 1563 1.1 mrg *total = COSTS_N_INSNS (2); /* Latency adjustment. */ 1564 1.1 mrg else 1565 1.1 mrg *total = COSTS_N_INSNS (1); 1566 1.1 mrg return false; 1567 1.1 mrg } 1568 1.1 mrg 1569 1.1 mrg case ASHIFT: 1570 1.1 mrg case ASHIFTRT: 1571 1.1 mrg case LSHIFTRT: 1572 1.1 mrg case ROTATE: 1573 1.1 mrg { 1574 1.1 mrg if (!speed) 1575 1.1 mrg *total = COSTS_N_INSNS (1); 1576 1.1 mrg else 1577 1.1 mrg *total = COSTS_N_INSNS (2); /* Latency adjustment. */ 1578 1.1 mrg return false; 1579 1.1 mrg } 1580 1.1 mrg 1581 1.1 mrg case ZERO_EXTRACT: 1582 1.1 mrg if (TARGET_HAS_BMX) 1583 1.1 mrg { 1584 1.1 mrg *total = COSTS_N_INSNS (1); 1585 1.1 mrg return true; 1586 1.1 mrg } 1587 1.1 mrg return false; 1588 1.1 mrg 1589 1.1 mrg case SIGN_EXTEND: 1590 1.1 mrg { 1591 1.1 mrg if (MEM_P (XEXP (x, 0))) 1592 1.1 mrg *total = COSTS_N_INSNS (1); 1593 1.1 mrg else 1594 1.1 mrg *total = COSTS_N_INSNS (3); 1595 1.1 mrg return false; 1596 1.1 mrg } 1597 1.1 mrg 1598 1.1 mrg case MEM: 1599 1.1 mrg { 1600 1.1 mrg rtx addr = XEXP (x, 0); 1601 1.1 mrg 1602 1.1 mrg /* Account for cost of different addressing modes. */ 1603 1.1 mrg *total = nios2_address_cost (addr, mode, ADDR_SPACE_GENERIC, speed); 1604 1.1 mrg 1605 1.1 mrg if (outer_code == SET && opno == 0) 1606 1.1 mrg /* Stores execute in 1 cycle accounted for by 1607 1.1 mrg the outer SET. */ 1608 1.1 mrg ; 1609 1.1 mrg else if (outer_code == SET || outer_code == SIGN_EXTEND 1610 1.1 mrg || outer_code == ZERO_EXTEND) 1611 1.1 mrg /* Latency adjustment. */ 1612 1.1 mrg { 1613 1.1 mrg if (speed) 1614 1.1 mrg *total += COSTS_N_INSNS (1); 1615 1.1 mrg } 1616 1.1 mrg else 1617 1.1 mrg /* This is going to have to be split into a load. */ 1618 1.1 mrg *total += COSTS_N_INSNS (speed ? 2 : 1); 1619 1.1 mrg return true; 1620 1.1 mrg } 1621 1.1 mrg 1622 1.1 mrg default: 1623 1.1 mrg return false; 1624 1.1 mrg } 1625 1.1 mrg } 1626 1.1 mrg 1627 1.1 mrg /* Implement TARGET_PREFERRED_RELOAD_CLASS. */ 1628 1.1 mrg static reg_class_t 1629 1.1 mrg nios2_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t regclass) 1630 1.1 mrg { 1631 1.1 mrg return regclass == NO_REGS ? GENERAL_REGS : regclass; 1632 1.1 mrg } 1633 1.1 mrg 1634 1.1 mrg /* Emit a call to __tls_get_addr. TI is the argument to this function. 1635 1.1 mrg RET is an RTX for the return value location. The entire insn sequence 1636 1.1 mrg is returned. */ 1637 1.1 mrg static GTY(()) rtx nios2_tls_symbol; 1638 1.1 mrg 1639 1.1 mrg static rtx 1640 1.1 mrg nios2_call_tls_get_addr (rtx ti) 1641 1.1 mrg { 1642 1.1 mrg rtx arg = gen_rtx_REG (Pmode, FIRST_ARG_REGNO); 1643 1.1 mrg rtx ret = gen_rtx_REG (Pmode, FIRST_RETVAL_REGNO); 1644 1.1 mrg rtx fn; 1645 1.1 mrg rtx_insn *insn; 1646 1.1 mrg 1647 1.1 mrg if (!nios2_tls_symbol) 1648 1.1 mrg nios2_tls_symbol = init_one_libfunc ("__tls_get_addr"); 1649 1.1 mrg 1650 1.1 mrg emit_move_insn (arg, ti); 1651 1.1 mrg fn = gen_rtx_MEM (QImode, nios2_tls_symbol); 1652 1.1 mrg insn = emit_call_insn (gen_call_value (ret, fn, const0_rtx)); 1653 1.1 mrg RTL_CONST_CALL_P (insn) = 1; 1654 1.1 mrg use_reg (&CALL_INSN_FUNCTION_USAGE (insn), ret); 1655 1.1 mrg use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg); 1656 1.1 mrg 1657 1.1 mrg return ret; 1658 1.1 mrg } 1659 1.1 mrg 1660 1.1 mrg /* Return true for large offsets requiring hiadj/lo relocation pairs. */ 1661 1.1 mrg static bool 1662 1.1 mrg nios2_large_offset_p (int unspec) 1663 1.1 mrg { 1664 1.1 mrg gcc_assert (nios2_unspec_reloc_name (unspec) != NULL); 1665 1.1 mrg 1666 1.1 mrg if (flag_pic == 2 1667 1.1 mrg /* FIXME: TLS GOT offset relocations will eventually also get this 1668 1.1 mrg treatment, after binutils support for those are also completed. */ 1669 1.1 mrg && (unspec == UNSPEC_PIC_SYM || unspec == UNSPEC_PIC_CALL_SYM)) 1670 1.1 mrg return true; 1671 1.1 mrg 1672 1.1 mrg /* 'gotoff' offsets are always hiadj/lo. */ 1673 1.1 mrg if (unspec == UNSPEC_PIC_GOTOFF_SYM) 1674 1.1 mrg return true; 1675 1.1 mrg 1676 1.1 mrg return false; 1677 1.1 mrg } 1678 1.1 mrg 1679 1.1 mrg /* Return true for conforming unspec relocations. Also used in 1680 1.1 mrg constraints.md and predicates.md. */ 1681 1.1 mrg bool 1682 1.1 mrg nios2_unspec_reloc_p (rtx op) 1683 1.1 mrg { 1684 1.1 mrg return (GET_CODE (op) == CONST 1685 1.1 mrg && GET_CODE (XEXP (op, 0)) == UNSPEC 1686 1.1 mrg && ! nios2_large_offset_p (XINT (XEXP (op, 0), 1))); 1687 1.1 mrg } 1688 1.1 mrg 1689 1.1 mrg static bool 1690 1.1 mrg nios2_large_unspec_reloc_p (rtx op) 1691 1.1 mrg { 1692 1.1 mrg return (GET_CODE (op) == CONST 1693 1.1 mrg && GET_CODE (XEXP (op, 0)) == UNSPEC 1694 1.1 mrg && nios2_large_offset_p (XINT (XEXP (op, 0), 1))); 1695 1.1 mrg } 1696 1.1 mrg 1697 1.1 mrg /* Helper to generate unspec constant. */ 1698 1.1 mrg static rtx 1699 1.1 mrg nios2_unspec_offset (rtx loc, int unspec) 1700 1.1 mrg { 1701 1.1 mrg return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc), 1702 1.1 mrg unspec)); 1703 1.1 mrg } 1704 1.1 mrg 1705 1.1 mrg /* Generate GOT pointer based address with large offset. */ 1706 1.1 mrg static rtx 1707 1.1 mrg nios2_large_got_address (rtx offset, rtx tmp) 1708 1.1 mrg { 1709 1.1 mrg if (!tmp) 1710 1.1 mrg tmp = gen_reg_rtx (Pmode); 1711 1.1 mrg emit_move_insn (tmp, offset); 1712 1.1 mrg return gen_rtx_PLUS (Pmode, tmp, pic_offset_table_rtx); 1713 1.1 mrg } 1714 1.1 mrg 1715 1.1 mrg /* Generate a GOT pointer based address. */ 1716 1.1 mrg static rtx 1717 1.1 mrg nios2_got_address (rtx loc, int unspec) 1718 1.1 mrg { 1719 1.1 mrg rtx offset = nios2_unspec_offset (loc, unspec); 1720 1.1 mrg crtl->uses_pic_offset_table = 1; 1721 1.1 mrg 1722 1.1 mrg if (nios2_large_offset_p (unspec)) 1723 1.1 mrg return force_reg (Pmode, nios2_large_got_address (offset, NULL_RTX)); 1724 1.1 mrg 1725 1.1 mrg return gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset); 1726 1.1 mrg } 1727 1.1 mrg 1728 1.1 mrg /* Generate the code to access LOC, a thread local SYMBOL_REF. The 1729 1.1 mrg return value will be a valid address and move_operand (either a REG 1730 1.1 mrg or a LO_SUM). */ 1731 1.1 mrg static rtx 1732 1.1 mrg nios2_legitimize_tls_address (rtx loc) 1733 1.1 mrg { 1734 1.1 mrg rtx tmp, mem, tp; 1735 1.1 mrg enum tls_model model = SYMBOL_REF_TLS_MODEL (loc); 1736 1.1 mrg 1737 1.1 mrg switch (model) 1738 1.1 mrg { 1739 1.1 mrg case TLS_MODEL_GLOBAL_DYNAMIC: 1740 1.1 mrg tmp = gen_reg_rtx (Pmode); 1741 1.1 mrg emit_move_insn (tmp, nios2_got_address (loc, UNSPEC_ADD_TLS_GD)); 1742 1.1 mrg return nios2_call_tls_get_addr (tmp); 1743 1.1 mrg 1744 1.1 mrg case TLS_MODEL_LOCAL_DYNAMIC: 1745 1.1 mrg tmp = gen_reg_rtx (Pmode); 1746 1.1 mrg emit_move_insn (tmp, nios2_got_address (loc, UNSPEC_ADD_TLS_LDM)); 1747 1.1 mrg return gen_rtx_PLUS (Pmode, nios2_call_tls_get_addr (tmp), 1748 1.1 mrg nios2_unspec_offset (loc, UNSPEC_ADD_TLS_LDO)); 1749 1.1 mrg 1750 1.1 mrg case TLS_MODEL_INITIAL_EXEC: 1751 1.1 mrg tmp = gen_reg_rtx (Pmode); 1752 1.1 mrg mem = gen_const_mem (Pmode, nios2_got_address (loc, UNSPEC_LOAD_TLS_IE)); 1753 1.1 mrg emit_move_insn (tmp, mem); 1754 1.1 mrg tp = gen_rtx_REG (Pmode, TP_REGNO); 1755 1.1 mrg return gen_rtx_PLUS (Pmode, tp, tmp); 1756 1.1 mrg 1757 1.1 mrg case TLS_MODEL_LOCAL_EXEC: 1758 1.1 mrg tp = gen_rtx_REG (Pmode, TP_REGNO); 1759 1.1 mrg return gen_rtx_PLUS (Pmode, tp, 1760 1.1 mrg nios2_unspec_offset (loc, UNSPEC_ADD_TLS_LE)); 1761 1.1 mrg default: 1762 1.1 mrg gcc_unreachable (); 1763 1.1 mrg } 1764 1.1 mrg } 1765 1.1 mrg 1766 1.1 mrg /* Divide Support 1767 1.1 mrg 1768 1.1 mrg If -O3 is used, we want to output a table lookup for 1769 1.1 mrg divides between small numbers (both num and den >= 0 1770 1.1 mrg and < 0x10). The overhead of this method in the worst 1771 1.1 mrg case is 40 bytes in the text section (10 insns) and 1772 1.1 mrg 256 bytes in the data section. Additional divides do 1773 1.1 mrg not incur additional penalties in the data section. 1774 1.1 mrg 1775 1.1 mrg Code speed is improved for small divides by about 5x 1776 1.1 mrg when using this method in the worse case (~9 cycles 1777 1.1 mrg vs ~45). And in the worst case divides not within the 1778 1.1 mrg table are penalized by about 10% (~5 cycles vs ~45). 1779 1.1 mrg However in the typical case the penalty is not as bad 1780 1.1 mrg because doing the long divide in only 45 cycles is 1781 1.1 mrg quite optimistic. 1782 1.1 mrg 1783 1.1 mrg ??? would be nice to have some benchmarks other 1784 1.1 mrg than Dhrystone to back this up. 1785 1.1 mrg 1786 1.1 mrg This bit of expansion is to create this instruction 1787 1.1 mrg sequence as rtl. 1788 1.1 mrg or $8, $4, $5 1789 1.1 mrg slli $9, $4, 4 1790 1.1 mrg cmpgeui $3, $8, 16 1791 1.1 mrg beq $3, $0, .L3 1792 1.1 mrg or $10, $9, $5 1793 1.1 mrg add $12, $11, divide_table 1794 1.1 mrg ldbu $2, 0($12) 1795 1.1 mrg br .L1 1796 1.1 mrg .L3: 1797 1.1 mrg call slow_div 1798 1.1 mrg .L1: 1799 1.1 mrg # continue here with result in $2 1800 1.1 mrg 1801 1.1 mrg ??? Ideally I would like the libcall block to contain all 1802 1.1 mrg of this code, but I don't know how to do that. What it 1803 1.1 mrg means is that if the divide can be eliminated, it may not 1804 1.1 mrg completely disappear. 1805 1.1 mrg 1806 1.1 mrg ??? The __divsi3_table label should ideally be moved out 1807 1.1 mrg of this block and into a global. If it is placed into the 1808 1.1 mrg sdata section we can save even more cycles by doing things 1809 1.1 mrg gp relative. */ 1810 1.1 mrg void 1811 1.1 mrg nios2_emit_expensive_div (rtx *operands, machine_mode mode) 1812 1.1 mrg { 1813 1.1 mrg rtx or_result, shift_left_result; 1814 1.1 mrg rtx lookup_value; 1815 1.1 mrg rtx_code_label *lab1, *lab3; 1816 1.1 mrg rtx_insn *insns; 1817 1.1 mrg rtx libfunc; 1818 1.1 mrg rtx final_result; 1819 1.1 mrg rtx_insn *tmp; 1820 1.1 mrg rtx table; 1821 1.1 mrg 1822 1.1 mrg /* It may look a little generic, but only SImode is supported for now. */ 1823 1.1 mrg gcc_assert (mode == SImode); 1824 1.1 mrg libfunc = optab_libfunc (sdiv_optab, SImode); 1825 1.1 mrg 1826 1.1 mrg lab1 = gen_label_rtx (); 1827 1.1 mrg lab3 = gen_label_rtx (); 1828 1.1 mrg 1829 1.1 mrg or_result = expand_simple_binop (SImode, IOR, 1830 1.1 mrg operands[1], operands[2], 1831 1.1 mrg 0, 0, OPTAB_LIB_WIDEN); 1832 1.1 mrg 1833 1.1 mrg emit_cmp_and_jump_insns (or_result, GEN_INT (15), GTU, 0, 1834 1.1 mrg GET_MODE (or_result), 0, lab3); 1835 1.1 mrg JUMP_LABEL (get_last_insn ()) = lab3; 1836 1.1 mrg 1837 1.1 mrg shift_left_result = expand_simple_binop (SImode, ASHIFT, 1838 1.1 mrg operands[1], GEN_INT (4), 1839 1.1 mrg 0, 0, OPTAB_LIB_WIDEN); 1840 1.1 mrg 1841 1.1 mrg lookup_value = expand_simple_binop (SImode, IOR, 1842 1.1 mrg shift_left_result, operands[2], 1843 1.1 mrg 0, 0, OPTAB_LIB_WIDEN); 1844 1.1 mrg table = gen_rtx_PLUS (SImode, lookup_value, 1845 1.1 mrg gen_rtx_SYMBOL_REF (SImode, "__divsi3_table")); 1846 1.1 mrg convert_move (operands[0], gen_rtx_MEM (QImode, table), 1); 1847 1.1 mrg 1848 1.1 mrg tmp = emit_jump_insn (gen_jump (lab1)); 1849 1.1 mrg JUMP_LABEL (tmp) = lab1; 1850 1.1 mrg emit_barrier (); 1851 1.1 mrg 1852 1.1 mrg emit_label (lab3); 1853 1.1 mrg LABEL_NUSES (lab3) = 1; 1854 1.1 mrg 1855 1.1 mrg start_sequence (); 1856 1.1 mrg final_result = emit_library_call_value (libfunc, NULL_RTX, 1857 1.1 mrg LCT_CONST, SImode, 1858 1.1 mrg operands[1], SImode, 1859 1.1 mrg operands[2], SImode); 1860 1.1 mrg 1861 1.1 mrg insns = get_insns (); 1862 1.1 mrg end_sequence (); 1863 1.1 mrg emit_libcall_block (insns, operands[0], final_result, 1864 1.1 mrg gen_rtx_DIV (SImode, operands[1], operands[2])); 1865 1.1 mrg 1866 1.1 mrg emit_label (lab1); 1867 1.1 mrg LABEL_NUSES (lab1) = 1; 1868 1.1 mrg } 1869 1.1 mrg 1870 1.1 mrg 1871 1.1 mrg /* Branches and compares. */ 1873 1.1 mrg 1874 1.1 mrg /* Return in *ALT_CODE and *ALT_OP, an alternate equivalent constant 1875 1.1 mrg comparison, e.g. >= 1 into > 0. */ 1876 1.1 mrg static void 1877 1.1 mrg nios2_alternate_compare_const (enum rtx_code code, rtx op, 1878 1.1 mrg enum rtx_code *alt_code, rtx *alt_op, 1879 1.1 mrg machine_mode mode) 1880 1.1 mrg { 1881 1.1 mrg gcc_assert (CONST_INT_P (op)); 1882 1.1 mrg 1883 1.1 mrg HOST_WIDE_INT opval = INTVAL (op); 1884 1.1 mrg enum rtx_code scode = signed_condition (code); 1885 1.1 mrg bool dec_p = (scode == LT || scode == GE); 1886 1.1 mrg 1887 1.1 mrg if (code == EQ || code == NE) 1888 1.1 mrg { 1889 1.1 mrg *alt_code = code; 1890 1.1 mrg *alt_op = op; 1891 1.1 mrg return; 1892 1.1 mrg } 1893 1.1 mrg 1894 1.1 mrg *alt_op = (dec_p 1895 1.1 mrg ? gen_int_mode (opval - 1, mode) 1896 1.1 mrg : gen_int_mode (opval + 1, mode)); 1897 1.1 mrg 1898 1.1 mrg /* The required conversion between [>,>=] and [<,<=] is captured 1899 1.1 mrg by a reverse + swap of condition codes. */ 1900 1.1 mrg *alt_code = reverse_condition (swap_condition (code)); 1901 1.1 mrg 1902 1.1 mrg { 1903 1.1 mrg /* Test if the incremented/decremented value crosses the over/underflow 1904 1.1 mrg boundary. Supposedly, such boundary cases should already be transformed 1905 1.1 mrg into always-true/false or EQ conditions, so use an assertion here. */ 1906 1.1 mrg unsigned HOST_WIDE_INT alt_opval = INTVAL (*alt_op); 1907 1.1 mrg if (code == scode) 1908 1.1 mrg alt_opval ^= (1 << (GET_MODE_BITSIZE (mode) - 1)); 1909 1.1 mrg alt_opval &= GET_MODE_MASK (mode); 1910 1.1 mrg gcc_assert (dec_p ? alt_opval != GET_MODE_MASK (mode) : alt_opval != 0); 1911 1.1 mrg } 1912 1.1 mrg } 1913 1.1 mrg 1914 1.1 mrg /* Return true if the constant comparison is supported by nios2. */ 1915 1.1 mrg static bool 1916 1.1 mrg nios2_valid_compare_const_p (enum rtx_code code, rtx op) 1917 1.1 mrg { 1918 1.1 mrg gcc_assert (CONST_INT_P (op)); 1919 1.1 mrg switch (code) 1920 1.1 mrg { 1921 1.1 mrg case EQ: case NE: case GE: case LT: 1922 1.1 mrg return SMALL_INT (INTVAL (op)); 1923 1.1 mrg case GEU: case LTU: 1924 1.1 mrg return SMALL_INT_UNSIGNED (INTVAL (op)); 1925 1.1 mrg default: 1926 1.1 mrg return false; 1927 1.1 mrg } 1928 1.1 mrg } 1929 1.1 mrg 1930 1.1 mrg /* Checks if the FPU comparison in *CMP, *OP1, and *OP2 can be supported in 1931 1.1 mrg the current configuration. Perform modifications if MODIFY_P is true. 1932 1.1 mrg Returns true if FPU compare can be done. */ 1933 1.1 mrg 1934 1.1 mrg bool 1935 1.1 mrg nios2_validate_fpu_compare (machine_mode mode, rtx *cmp, rtx *op1, rtx *op2, 1936 1.1 mrg bool modify_p) 1937 1.1 mrg { 1938 1.1 mrg bool rev_p = false; 1939 1.1 mrg enum rtx_code code = GET_CODE (*cmp); 1940 1.1 mrg 1941 1.1 mrg if (!nios2_fpu_compare_enabled (code, mode)) 1942 1.1 mrg { 1943 1.1 mrg code = swap_condition (code); 1944 1.1 mrg if (nios2_fpu_compare_enabled (code, mode)) 1945 1.1 mrg rev_p = true; 1946 1.1 mrg else 1947 1.1 mrg return false; 1948 1.1 mrg } 1949 1.1 mrg 1950 1.1 mrg if (modify_p) 1951 1.1 mrg { 1952 1.1 mrg if (rev_p) 1953 1.1 mrg { 1954 1.1 mrg rtx tmp = *op1; 1955 1.1 mrg *op1 = *op2; 1956 1.1 mrg *op2 = tmp; 1957 1.1 mrg } 1958 1.1 mrg *op1 = force_reg (mode, *op1); 1959 1.1 mrg *op2 = force_reg (mode, *op2); 1960 1.1 mrg *cmp = gen_rtx_fmt_ee (code, mode, *op1, *op2); 1961 1.1 mrg } 1962 1.1 mrg return true; 1963 1.1 mrg } 1964 1.1 mrg 1965 1.1 mrg /* Checks and modifies the comparison in *CMP, *OP1, and *OP2 into valid 1966 1.1 mrg nios2 supported form. Returns true if success. */ 1967 1.1 mrg bool 1968 1.1 mrg nios2_validate_compare (machine_mode mode, rtx *cmp, rtx *op1, rtx *op2) 1969 1.1 mrg { 1970 1.1 mrg enum rtx_code code = GET_CODE (*cmp); 1971 1.1 mrg enum rtx_code alt_code; 1972 1.1 mrg rtx alt_op2; 1973 1.1 mrg 1974 1.1 mrg if (GET_MODE_CLASS (mode) == MODE_FLOAT) 1975 1.1 mrg return nios2_validate_fpu_compare (mode, cmp, op1, op2, true); 1976 1.1 mrg 1977 1.1 mrg if (CONST_INT_P (*op2) && *op2 != const0_rtx) 1978 1.1 mrg { 1979 1.1 mrg /* Create alternate constant compare. */ 1980 1.1 mrg nios2_alternate_compare_const (code, *op2, &alt_code, &alt_op2, mode); 1981 1.1 mrg 1982 1.1 mrg /* If alterate op2 is zero(0), we can use it directly, possibly 1983 1.1 mrg swapping the compare code. */ 1984 1.1 mrg if (alt_op2 == const0_rtx) 1985 1.1 mrg { 1986 1.1 mrg code = alt_code; 1987 1.1 mrg *op2 = alt_op2; 1988 1.1 mrg goto check_rebuild_cmp; 1989 1.1 mrg } 1990 1.1 mrg 1991 1.1 mrg /* Check if either constant compare can be used. */ 1992 1.1 mrg if (nios2_valid_compare_const_p (code, *op2)) 1993 1.1 mrg return true; 1994 1.1 mrg else if (nios2_valid_compare_const_p (alt_code, alt_op2)) 1995 1.1 mrg { 1996 1.1 mrg code = alt_code; 1997 1.1 mrg *op2 = alt_op2; 1998 1.1 mrg goto rebuild_cmp; 1999 1.1 mrg } 2000 1.1 mrg 2001 1.1 mrg /* We have to force op2 into a register now. Try to pick one 2002 1.1 mrg with a lower cost. */ 2003 1.1 mrg if (! nios2_simple_const_p (*op2) 2004 1.1 mrg && nios2_simple_const_p (alt_op2)) 2005 1.1 mrg { 2006 1.1 mrg code = alt_code; 2007 1.1 mrg *op2 = alt_op2; 2008 1.1 mrg } 2009 1.1 mrg *op2 = force_reg (mode, *op2); 2010 1.1 mrg } 2011 1.1 mrg else if (!reg_or_0_operand (*op2, mode)) 2012 1.1 mrg *op2 = force_reg (mode, *op2); 2013 1.1 mrg 2014 1.1 mrg check_rebuild_cmp: 2015 1.1 mrg if (code == GT || code == GTU || code == LE || code == LEU) 2016 1.1 mrg { 2017 1.1 mrg rtx t = *op1; *op1 = *op2; *op2 = t; 2018 1.1 mrg code = swap_condition (code); 2019 1.1 mrg } 2020 1.1 mrg rebuild_cmp: 2021 1.1 mrg *cmp = gen_rtx_fmt_ee (code, mode, *op1, *op2); 2022 1.1 mrg return true; 2023 1.1 mrg } 2024 1.1 mrg 2025 1.1 mrg 2026 1.1 mrg /* Addressing modes and constants. */ 2027 1.1 mrg 2028 1.1 mrg /* Symbol references and other 32-bit constants are split into 2029 1.1 mrg high/lo_sum pairs during the split1 pass. After that, they are not 2030 1.1 mrg considered legitimate addresses. 2031 1.1 mrg This function returns true if in a pre-split context where these 2032 1.1 mrg constants are allowed. */ 2033 1.1 mrg static bool 2034 1.1 mrg nios2_large_constant_allowed (void) 2035 1.1 mrg { 2036 1.1 mrg /* The reload_completed check is for the benefit of 2037 1.1 mrg nios2_asm_output_mi_thunk and perhaps other places that try to 2038 1.1 mrg emulate a post-reload pass. */ 2039 1.1 mrg return !(cfun->curr_properties & PROP_rtl_split_insns) && !reload_completed; 2040 1.1 mrg } 2041 1.1 mrg 2042 1.1 mrg /* Return true if X is constant expression with a reference to an 2043 1.1 mrg "ordinary" symbol; not GOT-relative, not GP-relative, not TLS. */ 2044 1.1 mrg static bool 2045 1.1 mrg nios2_symbolic_constant_p (rtx x) 2046 1.1 mrg { 2047 1.1 mrg rtx base, offset; 2048 1.1 mrg 2049 1.1 mrg if (flag_pic) 2050 1.1 mrg return false; 2051 1.1 mrg if (GET_CODE (x) == LABEL_REF) 2052 1.1 mrg return true; 2053 1.1 mrg else if (CONSTANT_P (x)) 2054 1.1 mrg { 2055 1.1 mrg split_const (x, &base, &offset); 2056 1.1 mrg return (SYMBOL_REF_P (base) 2057 1.1 mrg && !SYMBOL_REF_TLS_MODEL (base) 2058 1.1 mrg && !gprel_constant_p (base) 2059 1.1 mrg && !r0rel_constant_p (base) 2060 1.1 mrg && SMALL_INT (INTVAL (offset))); 2061 1.1 mrg } 2062 1.1 mrg return false; 2063 1.1 mrg } 2064 1.1 mrg 2065 1.1 mrg /* Return true if X is an expression of the form 2066 1.1 mrg (PLUS reg large_constant). */ 2067 1.1 mrg static bool 2068 1.1 mrg nios2_plus_large_constant_p (rtx x) 2069 1.1 mrg { 2070 1.1 mrg return (GET_CODE (x) == PLUS 2071 1.1 mrg && REG_P (XEXP (x, 0)) 2072 1.1 mrg && nios2_large_constant_p (XEXP (x, 1))); 2073 1.1 mrg } 2074 1.1 mrg 2075 1.1 mrg /* Implement TARGET_LEGITIMATE_CONSTANT_P. */ 2076 1.1 mrg static bool 2077 1.1 mrg nios2_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x) 2078 1.1 mrg { 2079 1.1 mrg rtx base, offset; 2080 1.1 mrg split_const (x, &base, &offset); 2081 1.1 mrg return GET_CODE (base) != SYMBOL_REF || !SYMBOL_REF_TLS_MODEL (base); 2082 1.1 mrg } 2083 1.1 mrg 2084 1.1 mrg /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */ 2085 1.1 mrg static bool 2086 1.1 mrg nios2_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x) 2087 1.1 mrg { 2088 1.1 mrg return nios2_legitimate_constant_p (mode, x) == false; 2089 1.1 mrg } 2090 1.1 mrg 2091 1.1 mrg /* Return true if register REGNO is a valid base register. 2092 1.1 mrg STRICT_P is true if REG_OK_STRICT is in effect. */ 2093 1.1 mrg 2094 1.1 mrg bool 2095 1.1 mrg nios2_regno_ok_for_base_p (int regno, bool strict_p) 2096 1.1 mrg { 2097 1.1 mrg if (!HARD_REGISTER_NUM_P (regno)) 2098 1.1 mrg { 2099 1.1 mrg if (!strict_p) 2100 1.1 mrg return true; 2101 1.1 mrg 2102 1.1 mrg if (!reg_renumber) 2103 1.1 mrg return false; 2104 1.1 mrg 2105 1.1 mrg regno = reg_renumber[regno]; 2106 1.1 mrg } 2107 1.1 mrg 2108 1.1 mrg /* The fake registers will be eliminated to either the stack or 2109 1.1 mrg hard frame pointer, both of which are usually valid base registers. 2110 1.1 mrg Reload deals with the cases where the eliminated form isn't valid. */ 2111 1.1 mrg return (GP_REG_P (regno) 2112 1.1 mrg || regno == FRAME_POINTER_REGNUM 2113 1.1 mrg || regno == ARG_POINTER_REGNUM); 2114 1.1 mrg } 2115 1.1 mrg 2116 1.1 mrg /* Return true if OFFSET is permitted in a load/store address expression. 2117 1.1 mrg Normally any 16-bit value is permitted, but on R2 if we may be emitting 2118 1.1 mrg the IO forms of these instructions we must restrict the offset to fit 2119 1.1 mrg in a 12-bit field instead. */ 2120 1.1 mrg 2121 1.1 mrg static bool 2122 1.1 mrg nios2_valid_addr_offset_p (rtx offset) 2123 1.1 mrg { 2124 1.1 mrg return (CONST_INT_P (offset) 2125 1.1 mrg && ((TARGET_ARCH_R2 && (TARGET_BYPASS_CACHE 2126 1.1 mrg || TARGET_BYPASS_CACHE_VOLATILE)) 2127 1.1 mrg ? SMALL_INT12 (INTVAL (offset)) 2128 1.1 mrg : SMALL_INT (INTVAL (offset)))); 2129 1.1 mrg } 2130 1.1 mrg 2131 1.1 mrg /* Return true if the address expression formed by BASE + OFFSET is 2132 1.1 mrg valid. */ 2133 1.1 mrg static bool 2134 1.1 mrg nios2_valid_addr_expr_p (rtx base, rtx offset, bool strict_p) 2135 1.1 mrg { 2136 1.1 mrg if (!strict_p && GET_CODE (base) == SUBREG) 2137 1.1 mrg base = SUBREG_REG (base); 2138 1.1 mrg return (REG_P (base) 2139 1.1 mrg && nios2_regno_ok_for_base_p (REGNO (base), strict_p) 2140 1.1 mrg && (offset == NULL_RTX 2141 1.1 mrg || nios2_valid_addr_offset_p (offset) 2142 1.1 mrg || (nios2_large_constant_allowed () 2143 1.1 mrg && nios2_symbolic_constant_p (offset)) 2144 1.1 mrg || nios2_unspec_reloc_p (offset))); 2145 1.1 mrg } 2146 1.1 mrg 2147 1.1 mrg /* Implement TARGET_LEGITIMATE_ADDRESS_P. */ 2148 1.1 mrg static bool 2149 1.1 mrg nios2_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED, 2150 1.1 mrg rtx operand, bool strict_p) 2151 1.1 mrg { 2152 1.1 mrg switch (GET_CODE (operand)) 2153 1.1 mrg { 2154 1.1 mrg /* Direct. */ 2155 1.1 mrg case SYMBOL_REF: 2156 1.1 mrg if (SYMBOL_REF_TLS_MODEL (operand)) 2157 1.1 mrg return false; 2158 1.1 mrg 2159 1.1 mrg /* Else, fall through. */ 2160 1.1 mrg case CONST: 2161 1.1 mrg if (gprel_constant_p (operand) || r0rel_constant_p (operand)) 2162 1.1 mrg return true; 2163 1.1 mrg 2164 1.1 mrg /* Else, fall through. */ 2165 1.1 mrg case LABEL_REF: 2166 1.1 mrg if (nios2_large_constant_allowed () 2167 1.1 mrg && nios2_symbolic_constant_p (operand)) 2168 1.1 mrg return true; 2169 1.1 mrg return false; 2170 1.1 mrg 2171 1.1 mrg case CONST_INT: 2172 1.1 mrg if (r0rel_constant_p (operand)) 2173 1.1 mrg return true; 2174 1.1 mrg return nios2_large_constant_allowed (); 2175 1.1 mrg 2176 1.1 mrg case CONST_DOUBLE: 2177 1.1 mrg return false; 2178 1.1 mrg 2179 1.1 mrg /* Register indirect. */ 2180 1.1 mrg case REG: 2181 1.1 mrg return nios2_regno_ok_for_base_p (REGNO (operand), strict_p); 2182 1.1 mrg 2183 1.1 mrg /* Register indirect with displacement. */ 2184 1.1 mrg case PLUS: 2185 1.1 mrg { 2186 1.1 mrg rtx op0 = XEXP (operand, 0); 2187 1.1 mrg rtx op1 = XEXP (operand, 1); 2188 1.1 mrg 2189 1.1 mrg if (nios2_valid_addr_expr_p (op0, op1, strict_p) 2190 1.1 mrg || nios2_valid_addr_expr_p (op1, op0, strict_p)) 2191 1.1 mrg return true; 2192 1.1 mrg } 2193 1.1 mrg break; 2194 1.1 mrg 2195 1.1 mrg /* %lo(constant)(reg) 2196 1.1 mrg This requires a 16-bit relocation and isn't valid with R2 2197 1.1 mrg io-variant load/stores. */ 2198 1.1 mrg case LO_SUM: 2199 1.1 mrg if (TARGET_ARCH_R2 2200 1.1 mrg && (TARGET_BYPASS_CACHE || TARGET_BYPASS_CACHE_VOLATILE)) 2201 1.1 mrg return false; 2202 1.1 mrg else 2203 1.1 mrg { 2204 1.1 mrg rtx op0 = XEXP (operand, 0); 2205 1.1 mrg rtx op1 = XEXP (operand, 1); 2206 1.1 mrg 2207 1.1 mrg return (REG_P (op0) 2208 1.1 mrg && nios2_regno_ok_for_base_p (REGNO (op0), strict_p) 2209 1.1 mrg && nios2_large_constant_p (op1)); 2210 1.1 mrg } 2211 1.1 mrg 2212 1.1 mrg default: 2213 1.1 mrg break; 2214 1.1 mrg } 2215 1.1 mrg return false; 2216 1.1 mrg } 2217 1.1 mrg 2218 1.1 mrg /* Implement TARGET_ADDRESS_COST. 2219 1.1 mrg Experimentation has shown that we get better code by penalizing the 2220 1.1 mrg the (plus reg symbolic_constant) and (plus reg (const ...)) forms 2221 1.1 mrg but giving (plus reg symbol_ref) address modes the same cost as those 2222 1.1 mrg that don't require splitting. Also, from a theoretical point of view: 2223 1.1 mrg - This is in line with the recommendation in the GCC internals 2224 1.1 mrg documentation to make address forms involving multiple 2225 1.1 mrg registers more expensive than single-register forms. 2226 1.1 mrg - OTOH it still encourages fwprop1 to propagate constants into 2227 1.1 mrg address expressions more aggressively. 2228 1.1 mrg - We should discourage splitting (symbol + offset) into hi/lo pairs 2229 1.1 mrg to allow CSE'ing the symbol when it's used with more than one offset, 2230 1.1 mrg but not so heavily as to avoid this addressing mode at all. */ 2231 1.1 mrg static int 2232 1.1 mrg nios2_address_cost (rtx address, 2233 1.1 mrg machine_mode mode ATTRIBUTE_UNUSED, 2234 1.1 mrg addr_space_t as ATTRIBUTE_UNUSED, 2235 1.1 mrg bool speed ATTRIBUTE_UNUSED) 2236 1.1 mrg { 2237 1.1 mrg if (nios2_plus_large_constant_p (address)) 2238 1.1 mrg return COSTS_N_INSNS (1); 2239 1.1 mrg if (nios2_large_constant_p (address)) 2240 1.1 mrg { 2241 1.1 mrg if (GET_CODE (address) == CONST) 2242 1.1 mrg return COSTS_N_INSNS (1); 2243 1.1 mrg else 2244 1.1 mrg return COSTS_N_INSNS (0); 2245 1.1 mrg } 2246 1.1 mrg return COSTS_N_INSNS (0); 2247 1.1 mrg } 2248 1.1 mrg 2249 1.1 mrg /* Return true if X is a MEM whose address expression involves a large (32-bit) 2250 1.1 mrg constant. */ 2251 1.1 mrg bool 2252 1.1 mrg nios2_large_constant_memory_operand_p (rtx x) 2253 1.1 mrg { 2254 1.1 mrg rtx addr; 2255 1.1 mrg 2256 1.1 mrg if (GET_CODE (x) != MEM) 2257 1.1 mrg return false; 2258 1.1 mrg addr = XEXP (x, 0); 2259 1.1 mrg 2260 1.1 mrg return (nios2_large_constant_p (addr) 2261 1.1 mrg || nios2_plus_large_constant_p (addr)); 2262 1.1 mrg } 2263 1.1 mrg 2264 1.1 mrg 2265 1.1 mrg /* Return true if X is something that needs to be split into a 2266 1.1 mrg high/lo_sum pair. */ 2267 1.1 mrg bool 2268 1.1 mrg nios2_large_constant_p (rtx x) 2269 1.1 mrg { 2270 1.1 mrg return (nios2_symbolic_constant_p (x) 2271 1.1 mrg || nios2_large_unspec_reloc_p (x) 2272 1.1 mrg || (CONST_INT_P (x) && !SMALL_INT (INTVAL (x)))); 2273 1.1 mrg } 2274 1.1 mrg 2275 1.1 mrg /* Given an RTX X that satisfies nios2_large_constant_p, split it into 2276 1.1 mrg high and lo_sum parts using TEMP as a scratch register. Emit the high 2277 1.1 mrg instruction and return the lo_sum expression. 2278 1.1 mrg Also handle special cases involving constant integers. */ 2279 1.1 mrg rtx 2280 1.1 mrg nios2_split_large_constant (rtx x, rtx temp) 2281 1.1 mrg { 2282 1.1 mrg if (CONST_INT_P (x)) 2283 1.1 mrg { 2284 1.1 mrg HOST_WIDE_INT val = INTVAL (x); 2285 1.1 mrg if (SMALL_INT (val)) 2286 1.1 mrg return x; 2287 1.1 mrg else if (SMALL_INT_UNSIGNED (val) || UPPER16_INT (val)) 2288 1.1 mrg { 2289 1.1 mrg emit_move_insn (temp, x); 2290 1.1 mrg return temp; 2291 1.1 mrg } 2292 1.1 mrg else 2293 1.1 mrg { 2294 1.1 mrg HOST_WIDE_INT high = (val + 0x8000) & ~0xffff; 2295 1.1 mrg HOST_WIDE_INT low = val - high; 2296 1.1 mrg emit_move_insn (temp, gen_int_mode (high, Pmode)); 2297 1.1 mrg return gen_rtx_PLUS (Pmode, temp, gen_int_mode (low, Pmode)); 2298 1.1 mrg } 2299 1.1 mrg } 2300 1.1 mrg 2301 1.1 mrg emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (Pmode, copy_rtx (x)))); 2302 1.1 mrg return gen_rtx_LO_SUM (Pmode, temp, copy_rtx (x)); 2303 1.1 mrg } 2304 1.1 mrg 2305 1.1 mrg /* Split an RTX of the form 2306 1.1 mrg (plus op0 op1) 2307 1.1 mrg where op1 is a large constant into 2308 1.1 mrg (set temp (high op1)) 2309 1.1 mrg (set temp (plus op0 temp)) 2310 1.1 mrg (lo_sum temp op1) 2311 1.1 mrg returning the lo_sum expression as the value. */ 2312 1.1 mrg static rtx 2313 1.1 mrg nios2_split_plus_large_constant (rtx op0, rtx op1) 2314 1.1 mrg { 2315 1.1 mrg rtx temp = gen_reg_rtx (Pmode); 2316 1.1 mrg op0 = force_reg (Pmode, op0); 2317 1.1 mrg 2318 1.1 mrg emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (Pmode, copy_rtx (op1)))); 2319 1.1 mrg emit_insn (gen_rtx_SET (temp, gen_rtx_PLUS (Pmode, op0, temp))); 2320 1.1 mrg return gen_rtx_LO_SUM (Pmode, temp, copy_rtx (op1)); 2321 1.1 mrg } 2322 1.1 mrg 2323 1.1 mrg /* Given a MEM OP with an address that includes a splittable symbol or 2324 1.1 mrg other large constant, emit some instructions to do the split and 2325 1.1 mrg return a new MEM. */ 2326 1.1 mrg rtx 2327 1.1 mrg nios2_split_large_constant_memory_operand (rtx op) 2328 1.1 mrg { 2329 1.1 mrg rtx addr = XEXP (op, 0); 2330 1.1 mrg 2331 1.1 mrg if (nios2_large_constant_p (addr)) 2332 1.1 mrg addr = nios2_split_large_constant (addr, gen_reg_rtx (Pmode)); 2333 1.1 mrg else if (nios2_plus_large_constant_p (addr)) 2334 1.1 mrg addr = nios2_split_plus_large_constant (XEXP (addr, 0), XEXP (addr, 1)); 2335 1.1 mrg else 2336 1.1 mrg gcc_unreachable (); 2337 1.1 mrg return replace_equiv_address (op, addr, false); 2338 1.1 mrg } 2339 1.1 mrg 2340 1.1 mrg /* Return true if SECTION is a small section name. */ 2341 1.1 mrg static bool 2342 1.1 mrg nios2_small_section_name_p (const char *section) 2343 1.1 mrg { 2344 1.1 mrg return (strcmp (section, ".sbss") == 0 2345 1.1 mrg || startswith (section, ".sbss.") 2346 1.1 mrg || strcmp (section, ".sdata") == 0 2347 1.1 mrg || startswith (section, ".sdata.") 2348 1.1 mrg || (nios2_gprel_sec 2349 1.1 mrg && regexec (&nios2_gprel_sec_regex, section, 0, NULL, 0) == 0)); 2350 1.1 mrg } 2351 1.1 mrg 2352 1.1 mrg /* Return true if SECTION is a r0-relative section name. */ 2353 1.1 mrg static bool 2354 1.1 mrg nios2_r0rel_section_name_p (const char *section) 2355 1.1 mrg { 2356 1.1 mrg return (nios2_r0rel_sec 2357 1.1 mrg && regexec (&nios2_r0rel_sec_regex, section, 0, NULL, 0) == 0); 2358 1.1 mrg } 2359 1.1 mrg 2360 1.1 mrg /* Return true if EXP should be placed in the small data section. */ 2361 1.1 mrg static bool 2362 1.1 mrg nios2_in_small_data_p (const_tree exp) 2363 1.1 mrg { 2364 1.1 mrg /* We want to merge strings, so we never consider them small data. */ 2365 1.1 mrg if (TREE_CODE (exp) == STRING_CST) 2366 1.1 mrg return false; 2367 1.1 mrg 2368 1.1 mrg if (TREE_CODE (exp) == VAR_DECL) 2369 1.1 mrg { 2370 1.1 mrg if (DECL_SECTION_NAME (exp)) 2371 1.1 mrg { 2372 1.1 mrg const char *section = DECL_SECTION_NAME (exp); 2373 1.1 mrg if (nios2_small_section_name_p (section)) 2374 1.1 mrg return true; 2375 1.1 mrg } 2376 1.1 mrg else if (flexible_array_type_p (TREE_TYPE (exp)) 2377 1.1 mrg && (!TREE_PUBLIC (exp) || DECL_EXTERNAL (exp))) 2378 1.1 mrg { 2379 1.1 mrg /* We really should not consider any objects of any flexibly-sized 2380 1.1 mrg type to be small data, but pre-GCC 10 did not test 2381 1.1 mrg for this and just fell through to the next case. Thus older 2382 1.1 mrg code compiled with -mgpopt=global could contain GP-relative 2383 1.1 mrg accesses to objects defined in this compilation unit with 2384 1.1 mrg external linkage. We retain the possible small-data treatment 2385 1.1 mrg of such definitions for backward ABI compatibility, but 2386 1.1 mrg no longer generate GP-relative accesses for external 2387 1.1 mrg references (so that the ABI could be changed in the future 2388 1.1 mrg with less potential impact), or objects with internal 2389 1.1 mrg linkage. */ 2390 1.1 mrg return false; 2391 1.1 mrg } 2392 1.1 mrg else 2393 1.1 mrg { 2394 1.1 mrg HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp)); 2395 1.1 mrg 2396 1.1 mrg /* If this is an incomplete type with size 0, then we can't put it 2397 1.1 mrg in sdata because it might be too big when completed. */ 2398 1.1 mrg if (size > 0 2399 1.1 mrg && (unsigned HOST_WIDE_INT) size <= nios2_section_threshold) 2400 1.1 mrg return true; 2401 1.1 mrg } 2402 1.1 mrg } 2403 1.1 mrg 2404 1.1 mrg return false; 2405 1.1 mrg } 2406 1.1 mrg 2407 1.1 mrg /* Return true if symbol is in small data section. */ 2408 1.1 mrg 2409 1.1 mrg static bool 2410 1.1 mrg nios2_symbol_ref_in_small_data_p (rtx sym) 2411 1.1 mrg { 2412 1.1 mrg tree decl; 2413 1.1 mrg 2414 1.1 mrg gcc_assert (GET_CODE (sym) == SYMBOL_REF); 2415 1.1 mrg decl = SYMBOL_REF_DECL (sym); 2416 1.1 mrg 2417 1.1 mrg /* TLS variables are not accessed through the GP. */ 2418 1.1 mrg if (SYMBOL_REF_TLS_MODEL (sym) != 0) 2419 1.1 mrg return false; 2420 1.1 mrg 2421 1.1 mrg /* On Nios II R2, there is no GP-relative relocation that can be 2422 1.1 mrg used with "io" instructions. So, if we are implicitly generating 2423 1.1 mrg those instructions, we cannot emit GP-relative accesses. */ 2424 1.1 mrg if (TARGET_ARCH_R2 2425 1.1 mrg && (TARGET_BYPASS_CACHE || TARGET_BYPASS_CACHE_VOLATILE)) 2426 1.1 mrg return false; 2427 1.1 mrg 2428 1.1 mrg /* If the user has explicitly placed the symbol in a small data section 2429 1.1 mrg via an attribute, generate gp-relative addressing even if the symbol 2430 1.1 mrg is external, weak, or larger than we'd automatically put in the 2431 1.1 mrg small data section. OTOH, if the symbol is located in some 2432 1.1 mrg non-small-data section, we can't use gp-relative accesses on it 2433 1.1 mrg unless the user has requested gpopt_data or gpopt_all. */ 2434 1.1 mrg 2435 1.1 mrg switch (nios2_gpopt_option) 2436 1.1 mrg { 2437 1.1 mrg case gpopt_none: 2438 1.1 mrg /* Don't generate a gp-relative addressing mode if that's been 2439 1.1 mrg disabled. */ 2440 1.1 mrg return false; 2441 1.1 mrg 2442 1.1 mrg case gpopt_local: 2443 1.1 mrg /* Use GP-relative addressing for small data symbols that are 2444 1.1 mrg not external or weak or uninitialized common, plus any symbols 2445 1.1 mrg that have explicitly been placed in a small data section. */ 2446 1.1 mrg if (decl && DECL_SECTION_NAME (decl)) 2447 1.1 mrg return nios2_small_section_name_p (DECL_SECTION_NAME (decl)); 2448 1.1 mrg return (SYMBOL_REF_SMALL_P (sym) 2449 1.1 mrg && !SYMBOL_REF_EXTERNAL_P (sym) 2450 1.1 mrg && !(decl && DECL_WEAK (decl)) 2451 1.1 mrg && !(decl && DECL_COMMON (decl) 2452 1.1 mrg && (DECL_INITIAL (decl) == NULL 2453 1.1 mrg || (!in_lto_p 2454 1.1 mrg && DECL_INITIAL (decl) == error_mark_node)))); 2455 1.1 mrg 2456 1.1 mrg case gpopt_global: 2457 1.1 mrg /* Use GP-relative addressing for small data symbols, even if 2458 1.1 mrg they are external or weak. Note that SYMBOL_REF_SMALL_P 2459 1.1 mrg is also true of symbols that have explicitly been placed 2460 1.1 mrg in a small data section. */ 2461 1.1 mrg return SYMBOL_REF_SMALL_P (sym); 2462 1.1 mrg 2463 1.1 mrg case gpopt_data: 2464 1.1 mrg /* Use GP-relative addressing for all data symbols regardless 2465 1.1 mrg of the object size, but not for code symbols. This option 2466 1.1 mrg is equivalent to the user asserting that the entire data 2467 1.1 mrg section is accessible from the GP. */ 2468 1.1 mrg return !SYMBOL_REF_FUNCTION_P (sym); 2469 1.1 mrg 2470 1.1 mrg case gpopt_all: 2471 1.1 mrg /* Use GP-relative addressing for everything, including code. 2472 1.1 mrg Effectively, the user has asserted that the entire program 2473 1.1 mrg fits within the 64K range of the GP offset. */ 2474 1.1 mrg return true; 2475 1.1 mrg 2476 1.1 mrg default: 2477 1.1 mrg /* We shouldn't get here. */ 2478 1.1 mrg return false; 2479 1.1 mrg } 2480 1.1 mrg } 2481 1.1 mrg 2482 1.1 mrg /* Likewise for r0-relative addressing. */ 2483 1.1 mrg static bool 2484 1.1 mrg nios2_symbol_ref_in_r0rel_data_p (rtx sym) 2485 1.1 mrg { 2486 1.1 mrg tree decl; 2487 1.1 mrg 2488 1.1 mrg gcc_assert (GET_CODE (sym) == SYMBOL_REF); 2489 1.1 mrg decl = SYMBOL_REF_DECL (sym); 2490 1.1 mrg 2491 1.1 mrg /* TLS variables are not accessed through r0. */ 2492 1.1 mrg if (SYMBOL_REF_TLS_MODEL (sym) != 0) 2493 1.1 mrg return false; 2494 1.1 mrg 2495 1.1 mrg /* On Nios II R2, there is no r0-relative relocation that can be 2496 1.1 mrg used with "io" instructions. So, if we are implicitly generating 2497 1.1 mrg those instructions, we cannot emit r0-relative accesses. */ 2498 1.1 mrg if (TARGET_ARCH_R2 2499 1.1 mrg && (TARGET_BYPASS_CACHE || TARGET_BYPASS_CACHE_VOLATILE)) 2500 1.1 mrg return false; 2501 1.1 mrg 2502 1.1 mrg /* If the user has explicitly placed the symbol in a r0rel section 2503 1.1 mrg via an attribute, generate r0-relative addressing. */ 2504 1.1 mrg if (decl && DECL_SECTION_NAME (decl)) 2505 1.1 mrg return nios2_r0rel_section_name_p (DECL_SECTION_NAME (decl)); 2506 1.1 mrg return false; 2507 1.1 mrg } 2508 1.1 mrg 2509 1.1 mrg /* Implement TARGET_SECTION_TYPE_FLAGS. */ 2510 1.1 mrg 2511 1.1 mrg static unsigned int 2512 1.1 mrg nios2_section_type_flags (tree decl, const char *name, int reloc) 2513 1.1 mrg { 2514 1.1 mrg unsigned int flags; 2515 1.1 mrg 2516 1.1 mrg flags = default_section_type_flags (decl, name, reloc); 2517 1.1 mrg 2518 1.1 mrg if (nios2_small_section_name_p (name)) 2519 1.1 mrg flags |= SECTION_SMALL; 2520 1.1 mrg 2521 1.1 mrg return flags; 2522 1.1 mrg } 2523 1.1 mrg 2524 1.1 mrg /* Return true if SYMBOL_REF X binds locally. */ 2525 1.1 mrg 2526 1.1 mrg static bool 2527 1.1 mrg nios2_symbol_binds_local_p (const_rtx x) 2528 1.1 mrg { 2529 1.1 mrg return (SYMBOL_REF_DECL (x) 2530 1.1 mrg ? targetm.binds_local_p (SYMBOL_REF_DECL (x)) 2531 1.1 mrg : SYMBOL_REF_LOCAL_P (x)); 2532 1.1 mrg } 2533 1.1 mrg 2534 1.1 mrg /* Position independent code related. */ 2535 1.1 mrg 2536 1.1 mrg /* Emit code to load the PIC register. */ 2537 1.1 mrg static void 2538 1.1 mrg nios2_load_pic_register (void) 2539 1.1 mrg { 2540 1.1 mrg rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM); 2541 1.1 mrg 2542 1.1 mrg emit_insn (gen_load_got_register (pic_offset_table_rtx, tmp)); 2543 1.1 mrg emit_insn (gen_add3_insn (pic_offset_table_rtx, pic_offset_table_rtx, tmp)); 2544 1.1 mrg } 2545 1.1 mrg 2546 1.1 mrg /* Generate a PIC address as a MEM rtx. */ 2547 1.1 mrg static rtx 2548 1.1 mrg nios2_load_pic_address (rtx sym, int unspec, rtx tmp) 2549 1.1 mrg { 2550 1.1 mrg if (flag_pic == 2 2551 1.1 mrg && GET_CODE (sym) == SYMBOL_REF 2552 1.1 mrg && nios2_symbol_binds_local_p (sym)) 2553 1.1 mrg /* Under -fPIC, generate a GOTOFF address for local symbols. */ 2554 1.1 mrg { 2555 1.1 mrg rtx offset = nios2_unspec_offset (sym, UNSPEC_PIC_GOTOFF_SYM); 2556 1.1 mrg crtl->uses_pic_offset_table = 1; 2557 1.1 mrg return nios2_large_got_address (offset, tmp); 2558 1.1 mrg } 2559 1.1 mrg 2560 1.1 mrg return gen_const_mem (Pmode, nios2_got_address (sym, unspec)); 2561 1.1 mrg } 2562 1.1 mrg 2563 1.1 mrg /* Nonzero if the constant value X is a legitimate general operand 2564 1.1 mrg when generating PIC code. It is given that flag_pic is on and 2565 1.1 mrg that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ 2566 1.1 mrg bool 2567 1.1 mrg nios2_legitimate_pic_operand_p (rtx x) 2568 1.1 mrg { 2569 1.1 mrg if (nios2_large_unspec_reloc_p (x)) 2570 1.1 mrg return true; 2571 1.1 mrg 2572 1.1 mrg return ! (GET_CODE (x) == SYMBOL_REF 2573 1.1 mrg || GET_CODE (x) == LABEL_REF || GET_CODE (x) == CONST); 2574 1.1 mrg } 2575 1.1 mrg 2576 1.1 mrg /* Return TRUE if X is a thread-local symbol. */ 2577 1.1 mrg static bool 2578 1.1 mrg nios2_tls_symbol_p (rtx x) 2579 1.1 mrg { 2580 1.1 mrg return (targetm.have_tls && GET_CODE (x) == SYMBOL_REF 2581 1.1 mrg && SYMBOL_REF_TLS_MODEL (x) != 0); 2582 1.1 mrg } 2583 1.1 mrg 2584 1.1 mrg /* Legitimize addresses that are CONSTANT_P expressions. */ 2585 1.1 mrg static rtx 2586 1.1 mrg nios2_legitimize_constant_address (rtx addr) 2587 1.1 mrg { 2588 1.1 mrg rtx base, offset; 2589 1.1 mrg split_const (addr, &base, &offset); 2590 1.1 mrg 2591 1.1 mrg if (nios2_tls_symbol_p (base)) 2592 1.1 mrg base = nios2_legitimize_tls_address (base); 2593 1.1 mrg else if (flag_pic) 2594 1.1 mrg base = nios2_load_pic_address (base, UNSPEC_PIC_SYM, NULL_RTX); 2595 1.1 mrg else if (!nios2_large_constant_allowed () 2596 1.1 mrg && nios2_symbolic_constant_p (addr)) 2597 1.1 mrg return nios2_split_large_constant (addr, gen_reg_rtx (Pmode)); 2598 1.1 mrg else if (CONST_INT_P (addr)) 2599 1.1 mrg { 2600 1.1 mrg HOST_WIDE_INT val = INTVAL (addr); 2601 1.1 mrg if (SMALL_INT (val)) 2602 1.1 mrg /* Use r0-relative addressing. */ 2603 1.1 mrg return addr; 2604 1.1 mrg else if (!nios2_large_constant_allowed ()) 2605 1.1 mrg /* Split into high/lo pair. */ 2606 1.1 mrg return nios2_split_large_constant (addr, gen_reg_rtx (Pmode)); 2607 1.1 mrg } 2608 1.1 mrg else 2609 1.1 mrg return addr; 2610 1.1 mrg 2611 1.1 mrg if (offset != const0_rtx) 2612 1.1 mrg { 2613 1.1 mrg gcc_assert (can_create_pseudo_p ()); 2614 1.1 mrg return gen_rtx_PLUS (Pmode, force_reg (Pmode, base), 2615 1.1 mrg (CONST_INT_P (offset) 2616 1.1 mrg ? (SMALL_INT (INTVAL (offset)) 2617 1.1 mrg ? offset : force_reg (Pmode, offset)) 2618 1.1 mrg : offset)); 2619 1.1 mrg } 2620 1.1 mrg return base; 2621 1.1 mrg } 2622 1.1 mrg 2623 1.1 mrg /* Implement TARGET_LEGITIMIZE_ADDRESS. */ 2624 1.1 mrg static rtx 2625 1.1 mrg nios2_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, 2626 1.1 mrg machine_mode mode ATTRIBUTE_UNUSED) 2627 1.1 mrg { 2628 1.1 mrg rtx op0, op1; 2629 1.1 mrg 2630 1.1 mrg if (CONSTANT_P (x)) 2631 1.1 mrg return nios2_legitimize_constant_address (x); 2632 1.1 mrg 2633 1.1 mrg /* Remaining cases all involve something + a constant. */ 2634 1.1 mrg if (GET_CODE (x) != PLUS) 2635 1.1 mrg return x; 2636 1.1 mrg 2637 1.1 mrg op0 = XEXP (x, 0); 2638 1.1 mrg op1 = XEXP (x, 1); 2639 1.1 mrg 2640 1.1 mrg /* Target-independent code turns (exp + constant) into plain 2641 1.1 mrg register indirect. Although subsequent optimization passes will 2642 1.1 mrg eventually sort that out, ivopts uses the unoptimized form for 2643 1.1 mrg computing its cost model, so we get better results by generating 2644 1.1 mrg the correct form from the start. */ 2645 1.1 mrg if (nios2_valid_addr_offset_p (op1)) 2646 1.1 mrg return gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), copy_rtx (op1)); 2647 1.1 mrg 2648 1.1 mrg /* We may need to split symbolic constants now. */ 2649 1.1 mrg else if (nios2_symbolic_constant_p (op1)) 2650 1.1 mrg { 2651 1.1 mrg if (nios2_large_constant_allowed ()) 2652 1.1 mrg return gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), copy_rtx (op1)); 2653 1.1 mrg else 2654 1.1 mrg return nios2_split_plus_large_constant (op0, op1); 2655 1.1 mrg } 2656 1.1 mrg 2657 1.1 mrg /* For the TLS LE (Local Exec) model, the compiler may try to 2658 1.1 mrg combine constant offsets with unspec relocs, creating address RTXs 2659 1.1 mrg looking like this: 2660 1.1 mrg (plus:SI (reg:SI 23 r23) 2661 1.1 mrg (const:SI 2662 1.1 mrg (plus:SI 2663 1.1 mrg (unspec:SI [(symbol_ref:SI ("var"))] UNSPEC_ADD_TLS_LE) 2664 1.1 mrg (const_int 48 [0x30])))) 2665 1.1 mrg 2666 1.1 mrg This usually happens when 'var' is a thread-local struct variable, 2667 1.1 mrg and access of a field in var causes the addend. 2668 1.1 mrg 2669 1.1 mrg We typically want this combining, so transform the above into this 2670 1.1 mrg form, which is allowed: 2671 1.1 mrg (plus:SI (reg:SI 23 r23) 2672 1.1 mrg (const:SI 2673 1.1 mrg (unspec:SI 2674 1.1 mrg [(const:SI 2675 1.1 mrg (plus:SI (symbol_ref:SI ("var")) 2676 1.1 mrg (const_int 48 [0x30])))] UNSPEC_ADD_TLS_LE))) 2677 1.1 mrg 2678 1.1 mrg Which will be output as '%tls_le(var+48)(r23)' in assembly. */ 2679 1.1 mrg else if (GET_CODE (op1) == CONST) 2680 1.1 mrg { 2681 1.1 mrg rtx unspec, offset; 2682 1.1 mrg split_const (op1, &unspec, &offset); 2683 1.1 mrg if (GET_CODE (unspec) == UNSPEC 2684 1.1 mrg && !nios2_large_offset_p (XINT (unspec, 1)) 2685 1.1 mrg && offset != const0_rtx) 2686 1.1 mrg { 2687 1.1 mrg rtx reg = force_reg (Pmode, op0); 2688 1.1 mrg unspec = copy_rtx (unspec); 2689 1.1 mrg XVECEXP (unspec, 0, 0) 2690 1.1 mrg = plus_constant (Pmode, XVECEXP (unspec, 0, 0), INTVAL (offset)); 2691 1.1 mrg return gen_rtx_PLUS (Pmode, reg, gen_rtx_CONST (Pmode, unspec)); 2692 1.1 mrg } 2693 1.1 mrg } 2694 1.1 mrg 2695 1.1 mrg return x; 2696 1.1 mrg } 2697 1.1 mrg 2698 1.1 mrg static rtx 2699 1.1 mrg nios2_delegitimize_address (rtx x) 2700 1.1 mrg { 2701 1.1 mrg x = delegitimize_mem_from_attrs (x); 2702 1.1 mrg 2703 1.1 mrg if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC) 2704 1.1 mrg { 2705 1.1 mrg switch (XINT (XEXP (x, 0), 1)) 2706 1.1 mrg { 2707 1.1 mrg case UNSPEC_PIC_SYM: 2708 1.1 mrg case UNSPEC_PIC_CALL_SYM: 2709 1.1 mrg case UNSPEC_PIC_GOTOFF_SYM: 2710 1.1 mrg case UNSPEC_ADD_TLS_GD: 2711 1.1 mrg case UNSPEC_ADD_TLS_LDM: 2712 1.1 mrg case UNSPEC_LOAD_TLS_IE: 2713 1.1 mrg case UNSPEC_ADD_TLS_LE: 2714 1.1 mrg x = XVECEXP (XEXP (x, 0), 0, 0); 2715 1.1 mrg gcc_assert (CONSTANT_P (x)); 2716 1.1 mrg break; 2717 1.1 mrg } 2718 1.1 mrg } 2719 1.1 mrg return x; 2720 1.1 mrg } 2721 1.1 mrg 2722 1.1 mrg /* Main expander function for RTL moves. */ 2723 1.1 mrg bool 2724 1.1 mrg nios2_emit_move_sequence (rtx *operands, machine_mode mode) 2725 1.1 mrg { 2726 1.1 mrg rtx to = operands[0]; 2727 1.1 mrg rtx from = operands[1]; 2728 1.1 mrg 2729 1.1 mrg if (!register_operand (to, mode) && !reg_or_0_operand (from, mode)) 2730 1.1 mrg { 2731 1.1 mrg gcc_assert (can_create_pseudo_p ()); 2732 1.1 mrg from = copy_to_mode_reg (mode, from); 2733 1.1 mrg } 2734 1.1 mrg 2735 1.1 mrg if (CONSTANT_P (from)) 2736 1.1 mrg { 2737 1.1 mrg if (CONST_INT_P (from)) 2738 1.1 mrg { 2739 1.1 mrg if (!SMALL_INT (INTVAL (from)) 2740 1.1 mrg && !SMALL_INT_UNSIGNED (INTVAL (from)) 2741 1.1 mrg && !UPPER16_INT (INTVAL (from))) 2742 1.1 mrg { 2743 1.1 mrg HOST_WIDE_INT high = (INTVAL (from) + 0x8000) & ~0xffff; 2744 1.1 mrg HOST_WIDE_INT low = INTVAL (from) & 0xffff; 2745 1.1 mrg emit_move_insn (to, gen_int_mode (high, SImode)); 2746 1.1 mrg emit_insn (gen_add2_insn (to, gen_int_mode (low, HImode))); 2747 1.1 mrg set_unique_reg_note (get_last_insn (), REG_EQUAL, 2748 1.1 mrg copy_rtx (from)); 2749 1.1 mrg return true; 2750 1.1 mrg } 2751 1.1 mrg } 2752 1.1 mrg else if (gprel_constant_p (from) || r0rel_constant_p (from)) 2753 1.1 mrg /* Handled directly by movsi_internal as gp + offset 2754 1.1 mrg or r0 + offset. */ 2755 1.1 mrg ; 2756 1.1 mrg else if (nios2_large_constant_p (from)) 2757 1.1 mrg /* This case covers either a regular symbol reference or an UNSPEC 2758 1.1 mrg representing a 32-bit offset. We split the former 2759 1.1 mrg only conditionally and the latter always. */ 2760 1.1 mrg { 2761 1.1 mrg if (!nios2_large_constant_allowed () 2762 1.1 mrg || nios2_large_unspec_reloc_p (from)) 2763 1.1 mrg { 2764 1.1 mrg rtx lo = nios2_split_large_constant (from, to); 2765 1.1 mrg emit_insn (gen_rtx_SET (to, lo)); 2766 1.1 mrg set_unique_reg_note (get_last_insn (), REG_EQUAL, 2767 1.1 mrg copy_rtx (operands[1])); 2768 1.1 mrg return true; 2769 1.1 mrg } 2770 1.1 mrg } 2771 1.1 mrg else 2772 1.1 mrg /* This is a TLS or PIC symbol. */ 2773 1.1 mrg { 2774 1.1 mrg from = nios2_legitimize_constant_address (from); 2775 1.1 mrg if (CONSTANT_P (from)) 2776 1.1 mrg { 2777 1.1 mrg emit_insn (gen_rtx_SET (to, 2778 1.1 mrg gen_rtx_HIGH (Pmode, copy_rtx (from)))); 2779 1.1 mrg emit_insn (gen_rtx_SET (to, gen_rtx_LO_SUM (Pmode, to, from))); 2780 1.1 mrg set_unique_reg_note (get_last_insn (), REG_EQUAL, 2781 1.1 mrg copy_rtx (operands[1])); 2782 1.1 mrg return true; 2783 1.1 mrg } 2784 1.1 mrg } 2785 1.1 mrg } 2786 1.1 mrg 2787 1.1 mrg operands[0] = to; 2788 1.1 mrg operands[1] = from; 2789 1.1 mrg return false; 2790 1.1 mrg } 2791 1.1 mrg 2792 1.1 mrg /* The function with address *ADDR is being called. If the address 2793 1.1 mrg needs to be loaded from the GOT, emit the instruction to do so and 2794 1.1 mrg update *ADDR to point to the rtx for the loaded value. 2795 1.1 mrg If REG != NULL_RTX, it is used as the target/scratch register in the 2796 1.1 mrg GOT address calculation. */ 2797 1.1 mrg void 2798 1.1 mrg nios2_adjust_call_address (rtx *call_op, rtx reg) 2799 1.1 mrg { 2800 1.1 mrg if (MEM_P (*call_op)) 2801 1.1 mrg call_op = &XEXP (*call_op, 0); 2802 1.1 mrg 2803 1.1 mrg rtx addr = *call_op; 2804 1.1 mrg if (flag_pic && CONSTANT_P (addr)) 2805 1.1 mrg { 2806 1.1 mrg rtx tmp = reg ? reg : NULL_RTX; 2807 1.1 mrg if (!reg) 2808 1.1 mrg reg = gen_reg_rtx (Pmode); 2809 1.1 mrg addr = nios2_load_pic_address (addr, UNSPEC_PIC_CALL_SYM, tmp); 2810 1.1 mrg emit_insn (gen_rtx_SET (reg, addr)); 2811 1.1 mrg *call_op = reg; 2812 1.1 mrg } 2813 1.1 mrg } 2814 1.1 mrg 2815 1.1 mrg 2816 1.1 mrg /* Output assembly language related definitions. */ 2818 1.1 mrg 2819 1.1 mrg /* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P. */ 2820 1.1 mrg static bool 2821 1.1 mrg nios2_print_operand_punct_valid_p (unsigned char code) 2822 1.1 mrg { 2823 1.1 mrg return (code == '.' || code == '!'); 2824 1.1 mrg } 2825 1.1 mrg 2826 1.1 mrg 2827 1.1 mrg /* Print the operand OP to file stream FILE modified by LETTER. 2828 1.1 mrg LETTER can be one of: 2829 1.1 mrg 2830 1.1 mrg i: print i/hi/ui suffixes (used for mov instruction variants), 2831 1.1 mrg when OP is the appropriate immediate operand. 2832 1.1 mrg 2833 1.1 mrg u: like 'i', except without "ui" suffix case (used for cmpgeu/cmpltu) 2834 1.1 mrg 2835 1.1 mrg o: print "io" if OP needs volatile access (due to TARGET_BYPASS_CACHE 2836 1.1 mrg or TARGET_BYPASS_CACHE_VOLATILE). 2837 1.1 mrg 2838 1.1 mrg x: print i/hi/ci/chi suffixes for the and instruction, 2839 1.1 mrg when OP is the appropriate immediate operand. 2840 1.1 mrg 2841 1.1 mrg z: prints the third register immediate operand in assembly 2842 1.1 mrg instructions. Outputs const0_rtx as the 'zero' register 2843 1.1 mrg instead of '0'. 2844 1.1 mrg 2845 1.1 mrg y: same as 'z', but for specifically for logical instructions, 2846 1.1 mrg where the processing for immediates are slightly different. 2847 1.1 mrg 2848 1.1 mrg H: for %hiadj 2849 1.1 mrg L: for %lo 2850 1.1 mrg D: for the upper 32-bits of a 64-bit double value 2851 1.1 mrg R: prints reverse condition. 2852 1.1 mrg A: prints (reg) operand for ld[s]ex and st[s]ex. 2853 1.1 mrg 2854 1.1 mrg .: print .n suffix for 16-bit instructions. 2855 1.1 mrg !: print r.n suffix for 16-bit instructions. Used for jmpr.n. 2856 1.1 mrg */ 2857 1.1 mrg static void 2858 1.1 mrg nios2_print_operand (FILE *file, rtx op, int letter) 2859 1.1 mrg { 2860 1.1 mrg 2861 1.1 mrg /* First take care of the format letters that just insert a string 2862 1.1 mrg into the output stream. */ 2863 1.1 mrg switch (letter) 2864 1.1 mrg { 2865 1.1 mrg case '.': 2866 1.1 mrg if (current_output_insn && get_attr_length (current_output_insn) == 2) 2867 1.1 mrg fprintf (file, ".n"); 2868 1.1 mrg return; 2869 1.1 mrg 2870 1.1 mrg case '!': 2871 1.1 mrg if (current_output_insn && get_attr_length (current_output_insn) == 2) 2872 1.1 mrg fprintf (file, "r.n"); 2873 1.1 mrg return; 2874 1.1 mrg 2875 1.1 mrg case 'x': 2876 1.1 mrg if (CONST_INT_P (op)) 2877 1.1 mrg { 2878 1.1 mrg HOST_WIDE_INT val = INTVAL (op); 2879 1.1 mrg HOST_WIDE_INT low = val & 0xffff; 2880 1.1 mrg HOST_WIDE_INT high = (val >> 16) & 0xffff; 2881 1.1 mrg 2882 1.1 mrg if (val != 0) 2883 1.1 mrg { 2884 1.1 mrg if (high != 0) 2885 1.1 mrg { 2886 1.1 mrg if (low != 0) 2887 1.1 mrg { 2888 1.1 mrg gcc_assert (TARGET_ARCH_R2); 2889 1.1 mrg if (high == 0xffff) 2890 1.1 mrg fprintf (file, "c"); 2891 1.1 mrg else if (low == 0xffff) 2892 1.1 mrg fprintf (file, "ch"); 2893 1.1 mrg else 2894 1.1 mrg gcc_unreachable (); 2895 1.1 mrg } 2896 1.1 mrg else 2897 1.1 mrg fprintf (file, "h"); 2898 1.1 mrg } 2899 1.1 mrg fprintf (file, "i"); 2900 1.1 mrg } 2901 1.1 mrg } 2902 1.1 mrg return; 2903 1.1 mrg 2904 1.1 mrg case 'u': 2905 1.1 mrg case 'i': 2906 1.1 mrg if (CONST_INT_P (op)) 2907 1.1 mrg { 2908 1.1 mrg HOST_WIDE_INT val = INTVAL (op); 2909 1.1 mrg HOST_WIDE_INT low = val & 0xffff; 2910 1.1 mrg HOST_WIDE_INT high = (val >> 16) & 0xffff; 2911 1.1 mrg if (val != 0) 2912 1.1 mrg { 2913 1.1 mrg if (low == 0 && high != 0) 2914 1.1 mrg fprintf (file, "h"); 2915 1.1 mrg else if (high == 0 && (low & 0x8000) != 0 && letter != 'u') 2916 1.1 mrg fprintf (file, "u"); 2917 1.1 mrg } 2918 1.1 mrg } 2919 1.1 mrg if (CONSTANT_P (op) && op != const0_rtx) 2920 1.1 mrg fprintf (file, "i"); 2921 1.1 mrg return; 2922 1.1 mrg 2923 1.1 mrg case 'o': 2924 1.1 mrg if (GET_CODE (op) == MEM 2925 1.1 mrg && ((MEM_VOLATILE_P (op) && TARGET_BYPASS_CACHE_VOLATILE) 2926 1.1 mrg || TARGET_BYPASS_CACHE)) 2927 1.1 mrg { 2928 1.1 mrg gcc_assert (current_output_insn 2929 1.1 mrg && get_attr_length (current_output_insn) == 4); 2930 1.1 mrg fprintf (file, "io"); 2931 1.1 mrg } 2932 1.1 mrg return; 2933 1.1 mrg 2934 1.1 mrg default: 2935 1.1 mrg break; 2936 1.1 mrg } 2937 1.1 mrg 2938 1.1 mrg /* Handle comparison operator names. */ 2939 1.1 mrg if (comparison_operator (op, VOIDmode)) 2940 1.1 mrg { 2941 1.1 mrg enum rtx_code cond = GET_CODE (op); 2942 1.1 mrg if (letter == 0) 2943 1.1 mrg { 2944 1.1 mrg fprintf (file, "%s", GET_RTX_NAME (cond)); 2945 1.1 mrg return; 2946 1.1 mrg } 2947 1.1 mrg if (letter == 'R') 2948 1.1 mrg { 2949 1.1 mrg fprintf (file, "%s", GET_RTX_NAME (reverse_condition (cond))); 2950 1.1 mrg return; 2951 1.1 mrg } 2952 1.1 mrg } 2953 1.1 mrg 2954 1.1 mrg /* Now handle the cases where we actually need to format an operand. */ 2955 1.1 mrg switch (GET_CODE (op)) 2956 1.1 mrg { 2957 1.1 mrg case REG: 2958 1.1 mrg if (letter == 0 || letter == 'z' || letter == 'y') 2959 1.1 mrg { 2960 1.1 mrg fprintf (file, "%s", reg_names[REGNO (op)]); 2961 1.1 mrg return; 2962 1.1 mrg } 2963 1.1 mrg else if (letter == 'D') 2964 1.1 mrg { 2965 1.1 mrg fprintf (file, "%s", reg_names[REGNO (op)+1]); 2966 1.1 mrg return; 2967 1.1 mrg } 2968 1.1 mrg break; 2969 1.1 mrg 2970 1.1 mrg case CONST_INT: 2971 1.1 mrg { 2972 1.1 mrg rtx int_rtx = op; 2973 1.1 mrg HOST_WIDE_INT val = INTVAL (int_rtx); 2974 1.1 mrg HOST_WIDE_INT low = val & 0xffff; 2975 1.1 mrg HOST_WIDE_INT high = (val >> 16) & 0xffff; 2976 1.1 mrg 2977 1.1 mrg if (letter == 'y') 2978 1.1 mrg { 2979 1.1 mrg if (val == 0) 2980 1.1 mrg fprintf (file, "zero"); 2981 1.1 mrg else 2982 1.1 mrg { 2983 1.1 mrg if (high != 0) 2984 1.1 mrg { 2985 1.1 mrg if (low != 0) 2986 1.1 mrg { 2987 1.1 mrg gcc_assert (TARGET_ARCH_R2); 2988 1.1 mrg if (high == 0xffff) 2989 1.1 mrg /* andci. */ 2990 1.1 mrg int_rtx = gen_int_mode (low, SImode); 2991 1.1 mrg else if (low == 0xffff) 2992 1.1 mrg /* andchi. */ 2993 1.1 mrg int_rtx = gen_int_mode (high, SImode); 2994 1.1 mrg else 2995 1.1 mrg gcc_unreachable (); 2996 1.1 mrg } 2997 1.1 mrg else 2998 1.1 mrg /* andhi. */ 2999 1.1 mrg int_rtx = gen_int_mode (high, SImode); 3000 1.1 mrg } 3001 1.1 mrg else 3002 1.1 mrg /* andi. */ 3003 1.1 mrg int_rtx = gen_int_mode (low, SImode); 3004 1.1 mrg output_addr_const (file, int_rtx); 3005 1.1 mrg } 3006 1.1 mrg return; 3007 1.1 mrg } 3008 1.1 mrg else if (letter == 'z') 3009 1.1 mrg { 3010 1.1 mrg if (val == 0) 3011 1.1 mrg fprintf (file, "zero"); 3012 1.1 mrg else 3013 1.1 mrg { 3014 1.1 mrg if (low == 0 && high != 0) 3015 1.1 mrg int_rtx = gen_int_mode (high, SImode); 3016 1.1 mrg else if (low != 0) 3017 1.1 mrg { 3018 1.1 mrg gcc_assert (high == 0 || high == 0xffff); 3019 1.1 mrg int_rtx = gen_int_mode (low, high == 0 ? SImode : HImode); 3020 1.1 mrg } 3021 1.1 mrg else 3022 1.1 mrg gcc_unreachable (); 3023 1.1 mrg output_addr_const (file, int_rtx); 3024 1.1 mrg } 3025 1.1 mrg return; 3026 1.1 mrg } 3027 1.1 mrg } 3028 1.1 mrg 3029 1.1 mrg /* Else, fall through. */ 3030 1.1 mrg 3031 1.1 mrg case CONST: 3032 1.1 mrg case LABEL_REF: 3033 1.1 mrg case SYMBOL_REF: 3034 1.1 mrg case CONST_DOUBLE: 3035 1.1 mrg if (letter == 0 || letter == 'z') 3036 1.1 mrg { 3037 1.1 mrg output_addr_const (file, op); 3038 1.1 mrg return; 3039 1.1 mrg } 3040 1.1 mrg else if (letter == 'H' || letter == 'L') 3041 1.1 mrg { 3042 1.1 mrg fprintf (file, "%%"); 3043 1.1 mrg if (GET_CODE (op) == CONST 3044 1.1 mrg && GET_CODE (XEXP (op, 0)) == UNSPEC) 3045 1.1 mrg { 3046 1.1 mrg rtx unspec = XEXP (op, 0); 3047 1.1 mrg int unspec_reloc = XINT (unspec, 1); 3048 1.1 mrg gcc_assert (nios2_large_offset_p (unspec_reloc)); 3049 1.1 mrg fprintf (file, "%s_", nios2_unspec_reloc_name (unspec_reloc)); 3050 1.1 mrg op = XVECEXP (unspec, 0, 0); 3051 1.1 mrg } 3052 1.1 mrg fprintf (file, letter == 'H' ? "hiadj(" : "lo("); 3053 1.1 mrg output_addr_const (file, op); 3054 1.1 mrg fprintf (file, ")"); 3055 1.1 mrg return; 3056 1.1 mrg } 3057 1.1 mrg break; 3058 1.1 mrg 3059 1.1 mrg case SUBREG: 3060 1.1 mrg case MEM: 3061 1.1 mrg if (letter == 'A') 3062 1.1 mrg { 3063 1.1 mrg /* Address of '(reg)' form, with no index. */ 3064 1.1 mrg fprintf (file, "(%s)", reg_names[REGNO (XEXP (op, 0))]); 3065 1.1 mrg return; 3066 1.1 mrg } 3067 1.1 mrg if (letter == 0) 3068 1.1 mrg { 3069 1.1 mrg output_address (VOIDmode, op); 3070 1.1 mrg return; 3071 1.1 mrg } 3072 1.1 mrg break; 3073 1.1 mrg 3074 1.1 mrg case CODE_LABEL: 3075 1.1 mrg if (letter == 0) 3076 1.1 mrg { 3077 1.1 mrg output_addr_const (file, op); 3078 1.1 mrg return; 3079 1.1 mrg } 3080 1.1 mrg break; 3081 1.1 mrg 3082 1.1 mrg default: 3083 1.1 mrg break; 3084 1.1 mrg } 3085 1.1 mrg 3086 1.1 mrg debug_rtx (op); 3087 1.1 mrg output_operand_lossage ("Unsupported operand for code '%c'", letter); 3088 1.1 mrg gcc_unreachable (); 3089 1.1 mrg } 3090 1.1 mrg 3091 1.1 mrg /* Return true if this is a GP-relative accessible reference. */ 3092 1.1 mrg bool 3093 1.1 mrg gprel_constant_p (rtx op) 3094 1.1 mrg { 3095 1.1 mrg if (GET_CODE (op) == SYMBOL_REF 3096 1.1 mrg && nios2_symbol_ref_in_small_data_p (op)) 3097 1.1 mrg return true; 3098 1.1 mrg else if (GET_CODE (op) == CONST 3099 1.1 mrg && GET_CODE (XEXP (op, 0)) == PLUS) 3100 1.1 mrg return gprel_constant_p (XEXP (XEXP (op, 0), 0)); 3101 1.1 mrg 3102 1.1 mrg return false; 3103 1.1 mrg } 3104 1.1 mrg 3105 1.1 mrg /* Likewise if this is a zero-relative accessible reference. */ 3106 1.1 mrg bool 3107 1.1 mrg r0rel_constant_p (rtx op) 3108 1.1 mrg { 3109 1.1 mrg if (GET_CODE (op) == SYMBOL_REF 3110 1.1 mrg && nios2_symbol_ref_in_r0rel_data_p (op)) 3111 1.1 mrg return true; 3112 1.1 mrg else if (GET_CODE (op) == CONST 3113 1.1 mrg && GET_CODE (XEXP (op, 0)) == PLUS) 3114 1.1 mrg return r0rel_constant_p (XEXP (XEXP (op, 0), 0)); 3115 1.1 mrg else if (GET_CODE (op) == CONST_INT 3116 1.1 mrg && SMALL_INT (INTVAL (op))) 3117 1.1 mrg return true; 3118 1.1 mrg 3119 1.1 mrg return false; 3120 1.1 mrg } 3121 1.1 mrg 3122 1.1 mrg /* Return the name string for a supported unspec reloc offset. */ 3123 1.1 mrg static const char * 3124 1.1 mrg nios2_unspec_reloc_name (int unspec) 3125 1.1 mrg { 3126 1.1 mrg switch (unspec) 3127 1.1 mrg { 3128 1.1 mrg case UNSPEC_PIC_SYM: 3129 1.1 mrg return "got"; 3130 1.1 mrg case UNSPEC_PIC_CALL_SYM: 3131 1.1 mrg return "call"; 3132 1.1 mrg case UNSPEC_PIC_GOTOFF_SYM: 3133 1.1 mrg return "gotoff"; 3134 1.1 mrg case UNSPEC_LOAD_TLS_IE: 3135 1.1 mrg return "tls_ie"; 3136 1.1 mrg case UNSPEC_ADD_TLS_LE: 3137 1.1 mrg return "tls_le"; 3138 1.1 mrg case UNSPEC_ADD_TLS_GD: 3139 1.1 mrg return "tls_gd"; 3140 1.1 mrg case UNSPEC_ADD_TLS_LDM: 3141 1.1 mrg return "tls_ldm"; 3142 1.1 mrg case UNSPEC_ADD_TLS_LDO: 3143 1.1 mrg return "tls_ldo"; 3144 1.1 mrg default: 3145 1.1 mrg return NULL; 3146 1.1 mrg } 3147 1.1 mrg } 3148 1.1 mrg 3149 1.1 mrg /* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */ 3150 1.1 mrg static bool 3151 1.1 mrg nios2_output_addr_const_extra (FILE *file, rtx op) 3152 1.1 mrg { 3153 1.1 mrg const char *name; 3154 1.1 mrg gcc_assert (GET_CODE (op) == UNSPEC); 3155 1.1 mrg 3156 1.1 mrg /* Support for printing out const unspec relocations. */ 3157 1.1 mrg name = nios2_unspec_reloc_name (XINT (op, 1)); 3158 1.1 mrg if (name) 3159 1.1 mrg { 3160 1.1 mrg fprintf (file, "%%%s(", name); 3161 1.1 mrg output_addr_const (file, XVECEXP (op, 0, 0)); 3162 1.1 mrg fprintf (file, ")"); 3163 1.1 mrg return true; 3164 1.1 mrg } 3165 1.1 mrg return false; 3166 1.1 mrg } 3167 1.1 mrg 3168 1.1 mrg /* Implement TARGET_PRINT_OPERAND_ADDRESS. */ 3169 1.1 mrg static void 3170 1.1 mrg nios2_print_operand_address (FILE *file, machine_mode mode, rtx op) 3171 1.1 mrg { 3172 1.1 mrg switch (GET_CODE (op)) 3173 1.1 mrg { 3174 1.1 mrg case CONST: 3175 1.1 mrg case CONST_INT: 3176 1.1 mrg case LABEL_REF: 3177 1.1 mrg case CONST_DOUBLE: 3178 1.1 mrg case SYMBOL_REF: 3179 1.1 mrg if (gprel_constant_p (op)) 3180 1.1 mrg { 3181 1.1 mrg fprintf (file, "%%gprel("); 3182 1.1 mrg output_addr_const (file, op); 3183 1.1 mrg fprintf (file, ")(%s)", reg_names[GP_REGNO]); 3184 1.1 mrg return; 3185 1.1 mrg } 3186 1.1 mrg else if (r0rel_constant_p (op)) 3187 1.1 mrg { 3188 1.1 mrg if (CONST_INT_P (op)) 3189 1.1 mrg { 3190 1.1 mrg output_addr_const (file, op); 3191 1.1 mrg fprintf (file, "(r0)"); 3192 1.1 mrg return; 3193 1.1 mrg } 3194 1.1 mrg else 3195 1.1 mrg { 3196 1.1 mrg fprintf (file, "%%lo("); 3197 1.1 mrg output_addr_const (file, op); 3198 1.1 mrg fprintf (file, ")(r0)"); 3199 1.1 mrg return; 3200 1.1 mrg } 3201 1.1 mrg } 3202 1.1 mrg break; 3203 1.1 mrg 3204 1.1 mrg case PLUS: 3205 1.1 mrg { 3206 1.1 mrg rtx op0 = XEXP (op, 0); 3207 1.1 mrg rtx op1 = XEXP (op, 1); 3208 1.1 mrg 3209 1.1 mrg if (REG_P (op0) && CONSTANT_P (op1)) 3210 1.1 mrg { 3211 1.1 mrg output_addr_const (file, op1); 3212 1.1 mrg fprintf (file, "(%s)", reg_names[REGNO (op0)]); 3213 1.1 mrg return; 3214 1.1 mrg } 3215 1.1 mrg else if (REG_P (op1) && CONSTANT_P (op0)) 3216 1.1 mrg { 3217 1.1 mrg output_addr_const (file, op0); 3218 1.1 mrg fprintf (file, "(%s)", reg_names[REGNO (op1)]); 3219 1.1 mrg return; 3220 1.1 mrg } 3221 1.1 mrg } 3222 1.1 mrg break; 3223 1.1 mrg 3224 1.1 mrg case LO_SUM: 3225 1.1 mrg { 3226 1.1 mrg rtx op0 = XEXP (op, 0); 3227 1.1 mrg rtx op1 = XEXP (op, 1); 3228 1.1 mrg 3229 1.1 mrg if (REG_P (op0) && CONSTANT_P (op1)) 3230 1.1 mrg { 3231 1.1 mrg nios2_print_operand (file, op1, 'L'); 3232 1.1 mrg fprintf (file, "(%s)", reg_names[REGNO (op0)]); 3233 1.1 mrg return; 3234 1.1 mrg } 3235 1.1 mrg } 3236 1.1 mrg break; 3237 1.1 mrg 3238 1.1 mrg case REG: 3239 1.1 mrg fprintf (file, "0(%s)", reg_names[REGNO (op)]); 3240 1.1 mrg return; 3241 1.1 mrg 3242 1.1 mrg case MEM: 3243 1.1 mrg { 3244 1.1 mrg rtx base = XEXP (op, 0); 3245 1.1 mrg nios2_print_operand_address (file, mode, base); 3246 1.1 mrg return; 3247 1.1 mrg } 3248 1.1 mrg default: 3249 1.1 mrg break; 3250 1.1 mrg } 3251 1.1 mrg 3252 1.1 mrg fprintf (stderr, "Missing way to print address\n"); 3253 1.1 mrg debug_rtx (op); 3254 1.1 mrg gcc_unreachable (); 3255 1.1 mrg } 3256 1.1 mrg 3257 1.1 mrg /* Implement TARGET_ASM_OUTPUT_DWARF_DTPREL. */ 3258 1.1 mrg static void 3259 1.1 mrg nios2_output_dwarf_dtprel (FILE *file, int size, rtx x) 3260 1.1 mrg { 3261 1.1 mrg gcc_assert (size == 4); 3262 1.1 mrg fprintf (file, "\t.4byte\t%%tls_ldo("); 3263 1.1 mrg output_addr_const (file, x); 3264 1.1 mrg fprintf (file, ")"); 3265 1.1 mrg } 3266 1.1 mrg 3267 1.1 mrg /* Implemet TARGET_ASM_FILE_END. */ 3268 1.1 mrg 3269 1.1 mrg static void 3270 1.1 mrg nios2_asm_file_end (void) 3271 1.1 mrg { 3272 1.1 mrg /* The Nios II Linux stack is mapped non-executable by default, so add a 3273 1.1 mrg .note.GNU-stack section for switching to executable stacks only when 3274 1.1 mrg trampolines are generated. */ 3275 1.1 mrg if (TARGET_LINUX_ABI && trampolines_created) 3276 1.1 mrg file_end_indicate_exec_stack (); 3277 1.1 mrg } 3278 1.1 mrg 3279 1.1 mrg /* Implement TARGET_ASM_FUNCTION_PROLOGUE. */ 3280 1.1 mrg static void 3281 1.1 mrg nios2_asm_function_prologue (FILE *file) 3282 1.1 mrg { 3283 1.1 mrg if (flag_verbose_asm || flag_debug_asm) 3284 1.1 mrg { 3285 1.1 mrg nios2_compute_frame_layout (); 3286 1.1 mrg nios2_dump_frame_layout (file); 3287 1.1 mrg } 3288 1.1 mrg } 3289 1.1 mrg 3290 1.1 mrg /* Emit assembly of custom FPU instructions. */ 3291 1.1 mrg const char * 3292 1.1 mrg nios2_fpu_insn_asm (enum n2fpu_code code) 3293 1.1 mrg { 3294 1.1 mrg static char buf[256]; 3295 1.1 mrg const char *op1, *op2, *op3; 3296 1.1 mrg int ln = 256, n = 0; 3297 1.1 mrg 3298 1.1 mrg int N = N2FPU_N (code); 3299 1.1 mrg int num_operands = N2FPU (code).num_operands; 3300 1.1 mrg const char *insn_name = N2FPU_NAME (code); 3301 1.1 mrg tree ftype = nios2_ftype (N2FPU_FTCODE (code)); 3302 1.1 mrg machine_mode dst_mode = TYPE_MODE (TREE_TYPE (ftype)); 3303 1.1 mrg machine_mode src_mode = TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (ftype))); 3304 1.1 mrg 3305 1.1 mrg /* Prepare X register for DF input operands. */ 3306 1.1 mrg if (GET_MODE_SIZE (src_mode) == 8 && num_operands == 3) 3307 1.1 mrg n = snprintf (buf, ln, "custom\t%d, zero, %%1, %%D1 # fwrx %%1\n\t", 3308 1.1 mrg N2FPU_N (n2fpu_fwrx)); 3309 1.1 mrg 3310 1.1 mrg if (src_mode == SFmode) 3311 1.1 mrg { 3312 1.1 mrg if (dst_mode == VOIDmode) 3313 1.1 mrg { 3314 1.1 mrg /* The fwry case. */ 3315 1.1 mrg op1 = op3 = "zero"; 3316 1.1 mrg op2 = "%0"; 3317 1.1 mrg num_operands -= 1; 3318 1.1 mrg } 3319 1.1 mrg else 3320 1.1 mrg { 3321 1.1 mrg op1 = (dst_mode == DFmode ? "%D0" : "%0"); 3322 1.1 mrg op2 = "%1"; 3323 1.1 mrg op3 = (num_operands == 2 ? "zero" : "%2"); 3324 1.1 mrg } 3325 1.1 mrg } 3326 1.1 mrg else if (src_mode == DFmode) 3327 1.1 mrg { 3328 1.1 mrg if (dst_mode == VOIDmode) 3329 1.1 mrg { 3330 1.1 mrg /* The fwrx case. */ 3331 1.1 mrg op1 = "zero"; 3332 1.1 mrg op2 = "%0"; 3333 1.1 mrg op3 = "%D0"; 3334 1.1 mrg num_operands -= 1; 3335 1.1 mrg } 3336 1.1 mrg else 3337 1.1 mrg { 3338 1.1 mrg op1 = (dst_mode == DFmode ? "%D0" : "%0"); 3339 1.1 mrg op2 = (num_operands == 2 ? "%1" : "%2"); 3340 1.1 mrg op3 = (num_operands == 2 ? "%D1" : "%D2"); 3341 1.1 mrg } 3342 1.1 mrg } 3343 1.1 mrg else if (src_mode == VOIDmode) 3344 1.1 mrg { 3345 1.1 mrg /* frdxlo, frdxhi, frdy cases. */ 3346 1.1 mrg gcc_assert (dst_mode == SFmode); 3347 1.1 mrg op1 = "%0"; 3348 1.1 mrg op2 = op3 = "zero"; 3349 1.1 mrg } 3350 1.1 mrg else if (src_mode == SImode) 3351 1.1 mrg { 3352 1.1 mrg /* Conversion operators. */ 3353 1.1 mrg gcc_assert (num_operands == 2); 3354 1.1 mrg op1 = (dst_mode == DFmode ? "%D0" : "%0"); 3355 1.1 mrg op2 = "%1"; 3356 1.1 mrg op3 = "zero"; 3357 1.1 mrg } 3358 1.1 mrg else 3359 1.1 mrg gcc_unreachable (); 3360 1.1 mrg 3361 1.1 mrg /* Main instruction string. */ 3362 1.1 mrg n += snprintf (buf + n, ln - n, "custom\t%d, %s, %s, %s # %s %%0%s%s", 3363 1.1 mrg N, op1, op2, op3, insn_name, 3364 1.1 mrg (num_operands >= 2 ? ", %1" : ""), 3365 1.1 mrg (num_operands == 3 ? ", %2" : "")); 3366 1.1 mrg 3367 1.1 mrg /* Extraction of Y register for DF results. */ 3368 1.1 mrg if (dst_mode == DFmode) 3369 1.1 mrg snprintf (buf + n, ln - n, "\n\tcustom\t%d, %%0, zero, zero # frdy %%0", 3370 1.1 mrg N2FPU_N (n2fpu_frdy)); 3371 1.1 mrg return buf; 3372 1.1 mrg } 3373 1.1 mrg 3374 1.1 mrg 3375 1.1 mrg 3377 1.1 mrg /* Function argument related. */ 3378 1.1 mrg 3379 1.1 mrg /* Define where to put the arguments to a function. Value is zero to 3380 1.1 mrg push the argument on the stack, or a hard register in which to 3381 1.1 mrg store the argument. 3382 1.1 mrg 3383 1.1 mrg CUM is a variable of type CUMULATIVE_ARGS which gives info about 3384 1.1 mrg the preceding args and about the function being called. 3385 1.1 mrg ARG is a description of the argument. */ 3386 1.1 mrg 3387 1.1 mrg static rtx 3388 1.1 mrg nios2_function_arg (cumulative_args_t cum_v, const function_arg_info &arg) 3389 1.1 mrg { 3390 1.1 mrg CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 3391 1.1 mrg rtx return_rtx = NULL_RTX; 3392 1.1 mrg 3393 1.1 mrg if (cum->regs_used < NUM_ARG_REGS) 3394 1.1 mrg return_rtx = gen_rtx_REG (arg.mode, FIRST_ARG_REGNO + cum->regs_used); 3395 1.1 mrg 3396 1.1 mrg return return_rtx; 3397 1.1 mrg } 3398 1.1 mrg 3399 1.1 mrg /* Return number of bytes, at the beginning of the argument, that must be 3400 1.1 mrg put in registers. 0 is the argument is entirely in registers or entirely 3401 1.1 mrg in memory. */ 3402 1.1 mrg 3403 1.1 mrg static int 3404 1.1 mrg nios2_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg) 3405 1.1 mrg { 3406 1.1 mrg CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 3407 1.1 mrg HOST_WIDE_INT param_size = arg.promoted_size_in_bytes (); 3408 1.1 mrg gcc_assert (param_size >= 0); 3409 1.1 mrg 3410 1.1 mrg /* Convert to words (round up). */ 3411 1.1 mrg param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD; 3412 1.1 mrg 3413 1.1 mrg if (cum->regs_used < NUM_ARG_REGS 3414 1.1 mrg && cum->regs_used + param_size > NUM_ARG_REGS) 3415 1.1 mrg return (NUM_ARG_REGS - cum->regs_used) * UNITS_PER_WORD; 3416 1.1 mrg 3417 1.1 mrg return 0; 3418 1.1 mrg } 3419 1.1 mrg 3420 1.1 mrg /* Update the data in CUM to advance over argument ARG. */ 3421 1.1 mrg 3422 1.1 mrg static void 3423 1.1 mrg nios2_function_arg_advance (cumulative_args_t cum_v, 3424 1.1 mrg const function_arg_info &arg) 3425 1.1 mrg { 3426 1.1 mrg CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 3427 1.1 mrg HOST_WIDE_INT param_size = arg.promoted_size_in_bytes (); 3428 1.1 mrg gcc_assert (param_size >= 0); 3429 1.1 mrg 3430 1.1 mrg /* Convert to words (round up). */ 3431 1.1 mrg param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD; 3432 1.1 mrg 3433 1.1 mrg if (cum->regs_used + param_size > NUM_ARG_REGS) 3434 1.1 mrg cum->regs_used = NUM_ARG_REGS; 3435 1.1 mrg else 3436 1.1 mrg cum->regs_used += param_size; 3437 1.1 mrg } 3438 1.1 mrg 3439 1.1 mrg static pad_direction 3440 1.1 mrg nios2_function_arg_padding (machine_mode mode, const_tree type) 3441 1.1 mrg { 3442 1.1 mrg /* On little-endian targets, the first byte of every stack argument 3443 1.1 mrg is passed in the first byte of the stack slot. */ 3444 1.1 mrg if (!BYTES_BIG_ENDIAN) 3445 1.1 mrg return PAD_UPWARD; 3446 1.1 mrg 3447 1.1 mrg /* Otherwise, integral types are padded downward: the last byte of a 3448 1.1 mrg stack argument is passed in the last byte of the stack slot. */ 3449 1.1 mrg if (type != 0 3450 1.1 mrg ? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type) 3451 1.1 mrg : GET_MODE_CLASS (mode) == MODE_INT) 3452 1.1 mrg return PAD_DOWNWARD; 3453 1.1 mrg 3454 1.1 mrg /* Arguments smaller than a stack slot are padded downward. */ 3455 1.1 mrg if (mode != BLKmode) 3456 1.1 mrg return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY 3457 1.1 mrg ? PAD_UPWARD : PAD_DOWNWARD); 3458 1.1 mrg 3459 1.1 mrg return ((int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT)) 3460 1.1 mrg ? PAD_UPWARD : PAD_DOWNWARD); 3461 1.1 mrg } 3462 1.1 mrg 3463 1.1 mrg pad_direction 3464 1.1 mrg nios2_block_reg_padding (machine_mode mode, tree type, 3465 1.1 mrg int first ATTRIBUTE_UNUSED) 3466 1.1 mrg { 3467 1.1 mrg return nios2_function_arg_padding (mode, type); 3468 1.1 mrg } 3469 1.1 mrg 3470 1.1 mrg /* Emit RTL insns to initialize the variable parts of a trampoline. 3471 1.1 mrg FNADDR is an RTX for the address of the function's pure code. 3472 1.1 mrg CXT is an RTX for the static chain value for the function. 3473 1.1 mrg On Nios II, we handle this by a library call. */ 3474 1.1 mrg static void 3475 1.1 mrg nios2_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt) 3476 1.1 mrg { 3477 1.1 mrg rtx fnaddr = XEXP (DECL_RTL (fndecl), 0); 3478 1.1 mrg rtx ctx_reg = force_reg (Pmode, cxt); 3479 1.1 mrg rtx addr = force_reg (Pmode, XEXP (m_tramp, 0)); 3480 1.1 mrg 3481 1.1 mrg emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"), 3482 1.1 mrg LCT_NORMAL, VOIDmode, addr, Pmode, fnaddr, Pmode, 3483 1.1 mrg ctx_reg, Pmode); 3484 1.1 mrg } 3485 1.1 mrg 3486 1.1 mrg /* Implement TARGET_FUNCTION_VALUE. */ 3487 1.1 mrg static rtx 3488 1.1 mrg nios2_function_value (const_tree ret_type, const_tree fn ATTRIBUTE_UNUSED, 3489 1.1 mrg bool outgoing ATTRIBUTE_UNUSED) 3490 1.1 mrg { 3491 1.1 mrg return gen_rtx_REG (TYPE_MODE (ret_type), FIRST_RETVAL_REGNO); 3492 1.1 mrg } 3493 1.1 mrg 3494 1.1 mrg /* Implement TARGET_LIBCALL_VALUE. */ 3495 1.1 mrg static rtx 3496 1.1 mrg nios2_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED) 3497 1.1 mrg { 3498 1.1 mrg return gen_rtx_REG (mode, FIRST_RETVAL_REGNO); 3499 1.1 mrg } 3500 1.1 mrg 3501 1.1 mrg /* Implement TARGET_FUNCTION_VALUE_REGNO_P. */ 3502 1.1 mrg static bool 3503 1.1 mrg nios2_function_value_regno_p (const unsigned int regno) 3504 1.1 mrg { 3505 1.1 mrg return regno == FIRST_RETVAL_REGNO; 3506 1.1 mrg } 3507 1.1 mrg 3508 1.1 mrg /* Implement TARGET_RETURN_IN_MEMORY. */ 3509 1.1 mrg static bool 3510 1.1 mrg nios2_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) 3511 1.1 mrg { 3512 1.1 mrg return (int_size_in_bytes (type) > (2 * UNITS_PER_WORD) 3513 1.1 mrg || int_size_in_bytes (type) == -1); 3514 1.1 mrg } 3515 1.1 mrg 3516 1.1 mrg /* TODO: It may be possible to eliminate the copyback and implement 3517 1.1 mrg own va_arg type. */ 3518 1.1 mrg static void 3519 1.1 mrg nios2_setup_incoming_varargs (cumulative_args_t cum_v, 3520 1.1 mrg const function_arg_info &arg, 3521 1.1 mrg int *pretend_size, int second_time) 3522 1.1 mrg { 3523 1.1 mrg CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 3524 1.1 mrg CUMULATIVE_ARGS local_cum; 3525 1.1 mrg cumulative_args_t local_cum_v = pack_cumulative_args (&local_cum); 3526 1.1 mrg int regs_to_push; 3527 1.1 mrg int pret_size; 3528 1.1 mrg 3529 1.1 mrg cfun->machine->uses_anonymous_args = 1; 3530 1.1 mrg local_cum = *cum; 3531 1.1 mrg nios2_function_arg_advance (local_cum_v, arg); 3532 1.1 mrg 3533 1.1 mrg regs_to_push = NUM_ARG_REGS - local_cum.regs_used; 3534 1.1 mrg 3535 1.1 mrg /* If we can use CDX stwm to push the arguments on the stack, 3536 1.1 mrg nios2_expand_prologue will do that instead. */ 3537 1.1 mrg if (!TARGET_HAS_CDX && !second_time && regs_to_push > 0) 3538 1.1 mrg { 3539 1.1 mrg rtx ptr = virtual_incoming_args_rtx; 3540 1.1 mrg rtx mem = gen_rtx_MEM (BLKmode, ptr); 3541 1.1 mrg emit_insn (gen_blockage ()); 3542 1.1 mrg move_block_from_reg (local_cum.regs_used + FIRST_ARG_REGNO, mem, 3543 1.1 mrg regs_to_push); 3544 1.1 mrg emit_insn (gen_blockage ()); 3545 1.1 mrg } 3546 1.1 mrg 3547 1.1 mrg pret_size = regs_to_push * UNITS_PER_WORD; 3548 1.1 mrg if (pret_size) 3549 1.1 mrg *pretend_size = pret_size; 3550 1.1 mrg } 3551 1.1 mrg 3552 1.1 mrg 3553 1.1 mrg 3555 1.1 mrg /* Init FPU builtins. */ 3556 1.1 mrg static void 3557 1.1 mrg nios2_init_fpu_builtins (int start_code) 3558 1.1 mrg { 3559 1.1 mrg tree fndecl; 3560 1.1 mrg char builtin_name[64] = "__builtin_custom_"; 3561 1.1 mrg unsigned int i, n = strlen ("__builtin_custom_"); 3562 1.1 mrg 3563 1.1 mrg for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++) 3564 1.1 mrg { 3565 1.1 mrg snprintf (builtin_name + n, sizeof (builtin_name) - n, 3566 1.1 mrg "%s", N2FPU_NAME (i)); 3567 1.1 mrg fndecl = 3568 1.1 mrg add_builtin_function (builtin_name, nios2_ftype (N2FPU_FTCODE (i)), 3569 1.1 mrg start_code + i, BUILT_IN_MD, NULL, NULL_TREE); 3570 1.1 mrg nios2_register_builtin_fndecl (start_code + i, fndecl); 3571 1.1 mrg } 3572 1.1 mrg } 3573 1.1 mrg 3574 1.1 mrg /* Helper function for expanding FPU builtins. */ 3575 1.1 mrg static rtx 3576 1.1 mrg nios2_expand_fpu_builtin (tree exp, unsigned int code, rtx target) 3577 1.1 mrg { 3578 1.1 mrg struct expand_operand ops[MAX_RECOG_OPERANDS]; 3579 1.1 mrg enum insn_code icode = N2FPU_ICODE (code); 3580 1.1 mrg int nargs, argno, opno = 0; 3581 1.1 mrg int num_operands = N2FPU (code).num_operands; 3582 1.1 mrg machine_mode dst_mode = TYPE_MODE (TREE_TYPE (exp)); 3583 1.1 mrg bool has_target_p = (dst_mode != VOIDmode); 3584 1.1 mrg 3585 1.1 mrg if (N2FPU_N (code) < 0) 3586 1.1 mrg fatal_error (input_location, 3587 1.1 mrg "cannot call %<__builtin_custom_%s%> without specifying " 3588 1.1 mrg "switch %<-mcustom-%s%>", 3589 1.1 mrg N2FPU_NAME (code), N2FPU_NAME (code)); 3590 1.1 mrg if (has_target_p) 3591 1.1 mrg create_output_operand (&ops[opno++], target, dst_mode); 3592 1.1 mrg else 3593 1.1 mrg /* Subtract away the count of the VOID return, mainly for fwrx/fwry. */ 3594 1.1 mrg num_operands -= 1; 3595 1.1 mrg nargs = call_expr_nargs (exp); 3596 1.1 mrg for (argno = 0; argno < nargs; argno++) 3597 1.1 mrg { 3598 1.1 mrg tree arg = CALL_EXPR_ARG (exp, argno); 3599 1.1 mrg create_input_operand (&ops[opno++], expand_normal (arg), 3600 1.1 mrg TYPE_MODE (TREE_TYPE (arg))); 3601 1.1 mrg } 3602 1.1 mrg if (!maybe_expand_insn (icode, num_operands, ops)) 3603 1.1 mrg { 3604 1.1 mrg error ("invalid argument to built-in function"); 3605 1.1 mrg return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx; 3606 1.1 mrg } 3607 1.1 mrg return has_target_p ? ops[0].value : const0_rtx; 3608 1.1 mrg } 3609 1.1 mrg 3610 1.1 mrg /* Nios II has custom instruction built-in functions of the forms: 3611 1.1 mrg __builtin_custom_n 3612 1.1 mrg __builtin_custom_nX 3613 1.1 mrg __builtin_custom_nXX 3614 1.1 mrg __builtin_custom_Xn 3615 1.1 mrg __builtin_custom_XnX 3616 1.1 mrg __builtin_custom_XnXX 3617 1.1 mrg 3618 1.1 mrg where each X could be either 'i' (int), 'f' (float), or 'p' (void*). 3619 1.1 mrg Therefore with 0-1 return values, and 0-2 arguments, we have a 3620 1.1 mrg total of (3 + 1) * (1 + 3 + 9) == 52 custom builtin functions. 3621 1.1 mrg */ 3622 1.1 mrg #define NUM_CUSTOM_BUILTINS ((3 + 1) * (1 + 3 + 9)) 3623 1.1 mrg static char custom_builtin_name[NUM_CUSTOM_BUILTINS][5]; 3624 1.1 mrg 3625 1.1 mrg static void 3626 1.1 mrg nios2_init_custom_builtins (int start_code) 3627 1.1 mrg { 3628 1.1 mrg tree builtin_ftype, ret_type, fndecl; 3629 1.1 mrg char builtin_name[32] = "__builtin_custom_"; 3630 1.1 mrg int n = strlen ("__builtin_custom_"); 3631 1.1 mrg int builtin_code = 0; 3632 1.1 mrg int lhs, rhs1, rhs2; 3633 1.1 mrg 3634 1.1 mrg struct { tree type; const char *c; } op[4]; 3635 1.1 mrg /* z */ op[0].c = ""; op[0].type = NULL_TREE; 3636 1.1 mrg /* f */ op[1].c = "f"; op[1].type = float_type_node; 3637 1.1 mrg /* i */ op[2].c = "i"; op[2].type = integer_type_node; 3638 1.1 mrg /* p */ op[3].c = "p"; op[3].type = ptr_type_node; 3639 1.1 mrg 3640 1.1 mrg /* We enumerate through the possible operand types to create all the 3641 1.1 mrg __builtin_custom_XnXX function tree types. Note that these may slightly 3642 1.1 mrg overlap with the function types created for other fixed builtins. */ 3643 1.1 mrg 3644 1.1 mrg for (lhs = 0; lhs < 4; lhs++) 3645 1.1 mrg for (rhs1 = 0; rhs1 < 4; rhs1++) 3646 1.1 mrg for (rhs2 = 0; rhs2 < 4; rhs2++) 3647 1.1 mrg { 3648 1.1 mrg if (rhs1 == 0 && rhs2 != 0) 3649 1.1 mrg continue; 3650 1.1 mrg ret_type = (op[lhs].type ? op[lhs].type : void_type_node); 3651 1.1 mrg builtin_ftype 3652 1.1 mrg = build_function_type_list (ret_type, integer_type_node, 3653 1.1 mrg op[rhs1].type, op[rhs2].type, 3654 1.1 mrg NULL_TREE); 3655 1.1 mrg /* Save copy of parameter string into custom_builtin_name[]. */ 3656 1.1 mrg snprintf (custom_builtin_name[builtin_code], 5, "%sn%s%s", 3657 1.1 mrg op[lhs].c, op[rhs1].c, op[rhs2].c); 3658 1.1 mrg strncpy (builtin_name + n, custom_builtin_name[builtin_code], 5); 3659 1.1 mrg fndecl = 3660 1.1 mrg add_builtin_function (builtin_name, builtin_ftype, 3661 1.1 mrg start_code + builtin_code, 3662 1.1 mrg BUILT_IN_MD, NULL, NULL_TREE); 3663 1.1 mrg nios2_register_builtin_fndecl (start_code + builtin_code, fndecl); 3664 1.1 mrg builtin_code += 1; 3665 1.1 mrg } 3666 1.1 mrg } 3667 1.1 mrg 3668 1.1 mrg /* Helper function for expanding custom builtins. */ 3669 1.1 mrg static rtx 3670 1.1 mrg nios2_expand_custom_builtin (tree exp, unsigned int index, rtx target) 3671 1.1 mrg { 3672 1.1 mrg bool has_target_p = (TREE_TYPE (exp) != void_type_node); 3673 1.1 mrg machine_mode tmode = VOIDmode; 3674 1.1 mrg int nargs, argno; 3675 1.1 mrg rtx value, insn, unspec_args[3]; 3676 1.1 mrg tree arg; 3677 1.1 mrg 3678 1.1 mrg /* XnXX form. */ 3679 1.1 mrg if (has_target_p) 3680 1.1 mrg { 3681 1.1 mrg tmode = TYPE_MODE (TREE_TYPE (exp)); 3682 1.1 mrg if (!target || GET_MODE (target) != tmode 3683 1.1 mrg || !REG_P (target)) 3684 1.1 mrg target = gen_reg_rtx (tmode); 3685 1.1 mrg } 3686 1.1 mrg 3687 1.1 mrg nargs = call_expr_nargs (exp); 3688 1.1 mrg for (argno = 0; argno < nargs; argno++) 3689 1.1 mrg { 3690 1.1 mrg arg = CALL_EXPR_ARG (exp, argno); 3691 1.1 mrg value = expand_normal (arg); 3692 1.1 mrg unspec_args[argno] = value; 3693 1.1 mrg if (argno == 0) 3694 1.1 mrg { 3695 1.1 mrg if (!custom_insn_opcode (value, VOIDmode)) 3696 1.1 mrg error ("custom instruction opcode must be a compile-time " 3697 1.1 mrg "constant in the range 0-255 for %<__builtin_custom_%s%>", 3698 1.1 mrg custom_builtin_name[index]); 3699 1.1 mrg } 3700 1.1 mrg else 3701 1.1 mrg /* For other arguments, force into a register. */ 3702 1.1 mrg unspec_args[argno] = force_reg (TYPE_MODE (TREE_TYPE (arg)), 3703 1.1 mrg unspec_args[argno]); 3704 1.1 mrg } 3705 1.1 mrg /* Fill remaining unspec operands with zero. */ 3706 1.1 mrg for (; argno < 3; argno++) 3707 1.1 mrg unspec_args[argno] = const0_rtx; 3708 1.1 mrg 3709 1.1 mrg insn = (has_target_p 3710 1.1 mrg ? gen_rtx_SET (target, 3711 1.1 mrg gen_rtx_UNSPEC_VOLATILE (tmode, 3712 1.1 mrg gen_rtvec_v (3, unspec_args), 3713 1.1 mrg UNSPECV_CUSTOM_XNXX)) 3714 1.1 mrg : gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec_v (3, unspec_args), 3715 1.1 mrg UNSPECV_CUSTOM_NXX)); 3716 1.1 mrg emit_insn (insn); 3717 1.1 mrg return has_target_p ? target : const0_rtx; 3718 1.1 mrg } 3719 1.1 mrg 3720 1.1 mrg 3721 1.1 mrg 3722 1.1 mrg 3724 1.1 mrg /* Main definition of built-in functions. Nios II has a small number of fixed 3725 1.1 mrg builtins, plus a large number of FPU insn builtins, and builtins for 3726 1.1 mrg generating custom instructions. */ 3727 1.1 mrg 3728 1.1 mrg struct nios2_builtin_desc 3729 1.1 mrg { 3730 1.1 mrg enum insn_code icode; 3731 1.1 mrg enum nios2_arch_type arch; 3732 1.1 mrg enum nios2_ftcode ftype; 3733 1.1 mrg const char *name; 3734 1.1 mrg }; 3735 1.1 mrg 3736 1.1 mrg #define N2_BUILTINS \ 3737 1.1 mrg N2_BUILTIN_DEF (sync, R1, N2_FTYPE_VOID_VOID) \ 3738 1.1 mrg N2_BUILTIN_DEF (ldbio, R1, N2_FTYPE_SI_CVPTR) \ 3739 1.1 mrg N2_BUILTIN_DEF (ldbuio, R1, N2_FTYPE_UI_CVPTR) \ 3740 1.1 mrg N2_BUILTIN_DEF (ldhio, R1, N2_FTYPE_SI_CVPTR) \ 3741 1.1 mrg N2_BUILTIN_DEF (ldhuio, R1, N2_FTYPE_UI_CVPTR) \ 3742 1.1 mrg N2_BUILTIN_DEF (ldwio, R1, N2_FTYPE_SI_CVPTR) \ 3743 1.1 mrg N2_BUILTIN_DEF (stbio, R1, N2_FTYPE_VOID_VPTR_SI) \ 3744 1.1 mrg N2_BUILTIN_DEF (sthio, R1, N2_FTYPE_VOID_VPTR_SI) \ 3745 1.1 mrg N2_BUILTIN_DEF (stwio, R1, N2_FTYPE_VOID_VPTR_SI) \ 3746 1.1 mrg N2_BUILTIN_DEF (rdctl, R1, N2_FTYPE_SI_SI) \ 3747 1.1 mrg N2_BUILTIN_DEF (wrctl, R1, N2_FTYPE_VOID_SI_SI) \ 3748 1.1 mrg N2_BUILTIN_DEF (rdprs, R1, N2_FTYPE_SI_SI_SI) \ 3749 1.1 mrg N2_BUILTIN_DEF (flushd, R1, N2_FTYPE_VOID_VPTR) \ 3750 1.1 mrg N2_BUILTIN_DEF (flushda, R1, N2_FTYPE_VOID_VPTR) \ 3751 1.1 mrg N2_BUILTIN_DEF (wrpie, R2, N2_FTYPE_SI_SI) \ 3752 1.1 mrg N2_BUILTIN_DEF (eni, R2, N2_FTYPE_VOID_SI) \ 3753 1.1 mrg N2_BUILTIN_DEF (ldex, R2, N2_FTYPE_SI_CVPTR) \ 3754 1.1 mrg N2_BUILTIN_DEF (ldsex, R2, N2_FTYPE_SI_CVPTR) \ 3755 1.1 mrg N2_BUILTIN_DEF (stex, R2, N2_FTYPE_SI_VPTR_SI) \ 3756 1.1 mrg N2_BUILTIN_DEF (stsex, R2, N2_FTYPE_SI_VPTR_SI) 3757 1.1 mrg 3758 1.1 mrg enum nios2_builtin_code { 3759 1.1 mrg #define N2_BUILTIN_DEF(name, arch, ftype) NIOS2_BUILTIN_ ## name, 3760 1.1 mrg N2_BUILTINS 3761 1.1 mrg #undef N2_BUILTIN_DEF 3762 1.1 mrg NUM_FIXED_NIOS2_BUILTINS 3763 1.1 mrg }; 3764 1.1 mrg 3765 1.1 mrg static const struct nios2_builtin_desc nios2_builtins[] = { 3766 1.1 mrg #define N2_BUILTIN_DEF(name, arch, ftype) \ 3767 1.1 mrg { CODE_FOR_ ## name, ARCH_ ## arch, ftype, "__builtin_" #name }, 3768 1.1 mrg N2_BUILTINS 3769 1.1 mrg #undef N2_BUILTIN_DEF 3770 1.1 mrg }; 3771 1.1 mrg 3772 1.1 mrg /* Start/ends of FPU/custom insn builtin index ranges. */ 3773 1.1 mrg static unsigned int nios2_fpu_builtin_base; 3774 1.1 mrg static unsigned int nios2_custom_builtin_base; 3775 1.1 mrg static unsigned int nios2_custom_builtin_end; 3776 1.1 mrg 3777 1.1 mrg /* Implement TARGET_INIT_BUILTINS. */ 3778 1.1 mrg static void 3779 1.1 mrg nios2_init_builtins (void) 3780 1.1 mrg { 3781 1.1 mrg unsigned int i; 3782 1.1 mrg 3783 1.1 mrg /* Initialize fixed builtins. */ 3784 1.1 mrg for (i = 0; i < ARRAY_SIZE (nios2_builtins); i++) 3785 1.1 mrg { 3786 1.1 mrg const struct nios2_builtin_desc *d = &nios2_builtins[i]; 3787 1.1 mrg tree fndecl = 3788 1.1 mrg add_builtin_function (d->name, nios2_ftype (d->ftype), i, 3789 1.1 mrg BUILT_IN_MD, NULL, NULL); 3790 1.1 mrg nios2_register_builtin_fndecl (i, fndecl); 3791 1.1 mrg } 3792 1.1 mrg 3793 1.1 mrg /* Initialize FPU builtins. */ 3794 1.1 mrg nios2_fpu_builtin_base = ARRAY_SIZE (nios2_builtins); 3795 1.1 mrg nios2_init_fpu_builtins (nios2_fpu_builtin_base); 3796 1.1 mrg 3797 1.1 mrg /* Initialize custom insn builtins. */ 3798 1.1 mrg nios2_custom_builtin_base 3799 1.1 mrg = nios2_fpu_builtin_base + ARRAY_SIZE (nios2_fpu_insn); 3800 1.1 mrg nios2_custom_builtin_end 3801 1.1 mrg = nios2_custom_builtin_base + NUM_CUSTOM_BUILTINS; 3802 1.1 mrg nios2_init_custom_builtins (nios2_custom_builtin_base); 3803 1.1 mrg } 3804 1.1 mrg 3805 1.1 mrg /* Array of fndecls for TARGET_BUILTIN_DECL. */ 3806 1.1 mrg #define NIOS2_NUM_BUILTINS \ 3807 1.1 mrg (ARRAY_SIZE (nios2_builtins) + ARRAY_SIZE (nios2_fpu_insn) + NUM_CUSTOM_BUILTINS) 3808 1.1 mrg static GTY(()) tree nios2_builtin_decls[NIOS2_NUM_BUILTINS]; 3809 1.1 mrg 3810 1.1 mrg static void 3811 1.1 mrg nios2_register_builtin_fndecl (unsigned code, tree fndecl) 3812 1.1 mrg { 3813 1.1 mrg nios2_builtin_decls[code] = fndecl; 3814 1.1 mrg } 3815 1.1 mrg 3816 1.1 mrg /* Implement TARGET_BUILTIN_DECL. */ 3817 1.1 mrg static tree 3818 1.1 mrg nios2_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED) 3819 1.1 mrg { 3820 1.1 mrg gcc_assert (nios2_custom_builtin_end == ARRAY_SIZE (nios2_builtin_decls)); 3821 1.1 mrg 3822 1.1 mrg if (code >= nios2_custom_builtin_end) 3823 1.1 mrg return error_mark_node; 3824 1.1 mrg 3825 1.1 mrg if (code >= nios2_fpu_builtin_base 3826 1.1 mrg && code < nios2_custom_builtin_base 3827 1.1 mrg && ! N2FPU_ENABLED_P (code - nios2_fpu_builtin_base)) 3828 1.1 mrg return error_mark_node; 3829 1.1 mrg 3830 1.1 mrg return nios2_builtin_decls[code]; 3831 1.1 mrg } 3832 1.1 mrg 3833 1.1 mrg 3834 1.1 mrg /* Low-level built-in expand routine. */ 3836 1.1 mrg static rtx 3837 1.1 mrg nios2_expand_builtin_insn (const struct nios2_builtin_desc *d, int n, 3838 1.1 mrg struct expand_operand *ops, bool has_target_p) 3839 1.1 mrg { 3840 1.1 mrg if (maybe_expand_insn (d->icode, n, ops)) 3841 1.1 mrg return has_target_p ? ops[0].value : const0_rtx; 3842 1.1 mrg else 3843 1.1 mrg { 3844 1.1 mrg error ("invalid argument to built-in function %s", d->name); 3845 1.1 mrg return has_target_p ? gen_reg_rtx (ops[0].mode) : const0_rtx; 3846 1.1 mrg } 3847 1.1 mrg } 3848 1.1 mrg 3849 1.1 mrg /* Expand ldio/stio and ldex/ldsex/stex/stsex form load-store 3850 1.1 mrg instruction builtins. */ 3851 1.1 mrg static rtx 3852 1.1 mrg nios2_expand_ldst_builtin (tree exp, rtx target, 3853 1.1 mrg const struct nios2_builtin_desc *d) 3854 1.1 mrg { 3855 1.1 mrg bool has_target_p; 3856 1.1 mrg rtx addr, mem, val; 3857 1.1 mrg struct expand_operand ops[MAX_RECOG_OPERANDS]; 3858 1.1 mrg machine_mode mode = insn_data[d->icode].operand[0].mode; 3859 1.1 mrg 3860 1.1 mrg addr = expand_normal (CALL_EXPR_ARG (exp, 0)); 3861 1.1 mrg mem = gen_rtx_MEM (mode, addr); 3862 1.1 mrg 3863 1.1 mrg if (insn_data[d->icode].operand[0].allows_mem) 3864 1.1 mrg { 3865 1.1 mrg /* stxio/stex/stsex. */ 3866 1.1 mrg val = expand_normal (CALL_EXPR_ARG (exp, 1)); 3867 1.1 mrg if (CONST_INT_P (val)) 3868 1.1 mrg val = force_reg (mode, gen_int_mode (INTVAL (val), mode)); 3869 1.1 mrg val = simplify_gen_subreg (mode, val, GET_MODE (val), 0); 3870 1.1 mrg create_output_operand (&ops[0], mem, mode); 3871 1.1 mrg create_input_operand (&ops[1], val, mode); 3872 1.1 mrg if (insn_data[d->icode].n_operands == 3) 3873 1.1 mrg { 3874 1.1 mrg /* stex/stsex status value, returned as result of function. */ 3875 1.1 mrg create_output_operand (&ops[2], target, mode); 3876 1.1 mrg has_target_p = true; 3877 1.1 mrg } 3878 1.1 mrg else 3879 1.1 mrg has_target_p = false; 3880 1.1 mrg } 3881 1.1 mrg else 3882 1.1 mrg { 3883 1.1 mrg /* ldxio. */ 3884 1.1 mrg create_output_operand (&ops[0], target, mode); 3885 1.1 mrg create_input_operand (&ops[1], mem, mode); 3886 1.1 mrg has_target_p = true; 3887 1.1 mrg } 3888 1.1 mrg return nios2_expand_builtin_insn (d, insn_data[d->icode].n_operands, ops, 3889 1.1 mrg has_target_p); 3890 1.1 mrg } 3891 1.1 mrg 3892 1.1 mrg /* Expand rdctl/wrctl builtins. */ 3893 1.1 mrg static rtx 3894 1.1 mrg nios2_expand_rdwrctl_builtin (tree exp, rtx target, 3895 1.1 mrg const struct nios2_builtin_desc *d) 3896 1.1 mrg { 3897 1.1 mrg bool has_target_p = (insn_data[d->icode].operand[0].predicate 3898 1.1 mrg == register_operand); 3899 1.1 mrg rtx ctlcode = expand_normal (CALL_EXPR_ARG (exp, 0)); 3900 1.1 mrg struct expand_operand ops[MAX_RECOG_OPERANDS]; 3901 1.1 mrg if (!rdwrctl_operand (ctlcode, VOIDmode)) 3902 1.1 mrg { 3903 1.1 mrg error ("control register number must be in range 0-31 for %s", 3904 1.1 mrg d->name); 3905 1.1 mrg return has_target_p ? gen_reg_rtx (SImode) : const0_rtx; 3906 1.1 mrg } 3907 1.1 mrg if (has_target_p) 3908 1.1 mrg { 3909 1.1 mrg create_output_operand (&ops[0], target, SImode); 3910 1.1 mrg create_integer_operand (&ops[1], INTVAL (ctlcode)); 3911 1.1 mrg } 3912 1.1 mrg else 3913 1.1 mrg { 3914 1.1 mrg rtx val = expand_normal (CALL_EXPR_ARG (exp, 1)); 3915 1.1 mrg create_integer_operand (&ops[0], INTVAL (ctlcode)); 3916 1.1 mrg create_input_operand (&ops[1], val, SImode); 3917 1.1 mrg } 3918 1.1 mrg return nios2_expand_builtin_insn (d, 2, ops, has_target_p); 3919 1.1 mrg } 3920 1.1 mrg 3921 1.1 mrg static rtx 3922 1.1 mrg nios2_expand_rdprs_builtin (tree exp, rtx target, 3923 1.1 mrg const struct nios2_builtin_desc *d) 3924 1.1 mrg { 3925 1.1 mrg rtx reg = expand_normal (CALL_EXPR_ARG (exp, 0)); 3926 1.1 mrg rtx imm = expand_normal (CALL_EXPR_ARG (exp, 1)); 3927 1.1 mrg struct expand_operand ops[MAX_RECOG_OPERANDS]; 3928 1.1 mrg 3929 1.1 mrg if (!rdwrctl_operand (reg, VOIDmode)) 3930 1.1 mrg { 3931 1.1 mrg error ("register number must be in range 0-31 for %s", 3932 1.1 mrg d->name); 3933 1.1 mrg return gen_reg_rtx (SImode); 3934 1.1 mrg } 3935 1.1 mrg 3936 1.1 mrg if (!rdprs_dcache_operand (imm, VOIDmode)) 3937 1.1 mrg { 3938 1.1 mrg error ("immediate value must fit into a %d-bit integer for %s", 3939 1.1 mrg (TARGET_ARCH_R2) ? 12 : 16, d->name); 3940 1.1 mrg return gen_reg_rtx (SImode); 3941 1.1 mrg } 3942 1.1 mrg 3943 1.1 mrg create_output_operand (&ops[0], target, SImode); 3944 1.1 mrg create_input_operand (&ops[1], reg, SImode); 3945 1.1 mrg create_integer_operand (&ops[2], INTVAL (imm)); 3946 1.1 mrg 3947 1.1 mrg return nios2_expand_builtin_insn (d, 3, ops, true); 3948 1.1 mrg } 3949 1.1 mrg 3950 1.1 mrg static rtx 3951 1.1 mrg nios2_expand_cache_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, 3952 1.1 mrg const struct nios2_builtin_desc *d) 3953 1.1 mrg { 3954 1.1 mrg rtx mem, addr; 3955 1.1 mrg struct expand_operand ops[MAX_RECOG_OPERANDS]; 3956 1.1 mrg 3957 1.1 mrg addr = expand_normal (CALL_EXPR_ARG (exp, 0)); 3958 1.1 mrg mem = gen_rtx_MEM (SImode, addr); 3959 1.1 mrg 3960 1.1 mrg create_input_operand (&ops[0], mem, SImode); 3961 1.1 mrg 3962 1.1 mrg return nios2_expand_builtin_insn (d, 1, ops, false); 3963 1.1 mrg } 3964 1.1 mrg 3965 1.1 mrg static rtx 3966 1.1 mrg nios2_expand_wrpie_builtin (tree exp, rtx target, 3967 1.1 mrg const struct nios2_builtin_desc *d) 3968 1.1 mrg { 3969 1.1 mrg rtx val; 3970 1.1 mrg struct expand_operand ops[MAX_RECOG_OPERANDS]; 3971 1.1 mrg 3972 1.1 mrg val = expand_normal (CALL_EXPR_ARG (exp, 0)); 3973 1.1 mrg create_input_operand (&ops[1], val, SImode); 3974 1.1 mrg create_output_operand (&ops[0], target, SImode); 3975 1.1 mrg 3976 1.1 mrg return nios2_expand_builtin_insn (d, 2, ops, true); 3977 1.1 mrg } 3978 1.1 mrg 3979 1.1 mrg static rtx 3980 1.1 mrg nios2_expand_eni_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, 3981 1.1 mrg const struct nios2_builtin_desc *d) 3982 1.1 mrg { 3983 1.1 mrg rtx imm = expand_normal (CALL_EXPR_ARG (exp, 0)); 3984 1.1 mrg struct expand_operand ops[MAX_RECOG_OPERANDS]; 3985 1.1 mrg 3986 1.1 mrg if (INTVAL (imm) != 0 && INTVAL (imm) != 1) 3987 1.1 mrg { 3988 1.1 mrg error ("the ENI instruction operand must be either 0 or 1"); 3989 1.1 mrg return const0_rtx; 3990 1.1 mrg } 3991 1.1 mrg create_integer_operand (&ops[0], INTVAL (imm)); 3992 1.1 mrg 3993 1.1 mrg return nios2_expand_builtin_insn (d, 1, ops, false); 3994 1.1 mrg } 3995 1.1 mrg 3996 1.1 mrg /* Implement TARGET_EXPAND_BUILTIN. Expand an expression EXP that calls 3997 1.1 mrg a built-in function, with result going to TARGET if that's convenient 3998 1.1 mrg (and in mode MODE if that's convenient). 3999 1.1 mrg SUBTARGET may be used as the target for computing one of EXP's operands. 4000 1.1 mrg IGNORE is nonzero if the value is to be ignored. */ 4001 1.1 mrg 4002 1.1 mrg static rtx 4003 1.1 mrg nios2_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, 4004 1.1 mrg machine_mode mode ATTRIBUTE_UNUSED, 4005 1.1 mrg int ignore ATTRIBUTE_UNUSED) 4006 1.1 mrg { 4007 1.1 mrg tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 4008 1.1 mrg unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl); 4009 1.1 mrg 4010 1.1 mrg if (fcode < nios2_fpu_builtin_base) 4011 1.1 mrg { 4012 1.1 mrg const struct nios2_builtin_desc *d = &nios2_builtins[fcode]; 4013 1.1 mrg 4014 1.1 mrg if (d->arch > nios2_arch_option) 4015 1.1 mrg { 4016 1.1 mrg error ("built-in function %s requires Nios II R%d", 4017 1.1 mrg d->name, (int) d->arch); 4018 1.1 mrg /* Given it is invalid, just generate a normal call. */ 4019 1.1 mrg return expand_call (exp, target, ignore); 4020 1.1 mrg } 4021 1.1 mrg 4022 1.1 mrg switch (fcode) 4023 1.1 mrg { 4024 1.1 mrg case NIOS2_BUILTIN_sync: 4025 1.1 mrg emit_insn (gen_sync ()); 4026 1.1 mrg return const0_rtx; 4027 1.1 mrg 4028 1.1 mrg case NIOS2_BUILTIN_ldbio: 4029 1.1 mrg case NIOS2_BUILTIN_ldbuio: 4030 1.1 mrg case NIOS2_BUILTIN_ldhio: 4031 1.1 mrg case NIOS2_BUILTIN_ldhuio: 4032 1.1 mrg case NIOS2_BUILTIN_ldwio: 4033 1.1 mrg case NIOS2_BUILTIN_stbio: 4034 1.1 mrg case NIOS2_BUILTIN_sthio: 4035 1.1 mrg case NIOS2_BUILTIN_stwio: 4036 1.1 mrg case NIOS2_BUILTIN_ldex: 4037 1.1 mrg case NIOS2_BUILTIN_ldsex: 4038 1.1 mrg case NIOS2_BUILTIN_stex: 4039 1.1 mrg case NIOS2_BUILTIN_stsex: 4040 1.1 mrg return nios2_expand_ldst_builtin (exp, target, d); 4041 1.1 mrg 4042 1.1 mrg case NIOS2_BUILTIN_rdctl: 4043 1.1 mrg case NIOS2_BUILTIN_wrctl: 4044 1.1 mrg return nios2_expand_rdwrctl_builtin (exp, target, d); 4045 1.1 mrg 4046 1.1 mrg case NIOS2_BUILTIN_rdprs: 4047 1.1 mrg return nios2_expand_rdprs_builtin (exp, target, d); 4048 1.1 mrg 4049 1.1 mrg case NIOS2_BUILTIN_flushd: 4050 1.1 mrg case NIOS2_BUILTIN_flushda: 4051 1.1 mrg return nios2_expand_cache_builtin (exp, target, d); 4052 1.1 mrg 4053 1.1 mrg case NIOS2_BUILTIN_wrpie: 4054 1.1 mrg return nios2_expand_wrpie_builtin (exp, target, d); 4055 1.1 mrg 4056 1.1 mrg case NIOS2_BUILTIN_eni: 4057 1.1 mrg return nios2_expand_eni_builtin (exp, target, d); 4058 1.1 mrg 4059 1.1 mrg default: 4060 1.1 mrg gcc_unreachable (); 4061 1.1 mrg } 4062 1.1 mrg } 4063 1.1 mrg else if (fcode < nios2_custom_builtin_base) 4064 1.1 mrg /* FPU builtin range. */ 4065 1.1 mrg return nios2_expand_fpu_builtin (exp, fcode - nios2_fpu_builtin_base, 4066 1.1 mrg target); 4067 1.1 mrg else if (fcode < nios2_custom_builtin_end) 4068 1.1 mrg /* Custom insn builtin range. */ 4069 1.1 mrg return nios2_expand_custom_builtin (exp, fcode - nios2_custom_builtin_base, 4070 1.1 mrg target); 4071 1.1 mrg else 4072 1.1 mrg gcc_unreachable (); 4073 1.1 mrg } 4074 1.1 mrg 4075 1.1 mrg /* Implement TARGET_INIT_LIBFUNCS. */ 4076 1.1 mrg static void ATTRIBUTE_UNUSED 4077 1.1 mrg nios2_init_libfuncs (void) 4078 1.1 mrg { 4079 1.1 mrg init_sync_libfuncs (UNITS_PER_WORD); 4080 1.1 mrg } 4081 1.1 mrg 4082 1.1 mrg 4083 1.1 mrg 4085 1.1 mrg /* Register a custom code use, and signal error if a conflict was found. */ 4086 1.1 mrg static void 4087 1.1 mrg nios2_register_custom_code (unsigned int N, enum nios2_ccs_code status, 4088 1.1 mrg int index) 4089 1.1 mrg { 4090 1.1 mrg gcc_assert (N <= 255); 4091 1.1 mrg 4092 1.1 mrg if (status == CCS_FPU) 4093 1.1 mrg { 4094 1.1 mrg if (custom_code_status[N] == CCS_FPU && index != custom_code_index[N]) 4095 1.1 mrg { 4096 1.1 mrg custom_code_conflict = true; 4097 1.1 mrg error ("switch %<-mcustom-%s%> conflicts with " 4098 1.1 mrg "switch %<-mcustom-%s%>", 4099 1.1 mrg N2FPU_NAME (custom_code_index[N]), N2FPU_NAME (index)); 4100 1.1 mrg } 4101 1.1 mrg else if (custom_code_status[N] == CCS_BUILTIN_CALL) 4102 1.1 mrg { 4103 1.1 mrg custom_code_conflict = true; 4104 1.1 mrg error ("call to %<__builtin_custom_%s%> conflicts with " 4105 1.1 mrg "switch %<-mcustom-%s%>", 4106 1.1 mrg custom_builtin_name[custom_code_index[N]], 4107 1.1 mrg N2FPU_NAME (index)); 4108 1.1 mrg } 4109 1.1 mrg } 4110 1.1 mrg else if (status == CCS_BUILTIN_CALL) 4111 1.1 mrg { 4112 1.1 mrg if (custom_code_status[N] == CCS_FPU) 4113 1.1 mrg { 4114 1.1 mrg custom_code_conflict = true; 4115 1.1 mrg error ("call to %<__builtin_custom_%s%> conflicts with " 4116 1.1 mrg "switch %<-mcustom-%s%>", 4117 1.1 mrg custom_builtin_name[index], 4118 1.1 mrg N2FPU_NAME (custom_code_index[N])); 4119 1.1 mrg } 4120 1.1 mrg else 4121 1.1 mrg { 4122 1.1 mrg /* Note that code conflicts between different __builtin_custom_xnxx 4123 1.1 mrg calls are not checked. */ 4124 1.1 mrg } 4125 1.1 mrg } 4126 1.1 mrg else 4127 1.1 mrg gcc_unreachable (); 4128 1.1 mrg 4129 1.1 mrg custom_code_status[N] = status; 4130 1.1 mrg custom_code_index[N] = index; 4131 1.1 mrg } 4132 1.1 mrg 4133 1.1 mrg /* Mark a custom code as not in use. */ 4134 1.1 mrg static void 4135 1.1 mrg nios2_deregister_custom_code (unsigned int N) 4136 1.1 mrg { 4137 1.1 mrg if (N <= 255) 4138 1.1 mrg { 4139 1.1 mrg custom_code_status[N] = CCS_UNUSED; 4140 1.1 mrg custom_code_index[N] = 0; 4141 1.1 mrg } 4142 1.1 mrg } 4143 1.1 mrg 4144 1.1 mrg /* Target attributes can affect per-function option state, so we need to 4145 1.1 mrg save/restore the custom code tracking info using the 4146 1.1 mrg TARGET_OPTION_SAVE/TARGET_OPTION_RESTORE hooks. */ 4147 1.1 mrg 4148 1.1 mrg static void 4149 1.1 mrg nios2_option_save (struct cl_target_option *ptr, 4150 1.1 mrg struct gcc_options *opts ATTRIBUTE_UNUSED, 4151 1.1 mrg struct gcc_options *opts_set ATTRIBUTE_UNUSED) 4152 1.1 mrg { 4153 1.1 mrg unsigned int i; 4154 1.1 mrg for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++) 4155 1.1 mrg ptr->saved_fpu_custom_code[i] = N2FPU_N (i); 4156 1.1 mrg memcpy (ptr->saved_custom_code_status, custom_code_status, 4157 1.1 mrg sizeof (custom_code_status)); 4158 1.1 mrg memcpy (ptr->saved_custom_code_index, custom_code_index, 4159 1.1 mrg sizeof (custom_code_index)); 4160 1.1 mrg } 4161 1.1 mrg 4162 1.1 mrg static void 4163 1.1 mrg nios2_option_restore (struct gcc_options *opts ATTRIBUTE_UNUSED, 4164 1.1 mrg struct gcc_options *opts_set ATTRIBUTE_UNUSED, 4165 1.1 mrg struct cl_target_option *ptr) 4166 1.1 mrg { 4167 1.1 mrg unsigned int i; 4168 1.1 mrg for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++) 4169 1.1 mrg N2FPU_N (i) = ptr->saved_fpu_custom_code[i]; 4170 1.1 mrg memcpy (custom_code_status, ptr->saved_custom_code_status, 4171 1.1 mrg sizeof (custom_code_status)); 4172 1.1 mrg memcpy (custom_code_index, ptr->saved_custom_code_index, 4173 1.1 mrg sizeof (custom_code_index)); 4174 1.1 mrg } 4175 1.1 mrg 4176 1.1 mrg static bool 4177 1.1 mrg nios2_can_inline_p (tree caller, tree callee) 4178 1.1 mrg { 4179 1.1 mrg tree callee_opts = DECL_FUNCTION_SPECIFIC_TARGET (callee); 4180 1.1 mrg tree caller_opts = DECL_FUNCTION_SPECIFIC_TARGET (caller); 4181 1.1 mrg struct cl_target_option *callee_ptr, *caller_ptr; 4182 1.1 mrg unsigned int i; 4183 1.1 mrg 4184 1.1 mrg if (! callee_opts) 4185 1.1 mrg callee_opts = target_option_default_node; 4186 1.1 mrg if (! caller_opts) 4187 1.1 mrg caller_opts = target_option_default_node; 4188 1.1 mrg 4189 1.1 mrg /* If both caller and callee have attributes, assume that if the 4190 1.1 mrg pointer is different, the two functions have different target 4191 1.1 mrg options since build_target_option_node uses a hash table for the 4192 1.1 mrg options. */ 4193 1.1 mrg if (callee_opts == caller_opts) 4194 1.1 mrg return true; 4195 1.1 mrg 4196 1.1 mrg /* The only target options we recognize via function attributes are 4197 1.1 mrg those related to custom instructions. If we failed the above test, 4198 1.1 mrg check that any custom instructions enabled in the callee are also 4199 1.1 mrg enabled with the same value in the caller. */ 4200 1.1 mrg callee_ptr = TREE_TARGET_OPTION (callee_opts); 4201 1.1 mrg caller_ptr = TREE_TARGET_OPTION (caller_opts); 4202 1.1 mrg for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++) 4203 1.1 mrg if (callee_ptr->saved_fpu_custom_code[i] != -1 4204 1.1 mrg && (callee_ptr->saved_fpu_custom_code[i] 4205 1.1 mrg != caller_ptr->saved_fpu_custom_code[i])) 4206 1.1 mrg return false; 4207 1.1 mrg return true; 4208 1.1 mrg } 4209 1.1 mrg 4210 1.1 mrg /* Inner function to process the attribute((target(...))), take an argument and 4211 1.1 mrg set the current options from the argument. If we have a list, recursively 4212 1.1 mrg go over the list. */ 4213 1.1 mrg 4214 1.1 mrg static bool 4215 1.1 mrg nios2_valid_target_attribute_rec (tree args) 4216 1.1 mrg { 4217 1.1 mrg if (TREE_CODE (args) == TREE_LIST) 4218 1.1 mrg { 4219 1.1 mrg bool ret = true; 4220 1.1 mrg for (; args; args = TREE_CHAIN (args)) 4221 1.1 mrg if (TREE_VALUE (args) 4222 1.1 mrg && !nios2_valid_target_attribute_rec (TREE_VALUE (args))) 4223 1.1 mrg ret = false; 4224 1.1 mrg return ret; 4225 1.1 mrg } 4226 1.1 mrg else if (TREE_CODE (args) == STRING_CST) 4227 1.1 mrg { 4228 1.1 mrg char *argstr = ASTRDUP (TREE_STRING_POINTER (args)); 4229 1.1 mrg while (argstr && *argstr != '\0') 4230 1.1 mrg { 4231 1.1 mrg bool no_opt = false, end_p = false; 4232 1.1 mrg char *eq = NULL, *p; 4233 1.1 mrg while (ISSPACE (*argstr)) 4234 1.1 mrg argstr++; 4235 1.1 mrg p = argstr; 4236 1.1 mrg while (*p != '\0' && *p != ',') 4237 1.1 mrg { 4238 1.1 mrg if (!eq && *p == '=') 4239 1.1 mrg eq = p; 4240 1.1 mrg ++p; 4241 1.1 mrg } 4242 1.1 mrg if (*p == '\0') 4243 1.1 mrg end_p = true; 4244 1.1 mrg else 4245 1.1 mrg *p = '\0'; 4246 1.1 mrg if (eq) *eq = '\0'; 4247 1.1 mrg 4248 1.1 mrg if (startswith (argstr, "no-")) 4249 1.1 mrg { 4250 1.1 mrg no_opt = true; 4251 1.1 mrg argstr += 3; 4252 1.1 mrg } 4253 1.1 mrg if (startswith (argstr, "custom-fpu-cfg")) 4254 1.1 mrg { 4255 1.1 mrg char *end_eq = p; 4256 1.1 mrg if (no_opt) 4257 1.1 mrg { 4258 1.1 mrg error ("%<custom-fpu-cfg%> option does not support %<no-%>"); 4259 1.1 mrg return false; 4260 1.1 mrg } 4261 1.1 mrg if (!eq) 4262 1.1 mrg { 4263 1.1 mrg error ("%<custom-fpu-cfg%> option requires configuration " 4264 1.1 mrg "argument"); 4265 1.1 mrg return false; 4266 1.1 mrg } 4267 1.1 mrg /* Increment and skip whitespace. */ 4268 1.1 mrg while (ISSPACE (*(++eq))) ; 4269 1.1 mrg /* Decrement and skip to before any trailing whitespace. */ 4270 1.1 mrg while (ISSPACE (*(--end_eq))) ; 4271 1.1 mrg 4272 1.1 mrg nios2_handle_custom_fpu_cfg (eq, end_eq + 1, true); 4273 1.1 mrg } 4274 1.1 mrg else if (startswith (argstr, "custom-")) 4275 1.1 mrg { 4276 1.1 mrg int code = -1; 4277 1.1 mrg unsigned int i; 4278 1.1 mrg for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++) 4279 1.1 mrg if (startswith (argstr + 7, N2FPU_NAME (i))) 4280 1.1 mrg { 4281 1.1 mrg /* Found insn. */ 4282 1.1 mrg code = i; 4283 1.1 mrg break; 4284 1.1 mrg } 4285 1.1 mrg if (code >= 0) 4286 1.1 mrg { 4287 1.1 mrg if (no_opt) 4288 1.1 mrg { 4289 1.1 mrg if (eq) 4290 1.1 mrg { 4291 1.1 mrg error ("%<no-custom-%s%> does not accept arguments", 4292 1.1 mrg N2FPU_NAME (code)); 4293 1.1 mrg return false; 4294 1.1 mrg } 4295 1.1 mrg /* Disable option by setting to -1. */ 4296 1.1 mrg nios2_deregister_custom_code (N2FPU_N (code)); 4297 1.1 mrg N2FPU_N (code) = -1; 4298 1.1 mrg } 4299 1.1 mrg else 4300 1.1 mrg { 4301 1.1 mrg char *t; 4302 1.1 mrg if (eq) 4303 1.1 mrg while (ISSPACE (*(++eq))) ; 4304 1.1 mrg if (!eq || eq == p) 4305 1.1 mrg { 4306 1.1 mrg error ("%<custom-%s=%> requires argument", 4307 1.1 mrg N2FPU_NAME (code)); 4308 1.1 mrg return false; 4309 1.1 mrg } 4310 1.1 mrg for (t = eq; t != p; ++t) 4311 1.1 mrg { 4312 1.1 mrg if (ISSPACE (*t)) 4313 1.1 mrg continue; 4314 1.1 mrg if (!ISDIGIT (*t)) 4315 1.1 mrg { 4316 1.1 mrg error ("%<custom-%s=%> argument should be " 4317 1.1 mrg "a non-negative integer", N2FPU_NAME (code)); 4318 1.1 mrg return false; 4319 1.1 mrg } 4320 1.1 mrg } 4321 1.1 mrg /* Set option to argument. */ 4322 1.1 mrg N2FPU_N (code) = atoi (eq); 4323 1.1 mrg nios2_handle_custom_fpu_insn_option (code); 4324 1.1 mrg } 4325 1.1 mrg } 4326 1.1 mrg else 4327 1.1 mrg { 4328 1.1 mrg error ("%<custom-%s=%> is not recognized as FPU instruction", 4329 1.1 mrg argstr + 7); 4330 1.1 mrg return false; 4331 1.1 mrg } 4332 1.1 mrg } 4333 1.1 mrg else 4334 1.1 mrg { 4335 1.1 mrg error ("invalid custom instruction option %qs", argstr); 4336 1.1 mrg return false; 4337 1.1 mrg } 4338 1.1 mrg 4339 1.1 mrg if (end_p) 4340 1.1 mrg break; 4341 1.1 mrg else 4342 1.1 mrg argstr = p + 1; 4343 1.1 mrg } 4344 1.1 mrg return true; 4345 1.1 mrg } 4346 1.1 mrg else 4347 1.1 mrg gcc_unreachable (); 4348 1.1 mrg } 4349 1.1 mrg 4350 1.1 mrg /* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */ 4351 1.1 mrg 4352 1.1 mrg static tree 4353 1.1 mrg nios2_valid_target_attribute_tree (tree args) 4354 1.1 mrg { 4355 1.1 mrg if (!nios2_valid_target_attribute_rec (args)) 4356 1.1 mrg return NULL_TREE; 4357 1.1 mrg nios2_custom_check_insns (); 4358 1.1 mrg return build_target_option_node (&global_options, &global_options_set); 4359 1.1 mrg } 4360 1.1 mrg 4361 1.1 mrg /* Hook to validate attribute((target("string"))). */ 4362 1.1 mrg 4363 1.1 mrg static bool 4364 1.1 mrg nios2_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name), 4365 1.1 mrg tree args, int ARG_UNUSED (flags)) 4366 1.1 mrg { 4367 1.1 mrg struct cl_target_option cur_target; 4368 1.1 mrg bool ret = true; 4369 1.1 mrg tree old_optimize 4370 1.1 mrg = build_optimization_node (&global_options, &global_options_set); 4371 1.1 mrg tree new_target, new_optimize; 4372 1.1 mrg tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl); 4373 1.1 mrg 4374 1.1 mrg /* If the function changed the optimization levels as well as setting target 4375 1.1 mrg options, start with the optimizations specified. */ 4376 1.1 mrg if (func_optimize && func_optimize != old_optimize) 4377 1.1 mrg cl_optimization_restore (&global_options, &global_options_set, 4378 1.1 mrg TREE_OPTIMIZATION (func_optimize)); 4379 1.1 mrg 4380 1.1 mrg /* The target attributes may also change some optimization flags, so update 4381 1.1 mrg the optimization options if necessary. */ 4382 1.1 mrg cl_target_option_save (&cur_target, &global_options, &global_options_set); 4383 1.1 mrg new_target = nios2_valid_target_attribute_tree (args); 4384 1.1 mrg new_optimize = build_optimization_node (&global_options, &global_options_set); 4385 1.1 mrg 4386 1.1 mrg if (!new_target) 4387 1.1 mrg ret = false; 4388 1.1 mrg 4389 1.1 mrg else if (fndecl) 4390 1.1 mrg { 4391 1.1 mrg DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target; 4392 1.1 mrg 4393 1.1 mrg if (old_optimize != new_optimize) 4394 1.1 mrg DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize; 4395 1.1 mrg } 4396 1.1 mrg 4397 1.1 mrg cl_target_option_restore (&global_options, &global_options_set, &cur_target); 4398 1.1 mrg 4399 1.1 mrg if (old_optimize != new_optimize) 4400 1.1 mrg cl_optimization_restore (&global_options, &global_options_set, 4401 1.1 mrg TREE_OPTIMIZATION (old_optimize)); 4402 1.1 mrg return ret; 4403 1.1 mrg } 4404 1.1 mrg 4405 1.1 mrg /* Remember the last target of nios2_set_current_function. */ 4406 1.1 mrg static GTY(()) tree nios2_previous_fndecl; 4407 1.1 mrg 4408 1.1 mrg /* Establish appropriate back-end context for processing the function 4409 1.1 mrg FNDECL. The argument might be NULL to indicate processing at top 4410 1.1 mrg level, outside of any function scope. */ 4411 1.1 mrg static void 4412 1.1 mrg nios2_set_current_function (tree fndecl) 4413 1.1 mrg { 4414 1.1 mrg tree old_tree = (nios2_previous_fndecl 4415 1.1 mrg ? DECL_FUNCTION_SPECIFIC_TARGET (nios2_previous_fndecl) 4416 1.1 mrg : NULL_TREE); 4417 1.1 mrg 4418 1.1 mrg tree new_tree = (fndecl 4419 1.1 mrg ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl) 4420 1.1 mrg : NULL_TREE); 4421 1.1 mrg 4422 1.1 mrg if (fndecl && fndecl != nios2_previous_fndecl) 4423 1.1 mrg { 4424 1.1 mrg nios2_previous_fndecl = fndecl; 4425 1.1 mrg if (old_tree == new_tree) 4426 1.1 mrg ; 4427 1.1 mrg 4428 1.1 mrg else if (new_tree) 4429 1.1 mrg { 4430 1.1 mrg cl_target_option_restore (&global_options, &global_options_set, 4431 1.1 mrg TREE_TARGET_OPTION (new_tree)); 4432 1.1 mrg target_reinit (); 4433 1.1 mrg } 4434 1.1 mrg 4435 1.1 mrg else if (old_tree) 4436 1.1 mrg { 4437 1.1 mrg struct cl_target_option *def 4438 1.1 mrg = TREE_TARGET_OPTION (target_option_current_node); 4439 1.1 mrg 4440 1.1 mrg cl_target_option_restore (&global_options, &global_options_set, def); 4441 1.1 mrg target_reinit (); 4442 1.1 mrg } 4443 1.1 mrg } 4444 1.1 mrg } 4445 1.1 mrg 4446 1.1 mrg /* Hook to validate the current #pragma GCC target and set the FPU custom 4447 1.1 mrg code option state. If ARGS is NULL, then POP_TARGET is used to reset 4448 1.1 mrg the options. */ 4449 1.1 mrg static bool 4450 1.1 mrg nios2_pragma_target_parse (tree args, tree pop_target) 4451 1.1 mrg { 4452 1.1 mrg tree cur_tree; 4453 1.1 mrg if (! args) 4454 1.1 mrg { 4455 1.1 mrg cur_tree = ((pop_target) 4456 1.1 mrg ? pop_target 4457 1.1 mrg : target_option_default_node); 4458 1.1 mrg cl_target_option_restore (&global_options, &global_options_set, 4459 1.1 mrg TREE_TARGET_OPTION (cur_tree)); 4460 1.1 mrg } 4461 1.1 mrg else 4462 1.1 mrg { 4463 1.1 mrg cur_tree = nios2_valid_target_attribute_tree (args); 4464 1.1 mrg if (!cur_tree) 4465 1.1 mrg return false; 4466 1.1 mrg } 4467 1.1 mrg 4468 1.1 mrg target_option_current_node = cur_tree; 4469 1.1 mrg return true; 4470 1.1 mrg } 4471 1.1 mrg 4472 1.1 mrg /* Implement TARGET_MERGE_DECL_ATTRIBUTES. 4473 1.1 mrg We are just using this hook to add some additional error checking to 4474 1.1 mrg the default behavior. GCC does not provide a target hook for merging 4475 1.1 mrg the target options, and only correctly handles merging empty vs non-empty 4476 1.1 mrg option data; see merge_decls() in c-decl.cc. 4477 1.1 mrg So here we require either that at least one of the decls has empty 4478 1.1 mrg target options, or that the target options/data be identical. */ 4479 1.1 mrg static tree 4480 1.1 mrg nios2_merge_decl_attributes (tree olddecl, tree newdecl) 4481 1.1 mrg { 4482 1.1 mrg tree oldopts = lookup_attribute ("target", DECL_ATTRIBUTES (olddecl)); 4483 1.1 mrg tree newopts = lookup_attribute ("target", DECL_ATTRIBUTES (newdecl)); 4484 1.1 mrg if (newopts && oldopts && newopts != oldopts) 4485 1.1 mrg { 4486 1.1 mrg tree oldtree = DECL_FUNCTION_SPECIFIC_TARGET (olddecl); 4487 1.1 mrg tree newtree = DECL_FUNCTION_SPECIFIC_TARGET (newdecl); 4488 1.1 mrg if (oldtree && newtree && oldtree != newtree) 4489 1.1 mrg { 4490 1.1 mrg struct cl_target_option *olddata = TREE_TARGET_OPTION (oldtree); 4491 1.1 mrg struct cl_target_option *newdata = TREE_TARGET_OPTION (newtree); 4492 1.1 mrg if (olddata != newdata 4493 1.1 mrg && memcmp (olddata, newdata, sizeof (struct cl_target_option))) 4494 1.1 mrg error ("%qE redeclared with conflicting %qs attributes", 4495 1.1 mrg DECL_NAME (newdecl), "target"); 4496 1.1 mrg } 4497 1.1 mrg } 4498 1.1 mrg return merge_attributes (DECL_ATTRIBUTES (olddecl), 4499 1.1 mrg DECL_ATTRIBUTES (newdecl)); 4500 1.1 mrg } 4501 1.1 mrg 4502 1.1 mrg /* Implement TARGET_ASM_OUTPUT_MI_THUNK. */ 4503 1.1 mrg static void 4504 1.1 mrg nios2_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, 4505 1.1 mrg HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset, 4506 1.1 mrg tree function) 4507 1.1 mrg { 4508 1.1 mrg const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl)); 4509 1.1 mrg rtx this_rtx, funexp; 4510 1.1 mrg rtx_insn *insn; 4511 1.1 mrg 4512 1.1 mrg /* Pretend to be a post-reload pass while generating rtl. */ 4513 1.1 mrg reload_completed = 1; 4514 1.1 mrg 4515 1.1 mrg if (flag_pic) 4516 1.1 mrg nios2_load_pic_register (); 4517 1.1 mrg 4518 1.1 mrg /* Mark the end of the (empty) prologue. */ 4519 1.1 mrg emit_note (NOTE_INSN_PROLOGUE_END); 4520 1.1 mrg 4521 1.1 mrg /* Find the "this" pointer. If the function returns a structure, 4522 1.1 mrg the structure return pointer is in $5. */ 4523 1.1 mrg if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)) 4524 1.1 mrg this_rtx = gen_rtx_REG (Pmode, FIRST_ARG_REGNO + 1); 4525 1.1 mrg else 4526 1.1 mrg this_rtx = gen_rtx_REG (Pmode, FIRST_ARG_REGNO); 4527 1.1 mrg 4528 1.1 mrg /* Add DELTA to THIS_RTX. */ 4529 1.1 mrg nios2_emit_add_constant (this_rtx, delta); 4530 1.1 mrg 4531 1.1 mrg /* If needed, add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */ 4532 1.1 mrg if (vcall_offset) 4533 1.1 mrg { 4534 1.1 mrg rtx tmp; 4535 1.1 mrg 4536 1.1 mrg tmp = gen_rtx_REG (Pmode, 2); 4537 1.1 mrg emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx)); 4538 1.1 mrg nios2_emit_add_constant (tmp, vcall_offset); 4539 1.1 mrg emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp)); 4540 1.1 mrg emit_insn (gen_add2_insn (this_rtx, tmp)); 4541 1.1 mrg } 4542 1.1 mrg 4543 1.1 mrg /* Generate a tail call to the target function. */ 4544 1.1 mrg if (!TREE_USED (function)) 4545 1.1 mrg { 4546 1.1 mrg assemble_external (function); 4547 1.1 mrg TREE_USED (function) = 1; 4548 1.1 mrg } 4549 1.1 mrg funexp = XEXP (DECL_RTL (function), 0); 4550 1.1 mrg /* Function address needs to be constructed under PIC, 4551 1.1 mrg provide r2 to use here. */ 4552 1.1 mrg nios2_adjust_call_address (&funexp, gen_rtx_REG (Pmode, 2)); 4553 1.1 mrg insn = emit_call_insn (gen_sibcall_internal (funexp, const0_rtx)); 4554 1.1 mrg SIBLING_CALL_P (insn) = 1; 4555 1.1 mrg 4556 1.1 mrg /* Run just enough of rest_of_compilation to get the insns emitted. 4557 1.1 mrg There's not really enough bulk here to make other passes such as 4558 1.1 mrg instruction scheduling worth while. */ 4559 1.1 mrg insn = get_insns (); 4560 1.1 mrg shorten_branches (insn); 4561 1.1 mrg assemble_start_function (thunk_fndecl, fnname); 4562 1.1 mrg final_start_function (insn, file, 1); 4563 1.1 mrg final (insn, file, 1); 4564 1.1 mrg final_end_function (); 4565 1.1 mrg assemble_end_function (thunk_fndecl, fnname); 4566 1.1 mrg 4567 1.1 mrg /* Stop pretending to be a post-reload pass. */ 4568 1.1 mrg reload_completed = 0; 4569 1.1 mrg } 4570 1.1 mrg 4571 1.1 mrg 4572 1.1 mrg /* Utility function to break a memory address into 4573 1.1 mrg base register + constant offset. Return false if something 4574 1.1 mrg unexpected is seen. */ 4575 1.1 mrg static bool 4576 1.1 mrg split_mem_address (rtx addr, rtx *base_reg, rtx *offset) 4577 1.1 mrg { 4578 1.1 mrg if (REG_P (addr)) 4579 1.1 mrg { 4580 1.1 mrg *base_reg = addr; 4581 1.1 mrg *offset = const0_rtx; 4582 1.1 mrg return true; 4583 1.1 mrg } 4584 1.1 mrg else if (GET_CODE (addr) == PLUS) 4585 1.1 mrg { 4586 1.1 mrg *base_reg = XEXP (addr, 0); 4587 1.1 mrg *offset = XEXP (addr, 1); 4588 1.1 mrg return true; 4589 1.1 mrg } 4590 1.1 mrg return false; 4591 1.1 mrg } 4592 1.1 mrg 4593 1.1 mrg /* Splits out the operands of an ALU insn, places them in *LHS, *RHS1, *RHS2. */ 4594 1.1 mrg static void 4595 1.1 mrg split_alu_insn (rtx_insn *insn, rtx *lhs, rtx *rhs1, rtx *rhs2) 4596 1.1 mrg { 4597 1.1 mrg rtx pat = PATTERN (insn); 4598 1.1 mrg gcc_assert (GET_CODE (pat) == SET); 4599 1.1 mrg *lhs = SET_DEST (pat); 4600 1.1 mrg *rhs1 = XEXP (SET_SRC (pat), 0); 4601 1.1 mrg if (GET_RTX_CLASS (GET_CODE (SET_SRC (pat))) != RTX_UNARY) 4602 1.1 mrg *rhs2 = XEXP (SET_SRC (pat), 1); 4603 1.1 mrg return; 4604 1.1 mrg } 4605 1.1 mrg 4606 1.1 mrg /* Returns true if OP is a REG and assigned a CDX reg. */ 4607 1.1 mrg static bool 4608 1.1 mrg cdxreg (rtx op) 4609 1.1 mrg { 4610 1.1 mrg return REG_P (op) && (!reload_completed || CDX_REG_P (REGNO (op))); 4611 1.1 mrg } 4612 1.1 mrg 4613 1.1 mrg /* Returns true if OP is within range of CDX addi.n immediates. */ 4614 1.1 mrg static bool 4615 1.1 mrg cdx_add_immed (rtx op) 4616 1.1 mrg { 4617 1.1 mrg if (CONST_INT_P (op)) 4618 1.1 mrg { 4619 1.1 mrg HOST_WIDE_INT ival = INTVAL (op); 4620 1.1 mrg return ival <= 128 && ival > 0 && (ival & (ival - 1)) == 0; 4621 1.1 mrg } 4622 1.1 mrg return false; 4623 1.1 mrg } 4624 1.1 mrg 4625 1.1 mrg /* Returns true if OP is within range of CDX andi.n immediates. */ 4626 1.1 mrg static bool 4627 1.1 mrg cdx_and_immed (rtx op) 4628 1.1 mrg { 4629 1.1 mrg if (CONST_INT_P (op)) 4630 1.1 mrg { 4631 1.1 mrg HOST_WIDE_INT ival = INTVAL (op); 4632 1.1 mrg return (ival == 1 || ival == 2 || ival == 3 || ival == 4 4633 1.1 mrg || ival == 8 || ival == 0xf || ival == 0x10 4634 1.1 mrg || ival == 0x1f || ival == 0x20 4635 1.1 mrg || ival == 0x3f || ival == 0x7f 4636 1.1 mrg || ival == 0x80 || ival == 0xff || ival == 0x7ff 4637 1.1 mrg || ival == 0xff00 || ival == 0xffff); 4638 1.1 mrg } 4639 1.1 mrg return false; 4640 1.1 mrg } 4641 1.1 mrg 4642 1.1 mrg /* Returns true if OP is within range of CDX movi.n immediates. */ 4643 1.1 mrg static bool 4644 1.1 mrg cdx_mov_immed (rtx op) 4645 1.1 mrg { 4646 1.1 mrg if (CONST_INT_P (op)) 4647 1.1 mrg { 4648 1.1 mrg HOST_WIDE_INT ival = INTVAL (op); 4649 1.1 mrg return ((ival >= 0 && ival <= 124) 4650 1.1 mrg || ival == 0xff || ival == -2 || ival == -1); 4651 1.1 mrg } 4652 1.1 mrg return false; 4653 1.1 mrg } 4654 1.1 mrg 4655 1.1 mrg /* Returns true if OP is within range of CDX slli.n/srli.n immediates. */ 4656 1.1 mrg static bool 4657 1.1 mrg cdx_shift_immed (rtx op) 4658 1.1 mrg { 4659 1.1 mrg if (CONST_INT_P (op)) 4660 1.1 mrg { 4661 1.1 mrg HOST_WIDE_INT ival = INTVAL (op); 4662 1.1 mrg return (ival == 1 || ival == 2 || ival == 3 || ival == 8 4663 1.1 mrg || ival == 12 || ival == 16 || ival == 24 4664 1.1 mrg || ival == 31); 4665 1.1 mrg } 4666 1.1 mrg return false; 4667 1.1 mrg } 4668 1.1 mrg 4669 1.1 mrg 4670 1.1 mrg 4671 1.1 mrg /* Classification of different kinds of add instructions. */ 4672 1.1 mrg enum nios2_add_insn_kind { 4673 1.1 mrg nios2_add_n_kind, 4674 1.1 mrg nios2_addi_n_kind, 4675 1.1 mrg nios2_subi_n_kind, 4676 1.1 mrg nios2_spaddi_n_kind, 4677 1.1 mrg nios2_spinci_n_kind, 4678 1.1 mrg nios2_spdeci_n_kind, 4679 1.1 mrg nios2_add_kind, 4680 1.1 mrg nios2_addi_kind 4681 1.1 mrg }; 4682 1.1 mrg 4683 1.1 mrg static const char *nios2_add_insn_names[] = { 4684 1.1 mrg "add.n", "addi.n", "subi.n", "spaddi.n", "spinci.n", "spdeci.n", 4685 1.1 mrg "add", "addi" }; 4686 1.1 mrg static bool nios2_add_insn_narrow[] = { 4687 1.1 mrg true, true, true, true, true, true, 4688 1.1 mrg false, false}; 4689 1.1 mrg 4690 1.1 mrg /* Function to classify kinds of add instruction patterns. */ 4691 1.1 mrg static enum nios2_add_insn_kind 4692 1.1 mrg nios2_add_insn_classify (rtx_insn *insn ATTRIBUTE_UNUSED, 4693 1.1 mrg rtx lhs, rtx rhs1, rtx rhs2) 4694 1.1 mrg { 4695 1.1 mrg if (TARGET_HAS_CDX) 4696 1.1 mrg { 4697 1.1 mrg if (cdxreg (lhs) && cdxreg (rhs1)) 4698 1.1 mrg { 4699 1.1 mrg if (cdxreg (rhs2)) 4700 1.1 mrg return nios2_add_n_kind; 4701 1.1 mrg if (CONST_INT_P (rhs2)) 4702 1.1 mrg { 4703 1.1 mrg HOST_WIDE_INT ival = INTVAL (rhs2); 4704 1.1 mrg if (ival > 0 && cdx_add_immed (rhs2)) 4705 1.1 mrg return nios2_addi_n_kind; 4706 1.1 mrg if (ival < 0 && cdx_add_immed (GEN_INT (-ival))) 4707 1.1 mrg return nios2_subi_n_kind; 4708 1.1 mrg } 4709 1.1 mrg } 4710 1.1 mrg else if (rhs1 == stack_pointer_rtx 4711 1.1 mrg && CONST_INT_P (rhs2)) 4712 1.1 mrg { 4713 1.1 mrg HOST_WIDE_INT imm7 = INTVAL (rhs2) >> 2; 4714 1.1 mrg HOST_WIDE_INT rem = INTVAL (rhs2) & 3; 4715 1.1 mrg if (rem == 0 && (imm7 & ~0x7f) == 0) 4716 1.1 mrg { 4717 1.1 mrg if (cdxreg (lhs)) 4718 1.1 mrg return nios2_spaddi_n_kind; 4719 1.1 mrg if (lhs == stack_pointer_rtx) 4720 1.1 mrg return nios2_spinci_n_kind; 4721 1.1 mrg } 4722 1.1 mrg imm7 = -INTVAL(rhs2) >> 2; 4723 1.1 mrg rem = -INTVAL (rhs2) & 3; 4724 1.1 mrg if (lhs == stack_pointer_rtx 4725 1.1 mrg && rem == 0 && (imm7 & ~0x7f) == 0) 4726 1.1 mrg return nios2_spdeci_n_kind; 4727 1.1 mrg } 4728 1.1 mrg } 4729 1.1 mrg return ((REG_P (rhs2) || rhs2 == const0_rtx) 4730 1.1 mrg ? nios2_add_kind : nios2_addi_kind); 4731 1.1 mrg } 4732 1.1 mrg 4733 1.1 mrg /* Emit assembly language for the different kinds of add instructions. */ 4734 1.1 mrg const char* 4735 1.1 mrg nios2_add_insn_asm (rtx_insn *insn, rtx *operands) 4736 1.1 mrg { 4737 1.1 mrg static char buf[256]; 4738 1.1 mrg int ln = 256; 4739 1.1 mrg enum nios2_add_insn_kind kind 4740 1.1 mrg = nios2_add_insn_classify (insn, operands[0], operands[1], operands[2]); 4741 1.1 mrg if (kind == nios2_subi_n_kind) 4742 1.1 mrg snprintf (buf, ln, "subi.n\t%%0, %%1, %d", (int) -INTVAL (operands[2])); 4743 1.1 mrg else if (kind == nios2_spaddi_n_kind) 4744 1.1 mrg snprintf (buf, ln, "spaddi.n\t%%0, %%2"); 4745 1.1 mrg else if (kind == nios2_spinci_n_kind) 4746 1.1 mrg snprintf (buf, ln, "spinci.n\t%%2"); 4747 1.1 mrg else if (kind == nios2_spdeci_n_kind) 4748 1.1 mrg snprintf (buf, ln, "spdeci.n\t%d", (int) -INTVAL (operands[2])); 4749 1.1 mrg else 4750 1.1 mrg snprintf (buf, ln, "%s\t%%0, %%1, %%z2", nios2_add_insn_names[(int)kind]); 4751 1.1 mrg return buf; 4752 1.1 mrg } 4753 1.1 mrg 4754 1.1 mrg /* This routine, which the default "length" attribute computation is 4755 1.1 mrg based on, encapsulates information about all the cases where CDX 4756 1.1 mrg provides a narrow 2-byte instruction form. */ 4757 1.1 mrg bool 4758 1.1 mrg nios2_cdx_narrow_form_p (rtx_insn *insn) 4759 1.1 mrg { 4760 1.1 mrg rtx pat, lhs, rhs1 = NULL_RTX, rhs2 = NULL_RTX; 4761 1.1 mrg enum attr_type type; 4762 1.1 mrg if (!TARGET_HAS_CDX) 4763 1.1 mrg return false; 4764 1.1 mrg type = get_attr_type (insn); 4765 1.1 mrg pat = PATTERN (insn); 4766 1.1 mrg gcc_assert (reload_completed); 4767 1.1 mrg switch (type) 4768 1.1 mrg { 4769 1.1 mrg case TYPE_CONTROL: 4770 1.1 mrg if (GET_CODE (pat) == SIMPLE_RETURN) 4771 1.1 mrg return true; 4772 1.1 mrg if (GET_CODE (pat) == PARALLEL) 4773 1.1 mrg pat = XVECEXP (pat, 0, 0); 4774 1.1 mrg if (GET_CODE (pat) == SET) 4775 1.1 mrg pat = SET_SRC (pat); 4776 1.1 mrg if (GET_CODE (pat) == IF_THEN_ELSE) 4777 1.1 mrg { 4778 1.1 mrg /* Conditional branch patterns; for these we 4779 1.1 mrg only check the comparison to find beqz.n/bnez.n cases. 4780 1.1 mrg For the 'nios2_cbranch' pattern, we cannot also check 4781 1.1 mrg the branch range here. That will be done at the md 4782 1.1 mrg pattern "length" attribute computation. */ 4783 1.1 mrg rtx cmp = XEXP (pat, 0); 4784 1.1 mrg return ((GET_CODE (cmp) == EQ || GET_CODE (cmp) == NE) 4785 1.1 mrg && cdxreg (XEXP (cmp, 0)) 4786 1.1 mrg && XEXP (cmp, 1) == const0_rtx); 4787 1.1 mrg } 4788 1.1 mrg if (GET_CODE (pat) == TRAP_IF) 4789 1.1 mrg /* trap.n is always usable. */ 4790 1.1 mrg return true; 4791 1.1 mrg if (GET_CODE (pat) == CALL) 4792 1.1 mrg pat = XEXP (XEXP (pat, 0), 0); 4793 1.1 mrg if (REG_P (pat)) 4794 1.1 mrg /* Control instructions taking a register operand are indirect 4795 1.1 mrg jumps and calls. The CDX instructions have a 5-bit register 4796 1.1 mrg field so any reg is valid. */ 4797 1.1 mrg return true; 4798 1.1 mrg else 4799 1.1 mrg { 4800 1.1 mrg gcc_assert (!insn_variable_length_p (insn)); 4801 1.1 mrg return false; 4802 1.1 mrg } 4803 1.1 mrg case TYPE_ADD: 4804 1.1 mrg { 4805 1.1 mrg enum nios2_add_insn_kind kind; 4806 1.1 mrg split_alu_insn (insn, &lhs, &rhs1, &rhs2); 4807 1.1 mrg kind = nios2_add_insn_classify (insn, lhs, rhs1, rhs2); 4808 1.1 mrg return nios2_add_insn_narrow[(int)kind]; 4809 1.1 mrg } 4810 1.1 mrg case TYPE_LD: 4811 1.1 mrg { 4812 1.1 mrg bool ret; 4813 1.1 mrg HOST_WIDE_INT offset, rem = 0; 4814 1.1 mrg rtx addr, reg = SET_DEST (pat), mem = SET_SRC (pat); 4815 1.1 mrg if (GET_CODE (mem) == SIGN_EXTEND) 4816 1.1 mrg /* No CDX form for sign-extended load. */ 4817 1.1 mrg return false; 4818 1.1 mrg if (GET_CODE (mem) == ZERO_EXTEND) 4819 1.1 mrg /* The load alternatives in the zero_extend* patterns. */ 4820 1.1 mrg mem = XEXP (mem, 0); 4821 1.1 mrg if (MEM_P (mem)) 4822 1.1 mrg { 4823 1.1 mrg /* ldxio. */ 4824 1.1 mrg if ((MEM_VOLATILE_P (mem) && TARGET_BYPASS_CACHE_VOLATILE) 4825 1.1 mrg || TARGET_BYPASS_CACHE) 4826 1.1 mrg return false; 4827 1.1 mrg addr = XEXP (mem, 0); 4828 1.1 mrg /* GP-based and R0-based references are never narrow. */ 4829 1.1 mrg if (gprel_constant_p (addr) || r0rel_constant_p (addr)) 4830 1.1 mrg return false; 4831 1.1 mrg /* %lo requires a 16-bit relocation and is never narrow. */ 4832 1.1 mrg if (GET_CODE (addr) == LO_SUM) 4833 1.1 mrg return false; 4834 1.1 mrg ret = split_mem_address (addr, &rhs1, &rhs2); 4835 1.1 mrg gcc_assert (ret); 4836 1.1 mrg } 4837 1.1 mrg else 4838 1.1 mrg return false; 4839 1.1 mrg 4840 1.1 mrg offset = INTVAL (rhs2); 4841 1.1 mrg if (GET_MODE (mem) == SImode) 4842 1.1 mrg { 4843 1.1 mrg rem = offset & 3; 4844 1.1 mrg offset >>= 2; 4845 1.1 mrg /* ldwsp.n case. */ 4846 1.1 mrg if (rtx_equal_p (rhs1, stack_pointer_rtx) 4847 1.1 mrg && rem == 0 && (offset & ~0x1f) == 0) 4848 1.1 mrg return true; 4849 1.1 mrg } 4850 1.1 mrg else if (GET_MODE (mem) == HImode) 4851 1.1 mrg { 4852 1.1 mrg rem = offset & 1; 4853 1.1 mrg offset >>= 1; 4854 1.1 mrg } 4855 1.1 mrg /* ldbu.n, ldhu.n, ldw.n cases. */ 4856 1.1 mrg return (cdxreg (reg) && cdxreg (rhs1) 4857 1.1 mrg && rem == 0 && (offset & ~0xf) == 0); 4858 1.1 mrg } 4859 1.1 mrg case TYPE_ST: 4860 1.1 mrg if (GET_CODE (pat) == PARALLEL) 4861 1.1 mrg /* stex, stsex. */ 4862 1.1 mrg return false; 4863 1.1 mrg else 4864 1.1 mrg { 4865 1.1 mrg bool ret; 4866 1.1 mrg HOST_WIDE_INT offset, rem = 0; 4867 1.1 mrg rtx addr, reg = SET_SRC (pat), mem = SET_DEST (pat); 4868 1.1 mrg if (!MEM_P (mem)) 4869 1.1 mrg return false; 4870 1.1 mrg /* stxio. */ 4871 1.1 mrg if ((MEM_VOLATILE_P (mem) && TARGET_BYPASS_CACHE_VOLATILE) 4872 1.1 mrg || TARGET_BYPASS_CACHE) 4873 1.1 mrg return false; 4874 1.1 mrg addr = XEXP (mem, 0); 4875 1.1 mrg /* GP-based and r0-based references are never narrow. */ 4876 1.1 mrg if (gprel_constant_p (addr) || r0rel_constant_p (addr)) 4877 1.1 mrg return false; 4878 1.1 mrg /* %lo requires a 16-bit relocation and is never narrow. */ 4879 1.1 mrg if (GET_CODE (addr) == LO_SUM) 4880 1.1 mrg return false; 4881 1.1 mrg ret = split_mem_address (addr, &rhs1, &rhs2); 4882 1.1 mrg gcc_assert (ret); 4883 1.1 mrg offset = INTVAL (rhs2); 4884 1.1 mrg if (GET_MODE (mem) == SImode) 4885 1.1 mrg { 4886 1.1 mrg rem = offset & 3; 4887 1.1 mrg offset >>= 2; 4888 1.1 mrg /* stwsp.n case. */ 4889 1.1 mrg if (rtx_equal_p (rhs1, stack_pointer_rtx) 4890 1.1 mrg && rem == 0 && (offset & ~0x1f) == 0) 4891 1.1 mrg return true; 4892 1.1 mrg /* stwz.n case. */ 4893 1.1 mrg else if (reg == const0_rtx && cdxreg (rhs1) 4894 1.1 mrg && rem == 0 && (offset & ~0x3f) == 0) 4895 1.1 mrg return true; 4896 1.1 mrg } 4897 1.1 mrg else if (GET_MODE (mem) == HImode) 4898 1.1 mrg { 4899 1.1 mrg rem = offset & 1; 4900 1.1 mrg offset >>= 1; 4901 1.1 mrg } 4902 1.1 mrg else 4903 1.1 mrg { 4904 1.1 mrg gcc_assert (GET_MODE (mem) == QImode); 4905 1.1 mrg /* stbz.n case. */ 4906 1.1 mrg if (reg == const0_rtx && cdxreg (rhs1) 4907 1.1 mrg && (offset & ~0x3f) == 0) 4908 1.1 mrg return true; 4909 1.1 mrg } 4910 1.1 mrg 4911 1.1 mrg /* stbu.n, sthu.n, stw.n cases. */ 4912 1.1 mrg return (cdxreg (reg) && cdxreg (rhs1) 4913 1.1 mrg && rem == 0 && (offset & ~0xf) == 0); 4914 1.1 mrg } 4915 1.1 mrg case TYPE_MOV: 4916 1.1 mrg lhs = SET_DEST (pat); 4917 1.1 mrg rhs1 = SET_SRC (pat); 4918 1.1 mrg if (CONST_INT_P (rhs1)) 4919 1.1 mrg return (cdxreg (lhs) && cdx_mov_immed (rhs1)); 4920 1.1 mrg gcc_assert (REG_P (lhs) && REG_P (rhs1)); 4921 1.1 mrg return true; 4922 1.1 mrg 4923 1.1 mrg case TYPE_AND: 4924 1.1 mrg /* Some zero_extend* alternatives are and insns. */ 4925 1.1 mrg if (GET_CODE (SET_SRC (pat)) == ZERO_EXTEND) 4926 1.1 mrg return (cdxreg (SET_DEST (pat)) 4927 1.1 mrg && cdxreg (XEXP (SET_SRC (pat), 0))); 4928 1.1 mrg split_alu_insn (insn, &lhs, &rhs1, &rhs2); 4929 1.1 mrg if (CONST_INT_P (rhs2)) 4930 1.1 mrg return (cdxreg (lhs) && cdxreg (rhs1) && cdx_and_immed (rhs2)); 4931 1.1 mrg return (cdxreg (lhs) && cdxreg (rhs2) 4932 1.1 mrg && (!reload_completed || rtx_equal_p (lhs, rhs1))); 4933 1.1 mrg 4934 1.1 mrg case TYPE_OR: 4935 1.1 mrg case TYPE_XOR: 4936 1.1 mrg /* Note the two-address limitation for CDX form. */ 4937 1.1 mrg split_alu_insn (insn, &lhs, &rhs1, &rhs2); 4938 1.1 mrg return (cdxreg (lhs) && cdxreg (rhs2) 4939 1.1 mrg && (!reload_completed || rtx_equal_p (lhs, rhs1))); 4940 1.1 mrg 4941 1.1 mrg case TYPE_SUB: 4942 1.1 mrg split_alu_insn (insn, &lhs, &rhs1, &rhs2); 4943 1.1 mrg return (cdxreg (lhs) && cdxreg (rhs1) && cdxreg (rhs2)); 4944 1.1 mrg 4945 1.1 mrg case TYPE_NEG: 4946 1.1 mrg case TYPE_NOT: 4947 1.1 mrg split_alu_insn (insn, &lhs, &rhs1, NULL); 4948 1.1 mrg return (cdxreg (lhs) && cdxreg (rhs1)); 4949 1.1 mrg 4950 1.1 mrg case TYPE_SLL: 4951 1.1 mrg case TYPE_SRL: 4952 1.1 mrg split_alu_insn (insn, &lhs, &rhs1, &rhs2); 4953 1.1 mrg return (cdxreg (lhs) 4954 1.1 mrg && ((cdxreg (rhs1) && cdx_shift_immed (rhs2)) 4955 1.1 mrg || (cdxreg (rhs2) 4956 1.1 mrg && (!reload_completed || rtx_equal_p (lhs, rhs1))))); 4957 1.1 mrg case TYPE_NOP: 4958 1.1 mrg case TYPE_PUSH: 4959 1.1 mrg case TYPE_POP: 4960 1.1 mrg return true; 4961 1.1 mrg default: 4962 1.1 mrg break; 4963 1.1 mrg } 4964 1.1 mrg return false; 4965 1.1 mrg } 4966 1.1 mrg 4967 1.1 mrg /* Main function to implement the pop_operation predicate that 4968 1.1 mrg check pop.n insn pattern integrity. The CDX pop.n patterns mostly 4969 1.1 mrg hardcode the restored registers, so the main checking is for the 4970 1.1 mrg SP offsets. */ 4971 1.1 mrg bool 4972 1.1 mrg pop_operation_p (rtx op) 4973 1.1 mrg { 4974 1.1 mrg int i; 4975 1.1 mrg HOST_WIDE_INT last_offset = -1, len = XVECLEN (op, 0); 4976 1.1 mrg rtx base_reg, offset; 4977 1.1 mrg 4978 1.1 mrg if (len < 3 /* At least has a return, SP-update, and RA restore. */ 4979 1.1 mrg || GET_CODE (XVECEXP (op, 0, 0)) != RETURN 4980 1.1 mrg || !base_reg_adjustment_p (XVECEXP (op, 0, 1), &base_reg, &offset) 4981 1.1 mrg || !rtx_equal_p (base_reg, stack_pointer_rtx) 4982 1.1 mrg || !CONST_INT_P (offset) 4983 1.1 mrg || (INTVAL (offset) & 3) != 0) 4984 1.1 mrg return false; 4985 1.1 mrg 4986 1.1 mrg for (i = len - 1; i > 1; i--) 4987 1.1 mrg { 4988 1.1 mrg rtx set = XVECEXP (op, 0, i); 4989 1.1 mrg rtx curr_base_reg, curr_offset; 4990 1.1 mrg 4991 1.1 mrg if (GET_CODE (set) != SET || !MEM_P (SET_SRC (set)) 4992 1.1 mrg || !split_mem_address (XEXP (SET_SRC (set), 0), 4993 1.1 mrg &curr_base_reg, &curr_offset) 4994 1.1 mrg || !rtx_equal_p (base_reg, curr_base_reg) 4995 1.1 mrg || !CONST_INT_P (curr_offset)) 4996 1.1 mrg return false; 4997 1.1 mrg if (i == len - 1) 4998 1.1 mrg { 4999 1.1 mrg last_offset = INTVAL (curr_offset); 5000 1.1 mrg if ((last_offset & 3) != 0 || last_offset > 60) 5001 1.1 mrg return false; 5002 1.1 mrg } 5003 1.1 mrg else 5004 1.1 mrg { 5005 1.1 mrg last_offset += 4; 5006 1.1 mrg if (INTVAL (curr_offset) != last_offset) 5007 1.1 mrg return false; 5008 1.1 mrg } 5009 1.1 mrg } 5010 1.1 mrg if (last_offset < 0 || last_offset + 4 != INTVAL (offset)) 5011 1.1 mrg return false; 5012 1.1 mrg 5013 1.1 mrg return true; 5014 1.1 mrg } 5015 1.1 mrg 5016 1.1 mrg 5017 1.1 mrg /* Masks of registers that are valid for CDX ldwm/stwm instructions. 5018 1.1 mrg The instruction can encode subsets drawn from either R2-R13 or 5019 1.1 mrg R14-R23 + FP + RA. */ 5020 1.1 mrg #define CDX_LDSTWM_VALID_REGS_0 0x00003ffc 5021 1.1 mrg #define CDX_LDSTWM_VALID_REGS_1 0x90ffc000 5022 1.1 mrg 5023 1.1 mrg static bool 5024 1.1 mrg nios2_ldstwm_regset_p (unsigned int regno, unsigned int *regset) 5025 1.1 mrg { 5026 1.1 mrg if (*regset == 0) 5027 1.1 mrg { 5028 1.1 mrg if (CDX_LDSTWM_VALID_REGS_0 & (1 << regno)) 5029 1.1 mrg *regset = CDX_LDSTWM_VALID_REGS_0; 5030 1.1 mrg else if (CDX_LDSTWM_VALID_REGS_1 & (1 << regno)) 5031 1.1 mrg *regset = CDX_LDSTWM_VALID_REGS_1; 5032 1.1 mrg else 5033 1.1 mrg return false; 5034 1.1 mrg return true; 5035 1.1 mrg } 5036 1.1 mrg else 5037 1.1 mrg return (*regset & (1 << regno)) != 0; 5038 1.1 mrg } 5039 1.1 mrg 5040 1.1 mrg /* Main function to implement ldwm_operation/stwm_operation 5041 1.1 mrg predicates that check ldwm/stwm insn pattern integrity. */ 5042 1.1 mrg bool 5043 1.1 mrg ldstwm_operation_p (rtx op, bool load_p) 5044 1.1 mrg { 5045 1.1 mrg int start, i, end = XVECLEN (op, 0) - 1, last_regno = -1; 5046 1.1 mrg unsigned int regset = 0; 5047 1.1 mrg rtx base_reg, offset; 5048 1.1 mrg rtx first_elt = XVECEXP (op, 0, 0); 5049 1.1 mrg bool inc_p = true; 5050 1.1 mrg bool wb_p = base_reg_adjustment_p (first_elt, &base_reg, &offset); 5051 1.1 mrg if (GET_CODE (XVECEXP (op, 0, end)) == RETURN) 5052 1.1 mrg end--; 5053 1.1 mrg start = wb_p ? 1 : 0; 5054 1.1 mrg for (i = start; i <= end; i++) 5055 1.1 mrg { 5056 1.1 mrg int regno; 5057 1.1 mrg rtx reg, mem, elt = XVECEXP (op, 0, i); 5058 1.1 mrg /* Return early if not a SET at all. */ 5059 1.1 mrg if (GET_CODE (elt) != SET) 5060 1.1 mrg return false; 5061 1.1 mrg reg = load_p ? SET_DEST (elt) : SET_SRC (elt); 5062 1.1 mrg mem = load_p ? SET_SRC (elt) : SET_DEST (elt); 5063 1.1 mrg if (!REG_P (reg) || !MEM_P (mem)) 5064 1.1 mrg return false; 5065 1.1 mrg regno = REGNO (reg); 5066 1.1 mrg if (!nios2_ldstwm_regset_p (regno, ®set)) 5067 1.1 mrg return false; 5068 1.1 mrg /* If no writeback to determine direction, use offset of first MEM. */ 5069 1.1 mrg if (wb_p) 5070 1.1 mrg inc_p = INTVAL (offset) > 0; 5071 1.1 mrg else if (i == start) 5072 1.1 mrg { 5073 1.1 mrg rtx first_base, first_offset; 5074 1.1 mrg if (!split_mem_address (XEXP (mem, 0), 5075 1.1 mrg &first_base, &first_offset)) 5076 1.1 mrg return false; 5077 1.1 mrg if (!REG_P (first_base) || !CONST_INT_P (first_offset)) 5078 1.1 mrg return false; 5079 1.1 mrg base_reg = first_base; 5080 1.1 mrg inc_p = INTVAL (first_offset) >= 0; 5081 1.1 mrg } 5082 1.1 mrg /* Ensure that the base register is not loaded into. */ 5083 1.1 mrg if (load_p && regno == (int) REGNO (base_reg)) 5084 1.1 mrg return false; 5085 1.1 mrg /* Check for register order inc/dec integrity. */ 5086 1.1 mrg if (last_regno >= 0) 5087 1.1 mrg { 5088 1.1 mrg if (inc_p && last_regno >= regno) 5089 1.1 mrg return false; 5090 1.1 mrg if (!inc_p && last_regno <= regno) 5091 1.1 mrg return false; 5092 1.1 mrg } 5093 1.1 mrg last_regno = regno; 5094 1.1 mrg } 5095 1.1 mrg return true; 5096 1.1 mrg } 5097 1.1 mrg 5098 1.1 mrg /* Helper for nios2_ldst_parallel, for generating a parallel vector 5099 1.1 mrg SET element. */ 5100 1.1 mrg static rtx 5101 1.1 mrg gen_ldst (bool load_p, int regno, rtx base_mem, int offset) 5102 1.1 mrg { 5103 1.1 mrg rtx reg = gen_rtx_REG (SImode, regno); 5104 1.1 mrg rtx mem = adjust_address_nv (base_mem, SImode, offset); 5105 1.1 mrg return gen_rtx_SET (load_p ? reg : mem, 5106 1.1 mrg load_p ? mem : reg); 5107 1.1 mrg } 5108 1.1 mrg 5109 1.1 mrg /* A general routine for creating the body RTL pattern of 5110 1.1 mrg ldwm/stwm/push.n/pop.n insns. 5111 1.1 mrg LOAD_P: true/false for load/store direction. 5112 1.1 mrg REG_INC_P: whether registers are incrementing/decrementing in the 5113 1.1 mrg *RTL vector* (not necessarily the order defined in the ISA specification). 5114 1.1 mrg OFFSET_INC_P: Same as REG_INC_P, but for the memory offset order. 5115 1.1 mrg BASE_MEM: starting MEM. 5116 1.1 mrg BASE_UPDATE: amount to update base register; zero means no writeback. 5117 1.1 mrg REGMASK: register mask to load/store. 5118 1.1 mrg RET_P: true if to tag a (return) element at the end. 5119 1.1 mrg 5120 1.1 mrg Note that this routine does not do any checking. It's the job of the 5121 1.1 mrg caller to do the right thing, and the insn patterns to do the 5122 1.1 mrg safe-guarding. */ 5123 1.1 mrg static rtx 5124 1.1 mrg nios2_ldst_parallel (bool load_p, bool reg_inc_p, bool offset_inc_p, 5125 1.1 mrg rtx base_mem, int base_update, 5126 1.1 mrg unsigned HOST_WIDE_INT regmask, bool ret_p) 5127 1.1 mrg { 5128 1.1 mrg rtvec p; 5129 1.1 mrg int regno, b = 0, i = 0, n = 0, len = popcount_hwi (regmask); 5130 1.1 mrg if (ret_p) len++, i++, b++; 5131 1.1 mrg if (base_update != 0) len++, i++; 5132 1.1 mrg p = rtvec_alloc (len); 5133 1.1 mrg for (regno = (reg_inc_p ? 0 : 31); 5134 1.1 mrg regno != (reg_inc_p ? 32 : -1); 5135 1.1 mrg regno += (reg_inc_p ? 1 : -1)) 5136 1.1 mrg if ((regmask & (1 << regno)) != 0) 5137 1.1 mrg { 5138 1.1 mrg int offset = (offset_inc_p ? 4 : -4) * n++; 5139 1.1 mrg RTVEC_ELT (p, i++) = gen_ldst (load_p, regno, base_mem, offset); 5140 1.1 mrg } 5141 1.1 mrg if (ret_p) 5142 1.1 mrg RTVEC_ELT (p, 0) = ret_rtx; 5143 1.1 mrg if (base_update != 0) 5144 1.1 mrg { 5145 1.1 mrg rtx reg, offset; 5146 1.1 mrg if (!split_mem_address (XEXP (base_mem, 0), ®, &offset)) 5147 1.1 mrg gcc_unreachable (); 5148 1.1 mrg RTVEC_ELT (p, b) = 5149 1.1 mrg gen_rtx_SET (reg, plus_constant (Pmode, reg, base_update)); 5150 1.1 mrg } 5151 1.1 mrg return gen_rtx_PARALLEL (VOIDmode, p); 5152 1.1 mrg } 5153 1.1 mrg 5154 1.1 mrg /* CDX ldwm/stwm peephole optimization pattern related routines. */ 5155 1.1 mrg 5156 1.1 mrg /* Data structure and sorting function for ldwm/stwm peephole optimizers. */ 5157 1.1 mrg struct ldstwm_operand 5158 1.1 mrg { 5159 1.1 mrg int offset; /* Offset from base register. */ 5160 1.1 mrg rtx reg; /* Register to store at this offset. */ 5161 1.1 mrg rtx mem; /* Original mem. */ 5162 1.1 mrg bool bad; /* True if this load/store can't be combined. */ 5163 1.1 mrg bool rewrite; /* True if we should rewrite using scratch. */ 5164 1.1 mrg }; 5165 1.1 mrg 5166 1.1 mrg static int 5167 1.1 mrg compare_ldstwm_operands (const void *arg1, const void *arg2) 5168 1.1 mrg { 5169 1.1 mrg const struct ldstwm_operand *op1 = (const struct ldstwm_operand *) arg1; 5170 1.1 mrg const struct ldstwm_operand *op2 = (const struct ldstwm_operand *) arg2; 5171 1.1 mrg if (op1->bad) 5172 1.1 mrg return op2->bad ? 0 : 1; 5173 1.1 mrg else if (op2->bad) 5174 1.1 mrg return -1; 5175 1.1 mrg else 5176 1.1 mrg return op1->offset - op2->offset; 5177 1.1 mrg } 5178 1.1 mrg 5179 1.1 mrg /* Helper function: return true if a load/store using REGNO with address 5180 1.1 mrg BASEREG and offset OFFSET meets the constraints for a 2-byte CDX ldw.n, 5181 1.1 mrg stw.n, ldwsp.n, or stwsp.n instruction. */ 5182 1.1 mrg static bool 5183 1.1 mrg can_use_cdx_ldstw (int regno, int basereg, int offset) 5184 1.1 mrg { 5185 1.1 mrg if (CDX_REG_P (regno) && CDX_REG_P (basereg) 5186 1.1 mrg && (offset & 0x3) == 0 && offset >= 0 && offset < 0x40) 5187 1.1 mrg return true; 5188 1.1 mrg else if (basereg == SP_REGNO 5189 1.1 mrg && offset >= 0 && offset < 0x80 && (offset & 0x3) == 0) 5190 1.1 mrg return true; 5191 1.1 mrg return false; 5192 1.1 mrg } 5193 1.1 mrg 5194 1.1 mrg /* This function is called from peephole2 optimizers to try to merge 5195 1.1 mrg a series of individual loads and stores into a ldwm or stwm. It 5196 1.1 mrg can also rewrite addresses inside the individual loads and stores 5197 1.1 mrg using a common base register using a scratch register and smaller 5198 1.1 mrg offsets if that allows them to use CDX ldw.n or stw.n instructions 5199 1.1 mrg instead of 4-byte loads or stores. 5200 1.1 mrg N is the number of insns we are trying to merge. SCRATCH is non-null 5201 1.1 mrg if there is a scratch register available. The OPERANDS array contains 5202 1.1 mrg alternating REG (even) and MEM (odd) operands. */ 5203 1.1 mrg bool 5204 1.1 mrg gen_ldstwm_peep (bool load_p, int n, rtx scratch, rtx *operands) 5205 1.1 mrg { 5206 1.1 mrg /* CDX ldwm/stwm instructions allow a maximum of 12 registers to be 5207 1.1 mrg specified. */ 5208 1.1 mrg #define MAX_LDSTWM_OPS 12 5209 1.1 mrg struct ldstwm_operand sort[MAX_LDSTWM_OPS]; 5210 1.1 mrg int basereg = -1; 5211 1.1 mrg int baseoffset; 5212 1.1 mrg int i, m, lastoffset, lastreg; 5213 1.1 mrg unsigned int regmask = 0, usemask = 0, regset; 5214 1.1 mrg bool needscratch; 5215 1.1 mrg int newbasereg; 5216 1.1 mrg int nbytes; 5217 1.1 mrg 5218 1.1 mrg if (!TARGET_HAS_CDX) 5219 1.1 mrg return false; 5220 1.1 mrg if (n < 2 || n > MAX_LDSTWM_OPS) 5221 1.1 mrg return false; 5222 1.1 mrg 5223 1.1 mrg /* Check all the operands for validity and initialize the sort array. 5224 1.1 mrg The places where we return false here are all situations that aren't 5225 1.1 mrg expected to ever happen -- invalid patterns, invalid registers, etc. */ 5226 1.1 mrg for (i = 0; i < n; i++) 5227 1.1 mrg { 5228 1.1 mrg rtx base, offset; 5229 1.1 mrg rtx reg = operands[i]; 5230 1.1 mrg rtx mem = operands[i + n]; 5231 1.1 mrg int r, o, regno; 5232 1.1 mrg bool bad = false; 5233 1.1 mrg 5234 1.1 mrg if (!REG_P (reg) || !MEM_P (mem)) 5235 1.1 mrg return false; 5236 1.1 mrg 5237 1.1 mrg regno = REGNO (reg); 5238 1.1 mrg if (regno > 31) 5239 1.1 mrg return false; 5240 1.1 mrg if (load_p && (regmask & (1 << regno)) != 0) 5241 1.1 mrg return false; 5242 1.1 mrg regmask |= 1 << regno; 5243 1.1 mrg 5244 1.1 mrg if (!split_mem_address (XEXP (mem, 0), &base, &offset)) 5245 1.1 mrg return false; 5246 1.1 mrg r = REGNO (base); 5247 1.1 mrg o = INTVAL (offset); 5248 1.1 mrg 5249 1.1 mrg if (basereg == -1) 5250 1.1 mrg basereg = r; 5251 1.1 mrg else if (r != basereg) 5252 1.1 mrg bad = true; 5253 1.1 mrg usemask |= 1 << r; 5254 1.1 mrg 5255 1.1 mrg sort[i].bad = bad; 5256 1.1 mrg sort[i].rewrite = false; 5257 1.1 mrg sort[i].offset = o; 5258 1.1 mrg sort[i].reg = reg; 5259 1.1 mrg sort[i].mem = mem; 5260 1.1 mrg } 5261 1.1 mrg 5262 1.1 mrg /* If we are doing a series of register loads, we can't safely reorder 5263 1.1 mrg them if any of the regs used in addr expressions are also being set. */ 5264 1.1 mrg if (load_p && (regmask & usemask)) 5265 1.1 mrg return false; 5266 1.1 mrg 5267 1.1 mrg /* Sort the array by increasing mem offset order, then check that 5268 1.1 mrg offsets are valid and register order matches mem order. At the 5269 1.1 mrg end of this loop, m is the number of loads/stores we will try to 5270 1.1 mrg combine; the rest are leftovers. */ 5271 1.1 mrg qsort (sort, n, sizeof (struct ldstwm_operand), compare_ldstwm_operands); 5272 1.1 mrg 5273 1.1 mrg baseoffset = sort[0].offset; 5274 1.1 mrg needscratch = baseoffset != 0; 5275 1.1 mrg if (needscratch && !scratch) 5276 1.1 mrg return false; 5277 1.1 mrg 5278 1.1 mrg lastreg = regmask = regset = 0; 5279 1.1 mrg lastoffset = baseoffset; 5280 1.1 mrg for (m = 0; m < n && !sort[m].bad; m++) 5281 1.1 mrg { 5282 1.1 mrg int thisreg = REGNO (sort[m].reg); 5283 1.1 mrg if (sort[m].offset != lastoffset 5284 1.1 mrg || (m > 0 && lastreg >= thisreg) 5285 1.1 mrg || !nios2_ldstwm_regset_p (thisreg, ®set)) 5286 1.1 mrg break; 5287 1.1 mrg lastoffset += 4; 5288 1.1 mrg lastreg = thisreg; 5289 1.1 mrg regmask |= (1 << thisreg); 5290 1.1 mrg } 5291 1.1 mrg 5292 1.1 mrg /* For loads, make sure we are not overwriting the scratch reg. 5293 1.1 mrg The peephole2 pattern isn't supposed to match unless the register is 5294 1.1 mrg unused all the way through, so this isn't supposed to happen anyway. */ 5295 1.1 mrg if (load_p 5296 1.1 mrg && needscratch 5297 1.1 mrg && ((1 << REGNO (scratch)) & regmask) != 0) 5298 1.1 mrg return false; 5299 1.1 mrg newbasereg = needscratch ? (int) REGNO (scratch) : basereg; 5300 1.1 mrg 5301 1.1 mrg /* We may be able to combine only the first m of the n total loads/stores 5302 1.1 mrg into a single instruction. If m < 2, there's no point in emitting 5303 1.1 mrg a ldwm/stwm at all, but we might be able to do further optimizations 5304 1.1 mrg if we have a scratch. We will count the instruction lengths of the 5305 1.1 mrg old and new patterns and store the savings in nbytes. */ 5306 1.1 mrg if (m < 2) 5307 1.1 mrg { 5308 1.1 mrg if (!needscratch) 5309 1.1 mrg return false; 5310 1.1 mrg m = 0; 5311 1.1 mrg nbytes = 0; 5312 1.1 mrg } 5313 1.1 mrg else 5314 1.1 mrg nbytes = -4; /* Size of ldwm/stwm. */ 5315 1.1 mrg if (needscratch) 5316 1.1 mrg { 5317 1.1 mrg int bo = baseoffset > 0 ? baseoffset : -baseoffset; 5318 1.1 mrg if (CDX_REG_P (newbasereg) 5319 1.1 mrg && CDX_REG_P (basereg) 5320 1.1 mrg && bo <= 128 && bo > 0 && (bo & (bo - 1)) == 0) 5321 1.1 mrg nbytes -= 2; /* Size of addi.n/subi.n. */ 5322 1.1 mrg else 5323 1.1 mrg nbytes -= 4; /* Size of non-CDX addi. */ 5324 1.1 mrg } 5325 1.1 mrg 5326 1.1 mrg /* Count the size of the input load/store instructions being replaced. */ 5327 1.1 mrg for (i = 0; i < m; i++) 5328 1.1 mrg if (can_use_cdx_ldstw (REGNO (sort[i].reg), basereg, sort[i].offset)) 5329 1.1 mrg nbytes += 2; 5330 1.1 mrg else 5331 1.1 mrg nbytes += 4; 5332 1.1 mrg 5333 1.1 mrg /* We may also be able to save a bit if we can rewrite non-CDX 5334 1.1 mrg load/stores that can't be combined into the ldwm/stwm into CDX 5335 1.1 mrg load/stores using the scratch reg. For example, this might happen 5336 1.1 mrg if baseoffset is large, by bringing in the offsets in the load/store 5337 1.1 mrg instructions within the range that fits in the CDX instruction. */ 5338 1.1 mrg if (needscratch && CDX_REG_P (newbasereg)) 5339 1.1 mrg for (i = m; i < n && !sort[i].bad; i++) 5340 1.1 mrg if (!can_use_cdx_ldstw (REGNO (sort[i].reg), basereg, sort[i].offset) 5341 1.1 mrg && can_use_cdx_ldstw (REGNO (sort[i].reg), newbasereg, 5342 1.1 mrg sort[i].offset - baseoffset)) 5343 1.1 mrg { 5344 1.1 mrg sort[i].rewrite = true; 5345 1.1 mrg nbytes += 2; 5346 1.1 mrg } 5347 1.1 mrg 5348 1.1 mrg /* Are we good to go? */ 5349 1.1 mrg if (nbytes <= 0) 5350 1.1 mrg return false; 5351 1.1 mrg 5352 1.1 mrg /* Emit the scratch load. */ 5353 1.1 mrg if (needscratch) 5354 1.1 mrg emit_insn (gen_rtx_SET (scratch, XEXP (sort[0].mem, 0))); 5355 1.1 mrg 5356 1.1 mrg /* Emit the ldwm/stwm insn. */ 5357 1.1 mrg if (m > 0) 5358 1.1 mrg { 5359 1.1 mrg rtvec p = rtvec_alloc (m); 5360 1.1 mrg for (i = 0; i < m; i++) 5361 1.1 mrg { 5362 1.1 mrg int offset = sort[i].offset; 5363 1.1 mrg rtx mem, reg = sort[i].reg; 5364 1.1 mrg rtx base_reg = gen_rtx_REG (Pmode, newbasereg); 5365 1.1 mrg if (needscratch) 5366 1.1 mrg offset -= baseoffset; 5367 1.1 mrg mem = gen_rtx_MEM (SImode, plus_constant (Pmode, base_reg, offset)); 5368 1.1 mrg if (load_p) 5369 1.1 mrg RTVEC_ELT (p, i) = gen_rtx_SET (reg, mem); 5370 1.1 mrg else 5371 1.1 mrg RTVEC_ELT (p, i) = gen_rtx_SET (mem, reg); 5372 1.1 mrg } 5373 1.1 mrg emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); 5374 1.1 mrg } 5375 1.1 mrg 5376 1.1 mrg /* Emit any leftover load/stores as individual instructions, doing 5377 1.1 mrg the previously-noted rewrites to use the scratch reg. */ 5378 1.1 mrg for (i = m; i < n; i++) 5379 1.1 mrg { 5380 1.1 mrg rtx reg = sort[i].reg; 5381 1.1 mrg rtx mem = sort[i].mem; 5382 1.1 mrg if (sort[i].rewrite) 5383 1.1 mrg { 5384 1.1 mrg int offset = sort[i].offset - baseoffset; 5385 1.1 mrg mem = gen_rtx_MEM (SImode, plus_constant (Pmode, scratch, offset)); 5386 1.1 mrg } 5387 1.1 mrg if (load_p) 5388 1.1 mrg emit_move_insn (reg, mem); 5389 1.1 mrg else 5390 1.1 mrg emit_move_insn (mem, reg); 5391 1.1 mrg } 5392 1.1 mrg return true; 5393 1.1 mrg } 5394 1.1 mrg 5395 1.1 mrg /* Implement TARGET_MACHINE_DEPENDENT_REORG: 5396 1.1 mrg We use this hook when emitting CDX code to enforce the 4-byte 5397 1.1 mrg alignment requirement for labels that are used as the targets of 5398 1.1 mrg jmpi instructions. CDX code can otherwise contain a mix of 16-bit 5399 1.1 mrg and 32-bit instructions aligned on any 16-bit boundary, but functions 5400 1.1 mrg and jmpi labels have to be 32-bit aligned because of the way the address 5401 1.1 mrg is encoded in the instruction. */ 5402 1.1 mrg 5403 1.1 mrg static unsigned char *label_align; 5404 1.1 mrg static int min_labelno, max_labelno; 5405 1.1 mrg 5406 1.1 mrg static void 5407 1.1 mrg nios2_reorg (void) 5408 1.1 mrg { 5409 1.1 mrg bool changed = true; 5410 1.1 mrg rtx_insn *insn; 5411 1.1 mrg 5412 1.1 mrg if (!TARGET_HAS_CDX) 5413 1.1 mrg return; 5414 1.1 mrg 5415 1.1 mrg /* Initialize the data structures. */ 5416 1.1 mrg if (label_align) 5417 1.1 mrg free (label_align); 5418 1.1 mrg max_labelno = max_label_num (); 5419 1.1 mrg min_labelno = get_first_label_num (); 5420 1.1 mrg label_align = XCNEWVEC (unsigned char, max_labelno - min_labelno + 1); 5421 1.1 mrg 5422 1.1 mrg /* Iterate on inserting alignment and adjusting branch lengths until 5423 1.1 mrg no more changes. */ 5424 1.1 mrg while (changed) 5425 1.1 mrg { 5426 1.1 mrg changed = false; 5427 1.1 mrg shorten_branches (get_insns ()); 5428 1.1 mrg 5429 1.1 mrg for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn)) 5430 1.1 mrg if (JUMP_P (insn) && insn_variable_length_p (insn)) 5431 1.1 mrg { 5432 1.1 mrg rtx label = JUMP_LABEL (insn); 5433 1.1 mrg /* We use the current fact that all cases of 'jmpi' 5434 1.1 mrg doing the actual branch in the machine description 5435 1.1 mrg has a computed length of 6 or 8. Length 4 and below 5436 1.1 mrg are all PC-relative 'br' branches without the jump-align 5437 1.1 mrg problem. */ 5438 1.1 mrg if (label && LABEL_P (label) && get_attr_length (insn) > 4) 5439 1.1 mrg { 5440 1.1 mrg int index = CODE_LABEL_NUMBER (label) - min_labelno; 5441 1.1 mrg if (label_align[index] != 2) 5442 1.1 mrg { 5443 1.1 mrg label_align[index] = 2; 5444 1.1 mrg changed = true; 5445 1.1 mrg } 5446 1.1 mrg } 5447 1.1 mrg } 5448 1.1 mrg } 5449 1.1 mrg } 5450 1.1 mrg 5451 1.1 mrg /* Implement LABEL_ALIGN, using the information gathered in nios2_reorg. */ 5452 1.1 mrg int 5453 1.1 mrg nios2_label_align (rtx label) 5454 1.1 mrg { 5455 1.1 mrg int n = CODE_LABEL_NUMBER (label); 5456 1.1 mrg 5457 1.1 mrg if (label_align && n >= min_labelno && n <= max_labelno) 5458 1.1 mrg return MAX (label_align[n - min_labelno], align_labels.levels[0].log); 5459 1.1 mrg return align_labels.levels[0].log; 5460 1.1 mrg } 5461 1.1 mrg 5462 1.1 mrg /* Implement ADJUST_REG_ALLOC_ORDER. We use the default ordering 5463 1.1 mrg for R1 and non-CDX R2 code; for CDX we tweak thing to prefer 5464 1.1 mrg the registers that can be used as operands to instructions that 5465 1.1 mrg have 3-bit register fields. */ 5466 1.1 mrg void 5467 1.1 mrg nios2_adjust_reg_alloc_order (void) 5468 1.1 mrg { 5469 1.1 mrg const int cdx_reg_alloc_order[] = 5470 1.1 mrg { 5471 1.1 mrg /* Call-clobbered GPRs within CDX 3-bit encoded range. */ 5472 1.1 mrg 2, 3, 4, 5, 6, 7, 5473 1.1 mrg /* Call-saved GPRs within CDX 3-bit encoded range. */ 5474 1.1 mrg 16, 17, 5475 1.1 mrg /* Other call-clobbered GPRs. */ 5476 1.1 mrg 8, 9, 10, 11, 12, 13, 14, 15, 5477 1.1 mrg /* Other call-saved GPRs. RA placed first since it is always saved. */ 5478 1.1 mrg 31, 18, 19, 20, 21, 22, 23, 28, 5479 1.1 mrg /* Fixed GPRs, not used by the register allocator. */ 5480 1.1 mrg 0, 1, 24, 25, 26, 27, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39 5481 1.1 mrg }; 5482 1.1 mrg 5483 1.1 mrg if (TARGET_HAS_CDX) 5484 1.1 mrg memcpy (reg_alloc_order, cdx_reg_alloc_order, 5485 1.1 mrg sizeof (int) * FIRST_PSEUDO_REGISTER); 5486 1.1 mrg } 5487 1.1 mrg 5488 1.1 mrg 5489 1.1 mrg /* Initialize the GCC target structure. */ 5491 1.1 mrg #undef TARGET_ASM_FUNCTION_PROLOGUE 5492 1.1 mrg #define TARGET_ASM_FUNCTION_PROLOGUE nios2_asm_function_prologue 5493 1.1 mrg 5494 1.1 mrg #undef TARGET_IN_SMALL_DATA_P 5495 1.1 mrg #define TARGET_IN_SMALL_DATA_P nios2_in_small_data_p 5496 1.1 mrg 5497 1.1 mrg #undef TARGET_SECTION_TYPE_FLAGS 5498 1.1 mrg #define TARGET_SECTION_TYPE_FLAGS nios2_section_type_flags 5499 1.1 mrg 5500 1.1 mrg #undef TARGET_INIT_BUILTINS 5501 1.1 mrg #define TARGET_INIT_BUILTINS nios2_init_builtins 5502 1.1 mrg #undef TARGET_EXPAND_BUILTIN 5503 1.1 mrg #define TARGET_EXPAND_BUILTIN nios2_expand_builtin 5504 1.1 mrg #undef TARGET_BUILTIN_DECL 5505 1.1 mrg #define TARGET_BUILTIN_DECL nios2_builtin_decl 5506 1.1 mrg 5507 1.1 mrg #undef TARGET_FUNCTION_OK_FOR_SIBCALL 5508 1.1 mrg #define TARGET_FUNCTION_OK_FOR_SIBCALL hook_bool_tree_tree_true 5509 1.1 mrg 5510 1.1 mrg #undef TARGET_CAN_ELIMINATE 5511 1.1 mrg #define TARGET_CAN_ELIMINATE nios2_can_eliminate 5512 1.1 mrg 5513 1.1 mrg #undef TARGET_FUNCTION_ARG 5514 1.1 mrg #define TARGET_FUNCTION_ARG nios2_function_arg 5515 1.1 mrg 5516 1.1 mrg #undef TARGET_FUNCTION_ARG_ADVANCE 5517 1.1 mrg #define TARGET_FUNCTION_ARG_ADVANCE nios2_function_arg_advance 5518 1.1 mrg 5519 1.1 mrg #undef TARGET_FUNCTION_ARG_PADDING 5520 1.1 mrg #define TARGET_FUNCTION_ARG_PADDING nios2_function_arg_padding 5521 1.1 mrg 5522 1.1 mrg #undef TARGET_ARG_PARTIAL_BYTES 5523 1.1 mrg #define TARGET_ARG_PARTIAL_BYTES nios2_arg_partial_bytes 5524 1.1 mrg 5525 1.1 mrg #undef TARGET_TRAMPOLINE_INIT 5526 1.1 mrg #define TARGET_TRAMPOLINE_INIT nios2_trampoline_init 5527 1.1 mrg 5528 1.1 mrg #undef TARGET_FUNCTION_VALUE 5529 1.1 mrg #define TARGET_FUNCTION_VALUE nios2_function_value 5530 1.1 mrg 5531 1.1 mrg #undef TARGET_LIBCALL_VALUE 5532 1.1 mrg #define TARGET_LIBCALL_VALUE nios2_libcall_value 5533 1.1 mrg 5534 1.1 mrg #undef TARGET_FUNCTION_VALUE_REGNO_P 5535 1.1 mrg #define TARGET_FUNCTION_VALUE_REGNO_P nios2_function_value_regno_p 5536 1.1 mrg 5537 1.1 mrg #undef TARGET_RETURN_IN_MEMORY 5538 1.1 mrg #define TARGET_RETURN_IN_MEMORY nios2_return_in_memory 5539 1.1 mrg 5540 1.1 mrg #undef TARGET_PROMOTE_PROTOTYPES 5541 1.1 mrg #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true 5542 1.1 mrg 5543 1.1 mrg #undef TARGET_SETUP_INCOMING_VARARGS 5544 1.1 mrg #define TARGET_SETUP_INCOMING_VARARGS nios2_setup_incoming_varargs 5545 1.1 mrg 5546 1.1 mrg #undef TARGET_MUST_PASS_IN_STACK 5547 1.1 mrg #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size 5548 1.1 mrg 5549 1.1 mrg #undef TARGET_LEGITIMATE_CONSTANT_P 5550 1.1 mrg #define TARGET_LEGITIMATE_CONSTANT_P nios2_legitimate_constant_p 5551 1.1 mrg 5552 1.1 mrg #undef TARGET_LEGITIMIZE_ADDRESS 5553 1.1 mrg #define TARGET_LEGITIMIZE_ADDRESS nios2_legitimize_address 5554 1.1 mrg 5555 1.1 mrg #undef TARGET_DELEGITIMIZE_ADDRESS 5556 1.1 mrg #define TARGET_DELEGITIMIZE_ADDRESS nios2_delegitimize_address 5557 1.1 mrg 5558 1.1 mrg #undef TARGET_LEGITIMATE_ADDRESS_P 5559 1.1 mrg #define TARGET_LEGITIMATE_ADDRESS_P nios2_legitimate_address_p 5560 1.1 mrg 5561 1.1 mrg #undef TARGET_PREFERRED_RELOAD_CLASS 5562 1.1 mrg #define TARGET_PREFERRED_RELOAD_CLASS nios2_preferred_reload_class 5563 1.1 mrg 5564 1.1 mrg #undef TARGET_RTX_COSTS 5565 1.1 mrg #define TARGET_RTX_COSTS nios2_rtx_costs 5566 1.1 mrg 5567 1.1 mrg #undef TARGET_ADDRESS_COST 5568 1.1 mrg #define TARGET_ADDRESS_COST nios2_address_cost 5569 1.1 mrg 5570 1.1 mrg #undef TARGET_HAVE_TLS 5571 1.1 mrg #define TARGET_HAVE_TLS TARGET_LINUX_ABI 5572 1.1 mrg 5573 1.1 mrg #undef TARGET_CANNOT_FORCE_CONST_MEM 5574 1.1 mrg #define TARGET_CANNOT_FORCE_CONST_MEM nios2_cannot_force_const_mem 5575 1.1 mrg 5576 1.1 mrg #undef TARGET_ASM_OUTPUT_DWARF_DTPREL 5577 1.1 mrg #define TARGET_ASM_OUTPUT_DWARF_DTPREL nios2_output_dwarf_dtprel 5578 1.1 mrg 5579 1.1 mrg #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P 5580 1.1 mrg #define TARGET_PRINT_OPERAND_PUNCT_VALID_P nios2_print_operand_punct_valid_p 5581 1.1 mrg 5582 1.1 mrg #undef TARGET_PRINT_OPERAND 5583 1.1 mrg #define TARGET_PRINT_OPERAND nios2_print_operand 5584 1.1 mrg 5585 1.1 mrg #undef TARGET_PRINT_OPERAND_ADDRESS 5586 1.1 mrg #define TARGET_PRINT_OPERAND_ADDRESS nios2_print_operand_address 5587 1.1 mrg 5588 1.1 mrg #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA 5589 1.1 mrg #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA nios2_output_addr_const_extra 5590 1.1 mrg 5591 1.1 mrg #undef TARGET_ASM_FILE_END 5592 1.1 mrg #define TARGET_ASM_FILE_END nios2_asm_file_end 5593 1.1 mrg 5594 1.1 mrg #undef TARGET_OPTION_OVERRIDE 5595 1.1 mrg #define TARGET_OPTION_OVERRIDE nios2_option_override 5596 1.1 mrg 5597 1.1 mrg #undef TARGET_OPTION_SAVE 5598 1.1 mrg #define TARGET_OPTION_SAVE nios2_option_save 5599 1.1 mrg 5600 1.1 mrg #undef TARGET_OPTION_RESTORE 5601 1.1 mrg #define TARGET_OPTION_RESTORE nios2_option_restore 5602 1.1 mrg 5603 1.1 mrg #undef TARGET_CAN_INLINE_P 5604 1.1 mrg #define TARGET_CAN_INLINE_P nios2_can_inline_p 5605 1.1 mrg 5606 1.1 mrg #undef TARGET_SET_CURRENT_FUNCTION 5607 1.1 mrg #define TARGET_SET_CURRENT_FUNCTION nios2_set_current_function 5608 1.1 mrg 5609 1.1 mrg #undef TARGET_OPTION_VALID_ATTRIBUTE_P 5610 1.1 mrg #define TARGET_OPTION_VALID_ATTRIBUTE_P nios2_valid_target_attribute_p 5611 1.1 mrg 5612 1.1 mrg #undef TARGET_OPTION_PRAGMA_PARSE 5613 1.1 mrg #define TARGET_OPTION_PRAGMA_PARSE nios2_pragma_target_parse 5614 1.1 mrg 5615 1.1 mrg #undef TARGET_MERGE_DECL_ATTRIBUTES 5616 1.1 mrg #define TARGET_MERGE_DECL_ATTRIBUTES nios2_merge_decl_attributes 5617 1.1 mrg 5618 1.1 mrg #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK 5619 1.1 mrg #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \ 5620 1.1 mrg hook_bool_const_tree_hwi_hwi_const_tree_true 5621 1.1 mrg 5622 1.1 mrg #undef TARGET_ASM_OUTPUT_MI_THUNK 5623 1.1 mrg #define TARGET_ASM_OUTPUT_MI_THUNK nios2_asm_output_mi_thunk 5624 1.1 mrg 5625 #undef TARGET_MACHINE_DEPENDENT_REORG 5626 #define TARGET_MACHINE_DEPENDENT_REORG nios2_reorg 5627 5628 #undef TARGET_CONSTANT_ALIGNMENT 5629 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings 5630 5631 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE 5632 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed 5633 5634 struct gcc_target targetm = TARGET_INITIALIZER; 5635 5636 #include "gt-nios2.h" 5637