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_setmemqi) || defined (HAVE_setmemhi) || defined (HAVE_setmemsi) || defined (HAVE_setmemdi) || defined (HAVE_setmemti)
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 = fold_convert (ssizetype, inc); \
00133 else \
00134 (TO).var = size_binop (PLUS_EXPR, (TO).var, \
00135 fold_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 fold_convert (ssizetype, dec)); \
00146 else \
00147 (TO).var = size_binop (MINUS_EXPR, (TO).var, \
00148 fold_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, fold_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_normal (ARGS_SIZE_TREE (SIZE)))
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 rtx expand_val_compare_and_swap (rtx, rtx, rtx, rtx);
00314 rtx expand_bool_compare_and_swap (rtx, rtx, rtx, rtx);
00315 rtx expand_sync_operation (rtx, rtx, enum rtx_code);
00316 rtx expand_sync_fetch_operation (rtx, rtx, enum rtx_code, bool, rtx);
00317 rtx expand_sync_lock_test_and_set (rtx, rtx, rtx);
00318
00319
00320
00321
00322
00323 extern rtx negate_rtx (enum machine_mode, rtx);
00324
00325
00326 extern rtx expand_and (enum machine_mode, rtx, rtx, rtx);
00327
00328
00329 extern rtx emit_store_flag (rtx, enum rtx_code, rtx, rtx, enum machine_mode,
00330 int, int);
00331
00332
00333 extern rtx emit_store_flag_force (rtx, enum rtx_code, rtx, rtx,
00334 enum machine_mode, int, int);
00335
00336
00337 extern rtx expand_builtin (tree, rtx, rtx, enum machine_mode, int);
00338 extern tree std_build_builtin_va_list (void);
00339 extern void std_expand_builtin_va_start (tree, rtx);
00340 extern rtx default_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
00341 extern void expand_builtin_setjmp_setup (rtx, rtx);
00342 extern void expand_builtin_setjmp_receiver (rtx);
00343 extern rtx expand_builtin_saveregs (void);
00344 extern void expand_builtin_trap (void);
00345
00346
00347
00348
00349
00350 extern void init_expr_once (void);
00351
00352
00353 extern void init_expr (void);
00354
00355
00356
00357 extern void convert_move (rtx, rtx, int);
00358
00359
00360 extern rtx convert_to_mode (enum machine_mode, rtx, int);
00361
00362
00363 extern rtx convert_modes (enum machine_mode, enum machine_mode, rtx, int);
00364
00365
00366
00367 enum block_op_methods
00368 {
00369 BLOCK_OP_NORMAL,
00370 BLOCK_OP_NO_LIBCALL,
00371 BLOCK_OP_CALL_PARM,
00372
00373 BLOCK_OP_TAILCALL
00374 };
00375
00376 extern void init_block_move_fn (const char *);
00377 extern void init_block_clear_fn (const char *);
00378
00379 extern rtx emit_block_move (rtx, rtx, rtx, enum block_op_methods);
00380
00381
00382
00383 extern void move_block_to_reg (int, rtx, int, enum machine_mode);
00384
00385
00386
00387 extern void move_block_from_reg (int, rtx, int);
00388
00389
00390 extern rtx gen_group_rtx (rtx);
00391
00392
00393
00394 extern void emit_group_load (rtx, rtx, tree, int);
00395
00396
00397 extern rtx emit_group_load_into_temps (rtx, rtx, tree, int);
00398
00399
00400
00401 extern void emit_group_move (rtx, rtx);
00402
00403
00404 extern rtx emit_group_move_into_temps (rtx);
00405
00406
00407
00408 extern void emit_group_store (rtx, rtx, tree, int);
00409
00410
00411 extern rtx copy_blkmode_from_reg (rtx, rtx, tree);
00412
00413
00414 extern void use_reg (rtx *, rtx);
00415
00416
00417
00418 extern void use_regs (rtx *, int, int);
00419
00420
00421 extern void use_group_regs (rtx *, rtx);
00422
00423
00424
00425 extern rtx clear_storage (rtx, rtx, enum block_op_methods);
00426
00427
00428 extern bool set_storage_via_setmem (rtx, rtx, rtx, unsigned int);
00429
00430
00431
00432
00433 extern int can_move_by_pieces (unsigned HOST_WIDE_INT, unsigned int);
00434
00435
00436
00437
00438
00439
00440 extern int can_store_by_pieces (unsigned HOST_WIDE_INT,
00441 rtx (*) (void *, HOST_WIDE_INT,
00442 enum machine_mode),
00443 void *, unsigned int);
00444
00445
00446
00447
00448
00449
00450 extern rtx store_by_pieces (rtx, unsigned HOST_WIDE_INT,
00451 rtx (*) (void *, HOST_WIDE_INT, enum machine_mode),
00452 void *, unsigned int, int);
00453
00454
00455 extern rtx emit_move_insn (rtx, rtx);
00456
00457
00458 extern rtx emit_move_insn_1 (rtx, rtx);
00459
00460
00461
00462 extern rtx push_block (rtx, int, int);
00463
00464
00465 extern void emit_push_insn (rtx, enum machine_mode, tree, rtx, unsigned int,
00466 int, rtx, int, rtx, rtx, int, rtx);
00467
00468
00469 extern void expand_assignment (tree, tree);
00470
00471
00472
00473
00474
00475 extern rtx store_expr (tree, rtx, int);
00476
00477
00478
00479
00480 extern rtx force_operand (rtx, rtx);
00481
00482
00483 extern rtx expand_expr_real (tree, rtx, enum machine_mode,
00484 enum expand_modifier, rtx *);
00485
00486
00487
00488
00489 static inline rtx
00490 expand_expr (tree exp, rtx target, enum machine_mode mode,
00491 enum expand_modifier modifier)
00492 {
00493 return expand_expr_real (exp, target, mode, modifier, NULL);
00494 }
00495
00496 static inline rtx
00497 expand_normal (tree exp)
00498 {
00499 return expand_expr_real (exp, NULL_RTX, VOIDmode, EXPAND_NORMAL, NULL);
00500 }
00501
00502 extern void expand_var (tree);
00503
00504
00505
00506 extern void init_pending_stack_adjust (void);
00507
00508
00509 extern void discard_pending_stack_adjust (void);
00510
00511
00512
00513 extern void clear_pending_stack_adjust (void);
00514
00515
00516 extern void do_pending_stack_adjust (void);
00517
00518
00519
00520 extern tree string_constant (tree, tree *);
00521
00522
00523 extern void jumpifnot (tree, rtx);
00524
00525
00526 extern void jumpif (tree, rtx);
00527
00528
00529
00530 extern void do_jump (tree, rtx, rtx);
00531
00532
00533 extern rtx compare_from_rtx (rtx, rtx, enum rtx_code, int, enum machine_mode,
00534 rtx);
00535 extern void do_compare_rtx_and_jump (rtx, rtx, enum rtx_code, int,
00536 enum machine_mode, rtx, rtx, rtx);
00537
00538
00539 extern int try_casesi (tree, tree, tree, tree, rtx, rtx);
00540 extern int try_tablejump (tree, tree, tree, tree, rtx, rtx);
00541
00542
00543
00544 extern unsigned int case_values_threshold (void);
00545
00546
00547 #include "alias.h"
00548
00549
00550
00551
00552 extern rtx expr_size (tree);
00553
00554
00555
00556 extern HOST_WIDE_INT int_expr_size (tree);
00557
00558
00559
00560 extern rtx hard_function_value (tree, tree, tree, int);
00561
00562 extern rtx prepare_call_address (rtx, rtx, rtx *, int, int);
00563
00564 extern bool shift_return_value (enum machine_mode, bool, rtx);
00565
00566 extern rtx expand_call (tree, rtx, int);
00567
00568 extern void fixup_tail_calls (void);
00569
00570 #ifdef TREE_CODE
00571 extern rtx expand_shift (enum tree_code, enum machine_mode, rtx, tree, rtx,
00572 int);
00573 extern rtx expand_divmod (int, enum tree_code, enum machine_mode, rtx, rtx,
00574 rtx, int);
00575 #endif
00576
00577 extern void locate_and_pad_parm (enum machine_mode, tree, int, int, tree,
00578 struct args_size *,
00579 struct locate_and_pad_arg_data *);
00580
00581
00582 extern rtx label_rtx (tree);
00583
00584
00585
00586
00587 extern rtx force_label_rtx (tree);
00588
00589
00590 extern rtx promoted_input_arg (unsigned int, enum machine_mode *, int *);
00591
00592
00593
00594
00595 extern rtx eliminate_constant_term (rtx, rtx *);
00596
00597
00598
00599 extern rtx memory_address (enum machine_mode, rtx);
00600
00601
00602 extern rtx memory_address_noforce (enum machine_mode, rtx);
00603
00604
00605
00606
00607
00608 extern rtx change_address (rtx, enum machine_mode, rtx);
00609
00610
00611
00612 #define adjust_address(MEMREF, MODE, OFFSET) \
00613 adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1)
00614
00615
00616 #define adjust_address_nv(MEMREF, MODE, OFFSET) \
00617 adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1)
00618
00619
00620
00621
00622 #define adjust_automodify_address(MEMREF, MODE, ADDR, OFFSET) \
00623 adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 1)
00624
00625
00626 #define adjust_automodify_address_nv(MEMREF, MODE, ADDR, OFFSET) \
00627 adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 0)
00628
00629 extern rtx adjust_address_1 (rtx, enum machine_mode, HOST_WIDE_INT, int, int);
00630 extern rtx adjust_automodify_address_1 (rtx, enum machine_mode, rtx,
00631 HOST_WIDE_INT, int);
00632
00633
00634
00635
00636 extern rtx offset_address (rtx, rtx, unsigned HOST_WIDE_INT);
00637
00638
00639 #include "emit-rtl.h"
00640
00641
00642
00643 extern rtx widen_memory_access (rtx, enum machine_mode, HOST_WIDE_INT);
00644
00645
00646
00647 extern rtx validize_mem (rtx);
00648
00649 extern rtx use_anchored_address (rtx);
00650
00651
00652
00653
00654 extern void set_mem_attributes (rtx, tree, int);
00655
00656
00657
00658
00659 extern void set_mem_attributes_minus_bitpos (rtx, tree, int, HOST_WIDE_INT);
00660
00661
00662 extern rtx assemble_trampoline_template (void);
00663
00664
00665 extern rtx copy_to_reg (rtx);
00666
00667
00668 extern rtx copy_addr_to_reg (rtx);
00669
00670
00671 extern rtx copy_to_mode_reg (enum machine_mode, rtx);
00672
00673
00674 extern rtx copy_to_suggested_reg (rtx, rtx, enum machine_mode);
00675
00676
00677
00678 extern rtx force_reg (enum machine_mode, rtx);
00679
00680
00681 extern rtx force_not_mem (rtx);
00682
00683
00684 extern enum machine_mode promote_mode (tree, enum machine_mode, int *, int);
00685
00686
00687 extern void adjust_stack (rtx);
00688
00689
00690 extern void anti_adjust_stack (rtx);
00691
00692
00693 enum save_level {SAVE_BLOCK, SAVE_FUNCTION, SAVE_NONLOCAL};
00694
00695
00696 extern void emit_stack_save (enum save_level, rtx *, rtx);
00697
00698
00699 extern void emit_stack_restore (enum save_level, rtx, rtx);
00700
00701
00702 extern void update_nonlocal_goto_save_area (void);
00703
00704
00705
00706 extern rtx allocate_dynamic_stack_space (rtx, rtx, int);
00707
00708
00709
00710
00711
00712
00713 extern void probe_stack_range (HOST_WIDE_INT, rtx);
00714
00715
00716
00717 extern rtx hard_libcall_value (enum machine_mode);
00718
00719
00720
00721
00722
00723 enum extraction_pattern { EP_insv, EP_extv, EP_extzv };
00724 extern enum machine_mode
00725 mode_for_extraction (enum extraction_pattern, int);
00726
00727 extern rtx store_bit_field (rtx, unsigned HOST_WIDE_INT,
00728 unsigned HOST_WIDE_INT, enum machine_mode, rtx);
00729 extern rtx extract_bit_field (rtx, unsigned HOST_WIDE_INT,
00730 unsigned HOST_WIDE_INT, int, rtx,
00731 enum machine_mode, enum machine_mode);
00732 extern rtx expand_mult (enum machine_mode, rtx, rtx, rtx, int);
00733 extern rtx expand_mult_highpart_adjust (enum machine_mode, rtx, rtx, rtx, rtx, int);
00734
00735 extern rtx assemble_static_space (unsigned HOST_WIDE_INT);
00736 extern int safe_from_p (rtx, tree, int);
00737
00738
00739
00740 extern void init_optabs (void);
00741 extern void init_all_optabs (void);
00742
00743
00744 extern rtx init_one_libfunc (const char *);
00745
00746 extern int vector_mode_valid_p (enum machine_mode);
00747
00748 #endif