📄 fr30.c
字号:
return 0; if (type && mode == BLKmode) size = int_size_in_bytes (type); else size = GET_MODE_SIZE (mode); return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;}/* Returns the number of bytes in which *part* of a parameter of machine mode MODE and tree type TYPE (which may be NULL if the type is not known). If the argument fits entirely in the argument registers, or entirely on the stack, then 0 is returned. CUM is the number of argument registers already used by earlier parameters to the function. */static intfr30_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, bool named){ /* Unnamed arguments, i.e. those that are prototyped as ... are always passed on the stack. Also check here to see if all the argument registers are full. */ if (named == 0 || *cum >= FR30_NUM_ARG_REGS) return 0; /* Work out how many argument registers would be needed if this parameter were to be passed entirely in registers. If there are sufficient argument registers available (or if no registers are needed because the parameter must be passed on the stack) then return zero, as this parameter does not require partial register, partial stack stack space. */ if (*cum + fr30_num_arg_regs (mode, type) <= FR30_NUM_ARG_REGS) return 0; return (FR30_NUM_ARG_REGS - *cum) * UNITS_PER_WORD;}/*}}}*//*{{{ Operand predicates */ #ifndef Mmode#define Mmode enum machine_mode#endif/* Returns true if OPERAND is an integer value suitable for use in an ADDSP instruction. */intstack_add_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED){ return (GET_CODE (operand) == CONST_INT && INTVAL (operand) >= -512 && INTVAL (operand) <= 508 && ((INTVAL (operand) & 3) == 0));}/* Returns true if OPERAND is an integer value suitable for use in an ADD por ADD2 instruction, or if it is a register. */intadd_immediate_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED){ return (GET_CODE (operand) == REG || (GET_CODE (operand) == CONST_INT && INTVAL (operand) >= -16 && INTVAL (operand) <= 15));}/* Returns true if OPERAND is hard register in the range 8 - 15. */inthigh_register_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED){ return (GET_CODE (operand) == REG && REGNO (operand) <= 15 && REGNO (operand) >= 8);}/* Returns true if OPERAND is hard register in the range 0 - 7. */intlow_register_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED){ return (GET_CODE (operand) == REG && REGNO (operand) <= 7);}/* Returns true if OPERAND is suitable for use in a CALL insn. */intcall_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED){ return (GET_CODE (operand) == MEM && (GET_CODE (XEXP (operand, 0)) == SYMBOL_REF || GET_CODE (XEXP (operand, 0)) == REG));}/* Returns TRUE if OP is a valid operand of a DImode operation. */intdi_operand (rtx op, Mmode mode){ if (register_operand (op, mode)) return TRUE; if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode) return FALSE; if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); switch (GET_CODE (op)) { case CONST_DOUBLE: case CONST_INT: return TRUE; case MEM: return memory_address_p (DImode, XEXP (op, 0)); default: return FALSE; }}/* Returns TRUE if OP is a DImode register or MEM. */intnonimmediate_di_operand (rtx op, Mmode mode){ if (register_operand (op, mode)) return TRUE; if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode) return FALSE; if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); if (GET_CODE (op) == MEM) return memory_address_p (DImode, XEXP (op, 0)); return FALSE;}/* Returns true iff all the registers in the operands array are in descending or ascending order. */intfr30_check_multiple_regs (rtx *operands, int num_operands, int descending){ if (descending) { unsigned int prev_regno = 0; while (num_operands --) { if (GET_CODE (operands [num_operands]) != REG) return 0; if (REGNO (operands [num_operands]) < prev_regno) return 0; prev_regno = REGNO (operands [num_operands]); } } else { unsigned int prev_regno = CONDITION_CODE_REGNUM; while (num_operands --) { if (GET_CODE (operands [num_operands]) != REG) return 0; if (REGNO (operands [num_operands]) > prev_regno) return 0; prev_regno = REGNO (operands [num_operands]); } } return 1;}intfr30_const_double_is_zero (rtx operand){ REAL_VALUE_TYPE d; if (operand == NULL || GET_CODE (operand) != CONST_DOUBLE) return 0; REAL_VALUE_FROM_CONST_DOUBLE (d, operand); return REAL_VALUES_EQUAL (d, dconst0);}/*}}}*//*{{{ Instruction Output Routines *//* Output a double word move. It must be REG<-REG, REG<-MEM, MEM<-REG or REG<-CONST. On the FR30 we are constrained by the fact that it does not support offsetable addresses, and so we have to load the address of the secnd word into the second destination register before we can use it. */rtxfr30_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); if (GET_CODE (addr) != REG) abort (); 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; if (GET_CODE (addr) != REG) abort (); 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. */ abort (); val = get_insns (); end_sequence (); return val;}/*}}}*//* Local Variables: *//* folded-file: t *//* End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -