1 1.1 mrg /* FR30 specific functions. 2 1.1 mrg Copyright (C) 1998-2022 Free Software Foundation, Inc. 3 1.1 mrg Contributed by Cygnus Solutions. 4 1.1 mrg 5 1.1 mrg This file is part of GCC. 6 1.1 mrg 7 1.1 mrg GCC is free software; you can redistribute it and/or modify 8 1.1 mrg it under the terms of the GNU General Public License as published by 9 1.1 mrg the Free Software Foundation; either version 3, or (at your option) 10 1.1 mrg any later version. 11 1.1 mrg 12 1.1 mrg GCC is distributed in the hope that it will be useful, 13 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 mrg GNU General Public License for more details. 16 1.1 mrg 17 1.1 mrg You should have received a copy of the GNU General Public License 18 1.1 mrg along with GCC; see the file COPYING3. If not see 19 1.1 mrg <http://www.gnu.org/licenses/>. */ 20 1.1 mrg 21 1.1 mrg /*{{{ Includes */ 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 "emit-rtl.h" 37 1.1 mrg #include "stor-layout.h" 38 1.1 mrg #include "varasm.h" 39 1.1 mrg #include "output.h" 40 1.1 mrg #include "expr.h" 41 1.1 mrg #include "builtins.h" 42 1.1 mrg #include "calls.h" 43 1.1 mrg 44 1.1 mrg /* This file should be included last. */ 45 1.1 mrg #include "target-def.h" 46 1.1 mrg 47 1.1 mrg /*}}}*/ 48 1.1 mrg /*{{{ Function Prologues & Epilogues */ 49 1.1 mrg 50 1.1 mrg /* The FR30 stack looks like this: 51 1.1 mrg 52 1.1 mrg Before call After call 53 1.1 mrg FP ->| | | | 54 1.1 mrg +-----------------------+ +-----------------------+ high 55 1.1 mrg | | | | memory 56 1.1 mrg | local variables, | | local variables, | 57 1.1 mrg | reg save area, etc. | | reg save area, etc. | 58 1.1 mrg | | | | 59 1.1 mrg +-----------------------+ +-----------------------+ 60 1.1 mrg | | | | 61 1.1 mrg | args to the func that | | args to this func. | 62 1.1 mrg | is being called that | | | 63 1.1 mrg SP ->| do not fit in regs | | | 64 1.1 mrg +-----------------------+ +-----------------------+ 65 1.1 mrg | args that used to be | \ 66 1.1 mrg | in regs; only created | | pretend_size 67 1.1 mrg AP-> | for vararg funcs | / 68 1.1 mrg +-----------------------+ 69 1.1 mrg | | \ 70 1.1 mrg | register save area | | 71 1.1 mrg | | | 72 1.1 mrg +-----------------------+ | reg_size 73 1.1 mrg | return address | | 74 1.1 mrg +-----------------------+ | 75 1.1 mrg FP ->| previous frame ptr | / 76 1.1 mrg +-----------------------+ 77 1.1 mrg | | \ 78 1.1 mrg | local variables | | var_size 79 1.1 mrg | | / 80 1.1 mrg +-----------------------+ 81 1.1 mrg | | \ 82 1.1 mrg low | room for args to | | 83 1.1 mrg memory | other funcs called | | args_size 84 1.1 mrg | from this one | | 85 1.1 mrg SP ->| | / 86 1.1 mrg +-----------------------+ 87 1.1 mrg 88 1.1 mrg Note, AP is a fake hard register. It will be eliminated in favor of 89 1.1 mrg SP or FP as appropriate. 90 1.1 mrg 91 1.1 mrg Note, Some or all of the stack sections above may be omitted if they 92 1.1 mrg are not needed. */ 93 1.1 mrg 94 1.1 mrg /* Structure to be filled in by fr30_compute_frame_size() with register 95 1.1 mrg save masks, and offsets for the current function. */ 96 1.1 mrg struct fr30_frame_info 97 1.1 mrg { 98 1.1 mrg unsigned int total_size; /* # Bytes that the entire frame takes up. */ 99 1.1 mrg unsigned int pretend_size; /* # Bytes we push and pretend caller did. */ 100 1.1 mrg unsigned int args_size; /* # Bytes that outgoing arguments take up. */ 101 1.1 mrg unsigned int reg_size; /* # Bytes needed to store regs. */ 102 1.1 mrg unsigned int var_size; /* # Bytes that variables take up. */ 103 1.1 mrg unsigned int frame_size; /* # Bytes in current frame. */ 104 1.1 mrg unsigned int gmask; /* Mask of saved registers. */ 105 1.1 mrg unsigned int save_fp; /* Nonzero if frame pointer must be saved. */ 106 1.1 mrg unsigned int save_rp; /* Nonzero if return pointer must be saved. */ 107 1.1 mrg int initialised; /* Nonzero if frame size already calculated. */ 108 1.1 mrg }; 109 1.1 mrg 110 1.1 mrg /* Current frame information calculated by fr30_compute_frame_size(). */ 111 1.1 mrg static struct fr30_frame_info current_frame_info; 112 1.1 mrg 113 1.1 mrg /* Zero structure to initialize current_frame_info. */ 114 1.1 mrg static struct fr30_frame_info zero_frame_info; 115 1.1 mrg 116 1.1 mrg static void fr30_setup_incoming_varargs (cumulative_args_t, 117 1.1 mrg const function_arg_info &, 118 1.1 mrg int *, int); 119 1.1 mrg static bool fr30_must_pass_in_stack (const function_arg_info &); 120 1.1 mrg static int fr30_arg_partial_bytes (cumulative_args_t, 121 1.1 mrg const function_arg_info &); 122 1.1 mrg static rtx fr30_function_arg (cumulative_args_t, const function_arg_info &); 123 1.1 mrg static void fr30_function_arg_advance (cumulative_args_t, 124 1.1 mrg const function_arg_info &); 125 1.1 mrg static bool fr30_frame_pointer_required (void); 126 1.1 mrg static rtx fr30_function_value (const_tree, const_tree, bool); 127 1.1 mrg static rtx fr30_libcall_value (machine_mode, const_rtx); 128 1.1 mrg static bool fr30_function_value_regno_p (const unsigned int); 129 1.1 mrg static bool fr30_can_eliminate (const int, const int); 130 1.1 mrg static void fr30_asm_trampoline_template (FILE *); 131 1.1 mrg static void fr30_trampoline_init (rtx, tree, rtx); 132 1.1 mrg static int fr30_num_arg_regs (const function_arg_info &); 133 1.1 mrg 134 1.1 mrg #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM)) 135 1.1 mrg #define RETURN_POINTER_MASK (1 << (RETURN_POINTER_REGNUM)) 136 1.1 mrg 137 1.1 mrg /* Tell prologue and epilogue if register REGNO should be saved / restored. 138 1.1 mrg The return address and frame pointer are treated separately. 139 1.1 mrg Don't consider them here. */ 140 1.1 mrg #define MUST_SAVE_REGISTER(regno) \ 141 1.1 mrg ( (regno) != RETURN_POINTER_REGNUM \ 142 1.1 mrg && (regno) != FRAME_POINTER_REGNUM \ 143 1.1 mrg && df_regs_ever_live_p (regno) \ 144 1.1 mrg && ! call_used_or_fixed_reg_p (regno)) 145 1.1 mrg 146 1.1 mrg #define MUST_SAVE_FRAME_POINTER (df_regs_ever_live_p (FRAME_POINTER_REGNUM) || frame_pointer_needed) 147 1.1 mrg #define MUST_SAVE_RETURN_POINTER (df_regs_ever_live_p (RETURN_POINTER_REGNUM) || crtl->profile) 148 1.1 mrg 149 1.1 mrg #if UNITS_PER_WORD == 4 150 1.1 mrg #define WORD_ALIGN(SIZE) (((SIZE) + 3) & ~3) 151 1.1 mrg #endif 152 1.1 mrg 153 1.1 mrg /* Initialize the GCC target structure. */ 155 1.1 mrg #undef TARGET_ASM_ALIGNED_HI_OP 156 1.1 mrg #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t" 157 1.1 mrg #undef TARGET_ASM_ALIGNED_SI_OP 158 1.1 mrg #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" 159 1.1 mrg 160 1.1 mrg #undef TARGET_PROMOTE_PROTOTYPES 161 1.1 mrg #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true 162 1.1 mrg #undef TARGET_PASS_BY_REFERENCE 163 1.1 mrg #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack 164 1.1 mrg #undef TARGET_ARG_PARTIAL_BYTES 165 1.1 mrg #define TARGET_ARG_PARTIAL_BYTES fr30_arg_partial_bytes 166 1.1 mrg #undef TARGET_FUNCTION_ARG 167 1.1 mrg #define TARGET_FUNCTION_ARG fr30_function_arg 168 1.1 mrg #undef TARGET_FUNCTION_ARG_ADVANCE 169 1.1 mrg #define TARGET_FUNCTION_ARG_ADVANCE fr30_function_arg_advance 170 1.1 mrg 171 1.1 mrg #undef TARGET_FUNCTION_VALUE 172 1.1 mrg #define TARGET_FUNCTION_VALUE fr30_function_value 173 1.1 mrg #undef TARGET_LIBCALL_VALUE 174 1.1 mrg #define TARGET_LIBCALL_VALUE fr30_libcall_value 175 1.1 mrg #undef TARGET_FUNCTION_VALUE_REGNO_P 176 1.1 mrg #define TARGET_FUNCTION_VALUE_REGNO_P fr30_function_value_regno_p 177 1.1 mrg 178 1.1 mrg #undef TARGET_SETUP_INCOMING_VARARGS 179 1.1 mrg #define TARGET_SETUP_INCOMING_VARARGS fr30_setup_incoming_varargs 180 1.1 mrg #undef TARGET_MUST_PASS_IN_STACK 181 1.1 mrg #define TARGET_MUST_PASS_IN_STACK fr30_must_pass_in_stack 182 1.1 mrg 183 1.1 mrg #undef TARGET_FRAME_POINTER_REQUIRED 184 1.1 mrg #define TARGET_FRAME_POINTER_REQUIRED fr30_frame_pointer_required 185 1.1 mrg 186 1.1 mrg #undef TARGET_CAN_ELIMINATE 187 1.1 mrg #define TARGET_CAN_ELIMINATE fr30_can_eliminate 188 1.1 mrg 189 1.1 mrg #undef TARGET_LRA_P 190 1.1 mrg #define TARGET_LRA_P hook_bool_void_false 191 1.1 mrg 192 1.1 mrg #undef TARGET_ASM_TRAMPOLINE_TEMPLATE 193 1.1 mrg #define TARGET_ASM_TRAMPOLINE_TEMPLATE fr30_asm_trampoline_template 194 1.1 mrg #undef TARGET_TRAMPOLINE_INIT 195 1.1 mrg #define TARGET_TRAMPOLINE_INIT fr30_trampoline_init 196 1.1 mrg 197 1.1 mrg #undef TARGET_CONSTANT_ALIGNMENT 198 1.1 mrg #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings 199 1.1 mrg 200 1.1 mrg #undef TARGET_HAVE_SPECULATION_SAFE_VALUE 201 1.1 mrg #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed 202 1.1 mrg 203 1.1 mrg struct gcc_target targetm = TARGET_INITIALIZER; 204 1.1 mrg 205 1.1 mrg 207 1.1 mrg /* Worker function for TARGET_CAN_ELIMINATE. */ 208 1.1 mrg 209 1.1 mrg bool 210 1.1 mrg fr30_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) 211 1.1 mrg { 212 1.1 mrg return (to == FRAME_POINTER_REGNUM || ! frame_pointer_needed); 213 1.1 mrg } 214 1.1 mrg 215 1.1 mrg /* Returns the number of bytes offset between FROM_REG and TO_REG 216 1.1 mrg for the current function. As a side effect it fills in the 217 1.1 mrg current_frame_info structure, if the data is available. */ 218 1.1 mrg unsigned int 219 1.1 mrg fr30_compute_frame_size (int from_reg, int to_reg) 220 1.1 mrg { 221 1.1 mrg int regno; 222 1.1 mrg unsigned int return_value; 223 1.1 mrg unsigned int var_size; 224 1.1 mrg unsigned int args_size; 225 1.1 mrg unsigned int pretend_size; 226 1.1 mrg unsigned int reg_size; 227 1.1 mrg unsigned int gmask; 228 1.1 mrg 229 1.1 mrg var_size = WORD_ALIGN (get_frame_size ()); 230 1.1 mrg args_size = WORD_ALIGN (crtl->outgoing_args_size); 231 1.1 mrg pretend_size = crtl->args.pretend_args_size; 232 1.1 mrg 233 1.1 mrg reg_size = 0; 234 1.1 mrg gmask = 0; 235 1.1 mrg 236 1.1 mrg /* Calculate space needed for registers. */ 237 1.1 mrg for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno ++) 238 1.1 mrg { 239 1.1 mrg if (MUST_SAVE_REGISTER (regno)) 240 1.1 mrg { 241 1.1 mrg reg_size += UNITS_PER_WORD; 242 1.1 mrg gmask |= 1 << regno; 243 1.1 mrg } 244 1.1 mrg } 245 1.1 mrg 246 1.1 mrg current_frame_info.save_fp = MUST_SAVE_FRAME_POINTER; 247 1.1 mrg current_frame_info.save_rp = MUST_SAVE_RETURN_POINTER; 248 1.1 mrg 249 1.1 mrg reg_size += (current_frame_info.save_fp + current_frame_info.save_rp) 250 1.1 mrg * UNITS_PER_WORD; 251 1.1 mrg 252 1.1 mrg /* Save computed information. */ 253 1.1 mrg current_frame_info.pretend_size = pretend_size; 254 1.1 mrg current_frame_info.var_size = var_size; 255 1.1 mrg current_frame_info.args_size = args_size; 256 1.1 mrg current_frame_info.reg_size = reg_size; 257 1.1 mrg current_frame_info.frame_size = args_size + var_size; 258 1.1 mrg current_frame_info.total_size = args_size + var_size + reg_size + pretend_size; 259 1.1 mrg current_frame_info.gmask = gmask; 260 1.1 mrg current_frame_info.initialised = reload_completed; 261 1.1 mrg 262 1.1 mrg /* Calculate the required distance. */ 263 1.1 mrg return_value = 0; 264 1.1 mrg 265 1.1 mrg if (to_reg == STACK_POINTER_REGNUM) 266 1.1 mrg return_value += args_size + var_size; 267 1.1 mrg 268 1.1 mrg if (from_reg == ARG_POINTER_REGNUM) 269 1.1 mrg return_value += reg_size; 270 1.1 mrg 271 1.1 mrg return return_value; 272 1.1 mrg } 273 1.1 mrg 274 1.1 mrg /* Called after register allocation to add any instructions needed for the 275 1.1 mrg prologue. Using a prologue insn is favored compared to putting all of the 276 1.1 mrg instructions in output_function_prologue(), since it allows the scheduler 277 1.1 mrg to intermix instructions with the saves of the caller saved registers. In 278 1.1 mrg some cases, it might be necessary to emit a barrier instruction as the last 279 1.1 mrg insn to prevent such scheduling. */ 280 1.1 mrg 281 1.1 mrg void 282 1.1 mrg fr30_expand_prologue (void) 283 1.1 mrg { 284 1.1 mrg int regno; 285 1.1 mrg rtx insn; 286 1.1 mrg 287 1.1 mrg if (! current_frame_info.initialised) 288 1.1 mrg fr30_compute_frame_size (0, 0); 289 1.1 mrg 290 1.1 mrg /* This cases shouldn't happen. Catch it now. */ 291 1.1 mrg gcc_assert (current_frame_info.total_size || !current_frame_info.gmask); 292 1.1 mrg 293 1.1 mrg /* Allocate space for register arguments if this is a variadic function. */ 294 1.1 mrg if (current_frame_info.pretend_size) 295 1.1 mrg { 296 1.1 mrg int regs_to_save = current_frame_info.pretend_size / UNITS_PER_WORD; 297 1.1 mrg 298 1.1 mrg /* Push argument registers into the pretend arg area. */ 299 1.1 mrg for (regno = FIRST_ARG_REGNUM + FR30_NUM_ARG_REGS; regno --, regs_to_save --;) 300 1.1 mrg { 301 1.1 mrg insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno))); 302 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 303 1.1 mrg } 304 1.1 mrg } 305 1.1 mrg 306 1.1 mrg if (current_frame_info.gmask) 307 1.1 mrg { 308 1.1 mrg /* Save any needed call-saved regs. */ 309 1.1 mrg for (regno = STACK_POINTER_REGNUM; regno--;) 310 1.1 mrg { 311 1.1 mrg if ((current_frame_info.gmask & (1 << regno)) != 0) 312 1.1 mrg { 313 1.1 mrg insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno))); 314 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 315 1.1 mrg } 316 1.1 mrg } 317 1.1 mrg } 318 1.1 mrg 319 1.1 mrg /* Save return address if necessary. */ 320 1.1 mrg if (current_frame_info.save_rp) 321 1.1 mrg { 322 1.1 mrg insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, 323 1.1 mrg RETURN_POINTER_REGNUM))); 324 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 325 1.1 mrg } 326 1.1 mrg 327 1.1 mrg /* Save old frame pointer and create new one, if necessary. */ 328 1.1 mrg if (current_frame_info.save_fp) 329 1.1 mrg { 330 1.1 mrg if (current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD)) 331 1.1 mrg { 332 1.1 mrg int enter_size = current_frame_info.frame_size + UNITS_PER_WORD; 333 1.1 mrg rtx pattern; 334 1.1 mrg 335 1.1 mrg insn = emit_insn (gen_enter_func (GEN_INT (enter_size))); 336 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 337 1.1 mrg 338 1.1 mrg pattern = PATTERN (insn); 339 1.1 mrg 340 1.1 mrg /* Also mark all 3 subexpressions as RTX_FRAME_RELATED_P. */ 341 1.1 mrg if (GET_CODE (pattern) == PARALLEL) 342 1.1 mrg { 343 1.1 mrg int x; 344 1.1 mrg for (x = XVECLEN (pattern, 0); x--;) 345 1.1 mrg { 346 1.1 mrg rtx part = XVECEXP (pattern, 0, x); 347 1.1 mrg 348 1.1 mrg /* One of the insns in the ENTER pattern updates the 349 1.1 mrg frame pointer. If we do not actually need the frame 350 1.1 mrg pointer in this function then this is a side effect 351 1.1 mrg rather than a desired effect, so we do not mark that 352 1.1 mrg insn as being related to the frame set up. Doing this 353 1.1 mrg allows us to compile the crash66.C test file in the 354 1.1 mrg G++ testsuite. */ 355 1.1 mrg if (! frame_pointer_needed 356 1.1 mrg && GET_CODE (part) == SET 357 1.1 mrg && SET_DEST (part) == hard_frame_pointer_rtx) 358 1.1 mrg RTX_FRAME_RELATED_P (part) = 0; 359 1.1 mrg else 360 1.1 mrg RTX_FRAME_RELATED_P (part) = 1; 361 1.1 mrg } 362 1.1 mrg } 363 1.1 mrg } 364 1.1 mrg else 365 1.1 mrg { 366 1.1 mrg insn = emit_insn (gen_movsi_push (frame_pointer_rtx)); 367 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 368 1.1 mrg 369 1.1 mrg if (frame_pointer_needed) 370 1.1 mrg { 371 1.1 mrg insn = emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx)); 372 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 373 1.1 mrg } 374 1.1 mrg } 375 1.1 mrg } 376 1.1 mrg 377 1.1 mrg /* Allocate the stack frame. */ 378 1.1 mrg if (current_frame_info.frame_size == 0) 379 1.1 mrg ; /* Nothing to do. */ 380 1.1 mrg else if (current_frame_info.save_fp 381 1.1 mrg && current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD)) 382 1.1 mrg ; /* Nothing to do. */ 383 1.1 mrg else if (current_frame_info.frame_size <= 512) 384 1.1 mrg { 385 1.1 mrg insn = emit_insn (gen_add_to_stack 386 1.1 mrg (GEN_INT (- (signed) current_frame_info.frame_size))); 387 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 388 1.1 mrg } 389 1.1 mrg else 390 1.1 mrg { 391 1.1 mrg rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM); 392 1.1 mrg insn = emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size))); 393 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 394 1.1 mrg insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp)); 395 1.1 mrg RTX_FRAME_RELATED_P (insn) = 1; 396 1.1 mrg } 397 1.1 mrg 398 1.1 mrg if (crtl->profile) 399 1.1 mrg emit_insn (gen_blockage ()); 400 1.1 mrg } 401 1.1 mrg 402 1.1 mrg /* Called after register allocation to add any instructions needed for the 403 1.1 mrg epilogue. Using an epilogue insn is favored compared to putting all of the 404 1.1 mrg instructions in output_function_epilogue(), since it allows the scheduler 405 1.1 mrg to intermix instructions with the restores of the caller saved registers. 406 1.1 mrg In some cases, it might be necessary to emit a barrier instruction as the 407 1.1 mrg first insn to prevent such scheduling. */ 408 1.1 mrg void 409 1.1 mrg fr30_expand_epilogue (void) 410 1.1 mrg { 411 1.1 mrg int regno; 412 1.1 mrg 413 1.1 mrg /* Perform the inversion operations of the prologue. */ 414 1.1 mrg gcc_assert (current_frame_info.initialised); 415 1.1 mrg 416 1.1 mrg /* Pop local variables and arguments off the stack. 417 1.1 mrg If frame_pointer_needed is TRUE then the frame pointer register 418 1.1 mrg has actually been used as a frame pointer, and we can recover 419 1.1 mrg the stack pointer from it, otherwise we must unwind the stack 420 1.1 mrg manually. */ 421 1.1 mrg if (current_frame_info.frame_size > 0) 422 1.1 mrg { 423 1.1 mrg if (current_frame_info.save_fp && frame_pointer_needed) 424 1.1 mrg { 425 1.1 mrg emit_insn (gen_leave_func ()); 426 1.1 mrg current_frame_info.save_fp = 0; 427 1.1 mrg } 428 1.1 mrg else if (current_frame_info.frame_size <= 508) 429 1.1 mrg emit_insn (gen_add_to_stack 430 1.1 mrg (GEN_INT (current_frame_info.frame_size))); 431 1.1 mrg else 432 1.1 mrg { 433 1.1 mrg rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM); 434 1.1 mrg emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size))); 435 1.1 mrg emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp)); 436 1.1 mrg } 437 1.1 mrg } 438 1.1 mrg 439 1.1 mrg if (current_frame_info.save_fp) 440 1.1 mrg emit_insn (gen_movsi_pop (frame_pointer_rtx)); 441 1.1 mrg 442 1.1 mrg /* Pop all the registers that were pushed. */ 443 1.1 mrg if (current_frame_info.save_rp) 444 1.1 mrg emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, RETURN_POINTER_REGNUM))); 445 1.1 mrg 446 1.1 mrg for (regno = 0; regno < STACK_POINTER_REGNUM; regno ++) 447 1.1 mrg if (current_frame_info.gmask & (1 << regno)) 448 1.1 mrg emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, regno))); 449 1.1 mrg 450 1.1 mrg if (current_frame_info.pretend_size) 451 1.1 mrg emit_insn (gen_add_to_stack (GEN_INT (current_frame_info.pretend_size))); 452 1.1 mrg 453 1.1 mrg /* Reset state info for each function. */ 454 1.1 mrg current_frame_info = zero_frame_info; 455 1.1 mrg 456 1.1 mrg emit_jump_insn (gen_return_from_func ()); 457 1.1 mrg } 458 1.1 mrg 459 1.1 mrg /* Do any needed setup for a variadic function. We must create a register 460 1.1 mrg parameter block, and then copy any anonymous arguments, plus the last 461 1.1 mrg named argument, from registers into memory. * copying actually done in 462 1.1 mrg fr30_expand_prologue(). 463 1.1 mrg 464 1.1 mrg CUM has not been updated for the last named argument which has type TYPE 465 1.1 mrg and mode MODE, and we rely on this fact. */ 466 1.1 mrg void 467 1.1 mrg fr30_setup_incoming_varargs (cumulative_args_t arg_regs_used_so_far_v, 468 1.1 mrg const function_arg_info &arg, 469 1.1 mrg int *pretend_size, 470 1.1 mrg int second_time ATTRIBUTE_UNUSED) 471 1.1 mrg { 472 1.1 mrg CUMULATIVE_ARGS *arg_regs_used_so_far 473 1.1 mrg = get_cumulative_args (arg_regs_used_so_far_v); 474 1.1 mrg int size; 475 1.1 mrg 476 1.1 mrg /* All BLKmode values are passed by reference. */ 477 1.1 mrg gcc_assert (arg.mode != BLKmode); 478 1.1 mrg 479 1.1 mrg /* ??? This run-time test as well as the code inside the if 480 1.1 mrg statement is probably unnecessary. */ 481 1.1 mrg if (targetm.calls.strict_argument_naming (arg_regs_used_so_far_v)) 482 1.1 mrg /* If TARGET_STRICT_ARGUMENT_NAMING returns true, then the last named 483 1.1 mrg arg must not be treated as an anonymous arg. */ 484 1.1 mrg /* ??? This is a pointer increment, which makes no sense. */ 485 1.1 mrg arg_regs_used_so_far += fr30_num_arg_regs (arg); 486 1.1 mrg 487 1.1 mrg size = FR30_NUM_ARG_REGS - (* arg_regs_used_so_far); 488 1.1 mrg 489 1.1 mrg if (size <= 0) 490 1.1 mrg return; 491 1.1 mrg 492 1.1 mrg * pretend_size = (size * UNITS_PER_WORD); 493 1.1 mrg } 494 1.1 mrg 495 1.1 mrg /*}}}*/ 496 1.1 mrg /*{{{ Printing operands */ 497 1.1 mrg 498 1.1 mrg /* Print a memory address as an operand to reference that memory location. */ 499 1.1 mrg 500 1.1 mrg void 501 1.1 mrg fr30_print_operand_address (FILE *stream, rtx address) 502 1.1 mrg { 503 1.1 mrg switch (GET_CODE (address)) 504 1.1 mrg { 505 1.1 mrg case SYMBOL_REF: 506 1.1 mrg output_addr_const (stream, address); 507 1.1 mrg break; 508 1.1 mrg 509 1.1 mrg default: 510 1.1 mrg fprintf (stderr, "code = %x\n", GET_CODE (address)); 511 1.1 mrg debug_rtx (address); 512 1.1 mrg output_operand_lossage ("fr30_print_operand_address: unhandled address"); 513 1.1 mrg break; 514 1.1 mrg } 515 1.1 mrg } 516 1.1 mrg 517 1.1 mrg /* Print an operand. */ 518 1.1 mrg 519 1.1 mrg void 520 1.1 mrg fr30_print_operand (FILE *file, rtx x, int code) 521 1.1 mrg { 522 1.1 mrg rtx x0; 523 1.1 mrg 524 1.1 mrg switch (code) 525 1.1 mrg { 526 1.1 mrg case '#': 527 1.1 mrg /* Output a :D if this instruction is delayed. */ 528 1.1 mrg if (dbr_sequence_length () != 0) 529 1.1 mrg fputs (":D", file); 530 1.1 mrg return; 531 1.1 mrg 532 1.1 mrg case 'p': 533 1.1 mrg /* Compute the register name of the second register in a hi/lo 534 1.1 mrg register pair. */ 535 1.1 mrg if (GET_CODE (x) != REG) 536 1.1 mrg output_operand_lossage ("fr30_print_operand: unrecognized %%p code"); 537 1.1 mrg else 538 1.1 mrg fprintf (file, "r%d", REGNO (x) + 1); 539 1.1 mrg return; 540 1.1 mrg 541 1.1 mrg case 'b': 542 1.1 mrg /* Convert GCC's comparison operators into FR30 comparison codes. */ 543 1.1 mrg switch (GET_CODE (x)) 544 1.1 mrg { 545 1.1 mrg case EQ: fprintf (file, "eq"); break; 546 1.1 mrg case NE: fprintf (file, "ne"); break; 547 1.1 mrg case LT: fprintf (file, "lt"); break; 548 1.1 mrg case LE: fprintf (file, "le"); break; 549 1.1 mrg case GT: fprintf (file, "gt"); break; 550 1.1 mrg case GE: fprintf (file, "ge"); break; 551 1.1 mrg case LTU: fprintf (file, "c"); break; 552 1.1 mrg case LEU: fprintf (file, "ls"); break; 553 1.1 mrg case GTU: fprintf (file, "hi"); break; 554 1.1 mrg case GEU: fprintf (file, "nc"); break; 555 1.1 mrg default: 556 1.1 mrg output_operand_lossage ("fr30_print_operand: unrecognized %%b code"); 557 1.1 mrg break; 558 1.1 mrg } 559 1.1 mrg return; 560 1.1 mrg 561 1.1 mrg case 'B': 562 1.1 mrg /* Convert GCC's comparison operators into the complimentary FR30 563 1.1 mrg comparison codes. */ 564 1.1 mrg switch (GET_CODE (x)) 565 1.1 mrg { 566 1.1 mrg case EQ: fprintf (file, "ne"); break; 567 1.1 mrg case NE: fprintf (file, "eq"); break; 568 1.1 mrg case LT: fprintf (file, "ge"); break; 569 1.1 mrg case LE: fprintf (file, "gt"); break; 570 1.1 mrg case GT: fprintf (file, "le"); break; 571 1.1 mrg case GE: fprintf (file, "lt"); break; 572 1.1 mrg case LTU: fprintf (file, "nc"); break; 573 1.1 mrg case LEU: fprintf (file, "hi"); break; 574 1.1 mrg case GTU: fprintf (file, "ls"); break; 575 1.1 mrg case GEU: fprintf (file, "c"); break; 576 1.1 mrg default: 577 1.1 mrg output_operand_lossage ("fr30_print_operand: unrecognized %%B code"); 578 1.1 mrg break; 579 1.1 mrg } 580 1.1 mrg return; 581 1.1 mrg 582 1.1 mrg case 'A': 583 1.1 mrg /* Print a signed byte value as an unsigned value. */ 584 1.1 mrg if (GET_CODE (x) != CONST_INT) 585 1.1 mrg output_operand_lossage ("fr30_print_operand: invalid operand to %%A code"); 586 1.1 mrg else 587 1.1 mrg { 588 1.1 mrg HOST_WIDE_INT val; 589 1.1 mrg 590 1.1 mrg val = INTVAL (x); 591 1.1 mrg 592 1.1 mrg val &= 0xff; 593 1.1 mrg 594 1.1 mrg fprintf (file, HOST_WIDE_INT_PRINT_DEC, val); 595 1.1 mrg } 596 1.1 mrg return; 597 1.1 mrg 598 1.1 mrg case 'x': 599 1.1 mrg if (GET_CODE (x) != CONST_INT 600 1.1 mrg || INTVAL (x) < 16 601 1.1 mrg || INTVAL (x) > 32) 602 1.1 mrg output_operand_lossage ("fr30_print_operand: invalid %%x code"); 603 1.1 mrg else 604 1.1 mrg fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) - 16); 605 1.1 mrg return; 606 1.1 mrg 607 1.1 mrg case 'F': 608 1.1 mrg if (GET_CODE (x) != CONST_DOUBLE) 609 1.1 mrg output_operand_lossage ("fr30_print_operand: invalid %%F code"); 610 1.1 mrg else 611 1.1 mrg { 612 1.1 mrg char str[30]; 613 1.1 mrg 614 1.1 mrg real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x), 615 1.1 mrg sizeof (str), 0, 1); 616 1.1 mrg fputs (str, file); 617 1.1 mrg } 618 1.1 mrg return; 619 1.1 mrg 620 1.1 mrg case 0: 621 1.1 mrg /* Handled below. */ 622 1.1 mrg break; 623 1.1 mrg 624 1.1 mrg default: 625 1.1 mrg fprintf (stderr, "unknown code = %x\n", code); 626 1.1 mrg output_operand_lossage ("fr30_print_operand: unknown code"); 627 1.1 mrg return; 628 1.1 mrg } 629 1.1 mrg 630 1.1 mrg switch (GET_CODE (x)) 631 1.1 mrg { 632 1.1 mrg case REG: 633 1.1 mrg fputs (reg_names [REGNO (x)], file); 634 1.1 mrg break; 635 1.1 mrg 636 1.1 mrg case MEM: 637 1.1 mrg x0 = XEXP (x,0); 638 1.1 mrg 639 1.1 mrg switch (GET_CODE (x0)) 640 1.1 mrg { 641 1.1 mrg case REG: 642 1.1 mrg gcc_assert ((unsigned) REGNO (x0) < ARRAY_SIZE (reg_names)); 643 1.1 mrg fprintf (file, "@%s", reg_names [REGNO (x0)]); 644 1.1 mrg break; 645 1.1 mrg 646 1.1 mrg case PLUS: 647 1.1 mrg if (GET_CODE (XEXP (x0, 0)) != REG 648 1.1 mrg || REGNO (XEXP (x0, 0)) < FRAME_POINTER_REGNUM 649 1.1 mrg || REGNO (XEXP (x0, 0)) > STACK_POINTER_REGNUM 650 1.1 mrg || GET_CODE (XEXP (x0, 1)) != CONST_INT) 651 1.1 mrg { 652 1.1 mrg fprintf (stderr, "bad INDEXed address:"); 653 1.1 mrg debug_rtx (x); 654 1.1 mrg output_operand_lossage ("fr30_print_operand: unhandled MEM"); 655 1.1 mrg } 656 1.1 mrg else if (REGNO (XEXP (x0, 0)) == FRAME_POINTER_REGNUM) 657 1.1 mrg { 658 1.1 mrg HOST_WIDE_INT val = INTVAL (XEXP (x0, 1)); 659 1.1 mrg if (val < -(1 << 9) || val > ((1 << 9) - 4)) 660 1.1 mrg { 661 1.1 mrg fprintf (stderr, "frame INDEX out of range:"); 662 1.1 mrg debug_rtx (x); 663 1.1 mrg output_operand_lossage ("fr30_print_operand: unhandled MEM"); 664 1.1 mrg } 665 1.1 mrg fprintf (file, "@(r14, #" HOST_WIDE_INT_PRINT_DEC ")", val); 666 1.1 mrg } 667 1.1 mrg else 668 1.1 mrg { 669 1.1 mrg HOST_WIDE_INT val = INTVAL (XEXP (x0, 1)); 670 1.1 mrg if (val < 0 || val > ((1 << 6) - 4)) 671 1.1 mrg { 672 1.1 mrg fprintf (stderr, "stack INDEX out of range:"); 673 1.1 mrg debug_rtx (x); 674 1.1 mrg output_operand_lossage ("fr30_print_operand: unhandled MEM"); 675 1.1 mrg } 676 1.1 mrg fprintf (file, "@(r15, #" HOST_WIDE_INT_PRINT_DEC ")", val); 677 1.1 mrg } 678 1.1 mrg break; 679 1.1 mrg 680 1.1 mrg case SYMBOL_REF: 681 1.1 mrg output_address (VOIDmode, x0); 682 1.1 mrg break; 683 1.1 mrg 684 1.1 mrg default: 685 1.1 mrg fprintf (stderr, "bad MEM code = %x\n", GET_CODE (x0)); 686 1.1 mrg debug_rtx (x); 687 1.1 mrg output_operand_lossage ("fr30_print_operand: unhandled MEM"); 688 1.1 mrg break; 689 1.1 mrg } 690 1.1 mrg break; 691 1.1 mrg 692 1.1 mrg case CONST_DOUBLE : 693 1.1 mrg /* We handle SFmode constants here as output_addr_const doesn't. */ 694 1.1 mrg if (GET_MODE (x) == SFmode) 695 1.1 mrg { 696 1.1 mrg long l; 697 1.1 mrg 698 1.1 mrg REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l); 699 1.1 mrg fprintf (file, "0x%08lx", l); 700 1.1 mrg break; 701 1.1 mrg } 702 1.1 mrg 703 1.1 mrg /* FALLTHRU */ 704 1.1 mrg /* Let output_addr_const deal with it. */ 705 1.1 mrg default: 706 1.1 mrg output_addr_const (file, x); 707 1.1 mrg break; 708 1.1 mrg } 709 1.1 mrg 710 1.1 mrg return; 711 1.1 mrg } 712 1.1 mrg 713 1.1 mrg /*}}}*/ 714 1.1 mrg 715 1.1 mrg /* Implements TARGET_FUNCTION_VALUE. */ 716 1.1 mrg 717 1.1 mrg static rtx 718 1.1 mrg fr30_function_value (const_tree valtype, 719 1.1 mrg const_tree fntype_or_decli ATTRIBUTE_UNUSED, 720 1.1 mrg bool outgoing ATTRIBUTE_UNUSED) 721 1.1 mrg { 722 1.1 mrg return gen_rtx_REG (TYPE_MODE (valtype), RETURN_VALUE_REGNUM); 723 1.1 mrg } 724 1.1 mrg 725 1.1 mrg /* Implements TARGET_LIBCALL_VALUE. */ 726 1.1 mrg 727 1.1 mrg static rtx 728 1.1 mrg fr30_libcall_value (machine_mode mode, 729 1.1 mrg const_rtx fun ATTRIBUTE_UNUSED) 730 1.1 mrg { 731 1.1 mrg return gen_rtx_REG (mode, RETURN_VALUE_REGNUM); 732 1.1 mrg } 733 1.1 mrg 734 1.1 mrg /* Implements TARGET_FUNCTION_VALUE_REGNO_P. */ 735 1.1 mrg 736 1.1 mrg static bool 737 1.1 mrg fr30_function_value_regno_p (const unsigned int regno) 738 1.1 mrg { 739 1.1 mrg return (regno == RETURN_VALUE_REGNUM); 740 1.1 mrg } 741 1.1 mrg 742 1.1 mrg /*{{{ Function arguments */ 743 1.1 mrg 744 1.1 mrg /* Return true if we should pass an argument on the stack rather than 745 1.1 mrg in registers. */ 746 1.1 mrg 747 1.1 mrg static bool 748 1.1 mrg fr30_must_pass_in_stack (const function_arg_info &arg) 749 1.1 mrg { 750 1.1 mrg return arg.mode == BLKmode || arg.aggregate_type_p (); 751 1.1 mrg } 752 1.1 mrg 753 1.1 mrg /* Compute the number of word sized registers needed to hold function 754 1.1 mrg argument ARG. */ 755 1.1 mrg static int 756 1.1 mrg fr30_num_arg_regs (const function_arg_info &arg) 757 1.1 mrg { 758 1.1 mrg if (targetm.calls.must_pass_in_stack (arg)) 759 1.1 mrg return 0; 760 1.1 mrg 761 1.1 mrg int size = arg.promoted_size_in_bytes (); 762 1.1 mrg return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; 763 1.1 mrg } 764 1.1 mrg 765 1.1 mrg /* Returns the number of bytes of argument registers required to hold *part* 766 1.1 mrg of argument ARG. If the argument fits entirely in the argument registers, 767 1.1 mrg or entirely on the stack, then 0 is returned. CUM is the number of 768 1.1 mrg argument registers already used by earlier parameters to the function. */ 769 1.1 mrg 770 1.1 mrg static int 771 1.1 mrg fr30_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg) 772 1.1 mrg { 773 1.1 mrg CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 774 1.1 mrg 775 1.1 mrg /* Unnamed arguments, i.e. those that are prototyped as ... 776 1.1 mrg are always passed on the stack. 777 1.1 mrg Also check here to see if all the argument registers are full. */ 778 1.1 mrg if (!arg.named || *cum >= FR30_NUM_ARG_REGS) 779 1.1 mrg return 0; 780 1.1 mrg 781 1.1 mrg /* Work out how many argument registers would be needed if this 782 1.1 mrg parameter were to be passed entirely in registers. If there 783 1.1 mrg are sufficient argument registers available (or if no registers 784 1.1 mrg are needed because the parameter must be passed on the stack) 785 1.1 mrg then return zero, as this parameter does not require partial 786 1.1 mrg register, partial stack space. */ 787 1.1 mrg if (*cum + fr30_num_arg_regs (arg) <= FR30_NUM_ARG_REGS) 788 1.1 mrg return 0; 789 1.1 mrg 790 1.1 mrg return (FR30_NUM_ARG_REGS - *cum) * UNITS_PER_WORD; 791 1.1 mrg } 792 1.1 mrg 793 1.1 mrg static rtx 794 1.1 mrg fr30_function_arg (cumulative_args_t cum_v, const function_arg_info &arg) 795 1.1 mrg { 796 1.1 mrg CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 797 1.1 mrg 798 1.1 mrg if (!arg.named 799 1.1 mrg || fr30_must_pass_in_stack (arg) 800 1.1 mrg || *cum >= FR30_NUM_ARG_REGS) 801 1.1 mrg return NULL_RTX; 802 1.1 mrg else 803 1.1 mrg return gen_rtx_REG (arg.mode, *cum + FIRST_ARG_REGNUM); 804 1.1 mrg } 805 1.1 mrg 806 1.1 mrg /* Implement TARGET_FUNCTION_ARG_ADVANCE. */ 807 1.1 mrg static void 808 1.1 mrg fr30_function_arg_advance (cumulative_args_t cum, 809 1.1 mrg const function_arg_info &arg) 810 1.1 mrg { 811 1.1 mrg if (arg.named) 812 1.1 mrg *get_cumulative_args (cum) += fr30_num_arg_regs (arg); 813 1.1 mrg } 814 1.1 mrg 815 1.1 mrg /*}}}*/ 816 1.1 mrg /*{{{ Operand predicates */ 817 1.1 mrg 818 1.1 mrg #ifndef Mmode 819 1.1 mrg #define Mmode machine_mode 820 1.1 mrg #endif 821 1.1 mrg 822 1.1 mrg /* Returns true iff all the registers in the operands array 823 1.1 mrg are in descending or ascending order. */ 824 1.1 mrg int 825 1.1 mrg fr30_check_multiple_regs (rtx *operands, int num_operands, int descending) 826 1.1 mrg { 827 1.1 mrg if (descending) 828 1.1 mrg { 829 1.1 mrg unsigned int prev_regno = 0; 830 1.1 mrg 831 1.1 mrg while (num_operands --) 832 1.1 mrg { 833 1.1 mrg if (GET_CODE (operands [num_operands]) != REG) 834 1.1 mrg return 0; 835 1.1 mrg 836 1.1 mrg if (REGNO (operands [num_operands]) < prev_regno) 837 1.1 mrg return 0; 838 1.1 mrg 839 1.1 mrg prev_regno = REGNO (operands [num_operands]); 840 1.1 mrg } 841 1.1 mrg } 842 1.1 mrg else 843 1.1 mrg { 844 1.1 mrg unsigned int prev_regno = CONDITION_CODE_REGNUM; 845 1.1 mrg 846 1.1 mrg while (num_operands --) 847 1.1 mrg { 848 1.1 mrg if (GET_CODE (operands [num_operands]) != REG) 849 1.1 mrg return 0; 850 1.1 mrg 851 1.1 mrg if (REGNO (operands [num_operands]) > prev_regno) 852 1.1 mrg return 0; 853 1.1 mrg 854 1.1 mrg prev_regno = REGNO (operands [num_operands]); 855 1.1 mrg } 856 1.1 mrg } 857 1.1 mrg 858 1.1 mrg return 1; 859 1.1 mrg } 860 1.1 mrg 861 1.1 mrg int 862 1.1 mrg fr30_const_double_is_zero (rtx operand) 863 1.1 mrg { 864 1.1 mrg if (operand == NULL || GET_CODE (operand) != CONST_DOUBLE) 865 1.1 mrg return 0; 866 1.1 mrg 867 1.1 mrg return real_equal (CONST_DOUBLE_REAL_VALUE (operand), &dconst0); 868 1.1 mrg } 869 1.1 mrg 870 1.1 mrg /*}}}*/ 871 1.1 mrg /*{{{ Instruction Output Routines */ 872 1.1 mrg 873 1.1 mrg /* Output a double word move. 874 1.1 mrg It must be REG<-REG, REG<-MEM, MEM<-REG or REG<-CONST. 875 1.1 mrg On the FR30 we are constrained by the fact that it does not 876 1.1 mrg support offsetable addresses, and so we have to load the 877 1.1 mrg address of the secnd word into the second destination register 878 1.1 mrg before we can use it. */ 879 1.1 mrg 880 1.1 mrg rtx 881 1.1 mrg fr30_move_double (rtx * operands) 882 1.1 mrg { 883 1.1 mrg rtx src = operands[1]; 884 1.1 mrg rtx dest = operands[0]; 885 1.1 mrg enum rtx_code src_code = GET_CODE (src); 886 1.1 mrg enum rtx_code dest_code = GET_CODE (dest); 887 1.1 mrg machine_mode mode = GET_MODE (dest); 888 1.1 mrg rtx val; 889 1.1 mrg 890 1.1 mrg start_sequence (); 891 1.1 mrg 892 1.1 mrg if (dest_code == REG) 893 1.1 mrg { 894 1.1 mrg if (src_code == REG) 895 1.1 mrg { 896 1.1 mrg int reverse = (REGNO (dest) == REGNO (src) + 1); 897 1.1 mrg 898 1.1 mrg /* We normally copy the low-numbered register first. However, if 899 1.1 mrg the first register of operand 0 is the same as the second register 900 1.1 mrg of operand 1, we must copy in the opposite order. */ 901 1.1 mrg emit_insn (gen_rtx_SET (operand_subword (dest, reverse, TRUE, mode), 902 1.1 mrg operand_subword (src, reverse, TRUE, mode))); 903 1.1 mrg 904 1.1 mrg emit_insn 905 1.1 mrg (gen_rtx_SET (operand_subword (dest, !reverse, TRUE, mode), 906 1.1 mrg operand_subword (src, !reverse, TRUE, mode))); 907 1.1 mrg } 908 1.1 mrg else if (src_code == MEM) 909 1.1 mrg { 910 1.1 mrg rtx addr = XEXP (src, 0); 911 1.1 mrg rtx dest0 = operand_subword (dest, 0, TRUE, mode); 912 1.1 mrg rtx dest1 = operand_subword (dest, 1, TRUE, mode); 913 1.1 mrg rtx new_mem; 914 1.1 mrg 915 1.1 mrg gcc_assert (GET_CODE (addr) == REG); 916 1.1 mrg 917 1.1 mrg /* Copy the address before clobbering it. See PR 34174. */ 918 1.1 mrg emit_insn (gen_rtx_SET (dest1, addr)); 919 1.1 mrg emit_insn (gen_rtx_SET (dest0, adjust_address (src, SImode, 0))); 920 1.1 mrg emit_insn (gen_rtx_SET (dest1, plus_constant (SImode, dest1, 921 1.1 mrg UNITS_PER_WORD))); 922 1.1 mrg 923 1.1 mrg new_mem = gen_rtx_MEM (SImode, dest1); 924 1.1 mrg MEM_COPY_ATTRIBUTES (new_mem, src); 925 1.1 mrg 926 1.1 mrg emit_insn (gen_rtx_SET (dest1, new_mem)); 927 1.1 mrg } 928 1.1 mrg else if (src_code == CONST_INT || src_code == CONST_DOUBLE) 929 1.1 mrg { 930 1.1 mrg rtx words[2]; 931 1.1 mrg split_double (src, &words[0], &words[1]); 932 1.1 mrg emit_insn (gen_rtx_SET (operand_subword (dest, 0, TRUE, mode), 933 1.1 mrg words[0])); 934 1.1 mrg 935 1.1 mrg emit_insn (gen_rtx_SET (operand_subword (dest, 1, TRUE, mode), 936 1.1 mrg words[1])); 937 1.1 mrg } 938 1.1 mrg } 939 1.1 mrg else if (src_code == REG && dest_code == MEM) 940 1.1 mrg { 941 1.1 mrg rtx addr = XEXP (dest, 0); 942 1.1 mrg rtx src0; 943 1.1 mrg rtx src1; 944 1.1 mrg 945 1.1 mrg gcc_assert (GET_CODE (addr) == REG); 946 1.1 mrg 947 1.1 mrg src0 = operand_subword (src, 0, TRUE, mode); 948 1.1 mrg src1 = operand_subword (src, 1, TRUE, mode); 949 1.1 mrg 950 1.1 mrg emit_move_insn (adjust_address (dest, SImode, 0), src0); 951 1.1 mrg 952 1.1 mrg if (REGNO (addr) == STACK_POINTER_REGNUM 953 1.1 mrg || REGNO (addr) == FRAME_POINTER_REGNUM) 954 1.1 mrg emit_insn (gen_rtx_SET (adjust_address (dest, SImode, UNITS_PER_WORD), 955 1.1 mrg src1)); 956 1.1 mrg else 957 1.1 mrg { 958 1.1 mrg rtx new_mem; 959 1.1 mrg rtx scratch_reg_r0 = gen_rtx_REG (SImode, 0); 960 1.1 mrg 961 1.1 mrg /* We need a scratch register to hold the value of 'address + 4'. 962 1.1 mrg We use r0 for this purpose. It is used for example for long 963 1.1 mrg jumps and is already marked to not be used by normal register 964 1.1 mrg allocation. */ 965 1.1 mrg emit_insn (gen_movsi_internal (scratch_reg_r0, addr)); 966 1.1 mrg emit_insn (gen_addsi_small_int (scratch_reg_r0, scratch_reg_r0, 967 1.1 mrg GEN_INT (UNITS_PER_WORD))); 968 1.1 mrg new_mem = gen_rtx_MEM (SImode, scratch_reg_r0); 969 1.1 mrg MEM_COPY_ATTRIBUTES (new_mem, dest); 970 1.1 mrg emit_move_insn (new_mem, src1); 971 1.1 mrg emit_insn (gen_blockage ()); 972 1.1 mrg } 973 1.1 mrg } 974 1.1 mrg else 975 1.1 mrg /* This should have been prevented by the constraints on movdi_insn. */ 976 1.1 mrg gcc_unreachable (); 977 1.1 mrg 978 1.1 mrg val = get_insns (); 979 1.1 mrg end_sequence (); 980 1.1 mrg 981 1.1 mrg return val; 982 1.1 mrg } 983 1.1 mrg 984 1.1 mrg /* Implement TARGET_FRAME_POINTER_REQUIRED. */ 985 1.1 mrg 986 1.1 mrg bool 987 1.1 mrg fr30_frame_pointer_required (void) 988 1.1 mrg { 989 1.1 mrg return (flag_omit_frame_pointer == 0 || crtl->args.pretend_args_size > 0); 990 1.1 mrg } 991 1.1 mrg 992 1.1 mrg /*}}}*/ 993 1.1 mrg /*{{{ Trampoline Output Routines */ 994 1.1 mrg 995 1.1 mrg /* Implement TARGET_ASM_TRAMPOLINE_TEMPLATE. 996 1.1 mrg On the FR30, the trampoline is: 997 1.1 mrg 998 1.1 mrg nop 999 1.1 mrg ldi:32 STATIC, r12 1000 1.1 mrg nop 1001 1.1 mrg ldi:32 FUNCTION, r0 1002 1.1 mrg jmp @r0 1003 1.1 mrg 1004 1.1 mrg The no-ops are to guarantee that the static chain and final 1005 1.1 mrg target are 32 bit aligned within the trampoline. That allows us to 1006 1.1 mrg initialize those locations with simple SImode stores. The alternative 1007 1.1 mrg would be to use HImode stores. */ 1008 1.1 mrg 1009 1.1 mrg static void 1010 1.1 mrg fr30_asm_trampoline_template (FILE *f) 1011 1.1 mrg { 1012 1.1 mrg fprintf (f, "\tnop\n"); 1013 1.1 mrg fprintf (f, "\tldi:32\t#0, %s\n", reg_names [STATIC_CHAIN_REGNUM]); 1014 1.1 mrg fprintf (f, "\tnop\n"); 1015 1.1 mrg fprintf (f, "\tldi:32\t#0, %s\n", reg_names [COMPILER_SCRATCH_REGISTER]); 1016 1.1 mrg fprintf (f, "\tjmp\t@%s\n", reg_names [COMPILER_SCRATCH_REGISTER]); 1017 1.1 mrg } 1018 1.1 mrg 1019 1.1 mrg /* Implement TARGET_TRAMPOLINE_INIT. */ 1020 1.1 mrg 1021 1.1 mrg static void 1022 1.1 mrg fr30_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) 1023 1.1 mrg { 1024 1.1 mrg rtx fnaddr = XEXP (DECL_RTL (fndecl), 0); 1025 1.1 mrg rtx mem; 1026 1.1 mrg 1027 1.1 mrg emit_block_move (m_tramp, assemble_trampoline_template (), 1028 1.1 mrg GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); 1029 1.1 mrg 1030 1.1 mrg mem = adjust_address (m_tramp, SImode, 4); 1031 1.1 mrg emit_move_insn (mem, chain_value); 1032 1.1 mrg mem = adjust_address (m_tramp, SImode, 12); 1033 1.1 mrg emit_move_insn (mem, fnaddr); 1034 1.1 mrg } 1035 1.1 mrg 1036 1.1 mrg /*}}}*/ 1037 1.1 mrg /* Local Variables: */ 1038 /* folded-file: t */ 1039 /* End: */ 1040