/* Subroutines used for code generation of Andes NDS32 cpu for GNU compiler
- Copyright (C) 2012-2018 Free Software Foundation, Inc.
+ Copyright (C) 2012-2021 Free Software Foundation, Inc.
Contributed by Andes Technology Corporation.
This file is part of GCC.
frame_adjust_insn = emit_insn (frame_adjust_insn);
/* Because (tmp_reg <- full_value) may be split into two
- rtl patterns, we can not set its RTX_FRAME_RELATED_P.
+ rtl patterns, we cannot set its RTX_FRAME_RELATED_P.
We need to construct another (sp <- sp + full_value)
and then insert it into sp_adjust_insn's reg note to
represent a frame related expression.
/* -- Passing Arguments in Registers. */
static rtx
-nds32_function_arg (cumulative_args_t ca, machine_mode mode,
- const_tree type, bool named)
+nds32_function_arg (cumulative_args_t ca, const function_arg_info &arg)
{
unsigned int regno;
CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
+ tree type = arg.type;
+ machine_mode mode = arg.mode;
/* The last time this hook is called,
- it is called with MODE == VOIDmode. */
- if (mode == VOIDmode)
+ it is called with an end marker. */
+ if (arg.end_marker_p ())
return NULL_RTX;
/* For nameless arguments, we need to take care it individually. */
- if (!named)
+ if (!arg.named)
{
/* If we are under hard float abi, we have arguments passed on the
stack and all situation can be handled by GCC itself. */
}
static bool
-nds32_must_pass_in_stack (machine_mode mode, const_tree type)
+nds32_must_pass_in_stack (const function_arg_info &arg)
{
/* Return true if a type must be passed in memory.
If it is NOT using hard float abi, small aggregates can be
passed in a register even we are calling a variadic function.
So there is no need to take padding into consideration. */
if (TARGET_HARD_FLOAT)
- return must_pass_in_stack_var_size_or_pad (mode, type);
+ return must_pass_in_stack_var_size_or_pad (arg);
else
- return must_pass_in_stack_var_size (mode, type);
+ return must_pass_in_stack_var_size (arg);
}
static int
-nds32_arg_partial_bytes (cumulative_args_t ca, machine_mode mode,
- tree type, bool named ATTRIBUTE_UNUSED)
+nds32_arg_partial_bytes (cumulative_args_t ca, const function_arg_info &arg)
{
/* Returns the number of bytes at the beginning of an argument that
must be put in registers. The value must be zero for arguments that are
/* If we have already runned out of argument registers, return zero
so that the argument will be entirely pushed on the stack. */
- if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
+ if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, arg.mode, arg.type)
>= NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS)
return 0;
/* Calculate how many registers do we need for this argument. */
- needed_reg_count = NDS32_NEED_N_REGS_FOR_ARG (mode, type);
+ needed_reg_count = NDS32_NEED_N_REGS_FOR_ARG (arg.mode, arg.type);
/* Calculate how many argument registers have left for passing argument.
Note that we should count it from next available register number. */
remaining_reg_count
= NDS32_MAX_GPR_REGS_FOR_ARGS
- - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
+ - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset,
+ arg.mode, arg.type)
- NDS32_GPR_ARG_FIRST_REGNUM);
/* Note that we have to return the nubmer of bytes, not registers count. */
}
static void
-nds32_function_arg_advance (cumulative_args_t ca, machine_mode mode,
- const_tree type, bool named)
+nds32_function_arg_advance (cumulative_args_t ca,
+ const function_arg_info &arg)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
+ tree type = arg.type;
+ machine_mode mode = arg.mode;
- if (named)
+ if (arg.named)
{
/* We need to further check TYPE and MODE so that we can determine
which kind of register we shall advance. */
HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
tree function)
{
+ const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk));
int this_regno;
+ assemble_start_function (thunk, fnname);
/* Make sure unwind info is emitted for the thunk if needed. */
final_start_function (emit_barrier (), file, 1);
}
final_end_function ();
+ assemble_end_function (thunk, fnname);
}
/* -- Permitting tail calls. */
static void
nds32_setup_incoming_varargs (cumulative_args_t ca,
- machine_mode mode,
- tree type,
+ const function_arg_info &arg,
int *pretend_args_size,
int second_time ATTRIBUTE_UNUSED)
{
cum = get_cumulative_args (ca);
- /* The MODE and TYPE describe the last argument.
+ /* ARG describes the last argument.
We need those information to determine the remaining registers
for varargs. */
total_args_regs
= NDS32_MAX_GPR_REGS_FOR_ARGS + NDS32_GPR_ARG_FIRST_REGNUM;
num_of_used_regs
- = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
- + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
+ = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, arg.mode, arg.type)
+ + NDS32_NEED_N_REGS_FOR_ARG (arg.mode, arg.type);
remaining_reg_count = total_args_regs - num_of_used_regs;
*pretend_args_size = remaining_reg_count * UNITS_PER_WORD;
/* Now we see the [ + const_addr ] pattern, but we need
some further checking. */
- if (flag_pic)
+ if (flag_pic || SYMBOL_REF_TLS_MODEL (op0))
return false;
/* If -mcmodel=large, the 'const_addr' is not a valid address
gen_rtvec (4, dwarf_low_re, dwarf_high_re,
dwarf_high_im, dwarf_low_im));
}
- else if (mode == SFmode || mode == SImode)
+ else if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
{
- /* Create new dwarf information with adjusted register number. */
- dwarf_single = gen_rtx_REG (word_mode, regno);
- return gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, dwarf_single));
+ return NULL_RTX;
}
else
{
new_attrs = tree_cons (get_identifier ("noclone"), NULL, new_attrs);
if (!TREE_PUBLIC (decl))
- error("indirect_call attribute can't apply for static function");
+ error ("indirect_call attribute can%'t apply for static function");
*attributes = new_attrs;
}
target_flags &= ~MASK_EXT_STRING;
if (flag_pic)
- error ("not support -fpic option for v3m toolchain");
+ error ("not support %<-fpic%> option for v3m toolchain");
}
/* See if we are using reduced-set registers:
{
if (nds32_arch_option == ARCH_V3S || nds32_arch_option == ARCH_V3F)
error ("Disable FPU ISA, "
- "the ABI option must be enable '-mfloat-abi=soft'");
+ "the ABI option must be enable %<-mfloat-abi=soft%>");
else
- error ("'-mabi=2fp+' option only support when FPU available, "
- "must be enable '-mext-fpu-sp' or '-mext-fpu-dp'");
+ error ("%<-mabi=2fp+%> option only support when FPU available, "
+ "must be enable %<-mext-fpu-sp%> or %<-mext-fpu-dp%>");
}
nds32_init_rtx_costs ();
int sp_adjust;
/* Prior to reloading, we can't tell how many registers must be saved.
- Thus we can not determine whether this function has null epilogue. */
+ Thus we cannot determine whether this function has null epilogue. */
if (!reload_completed)
return 0;
return false;
const char *pass_name = current_pass->name;
- if (pass_name && ((strcmp (pass_name, "split4") == 0)
+ if (pass_name && ((strcmp (pass_name, "split3") == 0)
|| (strcmp (pass_name, "split5") == 0)))
return !satisfies_constraint_Da (mem) || MEM_VOLATILE_P (mem);