comparison gcc/config/v850/v850.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents a06113de4d67
children b7f97abdc517
comparison
equal deleted inserted replaced
52:c156f1bd5cd9 55:77e2b8dfacca
1 /* Subroutines for insn-output.c for NEC V850 series 1 /* Subroutines for insn-output.c for NEC V850 series
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 2006, 2007, 2008 Free Software Foundation, Inc. 3 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4 Contributed by Jeff Law (law@cygnus.com). 4 Contributed by Jeff Law (law@cygnus.com).
5 5
6 This file is part of GCC. 6 This file is part of GCC.
7 7
8 GCC is free software; you can redistribute it and/or modify it 8 GCC is free software; you can redistribute it and/or modify it
56 static bool v850_rtx_costs (rtx, int, int, int *, bool); 56 static bool v850_rtx_costs (rtx, int, int, int *, bool);
57 static void substitute_ep_register (rtx, rtx, int, int, rtx *, rtx *); 57 static void substitute_ep_register (rtx, rtx, int, int, rtx *, rtx *);
58 static void v850_reorg (void); 58 static void v850_reorg (void);
59 static int ep_memory_offset (enum machine_mode, int); 59 static int ep_memory_offset (enum machine_mode, int);
60 static void v850_set_data_area (tree, v850_data_area); 60 static void v850_set_data_area (tree, v850_data_area);
61 const struct attribute_spec v850_attribute_table[];
62 static tree v850_handle_interrupt_attribute (tree *, tree, tree, int, bool *); 61 static tree v850_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
63 static tree v850_handle_data_area_attribute (tree *, tree, tree, int, bool *); 62 static tree v850_handle_data_area_attribute (tree *, tree, tree, int, bool *);
64 static void v850_insert_attributes (tree, tree *); 63 static void v850_insert_attributes (tree, tree *);
65 static void v850_asm_init_sections (void); 64 static void v850_asm_init_sections (void);
66 static section *v850_select_section (tree, int, unsigned HOST_WIDE_INT); 65 static section *v850_select_section (tree, int, unsigned HOST_WIDE_INT);
67 static void v850_encode_data_area (tree, rtx); 66 static void v850_encode_data_area (tree, rtx);
68 static void v850_encode_section_info (tree, rtx, int); 67 static void v850_encode_section_info (tree, rtx, int);
69 static bool v850_return_in_memory (const_tree, const_tree); 68 static bool v850_return_in_memory (const_tree, const_tree);
69 static rtx v850_function_value (const_tree, const_tree, bool);
70 static void v850_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, 70 static void v850_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
71 tree, int *, int); 71 tree, int *, int);
72 static bool v850_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, 72 static bool v850_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
73 const_tree, bool); 73 const_tree, bool);
74 static int v850_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, 74 static int v850_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
75 tree, bool); 75 tree, bool);
76 static bool v850_can_eliminate (const int, const int);
77 static void v850_asm_trampoline_template (FILE *);
78 static void v850_trampoline_init (rtx, tree, rtx);
76 79
77 /* Information about the various small memory areas. */ 80 /* Information about the various small memory areas. */
78 struct small_memory_info small_memory[ (int)SMALL_MEMORY_max ] = 81 struct small_memory_info small_memory[ (int)SMALL_MEMORY_max ] =
79 { 82 {
80 /* name max physical max */ 83 /* name max physical max */
102 static GTY(()) section *rozdata_section; 105 static GTY(()) section *rozdata_section;
103 static GTY(()) section *tdata_section; 106 static GTY(()) section *tdata_section;
104 static GTY(()) section *zdata_section; 107 static GTY(()) section *zdata_section;
105 static GTY(()) section *zbss_section; 108 static GTY(()) section *zbss_section;
106 109
110 /* V850 specific attributes. */
111
112 static const struct attribute_spec v850_attribute_table[] =
113 {
114 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
115 { "interrupt_handler", 0, 0, true, false, false, v850_handle_interrupt_attribute },
116 { "interrupt", 0, 0, true, false, false, v850_handle_interrupt_attribute },
117 { "sda", 0, 0, true, false, false, v850_handle_data_area_attribute },
118 { "tda", 0, 0, true, false, false, v850_handle_data_area_attribute },
119 { "zda", 0, 0, true, false, false, v850_handle_data_area_attribute },
120 { NULL, 0, 0, false, false, false, NULL }
121 };
122
123
107 /* Initialize the GCC target structure. */ 124 /* Initialize the GCC target structure. */
108 #undef TARGET_ASM_ALIGNED_HI_OP 125 #undef TARGET_ASM_ALIGNED_HI_OP
109 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t" 126 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
110 127
111 #undef TARGET_ATTRIBUTE_TABLE 128 #undef TARGET_ATTRIBUTE_TABLE
146 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true 163 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
147 164
148 #undef TARGET_RETURN_IN_MEMORY 165 #undef TARGET_RETURN_IN_MEMORY
149 #define TARGET_RETURN_IN_MEMORY v850_return_in_memory 166 #define TARGET_RETURN_IN_MEMORY v850_return_in_memory
150 167
168 #undef TARGET_FUNCTION_VALUE
169 #define TARGET_FUNCTION_VALUE v850_function_value
170
151 #undef TARGET_PASS_BY_REFERENCE 171 #undef TARGET_PASS_BY_REFERENCE
152 #define TARGET_PASS_BY_REFERENCE v850_pass_by_reference 172 #define TARGET_PASS_BY_REFERENCE v850_pass_by_reference
153 173
154 #undef TARGET_CALLEE_COPIES 174 #undef TARGET_CALLEE_COPIES
155 #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true 175 #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
157 #undef TARGET_SETUP_INCOMING_VARARGS 177 #undef TARGET_SETUP_INCOMING_VARARGS
158 #define TARGET_SETUP_INCOMING_VARARGS v850_setup_incoming_varargs 178 #define TARGET_SETUP_INCOMING_VARARGS v850_setup_incoming_varargs
159 179
160 #undef TARGET_ARG_PARTIAL_BYTES 180 #undef TARGET_ARG_PARTIAL_BYTES
161 #define TARGET_ARG_PARTIAL_BYTES v850_arg_partial_bytes 181 #define TARGET_ARG_PARTIAL_BYTES v850_arg_partial_bytes
182
183 #undef TARGET_CAN_ELIMINATE
184 #define TARGET_CAN_ELIMINATE v850_can_eliminate
185
186 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
187 #define TARGET_ASM_TRAMPOLINE_TEMPLATE v850_asm_trampoline_template
188 #undef TARGET_TRAMPOLINE_INIT
189 #define TARGET_TRAMPOLINE_INIT v850_trampoline_init
162 190
163 struct gcc_target targetm = TARGET_INITIALIZER; 191 struct gcc_target targetm = TARGET_INITIALIZER;
164 192
165 /* Set the maximum size of small memory area TYPE to the value given 193 /* Set the maximum size of small memory area TYPE to the value given
166 by VALUE. Return true if VALUE was syntactically correct. VALUE 194 by VALUE. Return true if VALUE was syntactically correct. VALUE
234 size = GET_MODE_SIZE (mode); 262 size = GET_MODE_SIZE (mode);
235 263
236 return size > 8; 264 return size > 8;
237 } 265 }
238 266
239 /* Return an RTX to represent where a value with mode MODE will be returned 267 /* Return an RTX to represent where an argument with mode MODE
240 from a function. If the result is 0, the argument is pushed. */ 268 and type TYPE will be passed to a function. If the result
269 is NULL_RTX, the argument will be pushed. */
241 270
242 rtx 271 rtx
243 function_arg (CUMULATIVE_ARGS * cum, 272 function_arg (CUMULATIVE_ARGS * cum,
244 enum machine_mode mode, 273 enum machine_mode mode,
245 tree type, 274 tree type,
246 int named) 275 int named)
247 { 276 {
248 rtx result = 0; 277 rtx result = NULL_RTX;
249 int size, align; 278 int size, align;
250 279
251 if (TARGET_GHS && !named) 280 if (TARGET_GHS && !named)
252 return NULL_RTX; 281 return NULL_RTX;
253 282
255 size = int_size_in_bytes (type); 284 size = int_size_in_bytes (type);
256 else 285 else
257 size = GET_MODE_SIZE (mode); 286 size = GET_MODE_SIZE (mode);
258 287
259 if (size < 1) 288 if (size < 1)
260 return 0; 289 {
290 /* Once we have stopped using argument registers, do not start up again. */
291 cum->nbytes = 4 * UNITS_PER_WORD;
292 return NULL_RTX;
293 }
261 294
262 if (type) 295 if (type)
263 align = TYPE_ALIGN (type) / BITS_PER_UNIT; 296 align = TYPE_ALIGN (type) / BITS_PER_UNIT;
264 else 297 else
265 align = size; 298 align = size;
266 299
267 cum->nbytes = (cum->nbytes + align - 1) &~(align - 1); 300 cum->nbytes = (cum->nbytes + align - 1) &~(align - 1);
268 301
269 if (cum->nbytes > 4 * UNITS_PER_WORD) 302 if (cum->nbytes > 4 * UNITS_PER_WORD)
270 return 0; 303 return NULL_RTX;
271 304
272 if (type == NULL_TREE 305 if (type == NULL_TREE
273 && cum->nbytes + size > 4 * UNITS_PER_WORD) 306 && cum->nbytes + size > 4 * UNITS_PER_WORD)
274 return 0; 307 return NULL_RTX;
275 308
276 switch (cum->nbytes / UNITS_PER_WORD) 309 switch (cum->nbytes / UNITS_PER_WORD)
277 { 310 {
278 case 0: 311 case 0:
279 result = gen_rtx_REG (mode, 6); 312 result = gen_rtx_REG (mode, 6);
286 break; 319 break;
287 case 3: 320 case 3:
288 result = gen_rtx_REG (mode, 9); 321 result = gen_rtx_REG (mode, 9);
289 break; 322 break;
290 default: 323 default:
291 result = 0; 324 result = NULL_RTX;
292 } 325 }
293 326
294 return result; 327 return result;
295 } 328 }
296 329
310 if (mode == BLKmode) 343 if (mode == BLKmode)
311 size = int_size_in_bytes (type); 344 size = int_size_in_bytes (type);
312 else 345 else
313 size = GET_MODE_SIZE (mode); 346 size = GET_MODE_SIZE (mode);
314 347
348 if (size < 1)
349 size = 1;
350
315 if (type) 351 if (type)
316 align = TYPE_ALIGN (type) / BITS_PER_UNIT; 352 align = TYPE_ALIGN (type) / BITS_PER_UNIT;
317 else 353 else
318 align = size; 354 align = size;
319 355
320 cum->nbytes = (cum->nbytes + align - 1) &~(align - 1); 356 cum->nbytes = (cum->nbytes + align - 1) & ~ (align - 1);
321 357
322 if (cum->nbytes > 4 * UNITS_PER_WORD) 358 if (cum->nbytes > 4 * UNITS_PER_WORD)
323 return 0; 359 return 0;
324 360
325 if (cum->nbytes + size <= 4 * UNITS_PER_WORD) 361 if (cum->nbytes + size <= 4 * UNITS_PER_WORD)
418 } 454 }
419 } 455 }
420 456
421 static bool 457 static bool
422 v850_rtx_costs (rtx x, 458 v850_rtx_costs (rtx x,
423 int code, 459 int codearg,
424 int outer_code ATTRIBUTE_UNUSED, 460 int outer_code ATTRIBUTE_UNUSED,
425 int * total, bool speed) 461 int * total, bool speed)
426 { 462 {
463 enum rtx_code code = (enum rtx_code) codearg;
464
427 switch (code) 465 switch (code)
428 { 466 {
429 case CONST_INT: 467 case CONST_INT:
430 case CONST_DOUBLE: 468 case CONST_DOUBLE:
431 case CONST: 469 case CONST:
461 } 499 }
462 } 500 }
463 else 501 else
464 *total = 20; 502 *total = 20;
465 return true; 503 return true;
504
505 case ZERO_EXTRACT:
506 if (outer_code == COMPARE)
507 *total = 0;
508 return false;
466 509
467 default: 510 default:
468 return false; 511 return false;
469 } 512 }
470 } 513 }
1855 init_stack_free = 4 * num_restore; 1898 init_stack_free = 4 * num_restore;
1856 else 1899 else
1857 init_stack_free = (signed) actual_fsize; 1900 init_stack_free = (signed) actual_fsize;
1858 1901
1859 /* Deallocate the rest of the stack if it is > 32K. */ 1902 /* Deallocate the rest of the stack if it is > 32K. */
1860 if (actual_fsize > init_stack_free) 1903 if ((unsigned int) actual_fsize > init_stack_free)
1861 { 1904 {
1862 int diff; 1905 int diff;
1863 1906
1864 diff = actual_fsize - ((interrupt_handler) ? 0 : init_stack_free); 1907 diff = actual_fsize - ((interrupt_handler) ? 0 : init_stack_free);
1865 1908
1929 emit_jump_insn (gen_return_interrupt ()); 1972 emit_jump_insn (gen_return_interrupt ());
1930 } 1973 }
1931 else if (actual_fsize) 1974 else if (actual_fsize)
1932 emit_jump_insn (gen_return_internal ()); 1975 emit_jump_insn (gen_return_internal ());
1933 else 1976 else
1934 emit_jump_insn (gen_return ()); 1977 emit_jump_insn (gen_return_simple ());
1935 } 1978 }
1936 1979
1937 v850_interrupt_cache_p = FALSE; 1980 v850_interrupt_cache_p = FALSE;
1938 v850_interrupt_p = FALSE; 1981 v850_interrupt_p = FALSE;
1939 } 1982 }
2021 2064
2022 DECL_ATTRIBUTES (decl) = tree_cons 2065 DECL_ATTRIBUTES (decl) = tree_cons
2023 (name, NULL, DECL_ATTRIBUTES (decl)); 2066 (name, NULL, DECL_ATTRIBUTES (decl));
2024 } 2067 }
2025 2068
2026 const struct attribute_spec v850_attribute_table[] =
2027 {
2028 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
2029 { "interrupt_handler", 0, 0, true, false, false, v850_handle_interrupt_attribute },
2030 { "interrupt", 0, 0, true, false, false, v850_handle_interrupt_attribute },
2031 { "sda", 0, 0, true, false, false, v850_handle_data_area_attribute },
2032 { "tda", 0, 0, true, false, false, v850_handle_data_area_attribute },
2033 { "zda", 0, 0, true, false, false, v850_handle_data_area_attribute },
2034 { NULL, 0, 0, false, false, false, NULL }
2035 };
2036
2037 /* Handle an "interrupt" attribute; arguments as in 2069 /* Handle an "interrupt" attribute; arguments as in
2038 struct attribute_spec.handler. */ 2070 struct attribute_spec.handler. */
2039 static tree 2071 static tree
2040 v850_handle_interrupt_attribute (tree * node, 2072 v850_handle_interrupt_attribute (tree * node,
2041 tree name, 2073 tree name,
2043 int flags ATTRIBUTE_UNUSED, 2075 int flags ATTRIBUTE_UNUSED,
2044 bool * no_add_attrs) 2076 bool * no_add_attrs)
2045 { 2077 {
2046 if (TREE_CODE (*node) != FUNCTION_DECL) 2078 if (TREE_CODE (*node) != FUNCTION_DECL)
2047 { 2079 {
2048 warning (OPT_Wattributes, "%qs attribute only applies to functions", 2080 warning (OPT_Wattributes, "%qE attribute only applies to functions",
2049 IDENTIFIER_POINTER (name)); 2081 name);
2050 *no_add_attrs = true; 2082 *no_add_attrs = true;
2051 } 2083 }
2052 2084
2053 return NULL_TREE; 2085 return NULL_TREE;
2054 } 2086 }
2079 switch (TREE_CODE (decl)) 2111 switch (TREE_CODE (decl))
2080 { 2112 {
2081 case VAR_DECL: 2113 case VAR_DECL:
2082 if (current_function_decl != NULL_TREE) 2114 if (current_function_decl != NULL_TREE)
2083 { 2115 {
2084 error ("%Jdata area attributes cannot be specified for " 2116 error_at (DECL_SOURCE_LOCATION (decl),
2085 "local variables", decl); 2117 "data area attributes cannot be specified for "
2118 "local variables");
2086 *no_add_attrs = true; 2119 *no_add_attrs = true;
2087 } 2120 }
2088 2121
2089 /* Drop through. */ 2122 /* Drop through. */
2090 2123
2932 v850_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) 2965 v850_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2933 { 2966 {
2934 /* Return values > 8 bytes in length in memory. */ 2967 /* Return values > 8 bytes in length in memory. */
2935 return int_size_in_bytes (type) > 8 || TYPE_MODE (type) == BLKmode; 2968 return int_size_in_bytes (type) > 8 || TYPE_MODE (type) == BLKmode;
2936 } 2969 }
2970
2971 /* Worker function for TARGET_FUNCTION_VALUE. */
2972
2973 rtx
2974 v850_function_value (const_tree valtype,
2975 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
2976 bool outgoing ATTRIBUTE_UNUSED)
2977 {
2978 return gen_rtx_REG (TYPE_MODE (valtype), 10);
2979 }
2980
2937 2981
2938 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */ 2982 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
2939 2983
2940 static void 2984 static void
2941 v850_setup_incoming_varargs (CUMULATIVE_ARGS *ca, 2985 v850_setup_incoming_varargs (CUMULATIVE_ARGS *ca,
2945 int second_time ATTRIBUTE_UNUSED) 2989 int second_time ATTRIBUTE_UNUSED)
2946 { 2990 {
2947 ca->anonymous_args = (!TARGET_GHS ? 1 : 0); 2991 ca->anonymous_args = (!TARGET_GHS ? 1 : 0);
2948 } 2992 }
2949 2993
2994 /* Worker function for TARGET_CAN_ELIMINATE. */
2995
2996 static bool
2997 v850_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
2998 {
2999 return (to == STACK_POINTER_REGNUM ? ! frame_pointer_needed : true);
3000 }
3001
3002
3003 /* Worker function for TARGET_ASM_TRAMPOLINE_TEMPLATE. */
3004
3005 static void
3006 v850_asm_trampoline_template (FILE *f)
3007 {
3008 fprintf (f, "\tjarl .+4,r12\n");
3009 fprintf (f, "\tld.w 12[r12],r20\n");
3010 fprintf (f, "\tld.w 16[r12],r12\n");
3011 fprintf (f, "\tjmp [r12]\n");
3012 fprintf (f, "\tnop\n");
3013 fprintf (f, "\t.long 0\n");
3014 fprintf (f, "\t.long 0\n");
3015 }
3016
3017 /* Worker function for TARGET_TRAMPOLINE_INIT. */
3018
3019 static void
3020 v850_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
3021 {
3022 rtx mem, fnaddr = XEXP (DECL_RTL (fndecl), 0);
3023
3024 emit_block_move (m_tramp, assemble_trampoline_template (),
3025 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
3026
3027 mem = adjust_address (m_tramp, SImode, 16);
3028 emit_move_insn (mem, chain_value);
3029 mem = adjust_address (m_tramp, SImode, 20);
3030 emit_move_insn (mem, fnaddr);
3031 }
3032
2950 #include "gt-v850.h" 3033 #include "gt-v850.h"