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_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) { if (cfun->machine->size_for_adjusting_sp <= 255) { insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (cfun->machine->size_for_adjusting_sp))); RTX_FRAME_RELATED_P (insn) = 1; } else { insn = emit_insn (gen_movsi (gen_rtx_REG (Pmode, MOXIE_R5), GEN_INT (-cfun->machine->size_for_adjusting_sp))); RTX_FRAME_RELATED_P (insn) = 1; insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, gen_rtx_REG (Pmode, MOXIE_R5))); RTX_FRAME_RELATED_P (insn) = 1; } } }
rtx fr30_move_double (rtx * operands) { rtx src = operands[1]; rtx dest = operands[0]; enum rtx_code src_code = GET_CODE (src); enum rtx_code dest_code = GET_CODE (dest); enum machine_mode mode = GET_MODE (dest); rtx val; start_sequence (); if (dest_code == REG) { if (src_code == REG) { int reverse = (REGNO (dest) == REGNO (src) + 1); /* We normally copy the low-numbered register first. However, if the first register of operand 0 is the same as the second register of operand 1, we must copy in the opposite order. */ emit_insn (gen_rtx_SET (VOIDmode, operand_subword (dest, reverse, TRUE, mode), operand_subword (src, reverse, TRUE, mode))); emit_insn (gen_rtx_SET (VOIDmode, operand_subword (dest, !reverse, TRUE, mode), operand_subword (src, !reverse, TRUE, mode))); } else if (src_code == MEM) { rtx addr = XEXP (src, 0); int dregno = REGNO (dest); rtx dest0; rtx dest1; rtx new_mem; /* If the high-address word is used in the address, we must load it last. Otherwise, load it first. */ int reverse = (refers_to_regno_p (dregno, dregno + 1, addr, 0) != 0); gcc_assert (GET_CODE (addr) == REG); dest0 = operand_subword (dest, reverse, TRUE, mode); dest1 = operand_subword (dest, !reverse, TRUE, mode); if (reverse) { emit_insn (gen_rtx_SET (VOIDmode, dest1, adjust_address (src, SImode, 0))); emit_insn (gen_rtx_SET (SImode, dest0, gen_rtx_REG (SImode, REGNO (addr)))); emit_insn (gen_rtx_SET (SImode, dest0, plus_constant (dest0, UNITS_PER_WORD))); new_mem = gen_rtx_MEM (SImode, dest0); MEM_COPY_ATTRIBUTES (new_mem, src); emit_insn (gen_rtx_SET (VOIDmode, dest0, new_mem)); } else { emit_insn (gen_rtx_SET (VOIDmode, dest0, adjust_address (src, SImode, 0))); emit_insn (gen_rtx_SET (SImode, dest1, gen_rtx_REG (SImode, REGNO (addr)))); emit_insn (gen_rtx_SET (SImode, dest1, plus_constant (dest1, UNITS_PER_WORD))); new_mem = gen_rtx_MEM (SImode, dest1); MEM_COPY_ATTRIBUTES (new_mem, src); emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem)); } } else if (src_code == CONST_INT || src_code == CONST_DOUBLE) { rtx words[2]; split_double (src, &words[0], &words[1]); emit_insn (gen_rtx_SET (VOIDmode, operand_subword (dest, 0, TRUE, mode), words[0])); emit_insn (gen_rtx_SET (VOIDmode, operand_subword (dest, 1, TRUE, mode), words[1])); } } else if (src_code == REG && dest_code == MEM) { rtx addr = XEXP (dest, 0); rtx src0; rtx src1; gcc_assert (GET_CODE (addr) == REG); src0 = operand_subword (src, 0, TRUE, mode); src1 = operand_subword (src, 1, TRUE, mode); emit_insn (gen_rtx_SET (VOIDmode, adjust_address (dest, SImode, 0), src0)); if (REGNO (addr) == STACK_POINTER_REGNUM || REGNO (addr) == FRAME_POINTER_REGNUM) emit_insn (gen_rtx_SET (VOIDmode, adjust_address (dest, SImode, UNITS_PER_WORD), src1)); else { rtx new_mem; /* We need a scratch register to hold the value of 'address + 4'. We ought to allow gcc to find one for us, but for now, just push one of the source registers. */ emit_insn (gen_movsi_push (src0)); emit_insn (gen_movsi_internal (src0, addr)); emit_insn (gen_addsi_small_int (src0, src0, GEN_INT (UNITS_PER_WORD))); new_mem = gen_rtx_MEM (SImode, src0); MEM_COPY_ATTRIBUTES (new_mem, dest); emit_insn (gen_rtx_SET (VOIDmode, new_mem, src1)); emit_insn (gen_movsi_pop (src0)); } } else /* This should have been prevented by the constraints on movdi_insn. */ gcc_unreachable (); val = get_insns (); end_sequence (); return val; }
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 ()); }