Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(279)

Unified Diff: gcc/gcc/config/v850/v850.c

Issue 3050029: [gcc] GCC 4.5.0=>4.5.1 (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/nacl-toolchain.git
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gcc/gcc/config/v850/v850.h ('k') | gcc/gcc/config/v850/v850-c.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gcc/gcc/config/v850/v850.c
diff --git a/gcc/gcc/config/v850/v850.c b/gcc/gcc/config/v850/v850.c
index 51146e65d43e600298c008f55cc81cde5134c5a4..b7dd0921d4a876cc422eb5ed027b3e8d37d8c214 100644
--- a/gcc/gcc/config/v850/v850.c
+++ b/gcc/gcc/config/v850/v850.c
@@ -1,6 +1,6 @@
/* Subroutines for insn-output.c for NEC V850 series
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
Contributed by Jeff Law (law@cygnus.com).
This file is part of GCC.
@@ -58,7 +58,6 @@ static void substitute_ep_register (rtx, rtx, int, int, rtx *, rtx *);
static void v850_reorg (void);
static int ep_memory_offset (enum machine_mode, int);
static void v850_set_data_area (tree, v850_data_area);
-const struct attribute_spec v850_attribute_table[];
static tree v850_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
static tree v850_handle_data_area_attribute (tree *, tree, tree, int, bool *);
static void v850_insert_attributes (tree, tree *);
@@ -67,12 +66,16 @@ static section *v850_select_section (tree, int, unsigned HOST_WIDE_INT);
static void v850_encode_data_area (tree, rtx);
static void v850_encode_section_info (tree, rtx, int);
static bool v850_return_in_memory (const_tree, const_tree);
+static rtx v850_function_value (const_tree, const_tree, bool);
static void v850_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
tree, int *, int);
static bool v850_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
const_tree, bool);
static int v850_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
+static bool v850_can_eliminate (const int, const int);
+static void v850_asm_trampoline_template (FILE *);
+static void v850_trampoline_init (rtx, tree, rtx);
/* Information about the various small memory areas. */
struct small_memory_info small_memory[ (int)SMALL_MEMORY_max ] =
@@ -104,6 +107,20 @@ static GTY(()) section *tdata_section;
static GTY(()) section *zdata_section;
static GTY(()) section *zbss_section;
+/* V850 specific attributes. */
+
+static const struct attribute_spec v850_attribute_table[] =
+{
+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
+ { "interrupt_handler", 0, 0, true, false, false, v850_handle_interrupt_attribute },
+ { "interrupt", 0, 0, true, false, false, v850_handle_interrupt_attribute },
+ { "sda", 0, 0, true, false, false, v850_handle_data_area_attribute },
+ { "tda", 0, 0, true, false, false, v850_handle_data_area_attribute },
+ { "zda", 0, 0, true, false, false, v850_handle_data_area_attribute },
+ { NULL, 0, 0, false, false, false, NULL }
+};
+
+
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
@@ -148,6 +165,9 @@ static GTY(()) section *zbss_section;
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY v850_return_in_memory
+#undef TARGET_FUNCTION_VALUE
+#define TARGET_FUNCTION_VALUE v850_function_value
+
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE v850_pass_by_reference
@@ -160,6 +180,14 @@ static GTY(()) section *zbss_section;
#undef TARGET_ARG_PARTIAL_BYTES
#define TARGET_ARG_PARTIAL_BYTES v850_arg_partial_bytes
+#undef TARGET_CAN_ELIMINATE
+#define TARGET_CAN_ELIMINATE v850_can_eliminate
+
+#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
+#define TARGET_ASM_TRAMPOLINE_TEMPLATE v850_asm_trampoline_template
+#undef TARGET_TRAMPOLINE_INIT
+#define TARGET_TRAMPOLINE_INIT v850_trampoline_init
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Set the maximum size of small memory area TYPE to the value given
@@ -236,8 +264,9 @@ v850_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
return size > 8;
}
-/* Return an RTX to represent where a value with mode MODE will be returned
- from a function. If the result is 0, the argument is pushed. */
+/* Return an RTX to represent where an argument with mode MODE
+ and type TYPE will be passed to a function. If the result
+ is NULL_RTX, the argument will be pushed. */
rtx
function_arg (CUMULATIVE_ARGS * cum,
@@ -245,7 +274,7 @@ function_arg (CUMULATIVE_ARGS * cum,
tree type,
int named)
{
- rtx result = 0;
+ rtx result = NULL_RTX;
int size, align;
if (TARGET_GHS && !named)
@@ -257,7 +286,11 @@ function_arg (CUMULATIVE_ARGS * cum,
size = GET_MODE_SIZE (mode);
if (size < 1)
- return 0;
+ {
+ /* Once we have stopped using argument registers, do not start up again. */
+ cum->nbytes = 4 * UNITS_PER_WORD;
+ return NULL_RTX;
+ }
if (type)
align = TYPE_ALIGN (type) / BITS_PER_UNIT;
@@ -267,11 +300,11 @@ function_arg (CUMULATIVE_ARGS * cum,
cum->nbytes = (cum->nbytes + align - 1) &~(align - 1);
if (cum->nbytes > 4 * UNITS_PER_WORD)
- return 0;
+ return NULL_RTX;
if (type == NULL_TREE
&& cum->nbytes + size > 4 * UNITS_PER_WORD)
- return 0;
+ return NULL_RTX;
switch (cum->nbytes / UNITS_PER_WORD)
{
@@ -288,7 +321,7 @@ function_arg (CUMULATIVE_ARGS * cum,
result = gen_rtx_REG (mode, 9);
break;
default:
- result = 0;
+ result = NULL_RTX;
}
return result;
@@ -312,12 +345,15 @@ v850_arg_partial_bytes (CUMULATIVE_ARGS * cum, enum machine_mode mode,
else
size = GET_MODE_SIZE (mode);
+ if (size < 1)
+ size = 1;
+
if (type)
align = TYPE_ALIGN (type) / BITS_PER_UNIT;
else
align = size;
- cum->nbytes = (cum->nbytes + align - 1) &~(align - 1);
+ cum->nbytes = (cum->nbytes + align - 1) & ~ (align - 1);
if (cum->nbytes > 4 * UNITS_PER_WORD)
return 0;
@@ -420,10 +456,12 @@ const_costs (rtx r, enum rtx_code c)
static bool
v850_rtx_costs (rtx x,
- int code,
+ int codearg,
int outer_code ATTRIBUTE_UNUSED,
int * total, bool speed)
{
+ enum rtx_code code = (enum rtx_code) codearg;
+
switch (code)
{
case CONST_INT:
@@ -464,6 +502,11 @@ v850_rtx_costs (rtx x,
*total = 20;
return true;
+ case ZERO_EXTRACT:
+ if (outer_code == COMPARE)
+ *total = 0;
+ return false;
+
default:
return false;
}
@@ -1857,7 +1900,7 @@ Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",
init_stack_free = (signed) actual_fsize;
/* Deallocate the rest of the stack if it is > 32K. */
- if (actual_fsize > init_stack_free)
+ if ((unsigned int) actual_fsize > init_stack_free)
{
int diff;
@@ -1931,7 +1974,7 @@ Saved %d bytes via epilogue function (%d vs. %d) in function %s\n",
else if (actual_fsize)
emit_jump_insn (gen_return_internal ());
else
- emit_jump_insn (gen_return ());
+ emit_jump_insn (gen_return_simple ());
}
v850_interrupt_cache_p = FALSE;
@@ -2023,17 +2066,6 @@ v850_set_data_area (tree decl, v850_data_area data_area)
(name, NULL, DECL_ATTRIBUTES (decl));
}
-const struct attribute_spec v850_attribute_table[] =
-{
- /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
- { "interrupt_handler", 0, 0, true, false, false, v850_handle_interrupt_attribute },
- { "interrupt", 0, 0, true, false, false, v850_handle_interrupt_attribute },
- { "sda", 0, 0, true, false, false, v850_handle_data_area_attribute },
- { "tda", 0, 0, true, false, false, v850_handle_data_area_attribute },
- { "zda", 0, 0, true, false, false, v850_handle_data_area_attribute },
- { NULL, 0, 0, false, false, false, NULL }
-};
-
/* Handle an "interrupt" attribute; arguments as in
struct attribute_spec.handler. */
static tree
@@ -2045,8 +2077,8 @@ v850_handle_interrupt_attribute (tree * node,
{
if (TREE_CODE (*node) != FUNCTION_DECL)
{
- warning (OPT_Wattributes, "%qs attribute only applies to functions",
- IDENTIFIER_POINTER (name));
+ warning (OPT_Wattributes, "%qE attribute only applies to functions",
+ name);
*no_add_attrs = true;
}
@@ -2081,8 +2113,9 @@ v850_handle_data_area_attribute (tree* node,
case VAR_DECL:
if (current_function_decl != NULL_TREE)
{
- error ("%Jdata area attributes cannot be specified for "
- "local variables", decl);
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "data area attributes cannot be specified for "
+ "local variables");
*no_add_attrs = true;
}
@@ -2934,6 +2967,17 @@ v850_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
/* Return values > 8 bytes in length in memory. */
return int_size_in_bytes (type) > 8 || TYPE_MODE (type) == BLKmode;
}
+
+/* Worker function for TARGET_FUNCTION_VALUE. */
+
+rtx
+v850_function_value (const_tree valtype,
+ const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
+ bool outgoing ATTRIBUTE_UNUSED)
+{
+ return gen_rtx_REG (TYPE_MODE (valtype), 10);
+}
+
/* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
@@ -2947,4 +2991,43 @@ v850_setup_incoming_varargs (CUMULATIVE_ARGS *ca,
ca->anonymous_args = (!TARGET_GHS ? 1 : 0);
}
+/* Worker function for TARGET_CAN_ELIMINATE. */
+
+static bool
+v850_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
+{
+ return (to == STACK_POINTER_REGNUM ? ! frame_pointer_needed : true);
+}
+
+
+/* Worker function for TARGET_ASM_TRAMPOLINE_TEMPLATE. */
+
+static void
+v850_asm_trampoline_template (FILE *f)
+{
+ fprintf (f, "\tjarl .+4,r12\n");
+ fprintf (f, "\tld.w 12[r12],r20\n");
+ fprintf (f, "\tld.w 16[r12],r12\n");
+ fprintf (f, "\tjmp [r12]\n");
+ fprintf (f, "\tnop\n");
+ fprintf (f, "\t.long 0\n");
+ fprintf (f, "\t.long 0\n");
+}
+
+/* Worker function for TARGET_TRAMPOLINE_INIT. */
+
+static void
+v850_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
+{
+ rtx mem, fnaddr = XEXP (DECL_RTL (fndecl), 0);
+
+ emit_block_move (m_tramp, assemble_trampoline_template (),
+ GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
+
+ mem = adjust_address (m_tramp, SImode, 16);
+ emit_move_insn (mem, chain_value);
+ mem = adjust_address (m_tramp, SImode, 20);
+ emit_move_insn (mem, fnaddr);
+}
+
#include "gt-v850.h"
« no previous file with comments | « gcc/gcc/config/v850/v850.h ('k') | gcc/gcc/config/v850/v850-c.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698