Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/m68k/m68k.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 | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
31 #include "insn-config.h" | 31 #include "insn-config.h" |
32 #include "conditions.h" | 32 #include "conditions.h" |
33 #include "output.h" | 33 #include "output.h" |
34 #include "insn-attr.h" | 34 #include "insn-attr.h" |
35 #include "recog.h" | 35 #include "recog.h" |
36 #include "toplev.h" | 36 #include "diagnostic-core.h" |
37 #include "expr.h" | 37 #include "expr.h" |
38 #include "reload.h" | 38 #include "reload.h" |
39 #include "tm_p.h" | 39 #include "tm_p.h" |
40 #include "target.h" | 40 #include "target.h" |
41 #include "target-def.h" | 41 #include "target-def.h" |
130 static void m68k_sched_dfa_pre_advance_cycle (void); | 130 static void m68k_sched_dfa_pre_advance_cycle (void); |
131 static void m68k_sched_dfa_post_advance_cycle (void); | 131 static void m68k_sched_dfa_post_advance_cycle (void); |
132 static int m68k_sched_first_cycle_multipass_dfa_lookahead (void); | 132 static int m68k_sched_first_cycle_multipass_dfa_lookahead (void); |
133 | 133 |
134 static bool m68k_can_eliminate (const int, const int); | 134 static bool m68k_can_eliminate (const int, const int); |
135 static void m68k_conditional_register_usage (void); | |
135 static bool m68k_legitimate_address_p (enum machine_mode, rtx, bool); | 136 static bool m68k_legitimate_address_p (enum machine_mode, rtx, bool); |
136 static bool m68k_handle_option (size_t, const char *, int); | 137 static bool m68k_handle_option (size_t, const char *, int); |
138 static void m68k_option_override (void); | |
137 static rtx find_addr_reg (rtx); | 139 static rtx find_addr_reg (rtx); |
138 static const char *singlemove_string (rtx *); | 140 static const char *singlemove_string (rtx *); |
139 static void m68k_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, | 141 static void m68k_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, |
140 HOST_WIDE_INT, tree); | 142 HOST_WIDE_INT, tree); |
141 static rtx m68k_struct_value_rtx (tree, int); | 143 static rtx m68k_struct_value_rtx (tree, int); |
151 #if M68K_HONOR_TARGET_STRICT_ALIGNMENT | 153 #if M68K_HONOR_TARGET_STRICT_ALIGNMENT |
152 static bool m68k_return_in_memory (const_tree, const_tree); | 154 static bool m68k_return_in_memory (const_tree, const_tree); |
153 #endif | 155 #endif |
154 static void m68k_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; | 156 static void m68k_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; |
155 static void m68k_trampoline_init (rtx, tree, rtx); | 157 static void m68k_trampoline_init (rtx, tree, rtx); |
158 static int m68k_return_pops_args (tree, tree, int); | |
156 static rtx m68k_delegitimize_address (rtx); | 159 static rtx m68k_delegitimize_address (rtx); |
160 static void m68k_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, | |
161 const_tree, bool); | |
162 static rtx m68k_function_arg (CUMULATIVE_ARGS *, enum machine_mode, | |
163 const_tree, bool); | |
157 | 164 |
158 | 165 |
159 /* Specify the identification number of the library being built */ | 166 /* Specify the identification number of the library being built */ |
160 const char *m68k_library_id_string = "_current_shared_library_a5_offset_"; | 167 const char *m68k_library_id_string = "_current_shared_library_a5_offset_"; |
161 | 168 |
229 m68k_sched_first_cycle_multipass_dfa_lookahead | 236 m68k_sched_first_cycle_multipass_dfa_lookahead |
230 | 237 |
231 #undef TARGET_HANDLE_OPTION | 238 #undef TARGET_HANDLE_OPTION |
232 #define TARGET_HANDLE_OPTION m68k_handle_option | 239 #define TARGET_HANDLE_OPTION m68k_handle_option |
233 | 240 |
241 #undef TARGET_OPTION_OVERRIDE | |
242 #define TARGET_OPTION_OVERRIDE m68k_option_override | |
243 | |
234 #undef TARGET_RTX_COSTS | 244 #undef TARGET_RTX_COSTS |
235 #define TARGET_RTX_COSTS m68k_rtx_costs | 245 #define TARGET_RTX_COSTS m68k_rtx_costs |
236 | 246 |
237 #undef TARGET_ATTRIBUTE_TABLE | 247 #undef TARGET_ATTRIBUTE_TABLE |
238 #define TARGET_ATTRIBUTE_TABLE m68k_attribute_table | 248 #define TARGET_ATTRIBUTE_TABLE m68k_attribute_table |
266 #define TARGET_LEGITIMATE_ADDRESS_P m68k_legitimate_address_p | 276 #define TARGET_LEGITIMATE_ADDRESS_P m68k_legitimate_address_p |
267 | 277 |
268 #undef TARGET_CAN_ELIMINATE | 278 #undef TARGET_CAN_ELIMINATE |
269 #define TARGET_CAN_ELIMINATE m68k_can_eliminate | 279 #define TARGET_CAN_ELIMINATE m68k_can_eliminate |
270 | 280 |
281 #undef TARGET_CONDITIONAL_REGISTER_USAGE | |
282 #define TARGET_CONDITIONAL_REGISTER_USAGE m68k_conditional_register_usage | |
283 | |
271 #undef TARGET_TRAMPOLINE_INIT | 284 #undef TARGET_TRAMPOLINE_INIT |
272 #define TARGET_TRAMPOLINE_INIT m68k_trampoline_init | 285 #define TARGET_TRAMPOLINE_INIT m68k_trampoline_init |
273 | 286 |
287 #undef TARGET_RETURN_POPS_ARGS | |
288 #define TARGET_RETURN_POPS_ARGS m68k_return_pops_args | |
289 | |
274 #undef TARGET_DELEGITIMIZE_ADDRESS | 290 #undef TARGET_DELEGITIMIZE_ADDRESS |
275 #define TARGET_DELEGITIMIZE_ADDRESS m68k_delegitimize_address | 291 #define TARGET_DELEGITIMIZE_ADDRESS m68k_delegitimize_address |
292 | |
293 #undef TARGET_FUNCTION_ARG | |
294 #define TARGET_FUNCTION_ARG m68k_function_arg | |
295 | |
296 #undef TARGET_FUNCTION_ARG_ADVANCE | |
297 #define TARGET_FUNCTION_ARG_ADVANCE m68k_function_arg_advance | |
276 | 298 |
277 static const struct attribute_spec m68k_attribute_table[] = | 299 static const struct attribute_spec m68k_attribute_table[] = |
278 { | 300 { |
279 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ | 301 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ |
280 { "interrupt", 0, 0, true, false, false, m68k_handle_fndecl_attribute }, | 302 { "interrupt", 0, 0, true, false, false, m68k_handle_fndecl_attribute }, |
532 default: | 554 default: |
533 return true; | 555 return true; |
534 } | 556 } |
535 } | 557 } |
536 | 558 |
537 /* Sometimes certain combinations of command options do not make | 559 /* Implement TARGET_OPTION_OVERRIDE. */ |
538 sense on a particular target machine. You can define a macro | 560 |
539 `OVERRIDE_OPTIONS' to take account of this. This macro, if | 561 static void |
540 defined, is executed once just after all the command options have | 562 m68k_option_override (void) |
541 been parsed. | |
542 | |
543 Don't use this macro to turn on various extra optimizations for | |
544 `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */ | |
545 | |
546 void | |
547 override_options (void) | |
548 { | 563 { |
549 const struct m68k_target_selection *entry; | 564 const struct m68k_target_selection *entry; |
550 unsigned long target_mask; | 565 unsigned long target_mask; |
551 | 566 |
552 /* User can choose: | 567 /* User can choose: |
1036 | 1051 |
1037 void | 1052 void |
1038 m68k_expand_prologue (void) | 1053 m68k_expand_prologue (void) |
1039 { | 1054 { |
1040 HOST_WIDE_INT fsize_with_regs; | 1055 HOST_WIDE_INT fsize_with_regs; |
1041 rtx limit, src, dest, insn; | 1056 rtx limit, src, dest; |
1042 | 1057 |
1043 m68k_compute_frame_layout (); | 1058 m68k_compute_frame_layout (); |
1044 | 1059 |
1045 /* If the stack limit is a symbol, we can check it here, | 1060 /* If the stack limit is a symbol, we can check it here, |
1046 before actually allocating the space. */ | 1061 before actually allocating the space. */ |
1179 current_frame.reg_mask, true, true)); | 1194 current_frame.reg_mask, true, true)); |
1180 } | 1195 } |
1181 | 1196 |
1182 if (!TARGET_SEP_DATA | 1197 if (!TARGET_SEP_DATA |
1183 && crtl->uses_pic_offset_table) | 1198 && crtl->uses_pic_offset_table) |
1184 insn = emit_insn (gen_load_got (pic_offset_table_rtx)); | 1199 emit_insn (gen_load_got (pic_offset_table_rtx)); |
1185 } | 1200 } |
1186 | 1201 |
1187 /* Return true if a simple (return) instruction is sufficient for this | 1202 /* Return true if a simple (return) instruction is sufficient for this |
1188 instruction (i.e. if no epilogue is needed). */ | 1203 instruction (i.e. if no epilogue is needed). */ |
1189 | 1204 |
1468 the same. */ | 1483 the same. */ |
1469 if (decl && m68k_get_function_kind (decl) == kind) | 1484 if (decl && m68k_get_function_kind (decl) == kind) |
1470 return true; | 1485 return true; |
1471 | 1486 |
1472 return false; | 1487 return false; |
1488 } | |
1489 | |
1490 /* On the m68k all args are always pushed. */ | |
1491 | |
1492 static rtx | |
1493 m68k_function_arg (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, | |
1494 enum machine_mode mode ATTRIBUTE_UNUSED, | |
1495 const_tree type ATTRIBUTE_UNUSED, | |
1496 bool named ATTRIBUTE_UNUSED) | |
1497 { | |
1498 return NULL_RTX; | |
1499 } | |
1500 | |
1501 static void | |
1502 m68k_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, | |
1503 const_tree type, bool named ATTRIBUTE_UNUSED) | |
1504 { | |
1505 *cum += (mode != BLKmode | |
1506 ? (GET_MODE_SIZE (mode) + 3) & ~3 | |
1507 : (int_size_in_bytes (type) + 3) & ~3); | |
1473 } | 1508 } |
1474 | 1509 |
1475 /* Convert X to a legitimate function call memory reference and return the | 1510 /* Convert X to a legitimate function call memory reference and return the |
1476 result. */ | 1511 result. */ |
1477 | 1512 |
3475 return; | 3510 return; |
3476 } | 3511 } |
3477 | 3512 |
3478 /* Normal case: do the two words, low-numbered first. */ | 3513 /* Normal case: do the two words, low-numbered first. */ |
3479 | 3514 |
3515 m68k_final_prescan_insn (NULL, operands, 2); | |
3480 handle_movsi (operands); | 3516 handle_movsi (operands); |
3481 | 3517 |
3482 /* Do the middle one of the three words for long double */ | 3518 /* Do the middle one of the three words for long double */ |
3483 if (size == 12) | 3519 if (size == 12) |
3484 { | 3520 { |
3485 if (addreg0) | 3521 if (addreg0) |
3486 handle_reg_adjust (addreg0, 4); | 3522 handle_reg_adjust (addreg0, 4); |
3487 if (addreg1) | 3523 if (addreg1) |
3488 handle_reg_adjust (addreg1, 4); | 3524 handle_reg_adjust (addreg1, 4); |
3489 | 3525 |
3526 m68k_final_prescan_insn (NULL, middlehalf, 2); | |
3490 handle_movsi (middlehalf); | 3527 handle_movsi (middlehalf); |
3491 } | 3528 } |
3492 | 3529 |
3493 /* Make any unoffsettable addresses point at high-numbered word. */ | 3530 /* Make any unoffsettable addresses point at high-numbered word. */ |
3494 if (addreg0) | 3531 if (addreg0) |
3495 handle_reg_adjust (addreg0, 4); | 3532 handle_reg_adjust (addreg0, 4); |
3496 if (addreg1) | 3533 if (addreg1) |
3497 handle_reg_adjust (addreg1, 4); | 3534 handle_reg_adjust (addreg1, 4); |
3498 | 3535 |
3499 /* Do that word. */ | 3536 /* Do that word. */ |
3537 m68k_final_prescan_insn (NULL, latehalf, 2); | |
3500 handle_movsi (latehalf); | 3538 handle_movsi (latehalf); |
3501 | 3539 |
3502 /* Undo the adds we just did. */ | 3540 /* Undo the adds we just did. */ |
3503 if (addreg0) | 3541 if (addreg0) |
3504 handle_reg_adjust (addreg0, -(size - 4)); | 3542 handle_reg_adjust (addreg0, -(size - 4)); |
4595 switch (XINT (x, 1)) | 4633 switch (XINT (x, 1)) |
4596 { | 4634 { |
4597 case UNSPEC_RELOC16: | 4635 case UNSPEC_RELOC16: |
4598 case UNSPEC_RELOC32: | 4636 case UNSPEC_RELOC32: |
4599 output_addr_const (file, XVECEXP (x, 0, 0)); | 4637 output_addr_const (file, XVECEXP (x, 0, 0)); |
4600 fputs (m68k_get_reloc_decoration (INTVAL (XVECEXP (x, 0, 1))), file); | 4638 fputs (m68k_get_reloc_decoration |
4639 ((enum m68k_reloc) INTVAL (XVECEXP (x, 0, 1))), file); | |
4601 return true; | 4640 return true; |
4602 | 4641 |
4603 default: | 4642 default: |
4604 break; | 4643 break; |
4605 } | 4644 } |
4622 /* In the name of slightly smaller debug output, and to cater to | 4661 /* In the name of slightly smaller debug output, and to cater to |
4623 general assembler lossage, recognize various UNSPEC sequences | 4662 general assembler lossage, recognize various UNSPEC sequences |
4624 and turn them back into a direct symbol reference. */ | 4663 and turn them back into a direct symbol reference. */ |
4625 | 4664 |
4626 static rtx | 4665 static rtx |
4627 m68k_delegitimize_address (rtx x) | 4666 m68k_delegitimize_address (rtx orig_x) |
4628 { | 4667 { |
4629 rtx orig_x = delegitimize_mem_from_attrs (x); | 4668 rtx x; |
4630 rtx y; | 4669 struct m68k_address addr; |
4631 rtx addend = NULL_RTX; | 4670 rtx unspec; |
4632 rtx result; | 4671 |
4633 | 4672 orig_x = delegitimize_mem_from_attrs (orig_x); |
4634 x = orig_x; | 4673 x = orig_x; |
4635 if (MEM_P (x)) | 4674 if (MEM_P (x)) |
4636 x = XEXP (x, 0); | 4675 x = XEXP (x, 0); |
4637 | 4676 |
4638 if (GET_CODE (x) == PLUS | 4677 if (GET_CODE (x) != PLUS || GET_MODE (x) != Pmode) |
4639 && GET_CODE (XEXP (x, 1)) == CONST | 4678 return orig_x; |
4640 && REG_P (XEXP (x, 0)) | 4679 |
4641 && REGNO (XEXP (x, 0)) == PIC_REG) | 4680 if (!m68k_decompose_address (GET_MODE (x), x, false, &addr) |
4642 { | 4681 || addr.offset == NULL_RTX |
4643 y = x = XEXP (XEXP (x, 1), 0); | 4682 || GET_CODE (addr.offset) != CONST) |
4644 | 4683 return orig_x; |
4645 /* Handle an addend. */ | 4684 |
4646 if ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS) | 4685 unspec = XEXP (addr.offset, 0); |
4647 && CONST_INT_P (XEXP (x, 1))) | 4686 if (GET_CODE (unspec) == PLUS && CONST_INT_P (XEXP (unspec, 1))) |
4648 { | 4687 unspec = XEXP (unspec, 0); |
4649 addend = XEXP (x, 1); | 4688 if (GET_CODE (unspec) != UNSPEC |
4650 x = XEXP (x, 0); | 4689 || (XINT (unspec, 1) != UNSPEC_RELOC16 |
4651 } | 4690 && XINT (unspec, 1) != UNSPEC_RELOC32)) |
4652 | 4691 return orig_x; |
4653 if (GET_CODE (x) == UNSPEC | 4692 x = XVECEXP (unspec, 0, 0); |
4654 && (XINT (x, 1) == UNSPEC_RELOC16 | 4693 gcc_assert (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF); |
4655 || XINT (x, 1) == UNSPEC_RELOC32)) | 4694 if (unspec != XEXP (addr.offset, 0)) |
4656 { | 4695 x = gen_rtx_PLUS (Pmode, x, XEXP (XEXP (addr.offset, 0), 1)); |
4657 result = XVECEXP (x, 0, 0); | 4696 if (addr.index) |
4658 if (addend) | 4697 { |
4659 { | 4698 rtx idx = addr.index; |
4660 if (GET_CODE (y) == PLUS) | 4699 if (addr.scale != 1) |
4661 result = gen_rtx_PLUS (Pmode, result, addend); | 4700 idx = gen_rtx_MULT (Pmode, idx, GEN_INT (addr.scale)); |
4662 else | 4701 x = gen_rtx_PLUS (Pmode, idx, x); |
4663 result = gen_rtx_MINUS (Pmode, result, addend); | 4702 } |
4664 result = gen_rtx_CONST (Pmode, result); | 4703 if (addr.base) |
4665 } | 4704 x = gen_rtx_PLUS (Pmode, addr.base, x); |
4666 return result; | 4705 if (MEM_P (orig_x)) |
4667 } | 4706 x = replace_equiv_address_nv (orig_x, x); |
4668 } | 4707 return x; |
4669 | |
4670 return orig_x; | |
4671 } | 4708 } |
4672 | 4709 |
4673 | 4710 |
4674 /* A C compound statement to output to stdio stream STREAM the | 4711 /* A C compound statement to output to stdio stream STREAM the |
4675 assembler syntax for an instruction operand that is a memory | 4712 assembler syntax for an instruction operand that is a memory |
5606 case OP_TYPE_IMM_L: | 5643 case OP_TYPE_IMM_L: |
5607 return OPX_TYPE_IMM_L; | 5644 return OPX_TYPE_IMM_L; |
5608 | 5645 |
5609 default: | 5646 default: |
5610 gcc_unreachable (); | 5647 gcc_unreachable (); |
5611 return 0; | |
5612 } | 5648 } |
5613 } | 5649 } |
5614 | 5650 |
5615 /* Implement opy_type attribute. | 5651 /* Implement opy_type attribute. |
5616 Return type of INSN's operand Y. | 5652 Return type of INSN's operand Y. |
5650 case OP_TYPE_IMM_L: | 5686 case OP_TYPE_IMM_L: |
5651 return OPY_TYPE_IMM_L; | 5687 return OPY_TYPE_IMM_L; |
5652 | 5688 |
5653 default: | 5689 default: |
5654 gcc_unreachable (); | 5690 gcc_unreachable (); |
5655 return 0; | |
5656 } | 5691 } |
5657 } | 5692 } |
5658 | 5693 |
5659 /* Return size of INSN as int. */ | 5694 /* Return size of INSN as int. */ |
5660 static int | 5695 static int |
5756 case 3: | 5791 case 3: |
5757 return SIZE_3; | 5792 return SIZE_3; |
5758 | 5793 |
5759 default: | 5794 default: |
5760 gcc_unreachable (); | 5795 gcc_unreachable (); |
5761 return 0; | |
5762 } | 5796 } |
5763 } | 5797 } |
5764 | 5798 |
5765 /* Return operand X or Y (depending on OPX_P) of INSN, | 5799 /* Return operand X or Y (depending on OPX_P) of INSN, |
5766 if it is a MEM, or NULL overwise. */ | 5800 if it is a MEM, or NULL overwise. */ |
5788 case OPX_TYPE_MEM6: | 5822 case OPX_TYPE_MEM6: |
5789 return OP_TYPE_MEM6; | 5823 return OP_TYPE_MEM6; |
5790 | 5824 |
5791 default: | 5825 default: |
5792 gcc_unreachable (); | 5826 gcc_unreachable (); |
5793 return 0; | |
5794 } | 5827 } |
5795 } | 5828 } |
5796 else | 5829 else |
5797 { | 5830 { |
5798 switch (get_attr_opy_type (insn)) | 5831 switch (get_attr_opy_type (insn)) |
5814 case OPY_TYPE_MEM6: | 5847 case OPY_TYPE_MEM6: |
5815 return OP_TYPE_MEM6; | 5848 return OP_TYPE_MEM6; |
5816 | 5849 |
5817 default: | 5850 default: |
5818 gcc_unreachable (); | 5851 gcc_unreachable (); |
5819 return 0; | |
5820 } | 5852 } |
5821 } | 5853 } |
5822 } | 5854 } |
5823 | 5855 |
5824 /* Implement op_mem attribute. */ | 5856 /* Implement op_mem attribute. */ |
5847 case OPX_ACCESS_RW: | 5879 case OPX_ACCESS_RW: |
5848 return OP_MEM_11; | 5880 return OP_MEM_11; |
5849 | 5881 |
5850 default: | 5882 default: |
5851 gcc_unreachable (); | 5883 gcc_unreachable (); |
5852 return 0; | |
5853 } | 5884 } |
5854 } | 5885 } |
5855 | 5886 |
5856 if (opy == OP_TYPE_RN && opx == OP_TYPE_MEM6) | 5887 if (opy == OP_TYPE_RN && opx == OP_TYPE_MEM6) |
5857 { | 5888 { |
5866 case OPX_ACCESS_RW: | 5897 case OPX_ACCESS_RW: |
5867 return OP_MEM_I1; | 5898 return OP_MEM_I1; |
5868 | 5899 |
5869 default: | 5900 default: |
5870 gcc_unreachable (); | 5901 gcc_unreachable (); |
5871 return 0; | |
5872 } | 5902 } |
5873 } | 5903 } |
5874 | 5904 |
5875 if (opy == OP_TYPE_MEM1 && opx == OP_TYPE_RN) | 5905 if (opy == OP_TYPE_MEM1 && opx == OP_TYPE_RN) |
5876 return OP_MEM_10; | 5906 return OP_MEM_10; |
6148 m68k_sched_first_cycle_multipass_dfa_lookahead (void) | 6178 m68k_sched_first_cycle_multipass_dfa_lookahead (void) |
6149 { | 6179 { |
6150 return m68k_sched_issue_rate () - 1; | 6180 return m68k_sched_issue_rate () - 1; |
6151 } | 6181 } |
6152 | 6182 |
6153 /* Implementation of targetm.sched.md_init_global () hook. | 6183 /* Implementation of targetm.sched.init_global () hook. |
6154 It is invoked once per scheduling pass and is used here | 6184 It is invoked once per scheduling pass and is used here |
6155 to initialize scheduler constants. */ | 6185 to initialize scheduler constants. */ |
6156 static void | 6186 static void |
6157 m68k_sched_md_init_global (FILE *sched_dump ATTRIBUTE_UNUSED, | 6187 m68k_sched_md_init_global (FILE *sched_dump ATTRIBUTE_UNUSED, |
6158 int sched_verbose ATTRIBUTE_UNUSED, | 6188 int sched_verbose ATTRIBUTE_UNUSED, |
6256 | 6286 |
6257 free (sched_branch_type); | 6287 free (sched_branch_type); |
6258 sched_branch_type = NULL; | 6288 sched_branch_type = NULL; |
6259 } | 6289 } |
6260 | 6290 |
6261 /* Implementation of targetm.sched.md_init () hook. | 6291 /* Implementation of targetm.sched.init () hook. |
6262 It is invoked each time scheduler starts on the new block (basic block or | 6292 It is invoked each time scheduler starts on the new block (basic block or |
6263 extended basic block). */ | 6293 extended basic block). */ |
6264 static void | 6294 static void |
6265 m68k_sched_md_init (FILE *sched_dump ATTRIBUTE_UNUSED, | 6295 m68k_sched_md_init (FILE *sched_dump ATTRIBUTE_UNUSED, |
6266 int sched_verbose ATTRIBUTE_UNUSED, | 6296 int sched_verbose ATTRIBUTE_UNUSED, |
6523 emit_move_insn (mem, fnaddr); | 6553 emit_move_insn (mem, fnaddr); |
6524 | 6554 |
6525 FINALIZE_TRAMPOLINE (XEXP (m_tramp, 0)); | 6555 FINALIZE_TRAMPOLINE (XEXP (m_tramp, 0)); |
6526 } | 6556 } |
6527 | 6557 |
6558 /* On the 68000, the RTS insn cannot pop anything. | |
6559 On the 68010, the RTD insn may be used to pop them if the number | |
6560 of args is fixed, but if the number is variable then the caller | |
6561 must pop them all. RTD can't be used for library calls now | |
6562 because the library is compiled with the Unix compiler. | |
6563 Use of RTD is a selectable option, since it is incompatible with | |
6564 standard Unix calling sequences. If the option is not selected, | |
6565 the caller must always pop the args. */ | |
6566 | |
6567 static int | |
6568 m68k_return_pops_args (tree fundecl, tree funtype, int size) | |
6569 { | |
6570 return ((TARGET_RTD | |
6571 && (!fundecl | |
6572 || TREE_CODE (fundecl) != IDENTIFIER_NODE) | |
6573 && (!stdarg_p (funtype))) | |
6574 ? size : 0); | |
6575 } | |
6576 | |
6577 /* Make sure everything's fine if we *don't* have a given processor. | |
6578 This assumes that putting a register in fixed_regs will keep the | |
6579 compiler's mitts completely off it. We don't bother to zero it out | |
6580 of register classes. */ | |
6581 | |
6582 static void | |
6583 m68k_conditional_register_usage (void) | |
6584 { | |
6585 int i; | |
6586 HARD_REG_SET x; | |
6587 if (!TARGET_HARD_FLOAT) | |
6588 { | |
6589 COPY_HARD_REG_SET (x, reg_class_contents[(int)FP_REGS]); | |
6590 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
6591 if (TEST_HARD_REG_BIT (x, i)) | |
6592 fixed_regs[i] = call_used_regs[i] = 1; | |
6593 } | |
6594 if (flag_pic) | |
6595 fixed_regs[PIC_REG] = call_used_regs[PIC_REG] = 1; | |
6596 } | |
6597 | |
6528 #include "gt-m68k.h" | 6598 #include "gt-m68k.h" |