Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/crx/crx.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 /* Output routines for GCC for CRX. | 1 /* Output routines for GCC for CRX. |
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, | 2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, |
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 | 3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 |
4 Free Software Foundation, Inc. | 4 Free Software Foundation, Inc. |
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 |
41 #include "except.h" | 41 #include "except.h" |
42 #include "function.h" | 42 #include "function.h" |
43 #include "recog.h" | 43 #include "recog.h" |
44 #include "expr.h" | 44 #include "expr.h" |
45 #include "optabs.h" | 45 #include "optabs.h" |
46 #include "toplev.h" | 46 #include "diagnostic-core.h" |
47 #include "basic-block.h" | 47 #include "basic-block.h" |
48 #include "df.h" | 48 #include "df.h" |
49 #include "target.h" | 49 #include "target.h" |
50 #include "target-def.h" | 50 #include "target-def.h" |
51 | 51 |
127 int incoming ATTRIBUTE_UNUSED); | 127 int incoming ATTRIBUTE_UNUSED); |
128 static bool crx_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED); | 128 static bool crx_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED); |
129 static int crx_address_cost (rtx, bool); | 129 static int crx_address_cost (rtx, bool); |
130 static bool crx_legitimate_address_p (enum machine_mode, rtx, bool); | 130 static bool crx_legitimate_address_p (enum machine_mode, rtx, bool); |
131 static bool crx_can_eliminate (const int, const int); | 131 static bool crx_can_eliminate (const int, const int); |
132 static rtx crx_function_arg (CUMULATIVE_ARGS *, enum machine_mode, | |
133 const_tree, bool); | |
134 static void crx_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, | |
135 const_tree, bool); | |
132 | 136 |
133 /*****************************************************************************/ | 137 /*****************************************************************************/ |
134 /* RTL VALIDITY */ | 138 /* RTL VALIDITY */ |
135 /*****************************************************************************/ | 139 /*****************************************************************************/ |
136 | 140 |
150 #undef TARGET_STRUCT_VALUE_RTX | 154 #undef TARGET_STRUCT_VALUE_RTX |
151 #define TARGET_STRUCT_VALUE_RTX crx_struct_value_rtx | 155 #define TARGET_STRUCT_VALUE_RTX crx_struct_value_rtx |
152 | 156 |
153 #undef TARGET_RETURN_IN_MEMORY | 157 #undef TARGET_RETURN_IN_MEMORY |
154 #define TARGET_RETURN_IN_MEMORY crx_return_in_memory | 158 #define TARGET_RETURN_IN_MEMORY crx_return_in_memory |
159 | |
160 /*****************************************************************************/ | |
161 /* PASSING FUNCTION ARGUMENTS */ | |
162 /*****************************************************************************/ | |
163 | |
164 #undef TARGET_FUNCTION_ARG | |
165 #define TARGET_FUNCTION_ARG crx_function_arg | |
166 | |
167 #undef TARGET_FUNCTION_ARG_ADVANCE | |
168 #define TARGET_FUNCTION_ARG_ADVANCE crx_function_arg_advance | |
155 | 169 |
156 /*****************************************************************************/ | 170 /*****************************************************************************/ |
157 /* RELATIVE COSTS OF OPERATIONS */ | 171 /* RELATIVE COSTS OF OPERATIONS */ |
158 /*****************************************************************************/ | 172 /*****************************************************************************/ |
159 | 173 |
171 /* ISRs have special prologue and epilogue requirements. */ | 185 /* ISRs have special prologue and epilogue requirements. */ |
172 {"interrupt", 0, 0, false, true, true, NULL}, | 186 {"interrupt", 0, 0, false, true, true, NULL}, |
173 {NULL, 0, 0, false, false, false, NULL} | 187 {NULL, 0, 0, false, false, false, NULL} |
174 }; | 188 }; |
175 | 189 |
190 /* Option handling. */ | |
191 | |
192 #undef TARGET_OPTION_OPTIMIZATION_TABLE | |
193 #define TARGET_OPTION_OPTIMIZATION_TABLE crx_option_optimization_table | |
194 | |
195 static const struct default_options crx_option_optimization_table[] = | |
196 { | |
197 /* Put each function in its own section so that PAGE-instruction | |
198 relaxation can do its best. */ | |
199 { OPT_LEVELS_1_PLUS, OPT_ffunction_sections, NULL, 1 }, | |
200 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, | |
201 { OPT_LEVELS_NONE, 0, NULL, 0 } | |
202 }; | |
176 | 203 |
177 /* Initialize 'targetm' variable which contains pointers to functions and data | 204 /* Initialize 'targetm' variable which contains pointers to functions and data |
178 * relating to the target machine. */ | 205 * relating to the target machine. */ |
179 | 206 |
180 struct gcc_target targetm = TARGET_INITIALIZER; | 207 struct gcc_target targetm = TARGET_INITIALIZER; |
413 | 440 |
414 /* If enough param regs are available for passing the param of type TYPE return | 441 /* If enough param regs are available for passing the param of type TYPE return |
415 * the number of registers needed else 0. */ | 442 * the number of registers needed else 0. */ |
416 | 443 |
417 static int | 444 static int |
418 enough_regs_for_param (CUMULATIVE_ARGS * cum, tree type, | 445 enough_regs_for_param (CUMULATIVE_ARGS * cum, const_tree type, |
419 enum machine_mode mode) | 446 enum machine_mode mode) |
420 { | 447 { |
421 int type_size; | 448 int type_size; |
422 int remaining_size; | 449 int remaining_size; |
423 | 450 |
436 return (type_size + BITS_PER_WORD - 1) / BITS_PER_WORD; | 463 return (type_size + BITS_PER_WORD - 1) / BITS_PER_WORD; |
437 | 464 |
438 return 0; | 465 return 0; |
439 } | 466 } |
440 | 467 |
441 /* Implements the macro FUNCTION_ARG defined in crx.h. */ | 468 /* Implements TARGET_FUNCTION_ARG. */ |
442 | 469 |
443 rtx | 470 static rtx |
444 crx_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode, tree type, | 471 crx_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode, |
445 int named ATTRIBUTE_UNUSED) | 472 const_tree type, bool named ATTRIBUTE_UNUSED) |
446 { | 473 { |
447 last_parm_in_reg = 0; | 474 last_parm_in_reg = 0; |
448 | 475 |
449 /* Function_arg () is called with this type just after all the args have had | 476 /* Function_arg () is called with this type just after all the args have had |
450 * their registers assigned. The rtx that function_arg returns from this type | 477 * their registers assigned. The rtx that function_arg returns from this type |
504 return; | 531 return; |
505 } | 532 } |
506 } | 533 } |
507 } | 534 } |
508 | 535 |
509 /* Implements the macro FUNCTION_ARG_ADVANCE defined in crx.h. */ | 536 /* Implements TARGET_FUNCTION_ARG_ADVANCE. */ |
510 | 537 |
511 void | 538 static void |
512 crx_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode, | 539 crx_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode, |
513 tree type, int named ATTRIBUTE_UNUSED) | 540 const_tree type, bool named ATTRIBUTE_UNUSED) |
514 { | 541 { |
515 /* l holds the number of registers required */ | 542 /* l holds the number of registers required */ |
516 int l = GET_MODE_BITSIZE (mode) / BITS_PER_WORD; | 543 int l = GET_MODE_BITSIZE (mode) / BITS_PER_WORD; |
517 | 544 |
518 /* If the parameter isn't passed on a register don't advance cum. */ | 545 /* If the parameter isn't passed on a register don't advance cum. */ |
560 * Post modify --> reg + 12-bit disp. | 587 * Post modify --> reg + 12-bit disp. |
561 * Register relative --> reg | 32-bit disp. + reg | 4 bit + reg | 588 * Register relative --> reg | 32-bit disp. + reg | 4 bit + reg |
562 * Scaled index --> reg + reg | 22-bit disp. + reg + reg | | 589 * Scaled index --> reg + reg | 22-bit disp. + reg + reg | |
563 * 22-disp. + reg + reg + (2 | 4 | 8) */ | 590 * 22-disp. + reg + reg + (2 | 4 | 8) */ |
564 | 591 |
565 static int crx_addr_reg_p (rtx addr_reg) | 592 static rtx |
566 { | 593 crx_addr_reg (rtx addr_reg) |
567 rtx reg; | 594 { |
595 if (GET_MODE (addr_reg) != Pmode) | |
596 return NULL_RTX; | |
568 | 597 |
569 if (REG_P (addr_reg)) | 598 if (REG_P (addr_reg)) |
570 { | 599 return addr_reg; |
571 reg = addr_reg; | 600 else if (GET_CODE (addr_reg) == SUBREG |
572 } | |
573 else if ((GET_CODE (addr_reg) == SUBREG | |
574 && REG_P (SUBREG_REG (addr_reg)) | 601 && REG_P (SUBREG_REG (addr_reg)) |
575 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg))) | 602 && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (addr_reg))) |
576 <= UNITS_PER_WORD)) | 603 <= UNITS_PER_WORD)) |
577 { | 604 return SUBREG_REG (addr_reg); |
578 reg = SUBREG_REG (addr_reg); | |
579 } | |
580 else | 605 else |
581 return FALSE; | 606 return NULL_RTX; |
582 | |
583 if (GET_MODE (addr_reg) != Pmode) | |
584 { | |
585 return FALSE; | |
586 } | |
587 | |
588 return TRUE; | |
589 } | 607 } |
590 | 608 |
591 enum crx_addrtype | 609 enum crx_addrtype |
592 crx_decompose_address (rtx addr, struct crx_address *out) | 610 crx_decompose_address (rtx addr, struct crx_address *out) |
593 { | 611 { |
722 | 740 |
723 default: | 741 default: |
724 return CRX_INVALID; | 742 return CRX_INVALID; |
725 } | 743 } |
726 | 744 |
727 if (base && !crx_addr_reg_p (base)) return CRX_INVALID; | 745 if (base) |
728 if (index && !crx_addr_reg_p (index)) return CRX_INVALID; | 746 { |
747 base = crx_addr_reg (base); | |
748 if (!base) | |
749 return CRX_INVALID; | |
750 } | |
751 if (index) | |
752 { | |
753 index = crx_addr_reg (index); | |
754 if (!index) | |
755 return CRX_INVALID; | |
756 } | |
729 | 757 |
730 out->base = base; | 758 out->base = base; |
731 out->index = index; | 759 out->index = index; |
732 out->disp = disp; | 760 out->disp = disp; |
733 out->scale = scale; | 761 out->scale = scale; |
1409 * registers we save. - Generate the appropriate return insn. */ | 1437 * registers we save. - Generate the appropriate return insn. */ |
1410 | 1438 |
1411 void | 1439 void |
1412 crx_expand_epilogue (void) | 1440 crx_expand_epilogue (void) |
1413 { | 1441 { |
1414 rtx return_reg; | |
1415 | |
1416 /* Nonzero if we need to return and pop only RA. This will generate a | 1442 /* Nonzero if we need to return and pop only RA. This will generate a |
1417 * different insn. This differentiate is for the peepholes for call as last | 1443 * different insn. This differentiate is for the peepholes for call as last |
1418 * statement in function. */ | 1444 * statement in function. */ |
1419 int only_popret_RA = (save_regs[RETURN_ADDRESS_REGNUM] | 1445 int only_popret_RA = (save_regs[RETURN_ADDRESS_REGNUM] |
1420 && (sum_regs == UNITS_PER_WORD)); | 1446 && (sum_regs == UNITS_PER_WORD)); |
1421 | |
1422 /* Return register. */ | |
1423 return_reg = gen_rtx_REG (Pmode, RETURN_ADDRESS_REGNUM); | |
1424 | 1447 |
1425 if (frame_pointer_needed) | 1448 if (frame_pointer_needed) |
1426 /* Restore the stack pointer with the frame pointers value */ | 1449 /* Restore the stack pointer with the frame pointers value */ |
1427 emit_move_insn (stack_pointer_rtx, frame_pointer_rtx); | 1450 emit_move_insn (stack_pointer_rtx, frame_pointer_rtx); |
1428 | 1451 |