/* MIPS32 Release 2 */
{ "m4k", PROCESSOR_M4K, 33 },
- { "24k", PROCESSOR_24K, 33 },
- { "24kc", PROCESSOR_24K, 33 }, /* 24K no FPU */
- { "24kf", PROCESSOR_24K, 33 }, /* 24K 1:2 FPU */
- { "24kx", PROCESSOR_24KX, 33 }, /* 24K 1:1 FPU */
+ { "4kec", PROCESSOR_4KC, 33 },
+ { "4kem", PROCESSOR_4KC, 33 },
+ { "4kep", PROCESSOR_4KP, 33 },
+ { "24kc", PROCESSOR_24KC, 33 }, /* 24K no FPU */
+ { "24kf", PROCESSOR_24KF, 33 }, /* 24K 1:2 FPU */
+ { "24kx", PROCESSOR_24KX, 33 }, /* 24K 1:1 FPU */
+ { "24kec", PROCESSOR_24KC, 33 }, /* 24K with DSP */
+ { "24kef", PROCESSOR_24KF, 33 },
+ { "24kex", PROCESSOR_24KX, 33 },
+ { "34kc", PROCESSOR_24KC, 33 }, /* 34K with MT/DSP */
+ { "34kf", PROCESSOR_24KF, 33 },
+ { "34kx", PROCESSOR_24KX, 33 },
/* MIPS64 */
{ "5kc", PROCESSOR_5KC, 64 },
COSTS_N_INSNS (256), /* fp_div_sf */ \
COSTS_N_INSNS (256) /* fp_div_df */
+static struct mips_rtx_cost_data const mips_rtx_cost_optimize_size =
+ {
+ COSTS_N_INSNS (1), /* fp_add */
+ COSTS_N_INSNS (1), /* fp_mult_sf */
+ COSTS_N_INSNS (1), /* fp_mult_df */
+ COSTS_N_INSNS (1), /* fp_div_sf */
+ COSTS_N_INSNS (1), /* fp_div_df */
+ COSTS_N_INSNS (1), /* int_mult_si */
+ COSTS_N_INSNS (1), /* int_mult_di */
+ COSTS_N_INSNS (1), /* int_div_si */
+ COSTS_N_INSNS (1), /* int_div_di */
+ 2, /* branch_cost */
+ 4 /* memory_latency */
+ };
+
static struct mips_rtx_cost_data const mips_rtx_cost_data[PROCESSOR_MAX] =
{
{ /* R3000 */
{ /* 20KC */
DEFAULT_COSTS
},
- { /* 24k */
+ { /* 24KC */
+ SOFT_FP_COSTS,
+ COSTS_N_INSNS (5), /* int_mult_si */
+ COSTS_N_INSNS (5), /* int_mult_di */
+ COSTS_N_INSNS (41), /* int_div_si */
+ COSTS_N_INSNS (41), /* int_div_di */
+ 1, /* branch_cost */
+ 4 /* memory_latency */
+ },
+ { /* 24KF */
COSTS_N_INSNS (8), /* fp_add */
COSTS_N_INSNS (8), /* fp_mult_sf */
COSTS_N_INSNS (10), /* fp_mult_df */
1, /* branch_cost */
4 /* memory_latency */
},
- { /* 24kx */
+ { /* 24KX */
COSTS_N_INSNS (4), /* fp_add */
COSTS_N_INSNS (4), /* fp_mult_sf */
COSTS_N_INSNS (5), /* fp_mult_df */
static enum mips_symbol_type
mips_classify_symbol (rtx x)
{
+ tree decl;
+
if (GET_CODE (x) == LABEL_REF)
{
if (TARGET_MIPS16)
return SYMBOL_SMALL_DATA;
}
- if (SYMBOL_REF_SMALL_P (x))
+ /* Do not use small-data accesses for weak symbols; they may end up
+ being zero. */
+ if (SYMBOL_REF_SMALL_P (x)
+ && !SYMBOL_REF_WEAK (x))
return SYMBOL_SMALL_DATA;
if (TARGET_ABICALLS)
{
- if (SYMBOL_REF_DECL (x) == 0)
+ decl = SYMBOL_REF_DECL (x);
+ if (decl == 0)
{
if (!SYMBOL_REF_LOCAL_P (x))
return SYMBOL_GOT_GLOBAL;
In the third case we have more freedom since both forms of
access will work for any kind of symbol. However, there seems
- little point in doing things differently. */
- if (DECL_P (SYMBOL_REF_DECL (x))
- && TREE_PUBLIC (SYMBOL_REF_DECL (x))
- && !(TARGET_ABSOLUTE_ABICALLS
- && targetm.binds_local_p (SYMBOL_REF_DECL (x))))
+ little point in doing things differently.
+
+ Note that weakref symbols are not TREE_PUBLIC, but their
+ targets are global or weak symbols. Relocations in the
+ object file will be against the target symbol, so it's
+ that symbol's binding that matters here. */
+ if (DECL_P (decl)
+ && (TREE_PUBLIC (decl) || DECL_WEAK (decl))
+ && !(TARGET_ABSOLUTE_ABICALLS && targetm.binds_local_p (decl)))
return SYMBOL_GOT_GLOBAL;
}
*offset = 0;
if (GET_CODE (x) == CONST)
- x = XEXP (x, 0);
-
- if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
{
- *offset += INTVAL (XEXP (x, 1));
x = XEXP (x, 0);
+ if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ {
+ *offset += INTVAL (XEXP (x, 1));
+ x = XEXP (x, 0);
+ }
}
*base = x;
}
v1 = gen_rtx_REG (Pmode, GP_RETURN + 1);
model = SYMBOL_REF_TLS_MODEL (loc);
+ /* Only TARGET_ABICALLS code can have more than one module; other
+ code must be be static and should not use a GOT. All TLS models
+ reduce to local exec in this situation. */
+ if (!TARGET_ABICALLS)
+ model = TLS_MODEL_LOCAL_EXEC;
switch (model)
{
break;
case TLS_MODEL_LOCAL_EXEC:
-
if (Pmode == DImode)
emit_insn (gen_tls_get_tp_di (v1));
else
mips_expand_unaligned_store (rtx dest, rtx src, unsigned int width, int bitpos)
{
rtx left, right;
+ enum machine_mode mode;
if (!mips_get_unaligned_mem (&dest, width, bitpos, &left, &right))
return false;
- src = gen_lowpart (mode_for_size (width, MODE_INT, 0), src);
+ mode = mode_for_size (width, MODE_INT, 0);
+ src = gen_lowpart (mode, src);
- if (GET_MODE (src) == DImode)
+ if (mode == DImode)
{
emit_insn (gen_mov_sdl (dest, src, left));
emit_insn (gen_mov_sdr (copy_rtx (dest), copy_rtx (src), right));
return true;
}
+/* Return true if X is a MEM with the same size as MODE. */
+
+bool
+mips_mem_fits_mode_p (enum machine_mode mode, rtx x)
+{
+ rtx size;
+
+ if (!MEM_P (x))
+ return false;
+
+ size = MEM_SIZE (x);
+ return size && INTVAL (size) == GET_MODE_SIZE (mode);
+}
+
/* Return true if (zero_extract OP SIZE POSITION) can be used as the
source of an "ext" instruction or the destination of an "ins"
instruction. OP must be a register operand and the following
mips_set_tune (mips_arch_info);
/* Set cost structure for the processor. */
- mips_cost = &mips_rtx_cost_data[mips_tune];
+ if (optimize_size)
+ mips_cost = &mips_rtx_cost_optimize_size;
+ else
+ mips_cost = &mips_rtx_cost_data[mips_tune];
if ((target_flags_explicit & MASK_64BIT) != 0)
{
{
rtx mem;
- mem = gen_rtx_MEM (mode, plus_constant (stack_pointer_rtx, offset));
+ mem = gen_frame_mem (mode, plus_constant (stack_pointer_rtx, offset));
fn (gen_rtx_REG (mode, regno), mem);
}
return data_section;
}
-/* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
- access DECL using %gp_rel(...)($gp). */
+/* Implement TARGET_IN_SMALL_DATA_P. This function controls whether
+ locally-defined objects go in a small data section. It also controls
+ the setting of the SYMBOL_REF_SMALL_P flag, which in turn helps
+ mips_classify_symbol decide when to use %gp_rel(...)($gp) accesses. */
static bool
mips_in_small_data_p (tree decl)
int size;
/* ??? How should SCmode be handled? */
- if (type == NULL_TREE || mode == DImode || mode == DFmode)
+ if (mode == DImode || mode == DFmode)
return 0;
- size = int_size_in_bytes (type);
+ size = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
return size == -1 || size > UNITS_PER_WORD;
}
else
CMP_4S_BUILTINS (c, COND), \
CMP_4S_BUILTINS (cabs, COND)
-/* __builtin_mips_abs_ps() maps to the standard absM2 pattern. */
-#define CODE_FOR_mips_abs_ps CODE_FOR_absv2sf2
-
static const struct builtin_description mips_bdesc[] =
{
DIRECT_BUILTIN (pll_ps, MIPS_V2SF_FTYPE_V2SF_V2SF, MASK_PAIRED_SINGLE_FLOAT),
if (m->proc == PROCESSOR_MAX || (m->proc == mips_arch))
for (d = m->bdesc; d < &m->bdesc[m->size]; d++)
if ((d->target_flags & target_flags) == d->target_flags)
- lang_hooks.builtin_function (d->name, types[d->function_type],
- d - m->bdesc + offset,
- BUILT_IN_MD, NULL, NULL);
+ add_builtin_function (d->name, types[d->function_type],
+ d - m->bdesc + offset,
+ BUILT_IN_MD, NULL, NULL);
offset += m->size;
}
}