comparison gcc/config/m68hc11/m68hc11.c @ 67:f6334be47118

update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
date Tue, 22 Mar 2011 17:18:12 +0900
parents b7f97abdc517
children
comparison
equal deleted inserted replaced
65:65488c3d617d 67:f6334be47118
1 /* Subroutines for code generation on Motorola 68HC11 and 68HC12. 1 /* Subroutines for code generation on Motorola 68HC11 and 68HC12.
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3 2009 Free Software Foundation, Inc. 3 2009, 2010 Free Software Foundation, Inc.
4 Contributed by Stephane Carrez (stcarrez@nerim.fr) 4 Contributed by Stephane Carrez (stcarrez@nerim.fr)
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 8 GCC is free software; you can redistribute it and/or modify
30 30
31 ftp.unina.it/pub/electronics/motorola/68hc11/gcc/gcc-6811-fsf.tar.gz 31 ftp.unina.it/pub/electronics/motorola/68hc11/gcc/gcc-6811-fsf.tar.gz
32 32
33 */ 33 */
34 34
35 #include <stdio.h>
36 #include "config.h" 35 #include "config.h"
37 #include "system.h" 36 #include "system.h"
38 #include "coretypes.h" 37 #include "coretypes.h"
39 #include "tm.h" 38 #include "tm.h"
40 #include "rtl.h" 39 #include "rtl.h"
49 #include "insn-attr.h" 48 #include "insn-attr.h"
50 #include "flags.h" 49 #include "flags.h"
51 #include "recog.h" 50 #include "recog.h"
52 #include "expr.h" 51 #include "expr.h"
53 #include "libfuncs.h" 52 #include "libfuncs.h"
54 #include "toplev.h" 53 #include "diagnostic-core.h"
55 #include "basic-block.h" 54 #include "basic-block.h"
56 #include "function.h" 55 #include "function.h"
57 #include "ggc.h" 56 #include "ggc.h"
58 #include "reload.h" 57 #include "reload.h"
59 #include "target.h" 58 #include "target.h"
60 #include "target-def.h" 59 #include "target-def.h"
61 #include "df.h" 60 #include "df.h"
62 61
62 static void m68hc11_option_override (void);
63 static void emit_move_after_reload (rtx, rtx, rtx); 63 static void emit_move_after_reload (rtx, rtx, rtx);
64 static rtx simplify_logical (enum machine_mode, int, rtx, rtx *); 64 static rtx simplify_logical (enum machine_mode, int, rtx, rtx *);
65 static void m68hc11_emit_logical (enum machine_mode, enum rtx_code, rtx *); 65 static void m68hc11_emit_logical (enum machine_mode, enum rtx_code, rtx *);
66 static void m68hc11_reorg (void); 66 static void m68hc11_reorg (void);
67 static bool m68hc11_legitimate_address_p_1 (enum machine_mode, rtx, bool); 67 static bool m68hc11_legitimate_address_p_1 (enum machine_mode, rtx, bool);
72 static int m68hc11_shift_cost (enum machine_mode, rtx, int); 72 static int m68hc11_shift_cost (enum machine_mode, rtx, int);
73 static int m68hc11_rtx_costs_1 (rtx, enum rtx_code, enum rtx_code); 73 static int m68hc11_rtx_costs_1 (rtx, enum rtx_code, enum rtx_code);
74 static bool m68hc11_rtx_costs (rtx, int, int, int *, bool); 74 static bool m68hc11_rtx_costs (rtx, int, int, int *, bool);
75 static tree m68hc11_handle_fntype_attribute (tree *, tree, tree, int, bool *); 75 static tree m68hc11_handle_fntype_attribute (tree *, tree, tree, int, bool *);
76 static tree m68hc11_handle_page0_attribute (tree *, tree, tree, int, bool *); 76 static tree m68hc11_handle_page0_attribute (tree *, tree, tree, int, bool *);
77 static bool m68hc11_class_likely_spilled_p (reg_class_t);
77 78
78 void create_regs_rtx (void); 79 void create_regs_rtx (void);
79 80
80 static void asm_print_register (FILE *, int); 81 static void asm_print_register (FILE *, int);
82 static void m68hc11_print_operand (FILE *, rtx, int);
83 static void m68hc11_print_operand_address (FILE *, rtx);
81 static void m68hc11_output_function_epilogue (FILE *, HOST_WIDE_INT); 84 static void m68hc11_output_function_epilogue (FILE *, HOST_WIDE_INT);
82 static void m68hc11_asm_out_constructor (rtx, int); 85 static void m68hc11_asm_out_constructor (rtx, int);
83 static void m68hc11_asm_out_destructor (rtx, int); 86 static void m68hc11_asm_out_destructor (rtx, int);
84 static void m68hc11_file_start (void); 87 static void m68hc11_file_start (void);
85 static void m68hc11_encode_section_info (tree, rtx, int); 88 static void m68hc11_encode_section_info (tree, rtx, int);
89 static int m68hc11_make_autoinc_notes (rtx *, void *); 92 static int m68hc11_make_autoinc_notes (rtx *, void *);
90 static void m68hc11_init_libfuncs (void); 93 static void m68hc11_init_libfuncs (void);
91 static rtx m68hc11_struct_value_rtx (tree, int); 94 static rtx m68hc11_struct_value_rtx (tree, int);
92 static bool m68hc11_return_in_memory (const_tree, const_tree); 95 static bool m68hc11_return_in_memory (const_tree, const_tree);
93 static bool m68hc11_can_eliminate (const int, const int); 96 static bool m68hc11_can_eliminate (const int, const int);
97 static void m68hc11_conditional_register_usage (void);
94 static void m68hc11_trampoline_init (rtx, tree, rtx); 98 static void m68hc11_trampoline_init (rtx, tree, rtx);
99
100 static rtx m68hc11_function_arg (CUMULATIVE_ARGS*, enum machine_mode,
101 const_tree, bool);
102 static void m68hc11_function_arg_advance (CUMULATIVE_ARGS*, enum machine_mode,
103 const_tree, bool);
95 104
96 /* Must be set to 1 to produce debug messages. */ 105 /* Must be set to 1 to produce debug messages. */
97 int debug_m6811 = 0; 106 int debug_m6811 = 0;
98 107
99 extern FILE *asm_out_file; 108 extern FILE *asm_out_file;
236 #define TARGET_ATTRIBUTE_TABLE m68hc11_attribute_table 245 #define TARGET_ATTRIBUTE_TABLE m68hc11_attribute_table
237 246
238 #undef TARGET_ASM_ALIGNED_HI_OP 247 #undef TARGET_ASM_ALIGNED_HI_OP
239 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t" 248 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
240 249
250 #undef TARGET_PRINT_OPERAND
251 #define TARGET_PRINT_OPERAND m68hc11_print_operand
252 #undef TARGET_PRINT_OPERAND_ADDRESS
253 #define TARGET_PRINT_OPERAND_ADDRESS m68hc11_print_operand_address
254
241 #undef TARGET_ASM_FUNCTION_EPILOGUE 255 #undef TARGET_ASM_FUNCTION_EPILOGUE
242 #define TARGET_ASM_FUNCTION_EPILOGUE m68hc11_output_function_epilogue 256 #define TARGET_ASM_FUNCTION_EPILOGUE m68hc11_output_function_epilogue
243 257
244 #undef TARGET_ASM_FILE_START 258 #undef TARGET_ASM_FILE_START
245 #define TARGET_ASM_FILE_START m68hc11_file_start 259 #define TARGET_ASM_FILE_START m68hc11_file_start
263 #undef TARGET_MACHINE_DEPENDENT_REORG 277 #undef TARGET_MACHINE_DEPENDENT_REORG
264 #define TARGET_MACHINE_DEPENDENT_REORG m68hc11_reorg 278 #define TARGET_MACHINE_DEPENDENT_REORG m68hc11_reorg
265 279
266 #undef TARGET_INIT_LIBFUNCS 280 #undef TARGET_INIT_LIBFUNCS
267 #define TARGET_INIT_LIBFUNCS m68hc11_init_libfuncs 281 #define TARGET_INIT_LIBFUNCS m68hc11_init_libfuncs
282
283 #undef TARGET_FUNCTION_ARG
284 #define TARGET_FUNCTION_ARG m68hc11_function_arg
285 #undef TARGET_FUNCTION_ARG_ADVANCE
286 #define TARGET_FUNCTION_ARG_ADVANCE m68hc11_function_arg_advance
268 287
269 #undef TARGET_STRUCT_VALUE_RTX 288 #undef TARGET_STRUCT_VALUE_RTX
270 #define TARGET_STRUCT_VALUE_RTX m68hc11_struct_value_rtx 289 #define TARGET_STRUCT_VALUE_RTX m68hc11_struct_value_rtx
271 #undef TARGET_RETURN_IN_MEMORY 290 #undef TARGET_RETURN_IN_MEMORY
272 #define TARGET_RETURN_IN_MEMORY m68hc11_return_in_memory 291 #define TARGET_RETURN_IN_MEMORY m68hc11_return_in_memory
280 #define TARGET_LEGITIMATE_ADDRESS_P m68hc11_legitimate_address_p 299 #define TARGET_LEGITIMATE_ADDRESS_P m68hc11_legitimate_address_p
281 300
282 #undef TARGET_CAN_ELIMINATE 301 #undef TARGET_CAN_ELIMINATE
283 #define TARGET_CAN_ELIMINATE m68hc11_can_eliminate 302 #define TARGET_CAN_ELIMINATE m68hc11_can_eliminate
284 303
304 #undef TARGET_CONDITIONAL_REGISTER_USAGE
305 #define TARGET_CONDITIONAL_REGISTER_USAGE m68hc11_conditional_register_usage
306
307 #undef TARGET_CLASS_LIKELY_SPILLED_P
308 #define TARGET_CLASS_LIKELY_SPILLED_P m68hc11_class_likely_spilled_p
309
285 #undef TARGET_TRAMPOLINE_INIT 310 #undef TARGET_TRAMPOLINE_INIT
286 #define TARGET_TRAMPOLINE_INIT m68hc11_trampoline_init 311 #define TARGET_TRAMPOLINE_INIT m68hc11_trampoline_init
287 312
313 #undef TARGET_OPTION_OVERRIDE
314 #define TARGET_OPTION_OVERRIDE m68hc11_option_override
315
288 struct gcc_target targetm = TARGET_INITIALIZER; 316 struct gcc_target targetm = TARGET_INITIALIZER;
289 317
290 int 318 static void
291 m68hc11_override_options (void) 319 m68hc11_option_override (void)
292 { 320 {
293 memset (m68hc11_reg_valid_for_index, 0, 321 memset (m68hc11_reg_valid_for_index, 0,
294 sizeof (m68hc11_reg_valid_for_index)); 322 sizeof (m68hc11_reg_valid_for_index));
295 memset (m68hc11_reg_valid_for_base, 0, sizeof (m68hc11_reg_valid_for_base)); 323 memset (m68hc11_reg_valid_for_base, 0, sizeof (m68hc11_reg_valid_for_base));
296 324
351 m68hc11_soft_reg_count = 0; 379 m68hc11_soft_reg_count = 0;
352 380
353 if (TARGET_LONG_CALLS) 381 if (TARGET_LONG_CALLS)
354 current_function_far = 1; 382 current_function_far = 1;
355 } 383 }
356 return 0; 384 }
357 } 385
358 386
359 387 /* The soft-registers are disabled or enabled according to the
360 void 388 -msoft-reg-count=<n> option. */
389
390 static void
361 m68hc11_conditional_register_usage (void) 391 m68hc11_conditional_register_usage (void)
362 { 392 {
363 int i; 393 int i;
364 394
365 if (m68hc11_soft_reg_count > SOFT_REG_LAST - SOFT_REG_FIRST) 395 if (m68hc11_soft_reg_count > SOFT_REG_LAST - SOFT_REG_FIRST)
568 } 598 }
569 599
570 return rclass; 600 return rclass;
571 } 601 }
572 602
603 /* Implement TARGET_CLASS_LIKELY_SPILLED_P. */
604
605 static bool
606 m68hc11_class_likely_spilled_p (reg_class_t rclass)
607 {
608 switch (rclass)
609 {
610 case D_REGS:
611 case X_REGS:
612 case Y_REGS:
613 case A_REGS:
614 case SP_REGS:
615 case D_OR_X_REGS:
616 case D_OR_Y_REGS:
617 case X_OR_SP_REGS:
618 case Y_OR_SP_REGS:
619 case D_OR_SP_REGS:
620 return true;
621
622 default:
623 break;
624 }
625
626 return false;
627 }
628
573 /* Return 1 if the operand is a valid indexed addressing mode. 629 /* Return 1 if the operand is a valid indexed addressing mode.
574 For 68hc11: n,r with n in [0..255] and r in A_REGS class 630 For 68hc11: n,r with n in [0..255] and r in A_REGS class
575 For 68hc12: n,r no constraint on the constant, r in A_REGS class. */ 631 For 68hc12: n,r no constraint on the constant, r in A_REGS class. */
576 int 632 int
577 m68hc11_valid_addressing_p (rtx operand, enum machine_mode mode, int addr_mode) 633 m68hc11_valid_addressing_p (rtx operand, enum machine_mode mode, int addr_mode)
1434 1490
1435 /* Update the data in CUM to advance over an argument 1491 /* Update the data in CUM to advance over an argument
1436 of mode MODE and data type TYPE. 1492 of mode MODE and data type TYPE.
1437 (TYPE is null for libcalls where that information may not be available.) */ 1493 (TYPE is null for libcalls where that information may not be available.) */
1438 1494
1439 void 1495 static void
1440 m68hc11_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, 1496 m68hc11_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1441 tree type, int named ATTRIBUTE_UNUSED) 1497 const_tree type, bool named ATTRIBUTE_UNUSED)
1442 { 1498 {
1443 if (mode != BLKmode) 1499 if (mode != BLKmode)
1444 { 1500 {
1445 if (cum->words == 0 && GET_MODE_SIZE (mode) == 4) 1501 if (cum->words == 0 && GET_MODE_SIZE (mode) == 4)
1446 { 1502 {
1472 CUM is a variable of type CUMULATIVE_ARGS which gives info about 1528 CUM is a variable of type CUMULATIVE_ARGS which gives info about
1473 the preceding args and about the function being called. 1529 the preceding args and about the function being called.
1474 NAMED is nonzero if this argument is a named parameter 1530 NAMED is nonzero if this argument is a named parameter
1475 (otherwise it is an extra parameter matching an ellipsis). */ 1531 (otherwise it is an extra parameter matching an ellipsis). */
1476 1532
1477 struct rtx_def * 1533 static rtx
1478 m68hc11_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode, 1534 m68hc11_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
1479 tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED) 1535 const_tree type ATTRIBUTE_UNUSED,
1536 bool named ATTRIBUTE_UNUSED)
1480 { 1537 {
1481 if (cum->words != 0) 1538 if (cum->words != 0)
1482 { 1539 {
1483 return NULL_RTX; 1540 return NULL_RTX;
1484 } 1541 }
1945 { 2002 {
1946 return gen_int_mode (val >> 16, HImode); 2003 return gen_int_mode (val >> 16, HImode);
1947 } 2004 }
1948 else if (mode == SImode) 2005 else if (mode == SImode)
1949 { 2006 {
1950 return gen_int_mode (val >> 32, SImode); 2007 return gen_int_mode ((val >> 16) >> 16, SImode);
1951 } 2008 }
1952 } 2009 }
1953 if (mode == QImode && D_REG_P (x)) 2010 if (mode == QImode && D_REG_P (x))
1954 return gen_rtx_REG (mode, HARD_A_REGNUM); 2011 return gen_rtx_REG (mode, HARD_A_REGNUM);
1955 2012
2121 't' generate the temporary scratch register. The operand is 2178 't' generate the temporary scratch register. The operand is
2122 ignored. 2179 ignored.
2123 'T' generate the low-part temporary scratch register. The operand is 2180 'T' generate the low-part temporary scratch register. The operand is
2124 ignored. */ 2181 ignored. */
2125 2182
2126 void 2183 static void
2127 print_operand (FILE *file, rtx op, int letter) 2184 m68hc11_print_operand (FILE *file, rtx op, int letter)
2128 { 2185 {
2129 if (letter == 't') 2186 if (letter == 't')
2130 { 2187 {
2131 asm_print_register (file, SOFT_TMP_REGNUM); 2188 asm_print_register (file, SOFT_TMP_REGNUM);
2132 return; 2189 return;
2218 break; 2275 break;
2219 2276
2220 case MEM: 2277 case MEM:
2221 gcc_assert (TARGET_M6812); 2278 gcc_assert (TARGET_M6812);
2222 fprintf (file, "["); 2279 fprintf (file, "[");
2223 print_operand_address (file, XEXP (base, 0)); 2280 m68hc11_print_operand_address (file, XEXP (base, 0));
2224 fprintf (file, "]"); 2281 fprintf (file, "]");
2225 break; 2282 break;
2226 2283
2227 default: 2284 default:
2228 if (m68hc11_page0_symbol_p (base)) 2285 if (m68hc11_page0_symbol_p (base))
2314 2371
2315 /* A C compound statement to output to stdio stream STREAM the 2372 /* A C compound statement to output to stdio stream STREAM the
2316 assembler syntax for an instruction operand that is a memory 2373 assembler syntax for an instruction operand that is a memory
2317 reference whose address is ADDR. ADDR is an RTL expression. */ 2374 reference whose address is ADDR. ADDR is an RTL expression. */
2318 2375
2319 void 2376 static void
2320 print_operand_address (FILE *file, rtx addr) 2377 m68hc11_print_operand_address (FILE *file, rtx addr)
2321 { 2378 {
2322 rtx base; 2379 rtx base;
2323 rtx offset; 2380 rtx offset;
2324 int need_parenthesis = 0; 2381 int need_parenthesis = 0;
2325 2382
2913 emit_move_insn (operands[0], result); 2970 emit_move_insn (operands[0], result);
2914 } 2971 }
2915 } 2972 }
2916 else if (operands[1] != 0 && operands[2] != 0) 2973 else if (operands[1] != 0 && operands[2] != 0)
2917 { 2974 {
2918 rtx insn;
2919
2920 if (!H_REG_P (operands[0]) && operands[3]) 2975 if (!H_REG_P (operands[0]) && operands[3])
2921 { 2976 {
2922 emit_move_insn (operands[3], operands[1]); 2977 emit_move_insn (operands[3], operands[1]);
2923 emit_insn (gen_rtx_SET (mode, 2978 emit_insn (gen_rtx_SET (mode,
2924 operands[3], 2979 operands[3],
2925 gen_rtx_fmt_ee (code, mode, 2980 gen_rtx_fmt_ee (code, mode,
2926 operands[3], operands[2]))); 2981 operands[3], operands[2])));
2927 insn = emit_move_insn (operands[0], operands[3]); 2982 emit_move_insn (operands[0], operands[3]);
2928 } 2983 }
2929 else 2984 else
2930 { 2985 {
2931 insn = emit_insn (gen_rtx_SET (mode, 2986 emit_insn (gen_rtx_SET (mode, operands[0],
2932 operands[0], 2987 gen_rtx_fmt_ee (code, mode,
2933 gen_rtx_fmt_ee (code, mode, 2988 operands[0], operands[2])));
2934 operands[0],
2935 operands[2])));
2936 } 2989 }
2937 } 2990 }
2938 2991
2939 /* The logical operation is similar to a copy. */ 2992 /* The logical operation is similar to a copy. */
2940 else if (need_copy) 2993 else if (need_copy)
4603 } 4656 }
4604 return 1; 4657 return 1;
4605 } 4658 }
4606 if (GET_CODE (body) == CLOBBER) 4659 if (GET_CODE (body) == CLOBBER)
4607 { 4660 {
4661 rtx dst = XEXP (body, 0);
4662
4663 this_insn_uses_ix = reg_mentioned_p (ix_reg, dst);
4664 this_insn_uses_iy = reg_mentioned_p (iy_reg, dst);
4608 4665
4609 /* IX and IY are used at the same time, we have to restore 4666 /* IX and IY are used at the same time, we have to restore
4610 the value of the scratch register before this insn. */ 4667 the value of the scratch register before this insn. */
4611 if (this_insn_uses_ix && this_insn_uses_iy) 4668 if (this_insn_uses_ix && this_insn_uses_iy)
4612 { 4669 {