00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include "config.h"
00051 #include "system.h"
00052 #include "coretypes.h"
00053 #include "tm.h"
00054 #include "machmode.h"
00055 #include "rtl.h"
00056 #include "tree.h"
00057 #include "expr.h"
00058 #include "output.h"
00059 #include "toplev.h"
00060 #include "function.h"
00061 #include "target.h"
00062 #include "tm_p.h"
00063 #include "target-def.h"
00064 #include "ggc.h"
00065 #include "hard-reg-set.h"
00066 #include "reload.h"
00067 #include "optabs.h"
00068 #include "recog.h"
00069
00070
00071 void
00072 default_external_libcall (rtx fun ATTRIBUTE_UNUSED)
00073 {
00074 #ifdef ASM_OUTPUT_EXTERNAL_LIBCALL
00075 ASM_OUTPUT_EXTERNAL_LIBCALL(asm_out_file, fun);
00076 #endif
00077 }
00078
00079 enum machine_mode
00080 default_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
00081 {
00082 if (m1 == m2)
00083 return m1;
00084 return VOIDmode;
00085 }
00086
00087 bool
00088 default_return_in_memory (tree type,
00089 tree fntype ATTRIBUTE_UNUSED)
00090 {
00091 #ifndef RETURN_IN_MEMORY
00092 return (TYPE_MODE (type) == BLKmode);
00093 #else
00094 return RETURN_IN_MEMORY (type);
00095 #endif
00096 }
00097
00098 rtx
00099 default_expand_builtin_saveregs (void)
00100 {
00101 error ("__builtin_saveregs not supported by this target");
00102 return const0_rtx;
00103 }
00104
00105 void
00106 default_setup_incoming_varargs (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
00107 enum machine_mode mode ATTRIBUTE_UNUSED,
00108 tree type ATTRIBUTE_UNUSED,
00109 int *pretend_arg_size ATTRIBUTE_UNUSED,
00110 int second_time ATTRIBUTE_UNUSED)
00111 {
00112 }
00113
00114
00115
00116 rtx
00117 default_builtin_setjmp_frame_value (void)
00118 {
00119 return virtual_stack_vars_rtx;
00120 }
00121
00122
00123
00124 bool
00125 hook_bool_CUMULATIVE_ARGS_false (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
00126 {
00127 return false;
00128 }
00129
00130 bool
00131 default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
00132 {
00133 return (targetm.calls.setup_incoming_varargs
00134 != default_setup_incoming_varargs);
00135 }
00136
00137 enum machine_mode
00138 default_eh_return_filter_mode (void)
00139 {
00140 return word_mode;
00141 }
00142
00143
00144
00145 unsigned HOST_WIDE_INT
00146 default_shift_truncation_mask (enum machine_mode mode)
00147 {
00148 return SHIFT_COUNT_TRUNCATED ? GET_MODE_BITSIZE (mode) - 1 : 0;
00149 }
00150
00151
00152
00153 unsigned int
00154 default_min_divisions_for_recip_mul (enum machine_mode mode ATTRIBUTE_UNUSED)
00155 {
00156 return have_insn_for (DIV, mode) ? 3 : 2;
00157 }
00158
00159
00160
00161 int
00162 default_mode_rep_extended (enum machine_mode mode ATTRIBUTE_UNUSED,
00163 enum machine_mode mode_rep ATTRIBUTE_UNUSED)
00164 {
00165 return UNKNOWN;
00166 }
00167
00168
00169
00170 bool
00171 hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS * a ATTRIBUTE_UNUSED)
00172 {
00173 return true;
00174 }
00175
00176
00177
00178 tree
00179 default_cxx_guard_type (void)
00180 {
00181 return long_long_integer_type_node;
00182 }
00183
00184
00185
00186
00187
00188
00189 tree
00190 default_cxx_get_cookie_size (tree type)
00191 {
00192 tree cookie_size;
00193
00194
00195
00196 tree sizetype_size;
00197 tree type_align;
00198
00199 sizetype_size = size_in_bytes (sizetype);
00200 type_align = size_int (TYPE_ALIGN_UNIT (type));
00201 if (INT_CST_LT_UNSIGNED (type_align, sizetype_size))
00202 cookie_size = sizetype_size;
00203 else
00204 cookie_size = type_align;
00205
00206 return cookie_size;
00207 }
00208
00209
00210
00211
00212 bool
00213 hook_pass_by_reference_must_pass_in_stack (CUMULATIVE_ARGS *c ATTRIBUTE_UNUSED,
00214 enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED,
00215 bool named_arg ATTRIBUTE_UNUSED)
00216 {
00217 return targetm.calls.must_pass_in_stack (mode, type);
00218 }
00219
00220
00221
00222
00223 bool
00224 hook_callee_copies_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
00225 enum machine_mode mode ATTRIBUTE_UNUSED,
00226 tree type ATTRIBUTE_UNUSED, bool named)
00227 {
00228 return named;
00229 }
00230
00231
00232
00233 void
00234 default_unwind_emit (FILE * stream ATTRIBUTE_UNUSED,
00235 rtx insn ATTRIBUTE_UNUSED)
00236 {
00237
00238 gcc_unreachable ();
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 bool
00251 default_scalar_mode_supported_p (enum machine_mode mode)
00252 {
00253 int precision = GET_MODE_PRECISION (mode);
00254
00255 switch (GET_MODE_CLASS (mode))
00256 {
00257 case MODE_PARTIAL_INT:
00258 case MODE_INT:
00259 if (precision == CHAR_TYPE_SIZE)
00260 return true;
00261 if (precision == SHORT_TYPE_SIZE)
00262 return true;
00263 if (precision == INT_TYPE_SIZE)
00264 return true;
00265 if (precision == LONG_TYPE_SIZE)
00266 return true;
00267 if (precision == LONG_LONG_TYPE_SIZE)
00268 return true;
00269 if (precision == 2 * BITS_PER_WORD)
00270 return true;
00271 return false;
00272
00273 case MODE_FLOAT:
00274 if (precision == FLOAT_TYPE_SIZE)
00275 return true;
00276 if (precision == DOUBLE_TYPE_SIZE)
00277 return true;
00278 if (precision == LONG_DOUBLE_TYPE_SIZE)
00279 return true;
00280 return false;
00281
00282 case MODE_DECIMAL_FLOAT:
00283 return false;
00284
00285 default:
00286 gcc_unreachable ();
00287 }
00288 }
00289
00290
00291
00292 bool
00293 default_decimal_float_supported_p (void)
00294 {
00295 return ENABLE_DECIMAL_FLOAT;
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 const char *
00309 default_invalid_within_doloop (rtx insn)
00310 {
00311 if (CALL_P (insn))
00312 return "Function call in loop.";
00313
00314 if (JUMP_P (insn)
00315 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
00316 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
00317 return "Computed branch in the loop.";
00318
00319 return NULL;
00320 }
00321
00322 bool
00323 hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false (
00324 CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
00325 enum machine_mode mode ATTRIBUTE_UNUSED,
00326 tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
00327 {
00328 return false;
00329 }
00330
00331 bool
00332 hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true (
00333 CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
00334 enum machine_mode mode ATTRIBUTE_UNUSED,
00335 tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
00336 {
00337 return true;
00338 }
00339
00340 int
00341 hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 (
00342 CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
00343 enum machine_mode mode ATTRIBUTE_UNUSED,
00344 tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
00345 {
00346 return 0;
00347 }
00348
00349 void
00350 hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED)
00351 {
00352 }
00353
00354 const char *
00355 hook_invalid_arg_for_unprototyped_fn (
00356 tree typelist ATTRIBUTE_UNUSED,
00357 tree funcdecl ATTRIBUTE_UNUSED,
00358 tree val ATTRIBUTE_UNUSED)
00359 {
00360 return NULL;
00361 }
00362
00363
00364
00365
00366 static GTY(()) tree stack_chk_guard_decl;
00367
00368 tree
00369 default_stack_protect_guard (void)
00370 {
00371 tree t = stack_chk_guard_decl;
00372
00373 if (t == NULL)
00374 {
00375 t = build_decl (VAR_DECL, get_identifier ("__stack_chk_guard"),
00376 ptr_type_node);
00377 TREE_STATIC (t) = 1;
00378 TREE_PUBLIC (t) = 1;
00379 DECL_EXTERNAL (t) = 1;
00380 TREE_USED (t) = 1;
00381 TREE_THIS_VOLATILE (t) = 1;
00382 DECL_ARTIFICIAL (t) = 1;
00383 DECL_IGNORED_P (t) = 1;
00384
00385 stack_chk_guard_decl = t;
00386 }
00387
00388 return t;
00389 }
00390
00391 static GTY(()) tree stack_chk_fail_decl;
00392
00393 tree
00394 default_external_stack_protect_fail (void)
00395 {
00396 tree t = stack_chk_fail_decl;
00397
00398 if (t == NULL_TREE)
00399 {
00400 t = build_function_type_list (void_type_node, NULL_TREE);
00401 t = build_decl (FUNCTION_DECL, get_identifier ("__stack_chk_fail"), t);
00402 TREE_STATIC (t) = 1;
00403 TREE_PUBLIC (t) = 1;
00404 DECL_EXTERNAL (t) = 1;
00405 TREE_USED (t) = 1;
00406 TREE_THIS_VOLATILE (t) = 1;
00407 TREE_NOTHROW (t) = 1;
00408 DECL_ARTIFICIAL (t) = 1;
00409 DECL_IGNORED_P (t) = 1;
00410 DECL_VISIBILITY (t) = VISIBILITY_DEFAULT;
00411 DECL_VISIBILITY_SPECIFIED (t) = 1;
00412
00413 stack_chk_fail_decl = t;
00414 }
00415
00416 return build_function_call_expr (t, NULL_TREE);
00417 }
00418
00419 tree
00420 default_hidden_stack_protect_fail (void)
00421 {
00422 #ifndef HAVE_GAS_HIDDEN
00423 return default_external_stack_protect_fail ();
00424 #else
00425 tree t = stack_chk_fail_decl;
00426
00427 if (!flag_pic)
00428 return default_external_stack_protect_fail ();
00429
00430 if (t == NULL_TREE)
00431 {
00432 t = build_function_type_list (void_type_node, NULL_TREE);
00433 t = build_decl (FUNCTION_DECL,
00434 get_identifier ("__stack_chk_fail_local"), t);
00435 TREE_STATIC (t) = 1;
00436 TREE_PUBLIC (t) = 1;
00437 DECL_EXTERNAL (t) = 1;
00438 TREE_USED (t) = 1;
00439 TREE_THIS_VOLATILE (t) = 1;
00440 TREE_NOTHROW (t) = 1;
00441 DECL_ARTIFICIAL (t) = 1;
00442 DECL_IGNORED_P (t) = 1;
00443 DECL_VISIBILITY_SPECIFIED (t) = 1;
00444 DECL_VISIBILITY (t) = VISIBILITY_HIDDEN;
00445
00446 stack_chk_fail_decl = t;
00447 }
00448
00449 return build_function_call_expr (t, NULL_TREE);
00450 #endif
00451 }
00452
00453 bool
00454 hook_bool_rtx_commutative_p (rtx x, int outer_code ATTRIBUTE_UNUSED)
00455 {
00456 return COMMUTATIVE_P (x);
00457 }
00458
00459 rtx
00460 default_function_value (tree ret_type ATTRIBUTE_UNUSED,
00461 tree fn_decl_or_type,
00462 bool outgoing ATTRIBUTE_UNUSED)
00463 {
00464
00465 if (fn_decl_or_type
00466 && !DECL_P (fn_decl_or_type))
00467 fn_decl_or_type = NULL;
00468
00469 #ifdef FUNCTION_OUTGOING_VALUE
00470 if (outgoing)
00471 return FUNCTION_OUTGOING_VALUE (ret_type, fn_decl_or_type);
00472 #endif
00473
00474 #ifdef FUNCTION_VALUE
00475 return FUNCTION_VALUE (ret_type, fn_decl_or_type);
00476 #else
00477 return NULL_RTX;
00478 #endif
00479 }
00480
00481 rtx
00482 default_internal_arg_pointer (void)
00483 {
00484
00485
00486
00487
00488 if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
00489 || ! (fixed_regs[ARG_POINTER_REGNUM]
00490 || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM)))
00491 return copy_to_reg (virtual_incoming_args_rtx);
00492 else
00493 return virtual_incoming_args_rtx;
00494 }
00495
00496 enum reg_class
00497 default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
00498 enum reg_class reload_class ATTRIBUTE_UNUSED,
00499 enum machine_mode reload_mode ATTRIBUTE_UNUSED,
00500 secondary_reload_info *sri)
00501 {
00502 enum reg_class class = NO_REGS;
00503
00504 if (sri->prev_sri && sri->prev_sri->t_icode != CODE_FOR_nothing)
00505 {
00506 sri->icode = sri->prev_sri->t_icode;
00507 return NO_REGS;
00508 }
00509 #ifdef SECONDARY_INPUT_RELOAD_CLASS
00510 if (in_p)
00511 class = SECONDARY_INPUT_RELOAD_CLASS (reload_class, reload_mode, x);
00512 #endif
00513 #ifdef SECONDARY_OUTPUT_RELOAD_CLASS
00514 if (! in_p)
00515 class = SECONDARY_OUTPUT_RELOAD_CLASS (reload_class, reload_mode, x);
00516 #endif
00517 if (class != NO_REGS)
00518 {
00519 enum insn_code icode = (in_p ? reload_in_optab[(int) reload_mode]
00520 : reload_out_optab[(int) reload_mode]);
00521
00522 if (icode != CODE_FOR_nothing
00523 && insn_data[(int) icode].operand[in_p].predicate
00524 && ! insn_data[(int) icode].operand[in_p].predicate (x, reload_mode))
00525 icode = CODE_FOR_nothing;
00526 else if (icode != CODE_FOR_nothing)
00527 {
00528 const char *insn_constraint, *scratch_constraint;
00529 char insn_letter, scratch_letter;
00530 enum reg_class insn_class, scratch_class;
00531
00532 gcc_assert (insn_data[(int) icode].n_operands == 3);
00533 insn_constraint = insn_data[(int) icode].operand[!in_p].constraint;
00534 if (!*insn_constraint)
00535 insn_class = ALL_REGS;
00536 else
00537 {
00538 if (in_p)
00539 {
00540 gcc_assert (*insn_constraint == '=');
00541 insn_constraint++;
00542 }
00543 insn_letter = *insn_constraint;
00544 insn_class
00545 = (insn_letter == 'r' ? GENERAL_REGS
00546 : REG_CLASS_FROM_CONSTRAINT ((unsigned char) insn_letter,
00547 insn_constraint));
00548 gcc_assert (insn_class != NO_REGS);
00549 }
00550
00551 scratch_constraint = insn_data[(int) icode].operand[2].constraint;
00552
00553
00554
00555
00556 gcc_assert (scratch_constraint[0] == '='
00557 && (in_p || scratch_constraint[1] == '&'));
00558 scratch_constraint++;
00559 if (*scratch_constraint == '&')
00560 scratch_constraint++;
00561 scratch_letter = *scratch_constraint;
00562 scratch_class
00563 = (scratch_letter == 'r' ? GENERAL_REGS
00564 : REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter,
00565 scratch_constraint));
00566
00567 if (reg_class_subset_p (reload_class, insn_class))
00568 {
00569 gcc_assert (scratch_class == class);
00570 class = NO_REGS;
00571 }
00572 else
00573 class = insn_class;
00574
00575 }
00576 if (class == NO_REGS)
00577 sri->icode = icode;
00578 else
00579 sri->t_icode = icode;
00580 }
00581 return class;
00582 }
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 bool
00593 default_narrow_bitfield (void)
00594 {
00595 return !STRICT_ALIGNMENT;
00596 }
00597
00598
00599
00600
00601 int
00602 default_reloc_rw_mask (void)
00603 {
00604 return flag_pic ? 3 : 0;
00605 }
00606
00607 #include "gt-targhooks.h"