static bool nds32_expand_setmem_loop_v3m (rtx dstmem, rtx size, rtx value) { rtx base_reg = copy_to_mode_reg (Pmode, XEXP (dstmem, 0)); rtx need_align_bytes = gen_reg_rtx (SImode); rtx last_2_bit = gen_reg_rtx (SImode); rtx byte_loop_base = gen_reg_rtx (SImode); rtx byte_loop_size = gen_reg_rtx (SImode); rtx remain_size = gen_reg_rtx (SImode); rtx new_base_reg; rtx value4byte, value4doubleword; rtx byte_mode_size; rtx last_byte_loop_label = gen_label_rtx (); size = force_reg (SImode, size); value4doubleword = nds32_gen_dup_8_byte_to_double_word_value (value); value4byte = simplify_gen_subreg (QImode, value4doubleword, DImode, subreg_lowpart_offset (QImode, DImode)); emit_move_insn (byte_loop_size, size); emit_move_insn (byte_loop_base, base_reg); /* Jump to last byte loop if size is less than 16. */ emit_cmp_and_jump_insns (size, gen_int_mode (16, SImode), LE, NULL, SImode, 1, last_byte_loop_label); /* Make sure align to 4 byte first since v3m can't unalign access. */ emit_insn (gen_andsi3 (last_2_bit, base_reg, gen_int_mode (0x3, SImode))); emit_insn (gen_subsi3 (need_align_bytes, gen_int_mode (4, SImode), last_2_bit)); /* Align to 4 byte. */ new_base_reg = emit_setmem_byte_loop (base_reg, need_align_bytes, value4byte, true); /* Calculate remain size. */ emit_insn (gen_subsi3 (remain_size, size, need_align_bytes)); /* Set memory word by word. */ byte_mode_size = emit_setmem_doubleword_loop (new_base_reg, remain_size, value4doubleword); emit_move_insn (byte_loop_base, new_base_reg); emit_move_insn (byte_loop_size, byte_mode_size); emit_label (last_byte_loop_label); /* And set memory for remain bytes. */ emit_setmem_byte_loop (byte_loop_base, byte_loop_size, value4byte, false); return true; }
void moxie_expand_prologue (void) { int regno; rtx insn; moxie_compute_frame (); if (flag_stack_usage_info) current_function_static_stack_size = cfun->machine->size_for_adjusting_sp; /* Save callee-saved registers. */ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) { if (!fixed_regs[regno] && df_regs_ever_live_p (regno) && !call_used_regs[regno]) { insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno))); RTX_FRAME_RELATED_P (insn) = 1; } } if (cfun->machine->size_for_adjusting_sp > 0) { int i = cfun->machine->size_for_adjusting_sp; while ((i >= 255) && (i <= 510)) { insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (255))); RTX_FRAME_RELATED_P (insn) = 1; i -= 255; } if (i <= 255) { insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (i))); RTX_FRAME_RELATED_P (insn) = 1; } else { rtx reg = gen_rtx_REG (SImode, MOXIE_R12); insn = emit_move_insn (reg, GEN_INT (i)); RTX_FRAME_RELATED_P (insn) = 1; insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, reg)); RTX_FRAME_RELATED_P (insn) = 1; } } }
void moxie_expand_epilogue (void) { int regno; rtx reg; if (cfun->machine->callee_saved_reg_size != 0) { reg = gen_rtx_REG (Pmode, MOXIE_R12); if (cfun->machine->callee_saved_reg_size <= 255) { emit_move_insn (reg, hard_frame_pointer_rtx); emit_insn (gen_subsi3 (reg, reg, GEN_INT (cfun->machine->callee_saved_reg_size))); } else { emit_move_insn (reg, GEN_INT (-cfun->machine->callee_saved_reg_size)); emit_insn (gen_addsi3 (reg, reg, hard_frame_pointer_rtx)); } for (regno = FIRST_PSEUDO_REGISTER; regno-- > 0; ) if (!fixed_regs[regno] && !call_used_regs[regno] && df_regs_ever_live_p (regno)) { rtx preg = gen_rtx_REG (Pmode, regno); emit_insn (gen_movsi_pop (reg, preg)); } } emit_jump_insn (gen_returner ()); }
void moxie_expand_prologue (void) { int regno; rtx insn; moxie_compute_frame (); /* Save callee-saved registers. */ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) { if (!fixed_regs[regno] && df_regs_ever_live_p (regno) && !call_used_regs[regno]) { insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno))); RTX_FRAME_RELATED_P (insn) = 1; } } if (cfun->machine->size_for_adjusting_sp > 0) { int i = cfun->machine->size_for_adjusting_sp; while (i > 255) { insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (255))); RTX_FRAME_RELATED_P (insn) = 1; i -= 255; } if (i > 0) { insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (i))); RTX_FRAME_RELATED_P (insn) = 1; } } }
void fr30_expand_prologue (void) { int regno; rtx insn; if (! current_frame_info.initialised) fr30_compute_frame_size (0, 0); /* This cases shouldn't happen. Catch it now. */ gcc_assert (current_frame_info.total_size || !current_frame_info.gmask); /* Allocate space for register arguments if this is a variadic function. */ if (current_frame_info.pretend_size) { int regs_to_save = current_frame_info.pretend_size / UNITS_PER_WORD; /* Push argument registers into the pretend arg area. */ for (regno = FIRST_ARG_REGNUM + FR30_NUM_ARG_REGS; regno --, regs_to_save --;) { insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno))); RTX_FRAME_RELATED_P (insn) = 1; } } if (current_frame_info.gmask) { /* Save any needed call-saved regs. */ for (regno = STACK_POINTER_REGNUM; regno--;) { if ((current_frame_info.gmask & (1 << regno)) != 0) { insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno))); RTX_FRAME_RELATED_P (insn) = 1; } } } /* Save return address if necessary. */ if (current_frame_info.save_rp) { insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, RETURN_POINTER_REGNUM))); RTX_FRAME_RELATED_P (insn) = 1; } /* Save old frame pointer and create new one, if necessary. */ if (current_frame_info.save_fp) { if (current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD)) { int enter_size = current_frame_info.frame_size + UNITS_PER_WORD; rtx pattern; insn = emit_insn (gen_enter_func (GEN_INT (enter_size))); RTX_FRAME_RELATED_P (insn) = 1; pattern = PATTERN (insn); /* Also mark all 3 subexpressions as RTX_FRAME_RELATED_P. */ if (GET_CODE (pattern) == PARALLEL) { int x; for (x = XVECLEN (pattern, 0); x--;) { rtx part = XVECEXP (pattern, 0, x); /* One of the insns in the ENTER pattern updates the frame pointer. If we do not actually need the frame pointer in this function then this is a side effect rather than a desired effect, so we do not mark that insn as being related to the frame set up. Doing this allows us to compile the crash66.C test file in the G++ testsuite. */ if (! frame_pointer_needed && GET_CODE (part) == SET && REGNO (SET_DEST (part)) == HARD_FRAME_POINTER_REGNUM) RTX_FRAME_RELATED_P (part) = 0; else RTX_FRAME_RELATED_P (part) = 1; } } } else { insn = emit_insn (gen_movsi_push (frame_pointer_rtx)); RTX_FRAME_RELATED_P (insn) = 1; if (frame_pointer_needed) { insn = emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx)); RTX_FRAME_RELATED_P (insn) = 1; } } } /* Allocate the stack frame. */ if (current_frame_info.frame_size == 0) ; /* Nothing to do. */ else if (current_frame_info.save_fp && current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD)) ; /* Nothing to do. */ else if (current_frame_info.frame_size <= 512) { insn = emit_insn (gen_add_to_stack (GEN_INT (- current_frame_info.frame_size))); RTX_FRAME_RELATED_P (insn) = 1; } else { rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM); insn = emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size))); RTX_FRAME_RELATED_P (insn) = 1; insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp)); RTX_FRAME_RELATED_P (insn) = 1; } if (current_function_profile) emit_insn (gen_blockage ()); }