00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef GCC_EXPR_H
00024 #define GCC_EXPR_H
00025
00026
00027 #include "function.h"
00028
00029 #include "rtl.h"
00030
00031 #include "flags.h"
00032
00033
00034 #include "tree.h"
00035
00036 #include "machmode.h"
00037
00038
00039 #ifndef BRANCH_COST
00040 #define BRANCH_COST 1
00041 #endif
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 enum expand_modifier {EXPAND_NORMAL = 0, EXPAND_STACK_PARM, EXPAND_SUM,
00054 EXPAND_CONST_ADDRESS, EXPAND_INITIALIZER, EXPAND_WRITE,
00055 EXPAND_MEMORY};
00056
00057
00058
00059 #define NO_DEFER_POP (inhibit_defer_pop += 1)
00060
00061
00062
00063 #define OK_DEFER_POP (inhibit_defer_pop -= 1)
00064
00065
00066
00067
00068 #ifndef MOVE_RATIO
00069 #if defined (HAVE_movmemqi) || defined (HAVE_movmemhi) || defined (HAVE_movmemsi) || defined (HAVE_movmemdi) || defined (HAVE_movmemti)
00070 #define MOVE_RATIO 2
00071 #else
00072
00073 #define MOVE_RATIO (optimize_size ? 3 : 15)
00074 #endif
00075 #endif
00076
00077
00078
00079
00080 #ifndef CLEAR_RATIO
00081 #if defined (HAVE_clrmemqi) || defined (HAVE_clrmemhi) || defined (HAVE_clrmemsi) || defined (HAVE_clrmemdi) || defined (HAVE_clrmemti)
00082 #define CLEAR_RATIO 2
00083 #else
00084
00085 #define CLEAR_RATIO (optimize_size ? 3 : 15)
00086 #endif
00087 #endif
00088
00089 enum direction {none, upward, downward};
00090
00091
00092
00093
00094
00095
00096 struct args_size
00097 {
00098 HOST_WIDE_INT constant;
00099 tree var;
00100 };
00101
00102
00103
00104 struct locate_and_pad_arg_data
00105 {
00106
00107
00108
00109 struct args_size size;
00110
00111 struct args_size offset;
00112
00113
00114 struct args_size slot_offset;
00115
00116
00117 struct args_size alignment_pad;
00118
00119 enum direction where_pad;
00120
00121 unsigned int boundary;
00122 };
00123
00124
00125
00126 #define ADD_PARM_SIZE(TO, INC) \
00127 do { \
00128 tree inc = (INC); \
00129 if (host_integerp (inc, 0)) \
00130 (TO).constant += tree_low_cst (inc, 0); \
00131 else if ((TO).var == 0) \
00132 (TO).var = convert (ssizetype, inc); \
00133 else \
00134 (TO).var = size_binop (PLUS_EXPR, (TO).var, \
00135 convert (ssizetype, inc)); \
00136 } while (0)
00137
00138 #define SUB_PARM_SIZE(TO, DEC) \
00139 do { \
00140 tree dec = (DEC); \
00141 if (host_integerp (dec, 0)) \
00142 (TO).constant -= tree_low_cst (dec, 0); \
00143 else if ((TO).var == 0) \
00144 (TO).var = size_binop (MINUS_EXPR, ssize_int (0), \
00145 convert (ssizetype, dec)); \
00146 else \
00147 (TO).var = size_binop (MINUS_EXPR, (TO).var, \
00148 convert (ssizetype, dec)); \
00149 } while (0)
00150
00151
00152
00153 #define ARGS_SIZE_TREE(SIZE) \
00154 ((SIZE).var == 0 ? ssize_int ((SIZE).constant) \
00155 : size_binop (PLUS_EXPR, convert (ssizetype, (SIZE).var), \
00156 ssize_int ((SIZE).constant)))
00157
00158
00159 #define ARGS_SIZE_RTX(SIZE) \
00160 ((SIZE).var == 0 ? GEN_INT ((SIZE).constant) \
00161 : expand_expr (ARGS_SIZE_TREE (SIZE), NULL_RTX, VOIDmode, 0))
00162
00163
00164
00165
00166
00167 #define DEFAULT_FUNCTION_ARG_PADDING(MODE, TYPE) \
00168 (! BYTES_BIG_ENDIAN \
00169 ? upward \
00170 : (((MODE) == BLKmode \
00171 ? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
00172 && int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT)) \
00173 : GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY) \
00174 ? downward : upward))
00175
00176 #ifndef FUNCTION_ARG_PADDING
00177 #define FUNCTION_ARG_PADDING(MODE, TYPE) \
00178 DEFAULT_FUNCTION_ARG_PADDING ((MODE), (TYPE))
00179 #endif
00180
00181
00182
00183
00184
00185 #ifndef FUNCTION_ARG_BOUNDARY
00186 #define FUNCTION_ARG_BOUNDARY(MODE, TYPE) PARM_BOUNDARY
00187 #endif
00188
00189
00190
00191
00192 #ifndef STACK_SAVEAREA_MODE
00193 #define STACK_SAVEAREA_MODE(LEVEL) Pmode
00194 #endif
00195
00196
00197
00198
00199 #ifndef STACK_SIZE_MODE
00200 #define STACK_SIZE_MODE word_mode
00201 #endif
00202
00203
00204
00205 #ifndef STACK_CHECK_BUILTIN
00206 #define STACK_CHECK_BUILTIN 0
00207 #endif
00208
00209
00210 #ifndef STACK_CHECK_PROBE_INTERVAL
00211 #define STACK_CHECK_PROBE_INTERVAL 4096
00212 #endif
00213
00214
00215 #ifndef STACK_CHECK_PROBE_LOAD
00216 #define STACK_CHECK_PROBE_LOAD 0
00217 #endif
00218
00219
00220 #ifndef STACK_CHECK_PROTECT
00221 #define STACK_CHECK_PROTECT (75 * UNITS_PER_WORD)
00222 #endif
00223
00224
00225
00226 #ifndef STACK_CHECK_MAX_FRAME_SIZE
00227 #define STACK_CHECK_MAX_FRAME_SIZE \
00228 (STACK_CHECK_PROBE_INTERVAL - UNITS_PER_WORD)
00229 #endif
00230
00231
00232 #ifndef STACK_CHECK_FIXED_FRAME_SIZE
00233 #define STACK_CHECK_FIXED_FRAME_SIZE (4 * UNITS_PER_WORD)
00234 #endif
00235
00236
00237
00238
00239 #ifndef STACK_CHECK_MAX_VAR_SIZE
00240 #define STACK_CHECK_MAX_VAR_SIZE (STACK_CHECK_MAX_FRAME_SIZE / 100)
00241 #endif
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 enum optab_methods
00254 {
00255 OPTAB_DIRECT,
00256 OPTAB_LIB,
00257 OPTAB_WIDEN,
00258 OPTAB_LIB_WIDEN,
00259 OPTAB_MUST_WIDEN
00260 };
00261
00262
00263
00264
00265 extern rtx expand_simple_binop (enum machine_mode, enum rtx_code, rtx,
00266 rtx, rtx, int, enum optab_methods);
00267 extern rtx expand_simple_unop (enum machine_mode, enum rtx_code, rtx, rtx,
00268 int);
00269
00270
00271
00272 extern int have_insn_for (enum rtx_code, enum machine_mode);
00273
00274
00275 extern void emit_libcall_block (rtx, rtx, rtx, rtx);
00276
00277
00278
00279
00280 extern rtx gen_add2_insn (rtx, rtx);
00281 extern rtx gen_add3_insn (rtx, rtx, rtx);
00282 extern rtx gen_sub2_insn (rtx, rtx);
00283 extern rtx gen_sub3_insn (rtx, rtx, rtx);
00284 extern rtx gen_move_insn (rtx, rtx);
00285 extern int have_add2_insn (rtx, rtx);
00286 extern int have_sub2_insn (rtx, rtx);
00287
00288
00289
00290 extern void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx,
00291 enum machine_mode, int, rtx);
00292
00293
00294 extern void emit_indirect_jump (rtx);
00295
00296
00297 extern rtx gen_cond_trap (enum rtx_code, rtx, rtx, rtx);
00298
00299 #include "insn-config.h"
00300
00301 #ifdef HAVE_conditional_move
00302
00303 rtx emit_conditional_move (rtx, enum rtx_code, rtx, rtx, enum machine_mode,
00304 rtx, rtx, enum machine_mode, int);
00305
00306
00307 int can_conditionally_move_p (enum machine_mode mode);
00308
00309 #endif
00310 rtx emit_conditional_add (rtx, enum rtx_code, rtx, rtx, enum machine_mode,
00311 rtx, rtx, enum machine_mode, int);
00312
00313
00314
00315
00316
00317
00318 extern rtx negate_rtx (enum machine_mode, rtx);
00319
00320
00321 extern rtx expand_and (enum machine_mode, rtx, rtx, rtx);
00322
00323
00324 extern rtx emit_store_flag (rtx, enum rtx_code, rtx, rtx, enum machine_mode,
00325 int, int);
00326
00327
00328 extern rtx emit_store_flag_force (rtx, enum rtx_code, rtx, rtx,
00329 enum machine_mode, int, int);
00330
00331
00332 extern rtx expand_builtin (tree, rtx, rtx, enum machine_mode, int);
00333 extern tree std_build_builtin_va_list (void);
00334 extern void std_expand_builtin_va_start (tree, rtx);
00335 extern rtx default_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
00336 extern void expand_builtin_setjmp_setup (rtx, rtx);
00337 extern void expand_builtin_setjmp_receiver (rtx);
00338 extern rtx expand_builtin_saveregs (void);
00339
00340
00341
00342
00343
00344 extern void init_expr_once (void);
00345
00346
00347 extern void init_expr (void);
00348
00349
00350
00351 extern void convert_move (rtx, rtx, int);
00352
00353
00354 extern rtx convert_to_mode (enum machine_mode, rtx, int);
00355
00356
00357 extern rtx convert_modes (enum machine_mode, enum machine_mode, rtx, int);
00358
00359
00360
00361 enum block_op_methods
00362 {
00363 BLOCK_OP_NORMAL,
00364 BLOCK_OP_NO_LIBCALL,
00365 BLOCK_OP_CALL_PARM,
00366
00367 BLOCK_OP_TAILCALL
00368 };
00369
00370 extern void init_block_move_fn (const char *);
00371 extern void init_block_clear_fn (const char *);
00372
00373 extern rtx emit_block_move (rtx, rtx, rtx, enum block_op_methods);
00374
00375
00376
00377 extern void move_block_to_reg (int, rtx, int, enum machine_mode);
00378
00379
00380
00381 extern void move_block_from_reg (int, rtx, int);
00382
00383
00384 extern rtx gen_group_rtx (rtx);
00385
00386
00387
00388 extern void emit_group_load (rtx, rtx, tree, int);
00389
00390
00391 extern rtx emit_group_load_into_temps (rtx, rtx, tree, int);
00392
00393
00394
00395 extern void emit_group_move (rtx, rtx);
00396
00397
00398 extern rtx emit_group_move_into_temps (rtx);
00399
00400
00401
00402 extern void emit_group_store (rtx, rtx, tree, int);
00403
00404
00405 extern rtx copy_blkmode_from_reg (rtx, rtx, tree);
00406
00407
00408 extern void use_reg (rtx *, rtx);
00409
00410
00411
00412 extern void use_regs (rtx *, int, int);
00413
00414
00415 extern void use_group_regs (rtx *, rtx);
00416
00417
00418
00419 extern rtx clear_storage (rtx, rtx, enum block_op_methods);
00420
00421
00422
00423
00424 extern int can_move_by_pieces (unsigned HOST_WIDE_INT, unsigned int);
00425
00426
00427
00428
00429
00430
00431 extern int can_store_by_pieces (unsigned HOST_WIDE_INT,
00432 rtx (*) (void *, HOST_WIDE_INT,
00433 enum machine_mode),
00434 void *, unsigned int);
00435
00436
00437
00438
00439
00440
00441 extern rtx store_by_pieces (rtx, unsigned HOST_WIDE_INT,
00442 rtx (*) (void *, HOST_WIDE_INT, enum machine_mode),
00443 void *, unsigned int, int);
00444
00445
00446 extern rtx emit_move_insn (rtx, rtx);
00447
00448
00449 extern rtx emit_move_insn_1 (rtx, rtx);
00450
00451
00452
00453 extern rtx push_block (rtx, int, int);
00454
00455
00456 extern void emit_push_insn (rtx, enum machine_mode, tree, rtx, unsigned int,
00457 int, rtx, int, rtx, rtx, int, rtx);
00458
00459
00460 extern void expand_assignment (tree, tree);
00461
00462
00463
00464
00465
00466 extern rtx store_expr (tree, rtx, int);
00467
00468
00469
00470
00471 extern rtx force_operand (rtx, rtx);
00472
00473
00474 extern rtx expand_expr_real (tree, rtx, enum machine_mode,
00475 enum expand_modifier, rtx *);
00476
00477
00478
00479
00480 static inline rtx
00481 expand_expr (tree exp, rtx target, enum machine_mode mode,
00482 enum expand_modifier modifier)
00483 {
00484 return expand_expr_real (exp, target, mode, modifier, NULL);
00485 }
00486
00487 extern void expand_var (tree);
00488
00489
00490
00491 extern void init_pending_stack_adjust (void);
00492
00493
00494 extern void discard_pending_stack_adjust (void);
00495
00496
00497
00498 extern void clear_pending_stack_adjust (void);
00499
00500
00501 extern void do_pending_stack_adjust (void);
00502
00503
00504
00505 extern tree string_constant (tree, tree *);
00506
00507
00508 extern void jumpifnot (tree, rtx);
00509
00510
00511 extern void jumpif (tree, rtx);
00512
00513
00514
00515 extern void do_jump (tree, rtx, rtx);
00516
00517
00518 extern rtx compare_from_rtx (rtx, rtx, enum rtx_code, int, enum machine_mode,
00519 rtx);
00520 extern void do_compare_rtx_and_jump (rtx, rtx, enum rtx_code, int,
00521 enum machine_mode, rtx, rtx, rtx);
00522
00523
00524 extern int try_casesi (tree, tree, tree, tree, rtx, rtx);
00525 extern int try_tablejump (tree, tree, tree, tree, rtx, rtx);
00526
00527
00528
00529 extern unsigned int case_values_threshold (void);
00530
00531
00532 #include "alias.h"
00533
00534
00535
00536
00537 extern rtx expr_size (tree);
00538
00539
00540
00541 extern HOST_WIDE_INT int_expr_size (tree);
00542
00543
00544
00545 extern rtx hard_function_value (tree, tree, int);
00546
00547 extern rtx prepare_call_address (rtx, rtx, rtx *, int, int);
00548
00549 extern bool shift_return_value (enum machine_mode, bool, rtx);
00550
00551 extern rtx expand_call (tree, rtx, int);
00552
00553 extern void fixup_tail_calls (void);
00554
00555 #ifdef TREE_CODE
00556 extern rtx expand_shift (enum tree_code, enum machine_mode, rtx, tree, rtx,
00557 int);
00558 extern rtx expand_divmod (int, enum tree_code, enum machine_mode, rtx, rtx,
00559 rtx, int);
00560 #endif
00561
00562 extern void locate_and_pad_parm (enum machine_mode, tree, int, int, tree,
00563 struct args_size *,
00564 struct locate_and_pad_arg_data *);
00565
00566
00567 extern rtx label_rtx (tree);
00568
00569
00570
00571
00572 extern rtx force_label_rtx (tree);
00573
00574
00575 extern rtx promoted_input_arg (unsigned int, enum machine_mode *, int *);
00576
00577
00578
00579
00580 extern rtx eliminate_constant_term (rtx, rtx *);
00581
00582
00583
00584 extern rtx memory_address (enum machine_mode, rtx);
00585
00586
00587 extern rtx memory_address_noforce (enum machine_mode, rtx);
00588
00589
00590
00591
00592
00593 extern rtx change_address (rtx, enum machine_mode, rtx);
00594
00595
00596
00597 #define adjust_address(MEMREF, MODE, OFFSET) \
00598 adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1)
00599
00600
00601 #define adjust_address_nv(MEMREF, MODE, OFFSET) \
00602 adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1)
00603
00604
00605
00606
00607 #define adjust_automodify_address(MEMREF, MODE, ADDR, OFFSET) \
00608 adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 1)
00609
00610
00611 #define adjust_automodify_address_nv(MEMREF, MODE, ADDR, OFFSET) \
00612 adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 0)
00613
00614 extern rtx adjust_address_1 (rtx, enum machine_mode, HOST_WIDE_INT, int, int);
00615 extern rtx adjust_automodify_address_1 (rtx, enum machine_mode, rtx,
00616 HOST_WIDE_INT, int);
00617
00618
00619
00620
00621 extern rtx offset_address (rtx, rtx, unsigned HOST_WIDE_INT);
00622
00623
00624 #include "emit-rtl.h"
00625
00626
00627
00628 extern rtx widen_memory_access (rtx, enum machine_mode, HOST_WIDE_INT);
00629
00630
00631
00632 extern rtx validize_mem (rtx);
00633
00634
00635
00636
00637 extern void set_mem_attributes (rtx, tree, int);
00638
00639
00640
00641
00642 extern void set_mem_attributes_minus_bitpos (rtx, tree, int, HOST_WIDE_INT);
00643
00644
00645 extern rtx assemble_trampoline_template (void);
00646
00647
00648 extern rtx copy_to_reg (rtx);
00649
00650
00651 extern rtx copy_addr_to_reg (rtx);
00652
00653
00654 extern rtx copy_to_mode_reg (enum machine_mode, rtx);
00655
00656
00657 extern rtx copy_to_suggested_reg (rtx, rtx, enum machine_mode);
00658
00659
00660
00661 extern rtx force_reg (enum machine_mode, rtx);
00662
00663
00664 extern rtx force_not_mem (rtx);
00665
00666
00667 extern enum machine_mode promote_mode (tree, enum machine_mode, int *, int);
00668
00669
00670 extern void adjust_stack (rtx);
00671
00672
00673 extern void anti_adjust_stack (rtx);
00674
00675
00676 enum save_level {SAVE_BLOCK, SAVE_FUNCTION, SAVE_NONLOCAL};
00677
00678
00679 extern void emit_stack_save (enum save_level, rtx *, rtx);
00680
00681
00682 extern void emit_stack_restore (enum save_level, rtx, rtx);
00683
00684
00685 extern void update_nonlocal_goto_save_area (void);
00686
00687
00688
00689 extern rtx allocate_dynamic_stack_space (rtx, rtx, int);
00690
00691
00692
00693
00694
00695
00696 extern void probe_stack_range (HOST_WIDE_INT, rtx);
00697
00698
00699
00700 extern rtx hard_libcall_value (enum machine_mode);
00701
00702
00703
00704
00705
00706 enum extraction_pattern { EP_insv, EP_extv, EP_extzv };
00707 extern enum machine_mode
00708 mode_for_extraction (enum extraction_pattern, int);
00709
00710 extern rtx store_bit_field (rtx, unsigned HOST_WIDE_INT,
00711 unsigned HOST_WIDE_INT, enum machine_mode, rtx);
00712 extern rtx extract_bit_field (rtx, unsigned HOST_WIDE_INT,
00713 unsigned HOST_WIDE_INT, int, rtx,
00714 enum machine_mode, enum machine_mode);
00715 extern rtx expand_mult (enum machine_mode, rtx, rtx, rtx, int);
00716 extern bool const_mult_add_overflow_p (rtx, rtx, rtx, enum machine_mode, int);
00717 extern rtx expand_mult_add (rtx, rtx, rtx, rtx,enum machine_mode, int);
00718 extern rtx expand_mult_highpart_adjust (enum machine_mode, rtx, rtx, rtx, rtx, int);
00719
00720 extern rtx assemble_static_space (unsigned HOST_WIDE_INT);
00721 extern int safe_from_p (rtx, tree, int);
00722
00723
00724
00725 extern void init_optabs (void);
00726 extern void init_all_optabs (void);
00727
00728
00729 extern rtx init_one_libfunc (const char *);
00730
00731 extern void do_jump_by_parts_equality_rtx (rtx, rtx, rtx);
00732 extern void do_jump_by_parts_greater_rtx (enum machine_mode, int, rtx, rtx,
00733 rtx, rtx);
00734
00735 extern int vector_mode_valid_p (enum machine_mode);
00736
00737 #endif