/* Subroutines used for code generation on the Lattice Mico32 architecture.
Contributed by Jon Beniston <jon@beniston.com>
- Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
This file is part of GCC.
#include "tm_p.h"
#include "function.h"
#include "diagnostic-core.h"
-#include "toplev.h"
#include "optabs.h"
#include "libfuncs.h"
#include "ggc.h"
static void expand_save_restore (struct lm32_frame_info *info, int op);
static void stack_adjust (HOST_WIDE_INT amount);
static bool lm32_in_small_data_p (const_tree);
-static void lm32_setup_incoming_varargs (CUMULATIVE_ARGS * cum,
+static void lm32_setup_incoming_varargs (cumulative_args_t cum,
enum machine_mode mode, tree type,
int *pretend_size, int no_rtl);
-static bool lm32_rtx_costs (rtx x, int code, int outer_code, int *total,
- bool speed);
+static bool lm32_rtx_costs (rtx x, int code, int outer_code, int opno,
+ int *total, bool speed);
static bool lm32_can_eliminate (const int, const int);
static bool
lm32_legitimate_address_p (enum machine_mode mode, rtx x, bool strict);
static HOST_WIDE_INT lm32_compute_frame_size (int size);
static void lm32_option_override (void);
+static rtx lm32_function_arg (cumulative_args_t cum,
+ enum machine_mode mode, const_tree type,
+ bool named);
+static void lm32_function_arg_advance (cumulative_args_t cum,
+ enum machine_mode mode,
+ const_tree type, bool named);
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE lm32_option_override
#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
#undef TARGET_SETUP_INCOMING_VARARGS
#define TARGET_SETUP_INCOMING_VARARGS lm32_setup_incoming_varargs
+#undef TARGET_FUNCTION_ARG
+#define TARGET_FUNCTION_ARG lm32_function_arg
+#undef TARGET_FUNCTION_ARG_ADVANCE
+#define TARGET_FUNCTION_ARG_ADVANCE lm32_function_arg_advance
#undef TARGET_PROMOTE_PROTOTYPES
#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
#undef TARGET_MIN_ANCHOR_OFFSET
{
enum machine_mode mode;
int branch_p;
+ rtx temp;
+ rtx cond;
+ rtx label;
mode = GET_MODE (cmp0);
if (mode == VOIDmode)
case LT:
case LEU:
case LTU:
- code = swap_condition (code);
- rtx temp = cmp0;
- cmp0 = cmp1;
- cmp1 = temp;
- break;
+ {
+ rtx temp;
+
+ code = swap_condition (code);
+ temp = cmp0;
+ cmp0 = cmp1;
+ cmp1 = temp;
+ break;
+ }
default:
break;
}
if (branch_p)
{
- rtx insn;
+ rtx insn, cond, label;
/* Operands must be in registers. */
if (!register_operand (cmp0, mode))
cmp1 = force_reg (mode, cmp1);
/* Generate conditional branch instruction. */
- rtx cond = gen_rtx_fmt_ee (code, mode, cmp0, cmp1);
- rtx label = gen_rtx_LABEL_REF (VOIDmode, destination);
+ cond = gen_rtx_fmt_ee (code, mode, cmp0, cmp1);
+ label = gen_rtx_LABEL_REF (VOIDmode, destination);
insn = gen_rtx_SET (VOIDmode, pc_rtx,
gen_rtx_IF_THEN_ELSE (VOIDmode,
cond, label, pc_rtx));
/* Setup frame pointer if it's needed. */
if (frame_pointer_needed == 1)
{
- /* Load offset - Don't use total_size, as that includes pretend_size,
- which isn't part of this frame? */
- insn =
- emit_move_insn (frame_pointer_rtx,
- GEN_INT (current_frame_info.args_size +
- current_frame_info.callee_size +
- current_frame_info.locals_size));
- RTX_FRAME_RELATED_P (insn) = 1;
+ /* Move sp to fp. */
+ insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
+ RTX_FRAME_RELATED_P (insn) = 1;
- /* Add in sp. */
- insn = emit_add (frame_pointer_rtx,
- frame_pointer_rtx, stack_pointer_rtx);
+ /* Add offset - Don't use total_size, as that includes pretend_size,
+ which isn't part of this frame? */
+ insn = emit_add (frame_pointer_rtx,
+ frame_pointer_rtx,
+ GEN_INT (current_frame_info.args_size +
+ current_frame_info.callee_size +
+ current_frame_info.locals_size));
RTX_FRAME_RELATED_P (insn) = 1;
}
else if (GET_CODE (op) == CONST_DOUBLE)
{
if ((CONST_DOUBLE_LOW (op) != 0) || (CONST_DOUBLE_HIGH (op) != 0))
- output_operand_lossage ("Only 0.0 can be loaded as an immediate");
+ output_operand_lossage ("only 0.0 can be loaded as an immediate");
else
fprintf (file, "0");
}
NAMED is nonzero if this argument is a named parameter
(otherwise it is an extra parameter matching an ellipsis). */
-rtx
-lm32_function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode,
- tree type, int named)
+static rtx
+lm32_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
+ const_tree type, bool named)
{
+ CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+
if (mode == VOIDmode)
/* Compute operand 2 of the call insn. */
return GEN_INT (0);
if (targetm.calls.must_pass_in_stack (mode, type))
return NULL_RTX;
- if (!named || (cum + LM32_NUM_REGS2 (mode, type) > LM32_NUM_ARG_REGS))
+ if (!named || (*cum + LM32_NUM_REGS2 (mode, type) > LM32_NUM_ARG_REGS))
return NULL_RTX;
- return gen_rtx_REG (mode, cum + LM32_FIRST_ARG_REG);
+ return gen_rtx_REG (mode, *cum + LM32_FIRST_ARG_REG);
+}
+
+static void
+lm32_function_arg_advance (cumulative_args_t cum, enum machine_mode mode,
+ const_tree type, bool named ATTRIBUTE_UNUSED)
+{
+ *get_cumulative_args (cum) += LM32_NUM_REGS2 (mode, type);
}
HOST_WIDE_INT
}
static void
-lm32_setup_incoming_varargs (CUMULATIVE_ARGS * cum, enum machine_mode mode,
+lm32_setup_incoming_varargs (cumulative_args_t cum_v, enum machine_mode mode,
tree type, int *pretend_size, int no_rtl)
{
+ CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
int first_anon_arg;
tree fntype;
delta = bits / BITS_PER_UNIT;
/* Allocate a buffer for the temporary registers. */
- regs = alloca (sizeof (rtx) * length / delta);
+ regs = XALLOCAVEC (rtx, length / delta);
/* Load as many BITS-sized chunks as possible. */
for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
scanned. In either case, *TOTAL contains the cost result. */
static bool
-lm32_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
+lm32_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
+ int *total, bool speed)
{
enum machine_mode mode = GET_MODE (x);
bool small_mode;
return register_or_zero_operand (operands[1], mode);
return true;
}
-
-/* Implement LEGITIMATE_CONSTANT_P. */
-
-bool
-lm32_legitimate_constant_p (rtx x)
-{
- /* 32-bit addresses require multiple instructions. */
- if (!flag_pic && reloc_operand (x, GET_MODE (x)))
- return false;
-
- return true;
-}