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 #include "config.h"
00027 #include "system.h"
00028 #include "rtl.h"
00029 #include "tree.h"
00030 #include "tm_p.h"
00031 #include "regs.h"
00032 #include "hard-reg-set.h"
00033 #include "real.h"
00034 #include "insn-config.h"
00035 #include "conditions.h"
00036 #include "output.h"
00037 #include "insn-attr.h"
00038 #include "flags.h"
00039 #include "except.h"
00040 #include "function.h"
00041 #include "recog.h"
00042 #include "expr.h"
00043 #include "optabs.h"
00044 #include "toplev.h"
00045 #include "basic-block.h"
00046 #include "ggc.h"
00047 #include "target.h"
00048 #include "target-def.h"
00049 #include "langhooks.h"
00050
00051 #ifndef CHECK_STACK_LIMIT
00052 #define CHECK_STACK_LIMIT (-1)
00053 #endif
00054
00055
00056 static const
00057 struct processor_costs size_cost = {
00058 2,
00059 3,
00060 2,
00061 3,
00062 3,
00063 0,
00064 3,
00065 3,
00066 3,
00067 0,
00068 2,
00069 2,
00070 {2, 2, 2},
00071
00072
00073 {2, 2, 2},
00074 2,
00075 {2, 2, 2},
00076
00077 {2, 2, 2},
00078 3,
00079 {3, 3},
00080
00081 {3, 3},
00082
00083 3,
00084 {3, 3, 3},
00085
00086 {3, 3, 3},
00087
00088 3,
00089 0,
00090 0,
00091 2,
00092 2,
00093 2,
00094 2,
00095 2,
00096 2,
00097 };
00098
00099
00100 static const
00101 struct processor_costs i386_cost = {
00102 1,
00103 1,
00104 3,
00105 2,
00106 6,
00107 1,
00108 23,
00109 3,
00110 2,
00111 15,
00112 3,
00113 4,
00114 {2, 4, 2},
00115
00116
00117 {2, 4, 2},
00118 2,
00119 {8, 8, 8},
00120
00121 {8, 8, 8},
00122 2,
00123 {4, 8},
00124
00125 {4, 8},
00126
00127 2,
00128 {4, 8, 16},
00129
00130 {4, 8, 16},
00131
00132 3,
00133 0,
00134 0,
00135 23,
00136 27,
00137 88,
00138 22,
00139 24,
00140 122,
00141 };
00142
00143 static const
00144 struct processor_costs i486_cost = {
00145 1,
00146 1,
00147 3,
00148 2,
00149 12,
00150 1,
00151 40,
00152 3,
00153 2,
00154 15,
00155 3,
00156 4,
00157 {2, 4, 2},
00158
00159
00160 {2, 4, 2},
00161 2,
00162 {8, 8, 8},
00163
00164 {8, 8, 8},
00165 2,
00166 {4, 8},
00167
00168 {4, 8},
00169
00170 2,
00171 {4, 8, 16},
00172
00173 {4, 8, 16},
00174
00175 3,
00176 0,
00177 0,
00178 8,
00179 16,
00180 73,
00181 3,
00182 3,
00183 83,
00184 };
00185
00186 static const
00187 struct processor_costs pentium_cost = {
00188 1,
00189 1,
00190 4,
00191 1,
00192 11,
00193 0,
00194 25,
00195 3,
00196 2,
00197 8,
00198 6,
00199 6,
00200 {2, 4, 2},
00201
00202
00203 {2, 4, 2},
00204 2,
00205 {2, 2, 6},
00206
00207 {4, 4, 6},
00208 8,
00209 {8, 8},
00210
00211 {8, 8},
00212
00213 2,
00214 {4, 8, 16},
00215
00216 {4, 8, 16},
00217
00218 3,
00219 0,
00220 0,
00221 3,
00222 3,
00223 39,
00224 1,
00225 1,
00226 70,
00227 };
00228
00229 static const
00230 struct processor_costs pentiumpro_cost = {
00231 1,
00232 1,
00233 1,
00234 1,
00235 4,
00236 0,
00237 17,
00238 1,
00239 1,
00240 8,
00241 6,
00242 2,
00243 {4, 4, 4},
00244
00245
00246 {2, 2, 2},
00247 2,
00248 {2, 2, 6},
00249
00250 {4, 4, 6},
00251 2,
00252 {2, 2},
00253
00254 {2, 2},
00255
00256 2,
00257 {2, 2, 8},
00258
00259 {2, 2, 8},
00260
00261 3,
00262 32,
00263 6,
00264 3,
00265 5,
00266 56,
00267 2,
00268 2,
00269 56,
00270 };
00271
00272 static const
00273 struct processor_costs k6_cost = {
00274 1,
00275 2,
00276 1,
00277 1,
00278 3,
00279 0,
00280 18,
00281 2,
00282 2,
00283 8,
00284 4,
00285 3,
00286 {4, 5, 4},
00287
00288
00289 {2, 3, 2},
00290 4,
00291 {6, 6, 6},
00292
00293 {4, 4, 4},
00294 2,
00295 {2, 2},
00296
00297 {2, 2},
00298
00299 2,
00300 {2, 2, 8},
00301
00302 {2, 2, 8},
00303
00304 6,
00305 32,
00306 1,
00307 2,
00308 2,
00309 56,
00310 2,
00311 2,
00312 56,
00313 };
00314
00315 static const
00316 struct processor_costs athlon_cost = {
00317 1,
00318 2,
00319 1,
00320 1,
00321 5,
00322 0,
00323 42,
00324 1,
00325 1,
00326 8,
00327 9,
00328 4,
00329 {3, 4, 3},
00330
00331
00332 {3, 4, 3},
00333 4,
00334 {4, 4, 12},
00335
00336 {6, 6, 8},
00337 2,
00338 {4, 4},
00339
00340 {4, 4},
00341
00342 2,
00343 {4, 4, 6},
00344
00345 {4, 4, 5},
00346
00347 5,
00348 64,
00349 6,
00350 4,
00351 4,
00352 24,
00353 2,
00354 2,
00355 35,
00356 };
00357
00358 static const
00359 struct processor_costs pentium4_cost = {
00360 1,
00361 1,
00362 8,
00363 8,
00364 30,
00365 0,
00366 112,
00367 1,
00368 1,
00369 16,
00370 6,
00371 2,
00372 {4, 5, 4},
00373
00374
00375 {2, 3, 2},
00376 2,
00377 {2, 2, 6},
00378
00379 {4, 4, 6},
00380 2,
00381 {2, 2},
00382
00383 {2, 2},
00384
00385 12,
00386 {12, 12, 12},
00387
00388 {2, 2, 8},
00389
00390 10,
00391 64,
00392 6,
00393 5,
00394 7,
00395 43,
00396 2,
00397 2,
00398 43,
00399 };
00400
00401 const struct processor_costs *ix86_cost = &pentium_cost;
00402
00403
00404 #define m_386 (1<<PROCESSOR_I386)
00405 #define m_486 (1<<PROCESSOR_I486)
00406 #define m_PENT (1<<PROCESSOR_PENTIUM)
00407 #define m_PPRO (1<<PROCESSOR_PENTIUMPRO)
00408 #define m_K6 (1<<PROCESSOR_K6)
00409 #define m_ATHLON (1<<PROCESSOR_ATHLON)
00410 #define m_PENT4 (1<<PROCESSOR_PENTIUM4)
00411
00412 const int x86_use_leave = m_386 | m_K6 | m_ATHLON;
00413 const int x86_push_memory = m_386 | m_K6 | m_ATHLON | m_PENT4;
00414 const int x86_zero_extend_with_and = m_486 | m_PENT;
00415 const int x86_movx = m_ATHLON | m_PPRO | m_PENT4 ;
00416 const int x86_double_with_add = ~m_386;
00417 const int x86_use_bit_test = m_386;
00418 const int x86_unroll_strlen = m_486 | m_PENT | m_PPRO | m_ATHLON | m_K6;
00419 const int x86_cmove = m_PPRO | m_ATHLON | m_PENT4;
00420 const int x86_3dnow_a = m_ATHLON;
00421 const int x86_deep_branch = m_PPRO | m_K6 | m_ATHLON | m_PENT4;
00422 const int x86_branch_hints = m_PENT4;
00423 const int x86_use_sahf = m_PPRO | m_K6 | m_PENT4;
00424 const int x86_partial_reg_stall = m_PPRO;
00425 const int x86_use_loop = m_K6;
00426 const int x86_use_fiop = ~(m_PPRO | m_ATHLON | m_PENT);
00427 const int x86_use_mov0 = m_K6;
00428 const int x86_use_cltd = ~(m_PENT | m_K6);
00429 const int x86_read_modify_write = ~m_PENT;
00430 const int x86_read_modify = ~(m_PENT | m_PPRO);
00431 const int x86_split_long_moves = m_PPRO;
00432 const int x86_promote_QImode = m_K6 | m_PENT | m_386 | m_486 | m_ATHLON;
00433 const int x86_fast_prefix = ~(m_PENT | m_486 | m_386);
00434 const int x86_single_stringop = m_386 | m_PENT4;
00435 const int x86_qimode_math = ~(0);
00436 const int x86_promote_qi_regs = 0;
00437 const int x86_himode_math = ~(m_PPRO);
00438 const int x86_promote_hi_regs = m_PPRO;
00439 const int x86_sub_esp_4 = m_ATHLON | m_PPRO | m_PENT4;
00440 const int x86_sub_esp_8 = m_ATHLON | m_PPRO | m_386 | m_486 | m_PENT4;
00441 const int x86_add_esp_4 = m_ATHLON | m_K6 | m_PENT4;
00442 const int x86_add_esp_8 = m_ATHLON | m_PPRO | m_K6 | m_386 | m_486 | m_PENT4;
00443 const int x86_integer_DFmode_moves = ~(m_ATHLON | m_PENT4 | m_PPRO);
00444 const int x86_partial_reg_dependency = m_ATHLON | m_PENT4;
00445 const int x86_memory_mismatch_stall = m_ATHLON | m_PENT4;
00446 const int x86_accumulate_outgoing_args = m_ATHLON | m_PENT4 | m_PPRO;
00447 const int x86_prologue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
00448 const int x86_epilogue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
00449 const int x86_decompose_lea = m_PENT4;
00450 const int x86_shift1 = ~m_486;
00451 const int x86_arch_always_fancy_math_387 = m_PENT | m_PPRO | m_ATHLON | m_PENT4;
00452
00453
00454
00455
00456 #define FAST_PROLOGUE_INSN_COUNT 30
00457
00458
00459
00460 static int use_fast_prologue_epilogue;
00461
00462
00463 static const char *const qi_reg_name[] = QI_REGISTER_NAMES;
00464 static const char *const qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
00465 static const char *const hi_reg_name[] = HI_REGISTER_NAMES;
00466
00467
00468
00469
00470 enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] =
00471 {
00472
00473 AREG, DREG, CREG, BREG,
00474
00475 SIREG, DIREG, NON_Q_REGS, NON_Q_REGS,
00476
00477 FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
00478 FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
00479
00480 NON_Q_REGS,
00481
00482 NO_REGS, NO_REGS, NO_REGS, NON_Q_REGS,
00483 SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
00484 SSE_REGS, SSE_REGS,
00485 MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
00486 MMX_REGS, MMX_REGS,
00487 NON_Q_REGS, NON_Q_REGS, NON_Q_REGS, NON_Q_REGS,
00488 NON_Q_REGS, NON_Q_REGS, NON_Q_REGS, NON_Q_REGS,
00489 SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
00490 SSE_REGS, SSE_REGS,
00491 };
00492
00493
00494
00495 int const dbx_register_map[FIRST_PSEUDO_REGISTER] =
00496 {
00497 0, 2, 1, 3, 6, 7, 4, 5,
00498 12, 13, 14, 15, 16, 17, 18, 19,
00499 -1, -1, -1, -1, -1,
00500 21, 22, 23, 24, 25, 26, 27, 28,
00501 29, 30, 31, 32, 33, 34, 35, 36,
00502 -1, -1, -1, -1, -1, -1, -1, -1,
00503 -1, -1, -1, -1, -1, -1, -1, -1,
00504 };
00505
00506 static int const x86_64_int_parameter_registers[6] =
00507 {
00508 5 , 4 , 1 , 2 ,
00509 FIRST_REX_INT_REG , FIRST_REX_INT_REG + 1
00510 };
00511
00512 static int const x86_64_int_return_registers[4] =
00513 {
00514 0 , 1 , 5 , 4
00515 };
00516
00517
00518 int const dbx64_register_map[FIRST_PSEUDO_REGISTER] =
00519 {
00520 0, 1, 2, 3, 4, 5, 6, 7,
00521 33, 34, 35, 36, 37, 38, 39, 40,
00522 -1, -1, -1, -1, -1,
00523 17, 18, 19, 20, 21, 22, 23, 24,
00524 41, 42, 43, 44, 45, 46, 47, 48,
00525 8,9,10,11,12,13,14,15,
00526 25, 26, 27, 28, 29, 30, 31, 32,
00527 };
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] =
00584 {
00585 0, 2, 1, 3, 6, 7, 5, 4,
00586 11, 12, 13, 14, 15, 16, 17, 18,
00587 -1, 9, -1, -1, -1,
00588 21, 22, 23, 24, 25, 26, 27, 28,
00589 29, 30, 31, 32, 33, 34, 35, 36,
00590 -1, -1, -1, -1, -1, -1, -1, -1,
00591 -1, -1, -1, -1, -1, -1, -1, -1,
00592 };
00593
00594
00595
00596
00597 rtx ix86_compare_op0 = NULL_RTX;
00598 rtx ix86_compare_op1 = NULL_RTX;
00599
00600
00601
00602 static char const tls_model_chars[] = " GLil";
00603
00604 #define MAX_386_STACK_LOCALS 3
00605
00606 #define X86_64_VARARGS_SIZE (REGPARM_MAX * UNITS_PER_WORD + SSE_REGPARM_MAX * 16)
00607
00608
00609 struct machine_function GTY(())
00610 {
00611 rtx stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
00612 const char *some_ld_name;
00613 int save_varrargs_registers;
00614 int accesses_prev_frame;
00615 };
00616
00617 #define ix86_stack_locals (cfun->machine->stack_locals)
00618 #define ix86_save_varrargs_registers (cfun->machine->save_varrargs_registers)
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 struct ix86_frame
00640 {
00641 int nregs;
00642 int padding1;
00643 int va_arg_size;
00644 HOST_WIDE_INT frame;
00645 int padding2;
00646 int outgoing_arguments_size;
00647 int red_zone_size;
00648
00649 HOST_WIDE_INT to_allocate;
00650
00651 HOST_WIDE_INT frame_pointer_offset;
00652 HOST_WIDE_INT hard_frame_pointer_offset;
00653 HOST_WIDE_INT stack_pointer_offset;
00654 };
00655
00656
00657 const char *ix86_debug_arg_string, *ix86_debug_addr_string;
00658
00659 const char *ix86_cmodel_string;
00660
00661 enum cmodel ix86_cmodel;
00662
00663 const char *ix86_asm_string;
00664 enum asm_dialect ix86_asm_dialect = ASM_ATT;
00665
00666 const char *ix86_tls_dialect_string;
00667 enum tls_dialect ix86_tls_dialect = TLS_DIALECT_GNU;
00668
00669
00670 enum fpmath_unit ix86_fpmath;
00671
00672
00673 enum processor_type ix86_cpu;
00674
00675 enum processor_type ix86_arch;
00676
00677
00678 const char *ix86_cpu_string;
00679 const char *ix86_arch_string;
00680 const char *ix86_fpmath_string;
00681
00682
00683 const char *ix86_regparm_string;
00684
00685
00686 int x86_prefetch_sse;
00687
00688
00689 int ix86_regparm;
00690
00691
00692
00693
00694 const char *ix86_align_loops_string;
00695
00696
00697 const char *ix86_align_jumps_string;
00698
00699
00700 const char *ix86_preferred_stack_boundary_string;
00701
00702
00703 int ix86_preferred_stack_boundary;
00704
00705
00706 int ix86_branch_cost;
00707 const char *ix86_branch_cost_string;
00708
00709
00710 const char *ix86_align_funcs_string;
00711
00712
00713 static char internal_label_prefix[16];
00714 static int internal_label_prefix_len;
00715
00716 static int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
00717 static int tls_symbolic_operand_1 PARAMS ((rtx, enum tls_model));
00718 static void output_pic_addr_const PARAMS ((FILE *, rtx, int));
00719 static void put_condition_code PARAMS ((enum rtx_code, enum machine_mode,
00720 int, int, FILE *));
00721 static const char *get_some_local_dynamic_name PARAMS ((void));
00722 static int get_some_local_dynamic_name_1 PARAMS ((rtx *, void *));
00723 static rtx maybe_get_pool_constant PARAMS ((rtx));
00724 static rtx ix86_expand_int_compare PARAMS ((enum rtx_code, rtx, rtx));
00725 static enum rtx_code ix86_prepare_fp_compare_args PARAMS ((enum rtx_code,
00726 rtx *, rtx *));
00727 static rtx get_thread_pointer PARAMS ((int));
00728 static rtx legitimize_tls_address PARAMS ((rtx, enum tls_model, int));
00729 static void get_pc_thunk_name PARAMS ((char [32], unsigned int));
00730 static rtx gen_push PARAMS ((rtx));
00731 static int memory_address_length PARAMS ((rtx addr));
00732 static int ix86_flags_dependant PARAMS ((rtx, rtx, enum attr_type));
00733 static int ix86_agi_dependant PARAMS ((rtx, rtx, enum attr_type));
00734 static enum attr_ppro_uops ix86_safe_ppro_uops PARAMS ((rtx));
00735 static void ix86_dump_ppro_packet PARAMS ((FILE *));
00736 static void ix86_reorder_insn PARAMS ((rtx *, rtx *));
00737 static struct machine_function * ix86_init_machine_status PARAMS ((void));
00738 static int ix86_split_to_parts PARAMS ((rtx, rtx *, enum machine_mode));
00739 static int ix86_nsaved_regs PARAMS ((void));
00740 static void ix86_emit_save_regs PARAMS ((void));
00741 static void ix86_emit_save_regs_using_mov PARAMS ((rtx, HOST_WIDE_INT));
00742 static void ix86_emit_restore_regs_using_mov PARAMS ((rtx, int, int));
00743 static void ix86_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
00744 static void ix86_set_move_mem_attrs_1 PARAMS ((rtx, rtx, rtx, rtx, rtx));
00745 static void ix86_sched_reorder_ppro PARAMS ((rtx *, rtx *));
00746 static HOST_WIDE_INT ix86_GOT_alias_set PARAMS ((void));
00747 static void ix86_adjust_counter PARAMS ((rtx, HOST_WIDE_INT));
00748 static rtx ix86_expand_aligntest PARAMS ((rtx, int));
00749 static void ix86_expand_strlensi_unroll_1 PARAMS ((rtx, rtx));
00750 static int ix86_issue_rate PARAMS ((void));
00751 static int ix86_adjust_cost PARAMS ((rtx, rtx, rtx, int));
00752 static void ix86_sched_init PARAMS ((FILE *, int, int));
00753 static int ix86_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));
00754 static int ix86_variable_issue PARAMS ((FILE *, int, rtx, int));
00755 static int ia32_use_dfa_pipeline_interface PARAMS ((void));
00756 static int ia32_multipass_dfa_lookahead PARAMS ((void));
00757 static void ix86_init_mmx_sse_builtins PARAMS ((void));
00758 static rtx x86_this_parameter PARAMS ((tree));
00759 static void x86_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
00760 HOST_WIDE_INT, tree));
00761 static bool x86_can_output_mi_thunk PARAMS ((tree, HOST_WIDE_INT,
00762 HOST_WIDE_INT, tree));
00763
00764 struct ix86_address
00765 {
00766 rtx base, index, disp;
00767 HOST_WIDE_INT scale;
00768 enum ix86_address_seg { SEG_DEFAULT, SEG_FS, SEG_GS } seg;
00769 };
00770
00771 static int ix86_decompose_address PARAMS ((rtx, struct ix86_address *));
00772 static bool ix86_cannot_force_const_mem PARAMS ((rtx));
00773
00774 static void ix86_encode_section_info PARAMS ((tree, int)) ATTRIBUTE_UNUSED;
00775 static const char *ix86_strip_name_encoding PARAMS ((const char *))
00776 ATTRIBUTE_UNUSED;
00777
00778 struct builtin_description;
00779 static rtx ix86_expand_sse_comi PARAMS ((const struct builtin_description *,
00780 tree, rtx));
00781 static rtx ix86_expand_sse_compare PARAMS ((const struct builtin_description *,
00782 tree, rtx));
00783 static rtx ix86_expand_unop1_builtin PARAMS ((enum insn_code, tree, rtx));
00784 static rtx ix86_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx, int));
00785 static rtx ix86_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
00786 static rtx ix86_expand_store_builtin PARAMS ((enum insn_code, tree));
00787 static rtx safe_vector_operand PARAMS ((rtx, enum machine_mode));
00788 static enum rtx_code ix86_fp_compare_code_to_integer PARAMS ((enum rtx_code));
00789 static void ix86_fp_comparison_codes PARAMS ((enum rtx_code code,
00790 enum rtx_code *,
00791 enum rtx_code *,
00792 enum rtx_code *));
00793 static rtx ix86_expand_fp_compare PARAMS ((enum rtx_code, rtx, rtx, rtx,
00794 rtx *, rtx *));
00795 static int ix86_fp_comparison_arithmetics_cost PARAMS ((enum rtx_code code));
00796 static int ix86_fp_comparison_fcomi_cost PARAMS ((enum rtx_code code));
00797 static int ix86_fp_comparison_sahf_cost PARAMS ((enum rtx_code code));
00798 static int ix86_fp_comparison_cost PARAMS ((enum rtx_code code));
00799 static unsigned int ix86_select_alt_pic_regnum PARAMS ((void));
00800 static int ix86_save_reg PARAMS ((unsigned int, int));
00801 static void ix86_compute_frame_layout PARAMS ((struct ix86_frame *));
00802 static int ix86_comp_type_attributes PARAMS ((tree, tree));
00803 static int ix86_fntype_regparm PARAMS ((tree));
00804 const struct attribute_spec ix86_attribute_table[];
00805 static tree ix86_handle_cdecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
00806 static tree ix86_handle_regparm_attribute PARAMS ((tree *, tree, tree, int, bool *));
00807 static int ix86_value_regno PARAMS ((enum machine_mode));
00808 static bool contains_128bit_aligned_vector_p PARAMS ((tree));
00809
00810 #if defined (DO_GLOBAL_CTORS_BODY) && defined (HAS_INIT_SECTION)
00811 static void ix86_svr3_asm_out_constructor PARAMS ((rtx, int));
00812 #endif
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822 enum x86_64_reg_class
00823 {
00824 X86_64_NO_CLASS,
00825 X86_64_INTEGER_CLASS,
00826 X86_64_INTEGERSI_CLASS,
00827 X86_64_SSE_CLASS,
00828 X86_64_SSESF_CLASS,
00829 X86_64_SSEDF_CLASS,
00830 X86_64_SSEUP_CLASS,
00831 X86_64_X87_CLASS,
00832 X86_64_X87UP_CLASS,
00833 X86_64_MEMORY_CLASS
00834 };
00835 static const char * const x86_64_reg_class_name[] =
00836 {"no", "integer", "integerSI", "sse", "sseSF", "sseDF", "sseup", "x87", "x87up", "no"};
00837
00838 #define MAX_CLASSES 4
00839 static int classify_argument PARAMS ((enum machine_mode, tree,
00840 enum x86_64_reg_class [MAX_CLASSES],
00841 int));
00842 static int examine_argument PARAMS ((enum machine_mode, tree, int, int *,
00843 int *));
00844 static rtx construct_container PARAMS ((enum machine_mode, tree, int, int, int,
00845 const int *, int));
00846 static enum x86_64_reg_class merge_classes PARAMS ((enum x86_64_reg_class,
00847 enum x86_64_reg_class));
00848
00849
00850 #undef TARGET_ATTRIBUTE_TABLE
00851 #define TARGET_ATTRIBUTE_TABLE ix86_attribute_table
00852 #ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
00853 # undef TARGET_MERGE_DECL_ATTRIBUTES
00854 # define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
00855 #endif
00856
00857 #undef TARGET_COMP_TYPE_ATTRIBUTES
00858 #define TARGET_COMP_TYPE_ATTRIBUTES ix86_comp_type_attributes
00859
00860 #undef TARGET_INIT_BUILTINS
00861 #define TARGET_INIT_BUILTINS ix86_init_builtins
00862
00863 #undef TARGET_EXPAND_BUILTIN
00864 #define TARGET_EXPAND_BUILTIN ix86_expand_builtin
00865
00866 #undef TARGET_ASM_FUNCTION_EPILOGUE
00867 #define TARGET_ASM_FUNCTION_EPILOGUE ix86_output_function_epilogue
00868
00869 #undef TARGET_ASM_OPEN_PAREN
00870 #define TARGET_ASM_OPEN_PAREN ""
00871 #undef TARGET_ASM_CLOSE_PAREN
00872 #define TARGET_ASM_CLOSE_PAREN ""
00873
00874 #undef TARGET_ASM_ALIGNED_HI_OP
00875 #define TARGET_ASM_ALIGNED_HI_OP ASM_SHORT
00876 #undef TARGET_ASM_ALIGNED_SI_OP
00877 #define TARGET_ASM_ALIGNED_SI_OP ASM_LONG
00878 #ifdef ASM_QUAD
00879 #undef TARGET_ASM_ALIGNED_DI_OP
00880 #define TARGET_ASM_ALIGNED_DI_OP ASM_QUAD
00881 #endif
00882
00883 #undef TARGET_ASM_UNALIGNED_HI_OP
00884 #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
00885 #undef TARGET_ASM_UNALIGNED_SI_OP
00886 #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
00887 #undef TARGET_ASM_UNALIGNED_DI_OP
00888 #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
00889
00890 #undef TARGET_SCHED_ADJUST_COST
00891 #define TARGET_SCHED_ADJUST_COST ix86_adjust_cost
00892 #undef TARGET_SCHED_ISSUE_RATE
00893 #define TARGET_SCHED_ISSUE_RATE ix86_issue_rate
00894 #undef TARGET_SCHED_VARIABLE_ISSUE
00895 #define TARGET_SCHED_VARIABLE_ISSUE ix86_variable_issue
00896 #undef TARGET_SCHED_INIT
00897 #define TARGET_SCHED_INIT ix86_sched_init
00898 #undef TARGET_SCHED_REORDER
00899 #define TARGET_SCHED_REORDER ix86_sched_reorder
00900 #undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
00901 #define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE \
00902 ia32_use_dfa_pipeline_interface
00903 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
00904 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
00905 ia32_multipass_dfa_lookahead
00906
00907 #ifdef HAVE_AS_TLS
00908 #undef TARGET_HAVE_TLS
00909 #define TARGET_HAVE_TLS true
00910 #endif
00911 #undef TARGET_CANNOT_FORCE_CONST_MEM
00912 #define TARGET_CANNOT_FORCE_CONST_MEM ix86_cannot_force_const_mem
00913
00914 #undef TARGET_ASM_OUTPUT_MI_THUNK
00915 #define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
00916 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
00917 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK x86_can_output_mi_thunk
00918
00919 struct gcc_target targetm = TARGET_INITIALIZER;
00920
00921
00922
00923 #ifndef DEFAULT_PCC_STRUCT_RETURN
00924 #define DEFAULT_PCC_STRUCT_RETURN 1
00925 #endif
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936 void
00937 override_options ()
00938 {
00939 int i;
00940
00941 #define MAX_CODE_ALIGN 16
00942
00943 static struct ptt
00944 {
00945 const struct processor_costs *cost;
00946 const int target_enable;
00947 const int target_disable;
00948 const int align_loop;
00949 const int align_loop_max_skip;
00950 const int align_jump;
00951 const int align_jump_max_skip;
00952 const int align_func;
00953 const int branch_cost;
00954 }
00955 const processor_target_table[PROCESSOR_max] =
00956 {
00957 {&i386_cost, 0, 0, 4, 3, 4, 3, 4, 1},
00958 {&i486_cost, 0, 0, 16, 15, 16, 15, 16, 1},
00959 {&pentium_cost, 0, 0, 16, 7, 16, 7, 16, 1},
00960 {&pentiumpro_cost, 0, 0, 16, 15, 16, 7, 16, 1},
00961 {&k6_cost, 0, 0, 32, 7, 32, 7, 32, 1},
00962 {&athlon_cost, 0, 0, 16, 7, 64, 7, 16, 1},
00963 {&pentium4_cost, 0, 0, 0, 0, 0, 0, 0, 1}
00964 };
00965
00966 static const char * const cpu_names[] = TARGET_CPU_DEFAULT_NAMES;
00967 static struct pta
00968 {
00969 const char *const name;
00970 const enum processor_type processor;
00971 const enum pta_flags
00972 {
00973 PTA_SSE = 1,
00974 PTA_SSE2 = 2,
00975 PTA_MMX = 4,
00976 PTA_PREFETCH_SSE = 8,
00977 PTA_3DNOW = 16,
00978 PTA_3DNOW_A = 64
00979 } flags;
00980 }
00981 const processor_alias_table[] =
00982 {
00983 {"i386", PROCESSOR_I386, 0},
00984 {"i486", PROCESSOR_I486, 0},
00985 {"i586", PROCESSOR_PENTIUM, 0},
00986 {"pentium", PROCESSOR_PENTIUM, 0},
00987 {"pentium-mmx", PROCESSOR_PENTIUM, PTA_MMX},
00988 {"winchip-c6", PROCESSOR_I486, PTA_MMX},
00989 {"winchip2", PROCESSOR_I486, PTA_MMX | PTA_3DNOW},
00990 {"c3", PROCESSOR_I486, PTA_MMX | PTA_3DNOW},
00991 {"i686", PROCESSOR_PENTIUMPRO, 0},
00992 {"pentiumpro", PROCESSOR_PENTIUMPRO, 0},
00993 {"pentium2", PROCESSOR_PENTIUMPRO, PTA_MMX},
00994 {"pentium3", PROCESSOR_PENTIUMPRO, PTA_MMX | PTA_SSE | PTA_PREFETCH_SSE},
00995 {"pentium4", PROCESSOR_PENTIUM4, PTA_SSE | PTA_SSE2 |
00996 PTA_MMX | PTA_PREFETCH_SSE},
00997 {"k6", PROCESSOR_K6, PTA_MMX},
00998 {"k6-2", PROCESSOR_K6, PTA_MMX | PTA_3DNOW},
00999 {"k6-3", PROCESSOR_K6, PTA_MMX | PTA_3DNOW},
01000 {"athlon", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
01001 | PTA_3DNOW_A},
01002 {"athlon-tbird", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE
01003 | PTA_3DNOW | PTA_3DNOW_A},
01004 {"athlon-4", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
01005 | PTA_3DNOW_A | PTA_SSE},
01006 {"athlon-xp", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
01007 | PTA_3DNOW_A | PTA_SSE},
01008 {"athlon-mp", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
01009 | PTA_3DNOW_A | PTA_SSE},
01010 };
01011
01012 int const pta_size = ARRAY_SIZE (processor_alias_table);
01013
01014
01015
01016 real_format_for_mode[XFmode - QFmode] = &ieee_extended_intel_96_format;
01017 real_format_for_mode[TFmode - QFmode] = &ieee_extended_intel_128_format;
01018
01019
01020
01021 if (TARGET_64BIT)
01022 {
01023 if (flag_omit_frame_pointer == 2)
01024 flag_omit_frame_pointer = 1;
01025 if (flag_asynchronous_unwind_tables == 2)
01026 flag_asynchronous_unwind_tables = 1;
01027 if (flag_pcc_struct_return == 2)
01028 flag_pcc_struct_return = 0;
01029 }
01030 else
01031 {
01032 if (flag_omit_frame_pointer == 2)
01033 flag_omit_frame_pointer = 0;
01034 if (flag_asynchronous_unwind_tables == 2)
01035 flag_asynchronous_unwind_tables = 0;
01036 if (flag_pcc_struct_return == 2)
01037 flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN;
01038 }
01039
01040 #ifdef SUBTARGET_OVERRIDE_OPTIONS
01041 SUBTARGET_OVERRIDE_OPTIONS;
01042 #endif
01043
01044 if (!ix86_cpu_string && ix86_arch_string)
01045 ix86_cpu_string = ix86_arch_string;
01046 if (!ix86_cpu_string)
01047 ix86_cpu_string = cpu_names [TARGET_CPU_DEFAULT];
01048 if (!ix86_arch_string)
01049 ix86_arch_string = TARGET_64BIT ? "athlon-4" : "i386";
01050
01051 if (ix86_cmodel_string != 0)
01052 {
01053 if (!strcmp (ix86_cmodel_string, "small"))
01054 ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
01055 else if (flag_pic)
01056 sorry ("code model %s not supported in PIC mode", ix86_cmodel_string);
01057 else if (!strcmp (ix86_cmodel_string, "32"))
01058 ix86_cmodel = CM_32;
01059 else if (!strcmp (ix86_cmodel_string, "kernel") && !flag_pic)
01060 ix86_cmodel = CM_KERNEL;
01061 else if (!strcmp (ix86_cmodel_string, "medium") && !flag_pic)
01062 ix86_cmodel = CM_MEDIUM;
01063 else if (!strcmp (ix86_cmodel_string, "large") && !flag_pic)
01064 ix86_cmodel = CM_LARGE;
01065 else
01066 error ("bad value (%s) for -mcmodel= switch", ix86_cmodel_string);
01067 }
01068 else
01069 {
01070 ix86_cmodel = CM_32;
01071 if (TARGET_64BIT)
01072 ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
01073 }
01074 if (ix86_asm_string != 0)
01075 {
01076 if (!strcmp (ix86_asm_string, "intel"))
01077 ix86_asm_dialect = ASM_INTEL;
01078 else if (!strcmp (ix86_asm_string, "att"))
01079 ix86_asm_dialect = ASM_ATT;
01080 else
01081 error ("bad value (%s) for -masm= switch", ix86_asm_string);
01082 }
01083 if ((TARGET_64BIT == 0) != (ix86_cmodel == CM_32))
01084 error ("code model `%s' not supported in the %s bit mode",
01085 ix86_cmodel_string, TARGET_64BIT ? "64" : "32");
01086 if (ix86_cmodel == CM_LARGE)
01087 sorry ("code model `large' not supported yet");
01088 if ((TARGET_64BIT != 0) != ((target_flags & MASK_64BIT) != 0))
01089 sorry ("%i-bit mode not compiled in",
01090 (target_flags & MASK_64BIT) ? 64 : 32);
01091
01092 for (i = 0; i < pta_size; i++)
01093 if (! strcmp (ix86_arch_string, processor_alias_table[i].name))
01094 {
01095 ix86_arch = processor_alias_table[i].processor;
01096
01097 ix86_cpu = ix86_arch;
01098 if (processor_alias_table[i].flags & PTA_MMX
01099 && !(target_flags_explicit & MASK_MMX))
01100 target_flags |= MASK_MMX;
01101 if (processor_alias_table[i].flags & PTA_3DNOW
01102 && !(target_flags_explicit & MASK_3DNOW))
01103 target_flags |= MASK_3DNOW;
01104 if (processor_alias_table[i].flags & PTA_3DNOW_A
01105 && !(target_flags_explicit & MASK_3DNOW_A))
01106 target_flags |= MASK_3DNOW_A;
01107 if (processor_alias_table[i].flags & PTA_SSE
01108 && !(target_flags_explicit & MASK_SSE))
01109 target_flags |= MASK_SSE;
01110 if (processor_alias_table[i].flags & PTA_SSE2
01111 && !(target_flags_explicit & MASK_SSE2))
01112 target_flags |= MASK_SSE2;
01113 if (processor_alias_table[i].flags & PTA_PREFETCH_SSE)
01114 x86_prefetch_sse = true;
01115 break;
01116 }
01117
01118 if (i == pta_size)
01119 error ("bad value (%s) for -march= switch", ix86_arch_string);
01120
01121 for (i = 0; i < pta_size; i++)
01122 if (! strcmp (ix86_cpu_string, processor_alias_table[i].name))
01123 {
01124 ix86_cpu = processor_alias_table[i].processor;
01125 break;
01126 }
01127 if (processor_alias_table[i].flags & PTA_PREFETCH_SSE)
01128 x86_prefetch_sse = true;
01129 if (i == pta_size)
01130 error ("bad value (%s) for -mcpu= switch", ix86_cpu_string);
01131
01132 if (optimize_size)
01133 ix86_cost = &size_cost;
01134 else
01135 ix86_cost = processor_target_table[ix86_cpu].cost;
01136 target_flags |= processor_target_table[ix86_cpu].target_enable;
01137 target_flags &= ~processor_target_table[ix86_cpu].target_disable;
01138
01139
01140 init_machine_status = ix86_init_machine_status;
01141
01142
01143 if (ix86_regparm_string)
01144 {
01145 i = atoi (ix86_regparm_string);
01146 if (i < 0 || i > REGPARM_MAX)
01147 error ("-mregparm=%d is not between 0 and %d", i, REGPARM_MAX);
01148 else
01149 ix86_regparm = i;
01150 }
01151 else
01152 if (TARGET_64BIT)
01153 ix86_regparm = REGPARM_MAX;
01154
01155
01156
01157
01158 if (ix86_align_loops_string)
01159 {
01160 warning ("-malign-loops is obsolete, use -falign-loops");
01161 if (align_loops == 0)
01162 {
01163 i = atoi (ix86_align_loops_string);
01164 if (i < 0 || i > MAX_CODE_ALIGN)
01165 error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
01166 else
01167 align_loops = 1 << i;
01168 }
01169 }
01170
01171 if (ix86_align_jumps_string)
01172 {
01173 warning ("-malign-jumps is obsolete, use -falign-jumps");
01174 if (align_jumps == 0)
01175 {
01176 i = atoi (ix86_align_jumps_string);
01177 if (i < 0 || i > MAX_CODE_ALIGN)
01178 error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
01179 else
01180 align_jumps = 1 << i;
01181 }
01182 }
01183
01184 if (ix86_align_funcs_string)
01185 {
01186 warning ("-malign-functions is obsolete, use -falign-functions");
01187 if (align_functions == 0)
01188 {
01189 i = atoi (ix86_align_funcs_string);
01190 if (i < 0 || i > MAX_CODE_ALIGN)
01191 error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
01192 else
01193 align_functions = 1 << i;
01194 }
01195 }
01196
01197
01198 if (align_loops == 0)
01199 {
01200 align_loops = processor_target_table[ix86_cpu].align_loop;
01201 align_loops_max_skip = processor_target_table[ix86_cpu].align_loop_max_skip;
01202 }
01203 if (align_jumps == 0)
01204 {
01205 align_jumps = processor_target_table[ix86_cpu].align_jump;
01206 align_jumps_max_skip = processor_target_table[ix86_cpu].align_jump_max_skip;
01207 }
01208 if (align_functions == 0)
01209 {
01210 align_functions = processor_target_table[ix86_cpu].align_func;
01211 }
01212
01213
01214
01215
01216
01217 ix86_preferred_stack_boundary = (optimize_size
01218 ? TARGET_64BIT ? 128 : 32
01219 : 128);
01220 if (ix86_preferred_stack_boundary_string)
01221 {
01222 i = atoi (ix86_preferred_stack_boundary_string);
01223 if (i < (TARGET_64BIT ? 4 : 2) || i > 12)
01224 error ("-mpreferred-stack-boundary=%d is not between %d and 12", i,
01225 TARGET_64BIT ? 4 : 2);
01226 else
01227 ix86_preferred_stack_boundary = (1 << i) * BITS_PER_UNIT;
01228 }
01229
01230
01231 ix86_branch_cost = processor_target_table[ix86_cpu].branch_cost;
01232 if (ix86_branch_cost_string)
01233 {
01234 i = atoi (ix86_branch_cost_string);
01235 if (i < 0 || i > 5)
01236 error ("-mbranch-cost=%d is not between 0 and 5", i);
01237 else
01238 ix86_branch_cost = i;
01239 }
01240
01241 if (ix86_tls_dialect_string)
01242 {
01243 if (strcmp (ix86_tls_dialect_string, "gnu") == 0)
01244 ix86_tls_dialect = TLS_DIALECT_GNU;
01245 else if (strcmp (ix86_tls_dialect_string, "sun") == 0)
01246 ix86_tls_dialect = TLS_DIALECT_SUN;
01247 else
01248 error ("bad value (%s) for -mtls-dialect= switch",
01249 ix86_tls_dialect_string);
01250 }
01251
01252
01253 if (TARGET_OMIT_LEAF_FRAME_POINTER)
01254 flag_omit_frame_pointer = 1;
01255
01256
01257
01258 if (flag_unsafe_math_optimizations)
01259 target_flags &= ~MASK_IEEE_FP;
01260
01261
01262
01263 if (x86_arch_always_fancy_math_387 & (1 << ix86_arch))
01264 target_flags &= ~MASK_NO_FANCY_MATH_387;
01265
01266
01267 if (TARGET_PNI)
01268 target_flags |= MASK_SSE2;
01269
01270
01271 if (TARGET_SSE2)
01272 target_flags |= MASK_SSE;
01273
01274 if (TARGET_64BIT)
01275 {
01276 if (TARGET_ALIGN_DOUBLE)
01277 error ("-malign-double makes no sense in the 64bit mode");
01278 if (TARGET_RTD)
01279 error ("-mrtd calling convention not supported in the 64bit mode");
01280
01281 target_flags |= (MASK_SSE2 | MASK_SSE | MASK_MMX | MASK_128BIT_LONG_DOUBLE);
01282 ix86_fpmath = FPMATH_SSE;
01283 }
01284 else
01285 ix86_fpmath = FPMATH_387;
01286
01287 if (ix86_fpmath_string != 0)
01288 {
01289 if (! strcmp (ix86_fpmath_string, "387"))
01290 ix86_fpmath = FPMATH_387;
01291 else if (! strcmp (ix86_fpmath_string, "sse"))
01292 {
01293 if (!TARGET_SSE)
01294 {
01295 warning ("SSE instruction set disabled, using 387 arithmetics");
01296 ix86_fpmath = FPMATH_387;
01297 }
01298 else
01299 ix86_fpmath = FPMATH_SSE;
01300 }
01301 else if (! strcmp (ix86_fpmath_string, "387,sse")
01302 || ! strcmp (ix86_fpmath_string, "sse,387"))
01303 {
01304 if (!TARGET_SSE)
01305 {
01306 warning ("SSE instruction set disabled, using 387 arithmetics");
01307 ix86_fpmath = FPMATH_387;
01308 }
01309 else if (!TARGET_80387)
01310 {
01311 warning ("387 instruction set disabled, using SSE arithmetics");
01312 ix86_fpmath = FPMATH_SSE;
01313 }
01314 else
01315 ix86_fpmath = FPMATH_SSE | FPMATH_387;
01316 }
01317 else
01318 error ("bad value (%s) for -mfpmath= switch", ix86_fpmath_string);
01319 }
01320
01321
01322
01323 if (TARGET_SSE)
01324 {
01325 target_flags |= MASK_MMX;
01326 x86_prefetch_sse = true;
01327 }
01328
01329
01330 if (TARGET_3DNOW)
01331 {
01332 target_flags |= MASK_MMX;
01333
01334
01335 if (x86_3dnow_a & (1 << ix86_arch))
01336 target_flags |= MASK_3DNOW_A;
01337 }
01338 if ((x86_accumulate_outgoing_args & CPUMASK)
01339 && !(target_flags_explicit & MASK_ACCUMULATE_OUTGOING_ARGS)
01340 && !optimize_size)
01341 target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
01342
01343
01344 {
01345 char *p;
01346 ASM_GENERATE_INTERNAL_LABEL (internal_label_prefix, "LX", 0);
01347 p = strchr (internal_label_prefix, 'X');
01348 internal_label_prefix_len = p - internal_label_prefix;
01349 *p = '\0';
01350 }
01351 }
01352
01353 void
01354 optimization_options (level, size)
01355 int level;
01356 int size ATTRIBUTE_UNUSED;
01357 {
01358
01359
01360 #ifdef INSN_SCHEDULING
01361 if (level > 1)
01362 flag_schedule_insns = 0;
01363 #endif
01364
01365
01366
01367
01368
01369 if (optimize >= 1)
01370 flag_omit_frame_pointer = 2;
01371 flag_pcc_struct_return = 2;
01372 flag_asynchronous_unwind_tables = 2;
01373 }
01374
01375
01376 const struct attribute_spec ix86_attribute_table[] =
01377 {
01378
01379
01380
01381 { "stdcall", 0, 0, false, true, true, ix86_handle_cdecl_attribute },
01382
01383 { "cdecl", 0, 0, false, true, true, ix86_handle_cdecl_attribute },
01384
01385
01386 { "regparm", 1, 1, false, true, true, ix86_handle_regparm_attribute },
01387 #ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
01388 { "dllimport", 0, 0, false, false, false, ix86_handle_dll_attribute },
01389 { "dllexport", 0, 0, false, false, false, ix86_handle_dll_attribute },
01390 { "shared", 0, 0, true, false, false, ix86_handle_shared_attribute },
01391 #endif
01392 { NULL, 0, 0, false, false, false, NULL }
01393 };
01394
01395
01396
01397 static tree
01398 ix86_handle_cdecl_attribute (node, name, args, flags, no_add_attrs)
01399 tree *node;
01400 tree name;
01401 tree args ATTRIBUTE_UNUSED;
01402 int flags ATTRIBUTE_UNUSED;
01403 bool *no_add_attrs;
01404 {
01405 if (TREE_CODE (*node) != FUNCTION_TYPE
01406 && TREE_CODE (*node) != METHOD_TYPE
01407 && TREE_CODE (*node) != FIELD_DECL
01408 && TREE_CODE (*node) != TYPE_DECL)
01409 {
01410 warning ("`%s' attribute only applies to functions",
01411 IDENTIFIER_POINTER (name));
01412 *no_add_attrs = true;
01413 }
01414
01415 if (TARGET_64BIT)
01416 {
01417 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
01418 *no_add_attrs = true;
01419 }
01420
01421 return NULL_TREE;
01422 }
01423
01424
01425
01426 static tree
01427 ix86_handle_regparm_attribute (node, name, args, flags, no_add_attrs)
01428 tree *node;
01429 tree name;
01430 tree args;
01431 int flags ATTRIBUTE_UNUSED;
01432 bool *no_add_attrs;
01433 {
01434 if (TREE_CODE (*node) != FUNCTION_TYPE
01435 && TREE_CODE (*node) != METHOD_TYPE
01436 && TREE_CODE (*node) != FIELD_DECL
01437 && TREE_CODE (*node) != TYPE_DECL)
01438 {
01439 warning ("`%s' attribute only applies to functions",
01440 IDENTIFIER_POINTER (name));
01441 *no_add_attrs = true;
01442 }
01443 else
01444 {
01445 tree cst;
01446
01447 cst = TREE_VALUE (args);
01448 if (TREE_CODE (cst) != INTEGER_CST)
01449 {
01450 warning ("`%s' attribute requires an integer constant argument",
01451 IDENTIFIER_POINTER (name));
01452 *no_add_attrs = true;
01453 }
01454 else if (compare_tree_int (cst, REGPARM_MAX) > 0)
01455 {
01456 warning ("argument to `%s' attribute larger than %d",
01457 IDENTIFIER_POINTER (name), REGPARM_MAX);
01458 *no_add_attrs = true;
01459 }
01460 }
01461
01462 return NULL_TREE;
01463 }
01464
01465
01466
01467
01468
01469 static int
01470 ix86_comp_type_attributes (type1, type2)
01471 tree type1;
01472 tree type2;
01473 {
01474
01475 const char *const rtdstr = TARGET_RTD ? "cdecl" : "stdcall";
01476
01477 if (TREE_CODE (type1) != FUNCTION_TYPE)
01478 return 1;
01479
01480
01481 if (!lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type1))
01482 != !lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type2)))
01483 return 0;
01484 return 1;
01485 }
01486
01487
01488
01489 static int
01490 ix86_fntype_regparm (type)
01491 tree type;
01492 {
01493 tree attr;
01494
01495 attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
01496 if (attr)
01497 return TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
01498 else
01499 return ix86_regparm;
01500 }
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519 int
01520 ix86_return_pops_args (fundecl, funtype, size)
01521 tree fundecl;
01522 tree funtype;
01523 int size;
01524 {
01525 int rtd = TARGET_RTD && (!fundecl || TREE_CODE (fundecl) != IDENTIFIER_NODE);
01526
01527
01528 if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))) {
01529
01530
01531 if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)))
01532 rtd = 1;
01533
01534 if (rtd
01535 && (TYPE_ARG_TYPES (funtype) == NULL_TREE
01536 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype)))
01537 == void_type_node)))
01538 return size;
01539 }
01540
01541
01542 if (aggregate_value_p (TREE_TYPE (funtype))
01543 && !TARGET_64BIT)
01544 {
01545 int nregs = ix86_fntype_regparm (funtype);
01546
01547 if (!nregs)
01548 return GET_MODE_SIZE (Pmode);
01549 }
01550
01551 return 0;
01552 }
01553
01554
01555
01556
01557 bool
01558 ix86_function_arg_regno_p (regno)
01559 int regno;
01560 {
01561 int i;
01562 if (!TARGET_64BIT)
01563 return (regno < REGPARM_MAX
01564 || (TARGET_SSE && SSE_REGNO_P (regno) && !fixed_regs[regno]));
01565 if (SSE_REGNO_P (regno) && TARGET_SSE)
01566 return true;
01567
01568 if (!regno)
01569 return true;
01570 for (i = 0; i < REGPARM_MAX; i++)
01571 if (regno == x86_64_int_parameter_registers[i])
01572 return true;
01573 return false;
01574 }
01575
01576
01577
01578
01579
01580 void
01581 init_cumulative_args (cum, fntype, libname)
01582 CUMULATIVE_ARGS *cum;
01583 tree fntype;
01584 rtx libname;
01585 {
01586 static CUMULATIVE_ARGS zero_cum;
01587 tree param, next_param;
01588
01589 if (TARGET_DEBUG_ARG)
01590 {
01591 fprintf (stderr, "\ninit_cumulative_args (");
01592 if (fntype)
01593 fprintf (stderr, "fntype code = %s, ret code = %s",
01594 tree_code_name[(int) TREE_CODE (fntype)],
01595 tree_code_name[(int) TREE_CODE (TREE_TYPE (fntype))]);
01596 else
01597 fprintf (stderr, "no fntype");
01598
01599 if (libname)
01600 fprintf (stderr, ", libname = %s", XSTR (libname, 0));
01601 }
01602
01603 *cum = zero_cum;
01604
01605
01606 cum->nregs = ix86_regparm;
01607 cum->sse_nregs = SSE_REGPARM_MAX;
01608 if (fntype && !TARGET_64BIT)
01609 {
01610 tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype));
01611
01612 if (attr)
01613 cum->nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
01614 }
01615 cum->maybe_vaarg = false;
01616
01617
01618
01619
01620
01621
01622 if (cum->nregs)
01623 {
01624 for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
01625 param != 0; param = next_param)
01626 {
01627 next_param = TREE_CHAIN (param);
01628 if (next_param == 0 && TREE_VALUE (param) != void_type_node)
01629 {
01630 if (!TARGET_64BIT)
01631 cum->nregs = 0;
01632 cum->maybe_vaarg = true;
01633 }
01634 }
01635 }
01636 if ((!fntype && !libname)
01637 || (fntype && !TYPE_ARG_TYPES (fntype)))
01638 cum->maybe_vaarg = 1;
01639
01640 if (TARGET_DEBUG_ARG)
01641 fprintf (stderr, ", nregs=%d )\n", cum->nregs);
01642
01643 return;
01644 }
01645
01646
01647
01648
01649
01650
01651
01652
01653 static enum x86_64_reg_class
01654 merge_classes (class1, class2)
01655 enum x86_64_reg_class class1, class2;
01656 {
01657
01658 if (class1 == class2)
01659 return class1;
01660
01661
01662
01663 if (class1 == X86_64_NO_CLASS)
01664 return class2;
01665 if (class2 == X86_64_NO_CLASS)
01666 return class1;
01667
01668
01669 if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
01670 return X86_64_MEMORY_CLASS;
01671
01672
01673 if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
01674 || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
01675 return X86_64_INTEGERSI_CLASS;
01676 if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
01677 || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
01678 return X86_64_INTEGER_CLASS;
01679
01680
01681 if (class1 == X86_64_X87_CLASS || class1 == X86_64_X87UP_CLASS
01682 || class2 == X86_64_X87_CLASS || class2 == X86_64_X87UP_CLASS)
01683 return X86_64_MEMORY_CLASS;
01684
01685
01686 return X86_64_SSE_CLASS;
01687 }
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701 static int
01702 classify_argument (mode, type, classes, bit_offset)
01703 enum machine_mode mode;
01704 tree type;
01705 enum x86_64_reg_class classes[MAX_CLASSES];
01706 int bit_offset;
01707 {
01708 #ifdef KEY
01709
01710
01711
01712 HOST_WIDE_INT bytes =
01713 #else
01714 int bytes =
01715 #endif
01716 (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
01717 int words = (bytes + (bit_offset % 64) / 8 + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
01718
01719
01720 if (bytes < 0)
01721 return 0;
01722
01723 if (type && AGGREGATE_TYPE_P (type))
01724 {
01725 int i;
01726 tree field;
01727 enum x86_64_reg_class subclasses[MAX_CLASSES];
01728
01729
01730 if (bytes > 16)
01731 return 0;
01732
01733 for (i = 0; i < words; i++)
01734 classes[i] = X86_64_NO_CLASS;
01735
01736
01737
01738 if (!words)
01739 {
01740 classes[0] = X86_64_NO_CLASS;
01741 return 1;
01742 }
01743
01744
01745 if (TREE_CODE (type) == RECORD_TYPE)
01746 {
01747
01748 if (TYPE_BINFO (type) != NULL && TYPE_BINFO_BASETYPES (type) != NULL)
01749 {
01750 tree bases = TYPE_BINFO_BASETYPES (type);
01751 int n_bases = TREE_VEC_LENGTH (bases);
01752 int i;
01753
01754 for (i = 0; i < n_bases; ++i)
01755 {
01756 #ifdef KEY
01757 int j;
01758 #endif
01759 tree binfo = TREE_VEC_ELT (bases, i);
01760 int num;
01761 int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8;
01762 tree type = BINFO_TYPE (binfo);
01763
01764 num = classify_argument (TYPE_MODE (type),
01765 type, subclasses,
01766 (offset + bit_offset) % 256);
01767 if (!num)
01768 return 0;
01769
01770 #ifdef KEY
01771 for (j = 0; j < num; j++)
01772 {
01773 int pos = (offset + (bit_offset % 64)) / 8 / 8;
01774 classes[j + pos] =
01775 merge_classes (subclasses[j], classes[j + pos]);
01776 }
01777 #else
01778 for (i = 0; i < num; i++)
01779 {
01780 int pos = (offset + (bit_offset % 64)) / 8 / 8;
01781 classes[i + pos] =
01782 merge_classes (subclasses[i], classes[i + pos]);
01783 }
01784 #endif
01785 }
01786 }
01787
01788 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
01789 {
01790 if (TREE_CODE (field) == FIELD_DECL)
01791 {
01792 int num;
01793
01794
01795
01796
01797 if (DECL_BIT_FIELD (field))
01798 {
01799 for (i = int_bit_position (field) / 8 / 8;
01800 i < (int_bit_position (field)
01801 + tree_low_cst (DECL_SIZE (field), 0)
01802 + 63) / 8 / 8; i++)
01803 classes[i] =
01804 merge_classes (X86_64_INTEGER_CLASS,
01805 classes[i]);
01806 }
01807 else
01808 {
01809 num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
01810 TREE_TYPE (field), subclasses,
01811 (int_bit_position (field)
01812 + bit_offset) % 256);
01813 if (!num)
01814 return 0;
01815 for (i = 0; i < num; i++)
01816 {
01817 int pos =
01818 (int_bit_position (field) + (bit_offset % 64)) / 8 / 8;
01819 classes[i + pos] =
01820 merge_classes (subclasses[i], classes[i + pos]);
01821 }
01822 }
01823 }
01824 }
01825 }
01826
01827 else if (TREE_CODE (type) == ARRAY_TYPE)
01828 {
01829 int num;
01830 num = classify_argument (TYPE_MODE (TREE_TYPE (type)),
01831 TREE_TYPE (type), subclasses, bit_offset);
01832 if (!num)
01833 return 0;
01834
01835
01836 if (subclasses[0] == X86_64_SSESF_CLASS && bytes != 4)
01837 subclasses[0] = X86_64_SSE_CLASS;
01838 if (subclasses[0] == X86_64_INTEGERSI_CLASS && bytes != 4)
01839 subclasses[0] = X86_64_INTEGER_CLASS;
01840
01841 for (i = 0; i < words; i++)
01842 classes[i] = subclasses[i % num];
01843 }
01844
01845 else if (TREE_CODE (type) == UNION_TYPE
01846 || TREE_CODE (type) == QUAL_UNION_TYPE)
01847 {
01848
01849 if (TYPE_BINFO (type) != NULL && TYPE_BINFO_BASETYPES (type) != NULL)
01850 {
01851 tree bases = TYPE_BINFO_BASETYPES (type);
01852 int n_bases = TREE_VEC_LENGTH (bases);
01853 int i;
01854
01855 for (i = 0; i < n_bases; ++i)
01856 {
01857 tree binfo = TREE_VEC_ELT (bases, i);
01858 #ifdef KEY
01859 int j;
01860 #endif
01861 int num;
01862 int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8;
01863 tree type = BINFO_TYPE (binfo);
01864
01865 num = classify_argument (TYPE_MODE (type),
01866 type, subclasses,
01867 (offset + (bit_offset % 64)) % 256);
01868 if (!num)
01869 return 0;
01870 #ifdef KEY
01871 for (j = 0; j < num; j++)
01872 {
01873 int pos = (offset + (bit_offset % 64)) / 8 / 8;
01874 classes[j + pos] =
01875 merge_classes (subclasses[j], classes[j + pos]);
01876 }
01877 #else
01878 for (i = 0; i < num; i++)
01879 {
01880 int pos = (offset + (bit_offset % 64)) / 8 / 8;
01881 classes[i + pos] =
01882 merge_classes (subclasses[i], classes[i + pos]);
01883 }
01884 #endif
01885 }
01886 }
01887 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
01888 {
01889 if (TREE_CODE (field) == FIELD_DECL)
01890 {
01891 int num;
01892 num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
01893 TREE_TYPE (field), subclasses,
01894 bit_offset);
01895 if (!num)
01896 return 0;
01897 for (i = 0; i < num; i++)
01898 classes[i] = merge_classes (subclasses[i], classes[i]);
01899 }
01900 }
01901 }
01902 else
01903 abort ();
01904
01905
01906 for (i = 0; i < words; i++)
01907 {
01908
01909
01910 if (classes[i] == X86_64_MEMORY_CLASS)
01911 return 0;
01912
01913
01914
01915 if (classes[i] == X86_64_SSEUP_CLASS
01916 && (i == 0 || classes[i - 1] != X86_64_SSE_CLASS))
01917 classes[i] = X86_64_SSE_CLASS;
01918
01919
01920 if (classes[i] == X86_64_X87UP_CLASS
01921 && (i == 0 || classes[i - 1] != X86_64_X87_CLASS))
01922 classes[i] = X86_64_SSE_CLASS;
01923 }
01924 return words;
01925 }
01926
01927
01928
01929 if (mode != VOIDmode && mode != BLKmode)
01930 {
01931 int mode_alignment = GET_MODE_BITSIZE (mode);
01932
01933 if (mode == XFmode)
01934 mode_alignment = 128;
01935 else if (mode == XCmode)
01936 mode_alignment = 256;
01937
01938 if (bit_offset % mode_alignment)
01939 return 0;
01940 }
01941
01942
01943 switch (mode)
01944 {
01945 case DImode:
01946 case SImode:
01947 case HImode:
01948 case QImode:
01949 case CSImode:
01950 case CHImode:
01951 case CQImode:
01952 if (bit_offset + GET_MODE_BITSIZE (mode) <= 32)
01953 classes[0] = X86_64_INTEGERSI_CLASS;
01954 else
01955 classes[0] = X86_64_INTEGER_CLASS;
01956 return 1;
01957 case CDImode:
01958 case TImode:
01959 classes[0] = classes[1] = X86_64_INTEGER_CLASS;
01960 return 2;
01961 case CTImode:
01962 classes[0] = classes[1] = X86_64_INTEGER_CLASS;
01963 classes[2] = classes[3] = X86_64_INTEGER_CLASS;
01964 return 4;
01965 case SFmode:
01966 if (!(bit_offset % 64))
01967 classes[0] = X86_64_SSESF_CLASS;
01968 else
01969 classes[0] = X86_64_SSE_CLASS;
01970 return 1;
01971 case DFmode:
01972 classes[0] = X86_64_SSEDF_CLASS;
01973 return 1;
01974 case TFmode:
01975 classes[0] = X86_64_X87_CLASS;
01976 classes[1] = X86_64_X87UP_CLASS;
01977 return 2;
01978 case TCmode:
01979 classes[0] = X86_64_X87_CLASS;
01980 classes[1] = X86_64_X87UP_CLASS;
01981 classes[2] = X86_64_X87_CLASS;
01982 classes[3] = X86_64_X87UP_CLASS;
01983 return 4;
01984 case DCmode:
01985 classes[0] = X86_64_SSEDF_CLASS;
01986 classes[1] = X86_64_SSEDF_CLASS;
01987 return 2;
01988 case SCmode:
01989 classes[0] = X86_64_SSE_CLASS;
01990 return 1;
01991 case V4SFmode:
01992 case V4SImode:
01993 case V16QImode:
01994 case V8HImode:
01995 case V2DFmode:
01996 case V2DImode:
01997 classes[0] = X86_64_SSE_CLASS;
01998 classes[1] = X86_64_SSEUP_CLASS;
01999 return 2;
02000 case V2SFmode:
02001 case V2SImode:
02002 case V4HImode:
02003 case V8QImode:
02004 return 0;
02005 case BLKmode:
02006 case VOIDmode:
02007 return 0;
02008 default:
02009 abort ();
02010 }
02011 }
02012
02013
02014
02015 static int
02016 examine_argument (mode, type, in_return, int_nregs, sse_nregs)
02017 enum machine_mode mode;
02018 tree type;
02019 int *int_nregs, *sse_nregs;
02020 int in_return;
02021 {
02022 enum x86_64_reg_class class[MAX_CLASSES];
02023 int n = classify_argument (mode, type, class, 0);
02024
02025 *int_nregs = 0;
02026 *sse_nregs = 0;
02027 if (!n)
02028 return 0;
02029 for (n--; n >= 0; n--)
02030 switch (class[n])
02031 {
02032 case X86_64_INTEGER_CLASS:
02033 case X86_64_INTEGERSI_CLASS:
02034 (*int_nregs)++;
02035 break;
02036 case X86_64_SSE_CLASS:
02037 case X86_64_SSESF_CLASS:
02038 case X86_64_SSEDF_CLASS:
02039 (*sse_nregs)++;
02040 break;
02041 case X86_64_NO_CLASS:
02042 case X86_64_SSEUP_CLASS:
02043 break;
02044 case X86_64_X87_CLASS:
02045 case X86_64_X87UP_CLASS:
02046 if (!in_return)
02047 return 0;
02048 break;
02049 case X86_64_MEMORY_CLASS:
02050 abort ();
02051 }
02052 return 1;
02053 }
02054
02055
02056 static rtx
02057 construct_container (mode, type, in_return, nintregs, nsseregs, intreg, sse_regno)
02058 enum machine_mode mode;
02059 tree type;
02060 int in_return;
02061 int nintregs, nsseregs;
02062 const int * intreg;
02063 int sse_regno;
02064 {
02065 enum machine_mode tmpmode;
02066 int bytes =
02067 (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
02068 enum x86_64_reg_class class[MAX_CLASSES];
02069 int n;
02070 int i;
02071 int nexps = 0;
02072 int needed_sseregs, needed_intregs;
02073 rtx exp[MAX_CLASSES];
02074 rtx ret;
02075
02076 n = classify_argument (mode, type, class, 0);
02077 if (TARGET_DEBUG_ARG)
02078 {
02079 if (!n)
02080 fprintf (stderr, "Memory class\n");
02081 else
02082 {
02083 fprintf (stderr, "Classes:");
02084 for (i = 0; i < n; i++)
02085 {
02086 fprintf (stderr, " %s", x86_64_reg_class_name[class[i]]);
02087 }
02088 fprintf (stderr, "\n");
02089 }
02090 }
02091 if (!n)
02092 return NULL;
02093 if (!examine_argument (mode, type, in_return, &needed_intregs, &needed_sseregs))
02094 return NULL;
02095 if (needed_intregs > nintregs || needed_sseregs > nsseregs)
02096 return NULL;
02097
02098
02099
02100 if (n == 1 && mode != SCmode)
02101 switch (class[0])
02102 {
02103 case X86_64_INTEGER_CLASS:
02104 case X86_64_INTEGERSI_CLASS:
02105 return gen_rtx_REG (mode, intreg[0]);
02106 case X86_64_SSE_CLASS:
02107 case X86_64_SSESF_CLASS:
02108 case X86_64_SSEDF_CLASS:
02109 return gen_rtx_REG (mode, SSE_REGNO (sse_regno));
02110 case X86_64_X87_CLASS:
02111 return gen_rtx_REG (mode, FIRST_STACK_REG);
02112 case X86_64_NO_CLASS:
02113
02114 return NULL;
02115 default:
02116 abort ();
02117 }
02118 if (n == 2 && class[0] == X86_64_SSE_CLASS && class[1] == X86_64_SSEUP_CLASS)
02119 return gen_rtx_REG (mode, SSE_REGNO (sse_regno));
02120 if (n == 2
02121 && class[0] == X86_64_X87_CLASS && class[1] == X86_64_X87UP_CLASS)
02122 return gen_rtx_REG (TFmode, FIRST_STACK_REG);
02123 if (n == 2 && class[0] == X86_64_INTEGER_CLASS
02124 && class[1] == X86_64_INTEGER_CLASS
02125 && (mode == CDImode || mode == TImode)
02126 && intreg[0] + 1 == intreg[1])
02127 return gen_rtx_REG (mode, intreg[0]);
02128 if (n == 4
02129 && class[0] == X86_64_X87_CLASS && class[1] == X86_64_X87UP_CLASS
02130 && class[2] == X86_64_X87_CLASS && class[3] == X86_64_X87UP_CLASS)
02131 return gen_rtx_REG (TCmode, FIRST_STACK_REG);
02132
02133
02134 for (i = 0; i < n; i++)
02135 {
02136 switch (class[i])
02137 {
02138 case X86_64_NO_CLASS:
02139 break;
02140 case X86_64_INTEGER_CLASS:
02141 case X86_64_INTEGERSI_CLASS:
02142
02143 if (i * 8 + 8 > bytes)
02144 tmpmode = mode_for_size ((bytes - i * 8) * BITS_PER_UNIT, MODE_INT, 0);
02145 else if (class[i] == X86_64_INTEGERSI_CLASS)
02146 tmpmode = SImode;
02147 else
02148 tmpmode = DImode;
02149
02150 if (tmpmode == BLKmode)
02151 tmpmode = DImode;
02152 exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
02153 gen_rtx_REG (tmpmode, *intreg),
02154 GEN_INT (i*8));
02155 intreg++;
02156 break;
02157 case X86_64_SSESF_CLASS:
02158 exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
02159 gen_rtx_REG (SFmode,
02160 SSE_REGNO (sse_regno)),
02161 GEN_INT (i*8));
02162 sse_regno++;
02163 break;
02164 case X86_64_SSEDF_CLASS:
02165 exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
02166 gen_rtx_REG (DFmode,
02167 SSE_REGNO (sse_regno)),
02168 GEN_INT (i*8));
02169 sse_regno++;
02170 break;
02171 case X86_64_SSE_CLASS:
02172 if (i < n - 1 && class[i + 1] == X86_64_SSEUP_CLASS)
02173 tmpmode = TImode;
02174 else
02175 tmpmode = DImode;
02176 exp [nexps++] = gen_rtx_EXPR_LIST (VOIDmode,
02177 gen_rtx_REG (tmpmode,
02178 SSE_REGNO (sse_regno)),
02179 GEN_INT (i*8));
02180 if (tmpmode == TImode)
02181 i++;
02182 sse_regno++;
02183 break;
02184 default:
02185 abort ();
02186 }
02187 }
02188 ret = gen_rtx_PARALLEL (mode, rtvec_alloc (nexps));
02189 for (i = 0; i < nexps; i++)
02190 XVECEXP (ret, 0, i) = exp [i];
02191 return ret;
02192 }
02193
02194
02195
02196
02197
02198 void
02199 function_arg_advance (cum, mode, type, named)
02200 CUMULATIVE_ARGS *cum;
02201 enum machine_mode mode;
02202 tree type;
02203 int named;
02204 {
02205 int bytes =
02206 (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
02207 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
02208
02209 if (TARGET_DEBUG_ARG)
02210 fprintf (stderr,
02211 "function_adv (sz=%d, wds=%2d, nregs=%d, mode=%s, named=%d)\n\n",
02212 words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
02213 if (TARGET_64BIT)
02214 {
02215 int int_nregs, sse_nregs;
02216 if (!examine_argument (mode, type, 0, &int_nregs, &sse_nregs))
02217 cum->words += words;
02218 else if (sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs)
02219 {
02220 cum->nregs -= int_nregs;
02221 cum->sse_nregs -= sse_nregs;
02222 cum->regno += int_nregs;
02223 cum->sse_regno += sse_nregs;
02224 }
02225 else
02226 cum->words += words;
02227 }
02228 else
02229 {
02230 if (TARGET_SSE && mode == TImode)
02231 {
02232 cum->sse_words += words;
02233 cum->sse_nregs -= 1;
02234 cum->sse_regno += 1;
02235 if (cum->sse_nregs <= 0)
02236 {
02237 cum->sse_nregs = 0;
02238 cum->sse_regno = 0;
02239 }
02240 }
02241 else
02242 {
02243 cum->words += words;
02244 cum->nregs -= words;
02245 cum->regno += words;
02246
02247 if (cum->nregs <= 0)
02248 {
02249 cum->nregs = 0;
02250 cum->regno = 0;
02251 }
02252 }
02253 }
02254 return;
02255 }
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270 rtx
02271 function_arg (cum, mode, type, named)
02272 CUMULATIVE_ARGS *cum;
02273 enum machine_mode mode;
02274 tree type;
02275 int named;
02276 {
02277 rtx ret = NULL_RTX;
02278 int bytes =
02279 (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
02280 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
02281
02282
02283
02284
02285 if (mode == VOIDmode)
02286 {
02287 if (TARGET_64BIT)
02288 return GEN_INT (cum->maybe_vaarg
02289 ? (cum->sse_nregs < 0
02290 ? SSE_REGPARM_MAX
02291 : cum->sse_regno)
02292 : -1);
02293 else
02294 return constm1_rtx;
02295 }
02296 if (TARGET_64BIT)
02297 ret = construct_container (mode, type, 0, cum->nregs, cum->sse_nregs,
02298 &x86_64_int_parameter_registers [cum->regno],
02299 cum->sse_regno);
02300 else
02301 switch (mode)
02302 {
02303
02304 default:
02305 break;
02306
02307 case BLKmode:
02308 if (bytes < 0)
02309 break;
02310
02311 case DImode:
02312 case SImode:
02313 case HImode:
02314 case QImode:
02315 if (words <= cum->nregs)
02316 ret = gen_rtx_REG (mode, cum->regno);
02317 break;
02318 case TImode:
02319 if (cum->sse_nregs)
02320 ret = gen_rtx_REG (mode, cum->sse_regno);
02321 break;
02322 }
02323
02324 if (TARGET_DEBUG_ARG)
02325 {
02326 fprintf (stderr,
02327 "function_arg (size=%d, wds=%2d, nregs=%d, mode=%4s, named=%d, ",
02328 words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
02329
02330 if (ret)
02331 print_simple_rtl (stderr, ret);
02332 else
02333 fprintf (stderr, ", stack");
02334
02335 fprintf (stderr, " )\n");
02336 }
02337
02338 return ret;
02339 }
02340
02341
02342
02343 static bool
02344 contains_128bit_aligned_vector_p (type)
02345 tree type;
02346 {
02347 enum machine_mode mode = TYPE_MODE (type);
02348 if (SSE_REG_MODE_P (mode)
02349 && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
02350 return true;
02351 if (TYPE_ALIGN (type) < 128)
02352 return false;
02353
02354 if (AGGREGATE_TYPE_P (type))
02355 {
02356
02357 if (TREE_CODE (type) == RECORD_TYPE
02358 || TREE_CODE (type) == UNION_TYPE
02359 || TREE_CODE (type) == QUAL_UNION_TYPE)
02360 {
02361 tree field;
02362
02363 if (TYPE_BINFO (type) != NULL
02364 && TYPE_BINFO_BASETYPES (type) != NULL)
02365 {
02366 tree bases = TYPE_BINFO_BASETYPES (type);
02367 int n_bases = TREE_VEC_LENGTH (bases);
02368 int i;
02369
02370 for (i = 0; i < n_bases; ++i)
02371 {
02372 tree binfo = TREE_VEC_ELT (bases, i);
02373 tree type = BINFO_TYPE (binfo);
02374
02375 if (contains_128bit_aligned_vector_p (type))
02376 return true;
02377 }
02378 }
02379
02380 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
02381 {
02382 if (TREE_CODE (field) == FIELD_DECL
02383 && contains_128bit_aligned_vector_p (TREE_TYPE (field)))
02384 return true;
02385 }
02386 }
02387
02388 else if (TREE_CODE (type) == ARRAY_TYPE)
02389 {
02390 if (contains_128bit_aligned_vector_p (TREE_TYPE (type)))
02391 return true;
02392 }
02393 else
02394 abort ();
02395 }
02396 return false;
02397 }
02398
02399
02400
02401
02402
02403
02404
02405 int
02406 function_arg_pass_by_reference (cum, mode, type, named)
02407 CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
02408 enum machine_mode mode ATTRIBUTE_UNUSED;
02409 tree type;
02410 int named ATTRIBUTE_UNUSED;
02411 {
02412 if (!TARGET_64BIT)
02413 return 0;
02414
02415 if (type && int_size_in_bytes (type) == -1)
02416 {
02417 if (TARGET_DEBUG_ARG)
02418 fprintf (stderr, "function_arg_pass_by_reference\n");
02419 return 1;
02420 }
02421
02422 return 0;
02423 }
02424
02425
02426
02427
02428 int
02429 ix86_function_arg_boundary (mode, type)
02430 enum machine_mode mode;
02431 tree type;
02432 {
02433 int align;
02434 if (type)
02435 align = TYPE_ALIGN (type);
02436 else
02437 align = GET_MODE_ALIGNMENT (mode);
02438 if (align < PARM_BOUNDARY)
02439 align = PARM_BOUNDARY;
02440 if (!TARGET_64BIT)
02441 {
02442
02443
02444
02445
02446
02447
02448
02449 if (!type)
02450 {
02451 if (!SSE_REG_MODE_P (mode))
02452 align = PARM_BOUNDARY;
02453 }
02454 else
02455 {
02456 if (!contains_128bit_aligned_vector_p (type))
02457 align = PARM_BOUNDARY;
02458 }
02459 if (align != PARM_BOUNDARY && !TARGET_SSE)
02460 abort();
02461 }
02462 if (align > 128)
02463 align = 128;
02464 return align;
02465 }
02466
02467
02468 bool
02469 ix86_function_value_regno_p (regno)
02470 int regno;
02471 {
02472 if (!TARGET_64BIT)
02473 {
02474 return ((regno) == 0
02475 || ((regno) == FIRST_FLOAT_REG && TARGET_FLOAT_RETURNS_IN_80387)
02476 || ((regno) == FIRST_SSE_REG && TARGET_SSE));
02477 }
02478 return ((regno) == 0 || (regno) == FIRST_FLOAT_REG
02479 || ((regno) == FIRST_SSE_REG && TARGET_SSE)
02480 || ((regno) == FIRST_FLOAT_REG && TARGET_FLOAT_RETURNS_IN_80387));
02481 }
02482
02483
02484
02485
02486
02487 rtx
02488 ix86_function_value (valtype)
02489 tree valtype;
02490 {
02491 if (TARGET_64BIT)
02492 {
02493 rtx ret = construct_container (TYPE_MODE (valtype), valtype, 1,
02494 REGPARM_MAX, SSE_REGPARM_MAX,
02495 x86_64_int_return_registers, 0);
02496
02497
02498 if (!ret)
02499 ret = gen_rtx_REG (TYPE_MODE (valtype), 0);
02500 return ret;
02501 }
02502 else
02503 return gen_rtx_REG (TYPE_MODE (valtype),
02504 ix86_value_regno (TYPE_MODE (valtype)));
02505 }
02506
02507
02508 int
02509 ix86_return_in_memory (type)
02510 tree type;
02511 {
02512 int needed_intregs, needed_sseregs, size;
02513 enum machine_mode mode = TYPE_MODE (type);
02514
02515 if (TARGET_64BIT)
02516 return !examine_argument (mode, type, 1, &needed_intregs, &needed_sseregs);
02517
02518 if (mode == BLKmode)
02519 return 1;
02520
02521 size = int_size_in_bytes (type);
02522
02523 if (VECTOR_MODE_P (mode) || mode == TImode)
02524 {
02525
02526 if (size < 8)
02527 return 0;
02528
02529
02530
02531 if (size == 8)
02532 return 1;
02533
02534
02535
02536
02537
02538
02539
02540 if (size == 16)
02541 {
02542 static bool warned;
02543
02544 if (TARGET_SSE)
02545 return 0;
02546
02547 if (!warned)
02548 {
02549 warned = true;
02550 warning ("SSE vector return without SSE enabled changes the ABI");
02551 }
02552 return 1;
02553 }
02554 }
02555
02556 if (mode == TFmode)
02557 return 0;
02558 if (size > 12)
02559 return 1;
02560 return 0;
02561 }
02562
02563
02564
02565 rtx
02566 ix86_libcall_value (mode)
02567 enum machine_mode mode;
02568 {
02569 if (TARGET_64BIT)
02570 {
02571 switch (mode)
02572 {
02573 case SFmode:
02574 case SCmode:
02575 case DFmode:
02576 case DCmode:
02577 return gen_rtx_REG (mode, FIRST_SSE_REG);
02578 case TFmode:
02579 case TCmode:
02580 return gen_rtx_REG (mode, FIRST_FLOAT_REG);
02581 default:
02582 return gen_rtx_REG (mode, 0);
02583 }
02584 }
02585 else
02586 return gen_rtx_REG (mode, ix86_value_regno (mode));
02587 }
02588
02589
02590
02591 static int
02592 ix86_value_regno (mode)
02593 enum machine_mode mode;
02594 {
02595
02596 if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_FLOAT_RETURNS_IN_80387)
02597 return FIRST_FLOAT_REG;
02598
02599
02600 if (mode == TImode || (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 16))
02601 return FIRST_SSE_REG;
02602
02603 return 0;
02604 }
02605
02606
02607
02608 tree
02609 ix86_build_va_list ()
02610 {
02611 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
02612
02613
02614 if (!TARGET_64BIT)
02615 return build_pointer_type (char_type_node);
02616
02617 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
02618 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
02619
02620 f_gpr = build_decl (FIELD_DECL, get_identifier ("gp_offset"),
02621 unsigned_type_node);
02622 f_fpr = build_decl (FIELD_DECL, get_identifier ("fp_offset"),
02623 unsigned_type_node);
02624 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
02625 ptr_type_node);
02626 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
02627 ptr_type_node);
02628
02629 DECL_FIELD_CONTEXT (f_gpr) = record;
02630 DECL_FIELD_CONTEXT (f_fpr) = record;
02631 DECL_FIELD_CONTEXT (f_ovf) = record;
02632 DECL_FIELD_CONTEXT (f_sav) = record;
02633
02634 TREE_CHAIN (record) = type_decl;
02635 TYPE_NAME (record) = type_decl;
02636 TYPE_FIELDS (record) = f_gpr;
02637 TREE_CHAIN (f_gpr) = f_fpr;
02638 TREE_CHAIN (f_fpr) = f_ovf;
02639 TREE_CHAIN (f_ovf) = f_sav;
02640
02641 layout_type (record);
02642
02643
02644 return build_array_type (record, build_index_type (size_zero_node));
02645 }
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661 void
02662 ix86_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
02663 CUMULATIVE_ARGS *cum;
02664 enum machine_mode mode;
02665 tree type;
02666 int *pretend_size ATTRIBUTE_UNUSED;
02667 int no_rtl;
02668
02669 {
02670 CUMULATIVE_ARGS next_cum;
02671 rtx save_area = NULL_RTX, mem;
02672 rtx label;
02673 rtx label_ref;
02674 rtx tmp_reg;
02675 rtx nsse_reg;
02676 int set;
02677 tree fntype;
02678 int stdarg_p;
02679 int i;
02680
02681 if (!TARGET_64BIT)
02682 return;
02683
02684
02685 ix86_save_varrargs_registers = 1;
02686
02687 cfun->stack_alignment_needed = 128;
02688
02689 fntype = TREE_TYPE (current_function_decl);
02690 stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
02691 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
02692 != void_type_node));
02693
02694
02695
02696 next_cum = *cum;
02697 if (stdarg_p)
02698 function_arg_advance (&next_cum, mode, type, 1);
02699
02700 if (!no_rtl)
02701 save_area = frame_pointer_rtx;
02702
02703 set = get_varargs_alias_set ();
02704
02705 for (i = next_cum.regno; i < ix86_regparm; i++)
02706 {
02707 mem = gen_rtx_MEM (Pmode,
02708 plus_constant (save_area, i * UNITS_PER_WORD));
02709 set_mem_alias_set (mem, set);
02710 emit_move_insn (mem, gen_rtx_REG (Pmode,
02711 x86_64_int_parameter_registers[i]));
02712 }
02713
02714 if (next_cum.sse_nregs)
02715 {
02716
02717
02718
02719
02720
02721 label = gen_label_rtx ();
02722 label_ref = gen_rtx_LABEL_REF (Pmode, label);
02723
02724
02725
02726 tmp_reg = gen_reg_rtx (Pmode);
02727 nsse_reg = gen_reg_rtx (Pmode);
02728 emit_insn (gen_zero_extendqidi2 (nsse_reg, gen_rtx_REG (QImode, 0)));
02729 emit_insn (gen_rtx_SET (VOIDmode, tmp_reg,
02730 gen_rtx_MULT (Pmode, nsse_reg,
02731 GEN_INT (4))));
02732 if (next_cum.sse_regno)
02733 emit_move_insn
02734 (nsse_reg,
02735 gen_rtx_CONST (DImode,
02736 gen_rtx_PLUS (DImode,
02737 label_ref,
02738 GEN_INT (next_cum.sse_regno * 4))));
02739 else
02740 emit_move_insn (nsse_reg, label_ref);
02741 emit_insn (gen_subdi3 (nsse_reg, nsse_reg, tmp_reg));
02742
02743
02744
02745
02746 tmp_reg = gen_reg_rtx (Pmode);
02747 emit_insn (gen_rtx_SET (VOIDmode, tmp_reg,
02748 plus_constant (save_area,
02749 8 * REGPARM_MAX + 127)));
02750 mem = gen_rtx_MEM (BLKmode, plus_constant (tmp_reg, -127));
02751 set_mem_alias_set (mem, set);
02752 set_mem_align (mem, BITS_PER_WORD);
02753
02754
02755 emit_insn (gen_sse_prologue_save (mem, nsse_reg,
02756 GEN_INT (next_cum.sse_regno), label));
02757 }
02758
02759 }
02760
02761
02762
02763 void
02764 ix86_va_start (valist, nextarg)
02765 tree valist;
02766 rtx nextarg;
02767 {
02768 HOST_WIDE_INT words, n_gpr, n_fpr;
02769 tree f_gpr, f_fpr, f_ovf, f_sav;
02770 tree gpr, fpr, ovf, sav, t;
02771
02772
02773 if (!TARGET_64BIT)
02774 {
02775 std_expand_builtin_va_start (valist, nextarg);
02776 return;
02777 }
02778
02779 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
02780 f_fpr = TREE_CHAIN (f_gpr);
02781 f_ovf = TREE_CHAIN (f_fpr);
02782 f_sav = TREE_CHAIN (f_ovf);
02783
02784 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
02785 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
02786 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
02787 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
02788 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
02789
02790
02791 words = current_function_args_info.words;
02792 n_gpr = current_function_args_info.regno;
02793 n_fpr = current_function_args_info.sse_regno;
02794
02795 if (TARGET_DEBUG_ARG)
02796 fprintf (stderr, "va_start: words = %d, n_gpr = %d, n_fpr = %d\n",
02797 (int) words, (int) n_gpr, (int) n_fpr);
02798
02799 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
02800 build_int_2 (n_gpr * 8, 0));
02801 TREE_SIDE_EFFECTS (t) = 1;
02802 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
02803
02804 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
02805 build_int_2 (n_fpr * 16 + 8*REGPARM_MAX, 0));
02806 TREE_SIDE_EFFECTS (t) = 1;
02807 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
02808
02809
02810 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
02811 if (words != 0)
02812 t = build (PLUS_EXPR, TREE_TYPE (ovf), t,
02813 build_int_2 (words * UNITS_PER_WORD, 0));
02814 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
02815 TREE_SIDE_EFFECTS (t) = 1;
02816 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
02817
02818
02819
02820 t = make_tree (TREE_TYPE (sav), frame_pointer_rtx);
02821 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
02822 TREE_SIDE_EFFECTS (t) = 1;
02823 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
02824 }
02825
02826
02827 rtx
02828 ix86_va_arg (valist, type)
02829 tree valist, type;
02830 {
02831 static const int intreg[6] = { 0, 1, 2, 3, 4, 5 };
02832 tree f_gpr, f_fpr, f_ovf, f_sav;
02833 tree gpr, fpr, ovf, sav, t;
02834 int size, rsize;
02835 rtx lab_false, lab_over = NULL_RTX;
02836 rtx addr_rtx, r;
02837 rtx container;
02838 int indirect_p = 0;
02839
02840
02841 if (!TARGET_64BIT)
02842 {
02843 return std_expand_builtin_va_arg (valist, type);
02844 }
02845
02846 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
02847 f_fpr = TREE_CHAIN (f_gpr);
02848 f_ovf = TREE_CHAIN (f_fpr);
02849 f_sav = TREE_CHAIN (f_ovf);
02850
02851 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
02852 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
02853 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
02854 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
02855 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
02856
02857 size = int_size_in_bytes (type);
02858 if (size == -1)
02859 {
02860
02861 indirect_p = 1;
02862 type = build_pointer_type (type);
02863 size = int_size_in_bytes (type);
02864 }
02865 rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
02866
02867 container = construct_container (TYPE_MODE (type), type, 0,
02868 REGPARM_MAX, SSE_REGPARM_MAX, intreg, 0);
02869
02870
02871
02872
02873 addr_rtx = gen_reg_rtx (Pmode);
02874
02875 if (container)
02876 {
02877 rtx int_addr_rtx, sse_addr_rtx;
02878 int needed_intregs, needed_sseregs;
02879 int need_temp;
02880
02881 lab_over = gen_label_rtx ();
02882 lab_false = gen_label_rtx ();
02883
02884 examine_argument (TYPE_MODE (type), type, 0,
02885 &needed_intregs, &needed_sseregs);
02886
02887
02888 need_temp = ((needed_intregs && TYPE_ALIGN (type) > 64)
02889 || TYPE_ALIGN (type) > 128);
02890
02891
02892
02893 if (!need_temp && !REG_P (container))
02894 {
02895
02896 if (SSE_REGNO_P (REGNO (XEXP (XVECEXP (container, 0, 0), 0))))
02897 {
02898 int i;
02899
02900 for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
02901 {
02902 rtx slot = XVECEXP (container, 0, i);
02903 if (REGNO (XEXP (slot, 0)) != FIRST_SSE_REG + (unsigned int) i
02904 || INTVAL (XEXP (slot, 1)) != i * 16)
02905 need_temp = 1;
02906 }
02907 }
02908 else
02909 {
02910 int i;
02911
02912 for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
02913 {
02914 rtx slot = XVECEXP (container, 0, i);
02915 if (REGNO (XEXP (slot, 0)) != (unsigned int) i
02916 || INTVAL (XEXP (slot, 1)) != i * 8)
02917 need_temp = 1;
02918 }
02919 }
02920 }
02921 if (!need_temp)
02922 {
02923 int_addr_rtx = addr_rtx;
02924 sse_addr_rtx = addr_rtx;
02925 }
02926 else
02927 {
02928 int_addr_rtx = gen_reg_rtx (Pmode);
02929 sse_addr_rtx = gen_reg_rtx (Pmode);
02930 }
02931
02932 if (needed_intregs)
02933 {
02934 emit_cmp_and_jump_insns (expand_expr
02935 (gpr, NULL_RTX, SImode, EXPAND_NORMAL),
02936 GEN_INT ((REGPARM_MAX - needed_intregs +
02937 1) * 8), GE, const1_rtx, SImode,
02938 1, lab_false);
02939 }
02940 if (needed_sseregs)
02941 {
02942 emit_cmp_and_jump_insns (expand_expr
02943 (fpr, NULL_RTX, SImode, EXPAND_NORMAL),
02944 GEN_INT ((SSE_REGPARM_MAX -
02945 needed_sseregs + 1) * 16 +
02946 REGPARM_MAX * 8), GE, const1_rtx,
02947 SImode, 1, lab_false);
02948 }
02949
02950
02951 if (needed_intregs)
02952 {
02953 t = build (PLUS_EXPR, ptr_type_node, sav, gpr);
02954 r = expand_expr (t, int_addr_rtx, Pmode, EXPAND_NORMAL);
02955 if (r != int_addr_rtx)
02956 emit_move_insn (int_addr_rtx, r);
02957 }
02958 if (needed_sseregs)
02959 {
02960 t = build (PLUS_EXPR, ptr_type_node, sav, fpr);
02961 r = expand_expr (t, sse_addr_rtx, Pmode, EXPAND_NORMAL);
02962 if (r != sse_addr_rtx)
02963 emit_move_insn (sse_addr_rtx, r);
02964 }
02965 if (need_temp)
02966 {
02967 int i;
02968 rtx mem;
02969 rtx x;
02970
02971
02972 x = XEXP (assign_temp (type, 0, 1, 0), 0);
02973 mem = gen_rtx_MEM (BLKmode, x);
02974 force_operand (x, addr_rtx);
02975 set_mem_alias_set (mem, get_varargs_alias_set ());
02976 set_mem_align (mem, BITS_PER_UNIT);
02977
02978 for (i = 0; i < XVECLEN (container, 0); i++)
02979 {
02980 rtx slot = XVECEXP (container, 0, i);
02981 rtx reg = XEXP (slot, 0);
02982 enum machine_mode mode = GET_MODE (reg);
02983 rtx src_addr;
02984 rtx src_mem;
02985 int src_offset;
02986 rtx dest_mem;
02987
02988 if (SSE_REGNO_P (REGNO (reg)))
02989 {
02990 src_addr = sse_addr_rtx;
02991 src_offset = (REGNO (reg) - FIRST_SSE_REG) * 16;
02992 }
02993 else
02994 {
02995 src_addr = int_addr_rtx;
02996 src_offset = REGNO (reg) * 8;
02997 }
02998 src_mem = gen_rtx_MEM (mode, src_addr);
02999 set_mem_alias_set (src_mem, get_varargs_alias_set ());
03000 src_mem = adjust_address (src_mem, mode, src_offset);
03001 dest_mem = adjust_address (mem, mode, INTVAL (XEXP (slot, 1)));
03002 emit_move_insn (dest_mem, src_mem);
03003 }
03004 }
03005
03006 if (needed_intregs)
03007 {
03008 t =
03009 build (PLUS_EXPR, TREE_TYPE (gpr), gpr,
03010 build_int_2 (needed_intregs * 8, 0));
03011 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, t);
03012 TREE_SIDE_EFFECTS (t) = 1;
03013 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
03014 }
03015 if (needed_sseregs)
03016 {
03017 t =
03018 build (PLUS_EXPR, TREE_TYPE (fpr), fpr,
03019 build_int_2 (needed_sseregs * 16, 0));
03020 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, t);
03021 TREE_SIDE_EFFECTS (t) = 1;
03022 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
03023 }
03024
03025 emit_jump_insn (gen_jump (lab_over));
03026 emit_barrier ();
03027 emit_label (lab_false);
03028 }
03029
03030
03031
03032
03033 if (FUNCTION_ARG_BOUNDARY (VOIDmode, type) <= 64)
03034 t = ovf;
03035 else
03036 {
03037 HOST_WIDE_INT align = FUNCTION_ARG_BOUNDARY (VOIDmode, type) / 8;
03038 t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align - 1, 0));
03039 t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align, -1));
03040 }
03041 t = save_expr (t);
03042
03043 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
03044 if (r != addr_rtx)
03045 emit_move_insn (addr_rtx, r);
03046
03047 t =
03048 build (PLUS_EXPR, TREE_TYPE (t), t,
03049 build_int_2 (rsize * UNITS_PER_WORD, 0));
03050 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
03051 TREE_SIDE_EFFECTS (t) = 1;
03052 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
03053
03054 if (container)
03055 emit_label (lab_over);
03056
03057 if (indirect_p)
03058 {
03059 r = gen_rtx_MEM (Pmode, addr_rtx);
03060 set_mem_alias_set (r, get_varargs_alias_set ());
03061 emit_move_insn (addr_rtx, r);
03062 }
03063
03064 return addr_rtx;
03065 }
03066
03067
03068 int
03069 any_fp_register_operand (op, mode)
03070 rtx op;
03071 enum machine_mode mode ATTRIBUTE_UNUSED;
03072 {
03073 return ANY_FP_REG_P (op);
03074 }
03075
03076
03077 int
03078 fp_register_operand (op, mode)
03079 rtx op;
03080 enum machine_mode mode ATTRIBUTE_UNUSED;
03081 {
03082 return FP_REG_P (op);
03083 }
03084
03085
03086 int
03087 register_and_not_any_fp_reg_operand (op, mode)
03088 rtx op;
03089 enum machine_mode mode;
03090 {
03091 return register_operand (op, mode) && !ANY_FP_REG_P (op);
03092 }
03093
03094
03095
03096 int
03097 register_and_not_fp_reg_operand (op, mode)
03098 rtx op;
03099 enum machine_mode mode;
03100 {
03101 return register_operand (op, mode) && !FP_REG_P (op);
03102 }
03103
03104
03105
03106 int
03107 x86_64_general_operand (op, mode)
03108 rtx op;
03109 enum machine_mode mode;
03110 {
03111 if (!TARGET_64BIT)
03112 return general_operand (op, mode);
03113 if (nonimmediate_operand (op, mode))
03114 return 1;
03115 return x86_64_sign_extended_value (op);
03116 }
03117
03118
03119
03120
03121 int
03122 x86_64_szext_general_operand (op, mode)
03123 rtx op;
03124 enum machine_mode mode;
03125 {
03126 if (!TARGET_64BIT)
03127 return general_operand (op, mode);
03128 if (nonimmediate_operand (op, mode))
03129 return 1;
03130 return x86_64_sign_extended_value (op) || x86_64_zero_extended_value (op);
03131 }
03132
03133
03134
03135 int
03136 x86_64_nonmemory_operand (op, mode)
03137 rtx op;
03138 enum machine_mode mode;
03139 {
03140 if (!TARGET_64BIT)
03141 return nonmemory_operand (op, mode);
03142 if (register_operand (op, mode))
03143 return 1;
03144 return x86_64_sign_extended_value (op);
03145 }
03146
03147
03148
03149 int
03150 x86_64_movabs_operand (op, mode)
03151 rtx op;
03152 enum machine_mode mode;
03153 {
03154 if (!TARGET_64BIT || !flag_pic)
03155 return nonmemory_operand (op, mode);
03156 if (register_operand (op, mode) || x86_64_sign_extended_value (op))
03157 return 1;
03158 if (CONSTANT_P (op) && !symbolic_reference_mentioned_p (op))
03159 return 1;
03160 return 0;
03161 }
03162
03163
03164
03165
03166 int
03167 ix86_check_movabs (insn, opnum)
03168 rtx insn;
03169 int opnum;
03170 {
03171 rtx set, mem;
03172
03173 set = PATTERN (insn);
03174 if (GET_CODE (set) == PARALLEL)
03175 set = XVECEXP (set, 0, 0);
03176 if (GET_CODE (set) != SET)
03177 abort ();
03178 mem = XEXP (set, opnum);
03179 while (GET_CODE (mem) == SUBREG)
03180 mem = SUBREG_REG (mem);
03181 if (GET_CODE (mem) != MEM)
03182 abort ();
03183 return (volatile_ok || !MEM_VOLATILE_P (mem));
03184 }
03185
03186
03187
03188 int
03189 x86_64_szext_nonmemory_operand (op, mode)
03190 rtx op;
03191 enum machine_mode mode;
03192 {
03193 if (!TARGET_64BIT)
03194 return nonmemory_operand (op, mode);
03195 if (register_operand (op, mode))
03196 return 1;
03197 return x86_64_sign_extended_value (op) || x86_64_zero_extended_value (op);
03198 }
03199
03200
03201
03202 int
03203 x86_64_immediate_operand (op, mode)
03204 rtx op;
03205 enum machine_mode mode;
03206 {
03207 if (!TARGET_64BIT)
03208 return immediate_operand (op, mode);
03209 return x86_64_sign_extended_value (op);
03210 }
03211
03212
03213
03214 int
03215 x86_64_zext_immediate_operand (op, mode)
03216 rtx op;
03217 enum machine_mode mode ATTRIBUTE_UNUSED;
03218 {
03219 return x86_64_zero_extended_value (op);
03220 }
03221
03222
03223
03224 int
03225 const_int_1_operand (op, mode)
03226 rtx op;
03227 enum machine_mode mode ATTRIBUTE_UNUSED;
03228 {
03229 return (GET_CODE (op) == CONST_INT && INTVAL (op) == 1);
03230 }
03231
03232
03233
03234
03235
03236 int
03237 const_int_1_31_operand (op, mode)
03238 rtx op;
03239 enum machine_mode mode ATTRIBUTE_UNUSED;
03240 {
03241 return (GET_CODE (op) == CONST_INT && INTVAL (op) >= 1 && INTVAL (op) <= 31);
03242 }
03243
03244
03245
03246
03247 int
03248 symbolic_operand (op, mode)
03249 register rtx op;
03250 enum machine_mode mode ATTRIBUTE_UNUSED;
03251 {
03252 switch (GET_CODE (op))
03253 {
03254 case SYMBOL_REF:
03255 case LABEL_REF:
03256 return 1;
03257
03258 case CONST:
03259 op = XEXP (op, 0);
03260 if (GET_CODE (op) == SYMBOL_REF
03261 || GET_CODE (op) == LABEL_REF
03262 || (GET_CODE (op) == UNSPEC
03263 && (XINT (op, 1) == UNSPEC_GOT
03264 || XINT (op, 1) == UNSPEC_GOTOFF
03265 || XINT (op, 1) == UNSPEC_GOTPCREL)))
03266 return 1;
03267 if (GET_CODE (op) != PLUS
03268 || GET_CODE (XEXP (op, 1)) != CONST_INT)
03269 return 0;
03270
03271 op = XEXP (op, 0);
03272 if (GET_CODE (op) == SYMBOL_REF
03273 || GET_CODE (op) == LABEL_REF)
03274 return 1;
03275
03276 if (GET_CODE (op) != UNSPEC
03277 || XINT (op, 1) != UNSPEC_GOTOFF)
03278 return 0;
03279
03280 op = XVECEXP (op, 0, 0);
03281 if (GET_CODE (op) == SYMBOL_REF
03282 || GET_CODE (op) == LABEL_REF)
03283 return 1;
03284 return 0;
03285
03286 default:
03287 return 0;
03288 }
03289 }
03290
03291
03292
03293 int
03294 pic_symbolic_operand (op, mode)
03295 register rtx op;
03296 enum machine_mode mode ATTRIBUTE_UNUSED;
03297 {
03298 if (GET_CODE (op) != CONST)
03299 return 0;
03300 op = XEXP (op, 0);
03301 if (TARGET_64BIT)
03302 {
03303 if (GET_CODE (XEXP (op, 0)) == UNSPEC)
03304 return 1;
03305 }
03306 else
03307 {
03308 if (GET_CODE (op) == UNSPEC)
03309 return 1;
03310 if (GET_CODE (op) != PLUS
03311 || GET_CODE (XEXP (op, 1)) != CONST_INT)
03312 return 0;
03313 op = XEXP (op, 0);
03314 if (GET_CODE (op) == UNSPEC)
03315 return 1;
03316 }
03317 return 0;
03318 }
03319
03320
03321
03322 static int
03323 local_symbolic_operand (op, mode)
03324 rtx op;
03325 enum machine_mode mode ATTRIBUTE_UNUSED;
03326 {
03327 if (GET_CODE (op) == CONST
03328 && GET_CODE (XEXP (op, 0)) == PLUS
03329 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
03330 op = XEXP (XEXP (op, 0), 0);
03331
03332 if (GET_CODE (op) == LABEL_REF)
03333 return 1;
03334
03335 if (GET_CODE (op) != SYMBOL_REF)
03336 return 0;
03337
03338
03339
03340 if (CONSTANT_POOL_ADDRESS_P (op) || SYMBOL_REF_FLAG (op))
03341 return 1;
03342
03343
03344
03345
03346
03347
03348 if (strncmp (XSTR (op, 0), internal_label_prefix,
03349 internal_label_prefix_len) == 0)
03350 return 1;
03351
03352 return 0;
03353 }
03354
03355
03356
03357 int
03358 tls_symbolic_operand (op, mode)
03359 register rtx op;
03360 enum machine_mode mode ATTRIBUTE_UNUSED;
03361 {
03362 const char *symbol_str;
03363
03364 if (GET_CODE (op) != SYMBOL_REF)
03365 return 0;
03366 symbol_str = XSTR (op, 0);
03367
03368 if (symbol_str[0] != '%')
03369 return 0;
03370 return strchr (tls_model_chars, symbol_str[1]) - tls_model_chars;
03371 }
03372
03373 static int
03374 tls_symbolic_operand_1 (op, kind)
03375 rtx op;
03376 enum tls_model kind;
03377 {
03378 const char *symbol_str;
03379
03380 if (GET_CODE (op) != SYMBOL_REF)
03381 return 0;
03382 symbol_str = XSTR (op, 0);
03383
03384 return symbol_str[0] == '%' && symbol_str[1] == tls_model_chars[kind];
03385 }
03386
03387 int
03388 global_dynamic_symbolic_operand (op, mode)
03389 register rtx op;
03390 enum machine_mode mode ATTRIBUTE_UNUSED;
03391 {
03392 return tls_symbolic_operand_1 (op, TLS_MODEL_GLOBAL_DYNAMIC);
03393 }
03394
03395 int
03396 local_dynamic_symbolic_operand (op, mode)
03397 register rtx op;
03398 enum machine_mode mode ATTRIBUTE_UNUSED;
03399 {
03400 return tls_symbolic_operand_1 (op, TLS_MODEL_LOCAL_DYNAMIC);
03401 }
03402
03403 int
03404 initial_exec_symbolic_operand (op, mode)
03405 register rtx op;
03406 enum machine_mode mode ATTRIBUTE_UNUSED;
03407 {
03408 return tls_symbolic_operand_1 (op, TLS_MODEL_INITIAL_EXEC);
03409 }
03410
03411 int
03412 local_exec_symbolic_operand (op, mode)
03413 register rtx op;
03414 enum machine_mode mode ATTRIBUTE_UNUSED;
03415 {
03416 return tls_symbolic_operand_1 (op, TLS_MODEL_LOCAL_EXEC);
03417 }
03418
03419
03420
03421
03422
03423 int
03424 call_insn_operand (op, mode)
03425 rtx op;
03426 enum machine_mode mode ATTRIBUTE_UNUSED;
03427 {
03428
03429
03430 if (GET_CODE (op) == REG
03431 && (op == arg_pointer_rtx
03432 || op == frame_pointer_rtx
03433 || (REGNO (op) >= FIRST_PSEUDO_REGISTER
03434 && REGNO (op) <= LAST_VIRTUAL_REGISTER)))
03435 return 0;
03436
03437
03438
03439 if (GET_CODE (op) == CONST_INT)
03440 return 0;
03441
03442
03443 if (GET_CODE (op) == SYMBOL_REF)
03444 return 1;
03445
03446
03447 return general_operand (op, Pmode);
03448 }
03449
03450 int
03451 constant_call_address_operand (op, mode)
03452 rtx op;
03453 enum machine_mode mode ATTRIBUTE_UNUSED;
03454 {
03455 if (GET_CODE (op) == CONST
03456 && GET_CODE (XEXP (op, 0)) == PLUS
03457 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
03458 op = XEXP (XEXP (op, 0), 0);
03459 return GET_CODE (op) == SYMBOL_REF;
03460 }
03461
03462
03463
03464 int
03465 const0_operand (op, mode)
03466 register rtx op;
03467 enum machine_mode mode;
03468 {
03469 return op == CONST0_RTX (mode);
03470 }
03471
03472 int
03473 const1_operand (op, mode)
03474 register rtx op;
03475 enum machine_mode mode ATTRIBUTE_UNUSED;
03476 {
03477 return op == const1_rtx;
03478 }
03479
03480
03481
03482 int
03483 const248_operand (op, mode)
03484 register rtx op;
03485 enum machine_mode mode ATTRIBUTE_UNUSED;
03486 {
03487 return (GET_CODE (op) == CONST_INT
03488 && (INTVAL (op) == 2 || INTVAL (op) == 4 || INTVAL (op) == 8));
03489 }
03490
03491
03492
03493 int
03494 incdec_operand (op, mode)
03495 register rtx op;
03496 enum machine_mode mode ATTRIBUTE_UNUSED;
03497 {
03498
03499
03500 if (TARGET_PENTIUM4 && !optimize_size)
03501 return 0;
03502 return op == const1_rtx || op == constm1_rtx;
03503 }
03504
03505
03506
03507
03508 int
03509 shiftdi_operand (op, mode)
03510 rtx op;
03511 enum machine_mode mode ATTRIBUTE_UNUSED;
03512 {
03513 if (TARGET_64BIT)
03514 return nonimmediate_operand (op, mode);
03515 else
03516 return register_operand (op, mode);
03517 }
03518
03519
03520
03521
03522
03523
03524
03525
03526 int
03527 reg_no_sp_operand (op, mode)
03528 register rtx op;
03529 enum machine_mode mode;
03530 {
03531 rtx t = op;
03532 if (GET_CODE (t) == SUBREG)
03533 t = SUBREG_REG (t);
03534 if (t == stack_pointer_rtx || t == arg_pointer_rtx || t == frame_pointer_rtx)
03535 return 0;
03536
03537 return register_operand (op, mode);
03538 }
03539
03540 int
03541 mmx_reg_operand (op, mode)
03542 register rtx op;
03543 enum machine_mode mode ATTRIBUTE_UNUSED;
03544 {
03545 return MMX_REG_P (op);
03546 }
03547
03548
03549
03550
03551 int
03552 general_no_elim_operand (op, mode)
03553 register rtx op;
03554 enum machine_mode mode;
03555 {
03556 rtx t = op;
03557 if (GET_CODE (t) == SUBREG)
03558 t = SUBREG_REG (t);
03559 if (t == arg_pointer_rtx || t == frame_pointer_rtx
03560 || t == virtual_incoming_args_rtx || t == virtual_stack_vars_rtx
03561 || t == virtual_stack_dynamic_rtx)
03562 return 0;
03563 if (REG_P (t)
03564 && REGNO (t) >= FIRST_VIRTUAL_REGISTER
03565 && REGNO (t) <= LAST_VIRTUAL_REGISTER)
03566 return 0;
03567
03568 return general_operand (op, mode);
03569 }
03570
03571
03572
03573
03574 int
03575 nonmemory_no_elim_operand (op, mode)
03576 register rtx op;
03577 enum machine_mode mode;
03578 {
03579 rtx t = op;
03580 if (GET_CODE (t) == SUBREG)
03581 t = SUBREG_REG (t);
03582 if (t == arg_pointer_rtx || t == frame_pointer_rtx
03583 || t == virtual_incoming_args_rtx || t == virtual_stack_vars_rtx
03584 || t == virtual_stack_dynamic_rtx)
03585 return 0;
03586
03587 return GET_CODE (op) == CONST_INT || register_operand (op, mode);
03588 }
03589
03590
03591
03592
03593 int
03594 index_register_operand (op, mode)
03595 register rtx op;
03596 enum machine_mode mode;
03597 {
03598 rtx t = op;
03599 if (GET_CODE (t) == SUBREG)
03600 t = SUBREG_REG (t);
03601 if (!REG_P (t))
03602 return 0;
03603 if (t == arg_pointer_rtx
03604 || t == frame_pointer_rtx
03605 || t == virtual_incoming_args_rtx
03606 || t == virtual_stack_vars_rtx
03607 || t == virtual_stack_dynamic_rtx
03608 || REGNO (t) == STACK_POINTER_REGNUM)
03609 return 0;
03610
03611 return general_operand (op, mode);
03612 }
03613
03614
03615
03616 int
03617 q_regs_operand (op, mode)
03618 register rtx op;
03619 enum machine_mode mode;
03620 {
03621 if (mode != VOIDmode && GET_MODE (op) != mode)
03622 return 0;
03623 if (GET_CODE (op) == SUBREG)
03624 op = SUBREG_REG (op);
03625 return ANY_QI_REG_P (op);
03626 }
03627
03628
03629
03630 int
03631 non_q_regs_operand (op, mode)
03632 register rtx op;
03633 enum machine_mode mode;
03634 {
03635 if (mode != VOIDmode && GET_MODE (op) != mode)
03636 return 0;
03637 if (GET_CODE (op) == SUBREG)
03638 op = SUBREG_REG (op);
03639 return NON_QI_REG_P (op);
03640 }
03641
03642
03643 int
03644 vector_move_operand (op, mode)
03645 rtx op;
03646 enum machine_mode mode;
03647 {
03648 if (nonimmediate_operand (op, mode))
03649 return 1;
03650 if (GET_MODE (op) != mode && mode != VOIDmode)
03651 return 0;
03652 return (op == CONST0_RTX (GET_MODE (op)));
03653 }
03654
03655
03656
03657
03658 int
03659 no_seg_address_operand (op, mode)
03660 register rtx op;
03661 enum machine_mode mode;
03662 {
03663 struct ix86_address parts;
03664
03665 if (! address_operand (op, mode))
03666 return 0;
03667
03668 if (! ix86_decompose_address (op, &parts))
03669 abort ();
03670
03671 return parts.seg == SEG_DEFAULT;
03672 }
03673
03674
03675
03676 int
03677 sse_comparison_operator (op, mode)
03678 rtx op;
03679 enum machine_mode mode ATTRIBUTE_UNUSED;
03680 {
03681 enum rtx_code code = GET_CODE (op);
03682 switch (code)
03683 {
03684
03685 case EQ:
03686 case LT:
03687 case LE:
03688 case UNORDERED:
03689 case NE:
03690 case UNGE:
03691 case UNGT:
03692 case ORDERED:
03693 return 1;
03694
03695 case UNEQ:
03696 case UNLT:
03697 case UNLE:
03698 case LTGT:
03699 case GE:
03700 case GT:
03701 return !TARGET_IEEE_FP;
03702 default:
03703 return 0;
03704 }
03705 }
03706
03707 int
03708 ix86_comparison_operator (op, mode)
03709 register rtx op;
03710 enum machine_mode mode;
03711 {
03712 enum machine_mode inmode;
03713 enum rtx_code code = GET_CODE (op);
03714 if (mode != VOIDmode && GET_MODE (op) != mode)
03715 return 0;
03716 if (GET_RTX_CLASS (code) != '<')
03717 return 0;
03718 inmode = GET_MODE (XEXP (op, 0));
03719
03720 if (inmode == CCFPmode || inmode == CCFPUmode)
03721 {
03722 enum rtx_code second_code, bypass_code;
03723 ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
03724 return (bypass_code == NIL && second_code == NIL);
03725 }
03726 switch (code)
03727 {
03728 case EQ: case NE:
03729 return 1;
03730 case LT: case GE:
03731 if (inmode == CCmode || inmode == CCGCmode
03732 || inmode == CCGOCmode || inmode == CCNOmode)
03733 return 1;
03734 return 0;
03735 case LTU: case GTU: case LEU: case ORDERED: case UNORDERED: case GEU:
03736 if (inmode == CCmode)
03737 return 1;
03738 return 0;
03739 case GT: case LE:
03740 if (inmode == CCmode || inmode == CCGCmode || inmode == CCNOmode)
03741 return 1;
03742 return 0;
03743 default:
03744 return 0;
03745 }
03746 }
03747
03748
03749
03750 int
03751 fcmov_comparison_operator (op, mode)
03752 register rtx op;
03753 enum machine_mode mode;
03754 {
03755 enum machine_mode inmode;
03756 enum rtx_code code = GET_CODE (op);
03757 if (mode != VOIDmode && GET_MODE (op) != mode)
03758 return 0;
03759 if (GET_RTX_CLASS (code) != '<')
03760 return 0;
03761 inmode = GET_MODE (XEXP (op, 0));
03762 if (inmode == CCFPmode || inmode == CCFPUmode)
03763 {
03764 enum rtx_code second_code, bypass_code;
03765 ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
03766 if (bypass_code != NIL || second_code != NIL)
03767 return 0;
03768 code = ix86_fp_compare_code_to_integer (code);
03769 }
03770
03771 switch (code)
03772 {
03773 case LTU: case GTU: case LEU: case GEU:
03774 if (inmode == CCmode || inmode == CCFPmode || inmode == CCFPUmode)
03775 return 1;
03776 return 0;
03777 case ORDERED: case UNORDERED:
03778 case EQ: case NE:
03779 return 1;
03780 default:
03781 return 0;
03782 }
03783 }
03784
03785
03786
03787 int
03788 promotable_binary_operator (op, mode)
03789 register rtx op;
03790 enum machine_mode mode ATTRIBUTE_UNUSED;
03791 {
03792 switch (GET_CODE (op))
03793 {
03794 case MULT:
03795
03796
03797 return ix86_cpu > PROCESSOR_I486;
03798 case PLUS:
03799 case AND:
03800 case IOR:
03801 case XOR:
03802 case ASHIFT:
03803 return 1;
03804 default:
03805 return 0;
03806 }
03807 }
03808
03809
03810
03811
03812
03813 int
03814 cmp_fp_expander_operand (op, mode)
03815 register rtx op;
03816 enum machine_mode mode;
03817 {
03818 if (mode != VOIDmode && mode != GET_MODE (op))
03819 return 0;
03820 if (GET_CODE (op) == CONST_DOUBLE)
03821 return 1;
03822 return general_operand (op, mode);
03823 }
03824
03825
03826
03827 int
03828 ext_register_operand (op, mode)
03829 register rtx op;
03830 enum machine_mode mode ATTRIBUTE_UNUSED;
03831 {
03832 int regno;
03833 if ((!TARGET_64BIT || GET_MODE (op) != DImode)
03834 && GET_MODE (op) != SImode && GET_MODE (op) != HImode)
03835 return 0;
03836
03837 if (!register_operand (op, VOIDmode))
03838 return 0;
03839
03840
03841 regno = REG_P (op) ? REGNO (op) : REGNO (SUBREG_REG (op));
03842 return (regno > LAST_VIRTUAL_REGISTER || regno < 4);
03843 }
03844
03845
03846
03847
03848 int
03849 binary_fp_operator (op, mode)
03850 register rtx op;
03851 enum machine_mode mode;
03852 {
03853 if (mode != VOIDmode && mode != GET_MODE (op))
03854 return 0;
03855
03856 switch (GET_CODE (op))
03857 {
03858 case PLUS:
03859 case MINUS:
03860 case MULT:
03861 case DIV:
03862 return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
03863
03864 default:
03865 return 0;
03866 }
03867 }
03868
03869 int
03870 mult_operator (op, mode)
03871 register rtx op;
03872 enum machine_mode mode ATTRIBUTE_UNUSED;
03873 {
03874 return GET_CODE (op) == MULT;
03875 }
03876
03877 int
03878 div_operator (op, mode)
03879 register rtx op;
03880 enum machine_mode mode ATTRIBUTE_UNUSED;
03881 {
03882 return GET_CODE (op) == DIV;
03883 }
03884
03885 int
03886 arith_or_logical_operator (op, mode)
03887 rtx op;
03888 enum machine_mode mode;
03889 {
03890 return ((mode == VOIDmode || GET_MODE (op) == mode)
03891 && (GET_RTX_CLASS (GET_CODE (op)) == 'c'
03892 || GET_RTX_CLASS (GET_CODE (op)) == '2'));
03893 }
03894
03895
03896
03897 int
03898 memory_displacement_operand (op, mode)
03899 register rtx op;
03900 enum machine_mode mode;
03901 {
03902 struct ix86_address parts;
03903
03904 if (! memory_operand (op, mode))
03905 return 0;
03906
03907 if (! ix86_decompose_address (XEXP (op, 0), &parts))
03908 abort ();
03909
03910 return parts.disp != NULL_RTX;
03911 }
03912
03913
03914
03915
03916
03917
03918
03919 int
03920 cmpsi_operand (op, mode)
03921 rtx op;
03922 enum machine_mode mode;
03923 {
03924 if (nonimmediate_operand (op, mode))
03925 return 1;
03926
03927 if (GET_CODE (op) == AND
03928 && GET_MODE (op) == SImode
03929 && GET_CODE (XEXP (op, 0)) == ZERO_EXTRACT
03930 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
03931 && GET_CODE (XEXP (XEXP (op, 0), 2)) == CONST_INT
03932 && INTVAL (XEXP (XEXP (op, 0), 1)) == 8
03933 && INTVAL (XEXP (XEXP (op, 0), 2)) == 8
03934 && GET_CODE (XEXP (op, 1)) == CONST_INT)
03935 return 1;
03936
03937 return 0;
03938 }
03939
03940
03941
03942
03943 int
03944 long_memory_operand (op, mode)
03945 register rtx op;
03946 enum machine_mode mode;
03947 {
03948 if (! memory_operand (op, mode))
03949 return 0;
03950
03951 return memory_address_length (op) != 0;
03952 }
03953
03954
03955
03956 int
03957 aligned_operand (op, mode)
03958 rtx op;
03959 enum machine_mode mode;
03960 {
03961 struct ix86_address parts;
03962
03963 if (!general_operand (op, mode))
03964 return 0;
03965
03966
03967 if (GET_CODE (op) != MEM)
03968 return 1;
03969
03970
03971 if (MEM_VOLATILE_P (op))
03972 return 0;
03973
03974 op = XEXP (op, 0);
03975
03976
03977 if (GET_CODE (op) == PRE_DEC
03978 || GET_CODE (op) == POST_INC)
03979 return 1;
03980
03981
03982 if (! ix86_decompose_address (op, &parts))
03983 abort ();
03984
03985 if (parts.base && GET_CODE (parts.base) == SUBREG)
03986 parts.base = SUBREG_REG (parts.base);
03987 if (parts.index && GET_CODE (parts.index) == SUBREG)
03988 parts.index = SUBREG_REG (parts.index);
03989
03990
03991 if (parts.index)
03992 {
03993 if (parts.scale < 4
03994 && REGNO_POINTER_ALIGN (REGNO (parts.index)) < 32)
03995 return 0;
03996 }
03997 if (parts.base)
03998 {
03999 if (REGNO_POINTER_ALIGN (REGNO (parts.base)) < 32)
04000 return 0;
04001 }
04002 if (parts.disp)
04003 {
04004 if (GET_CODE (parts.disp) != CONST_INT
04005 || (INTVAL (parts.disp) & 3) != 0)
04006 return 0;
04007 }
04008
04009
04010 return 1;
04011 }
04012
04013
04014
04015
04016
04017 int
04018 standard_80387_constant_p (x)
04019 rtx x;
04020 {
04021 if (GET_CODE (x) != CONST_DOUBLE || !FLOAT_MODE_P (GET_MODE (x)))
04022 return -1;
04023
04024
04025
04026 if (x == CONST0_RTX (GET_MODE (x)))
04027 return 1;
04028 if (x == CONST1_RTX (GET_MODE (x)))
04029 return 2;
04030 return 0;
04031 }
04032
04033
04034
04035 int
04036 standard_sse_constant_p (x)
04037 rtx x;
04038 {
04039 if (x == const0_rtx)
04040 return 1;
04041 return (x == CONST0_RTX (GET_MODE (x)));
04042 }
04043
04044
04045
04046 int
04047 symbolic_reference_mentioned_p (op)
04048 rtx op;
04049 {
04050 register const char *fmt;
04051 register int i;
04052
04053 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
04054 return 1;
04055
04056 fmt = GET_RTX_FORMAT (GET_CODE (op));
04057 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
04058 {
04059 if (fmt[i] == 'E')
04060 {
04061 register int j;
04062
04063 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
04064 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
04065 return 1;
04066 }
04067
04068 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
04069 return 1;
04070 }
04071
04072 return 0;
04073 }
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083
04084
04085
04086
04087 int
04088 ix86_can_use_return_insn_p ()
04089 {
04090 struct ix86_frame frame;
04091
04092 #ifdef NON_SAVING_SETJMP
04093 if (NON_SAVING_SETJMP && current_function_calls_setjmp)
04094 return 0;
04095 #endif
04096
04097 if (! reload_completed || frame_pointer_needed)
04098 return 0;
04099
04100
04101
04102 if (current_function_pops_args
04103 && current_function_args_size >= 32768)
04104 return 0;
04105
04106 ix86_compute_frame_layout (&frame);
04107 return frame.to_allocate == 0 && frame.nregs == 0;
04108 }
04109
04110
04111 int
04112 x86_64_sign_extended_value (value)
04113 rtx value;
04114 {
04115 switch (GET_CODE (value))
04116 {
04117
04118
04119
04120 case CONST_INT:
04121 if (HOST_BITS_PER_WIDE_INT == 32)
04122 return 1;
04123 else
04124 {
04125 HOST_WIDE_INT val = trunc_int_for_mode (INTVAL (value), DImode);
04126 return trunc_int_for_mode (val, SImode) == val;
04127 }
04128 break;
04129
04130
04131
04132
04133
04134 case SYMBOL_REF:
04135 return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_KERNEL)
04136 && !tls_symbolic_operand (value, GET_MODE (value));
04137
04138
04139 case LABEL_REF:
04140 return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM
04141 || ix86_cmodel == CM_KERNEL);
04142
04143
04144
04145 case CONST:
04146 if (GET_CODE (XEXP (value, 0)) == UNSPEC)
04147 switch (XINT (XEXP (value, 0), 1))
04148 {
04149 case UNSPEC_GOTPCREL:
04150 case UNSPEC_DTPOFF:
04151 case UNSPEC_GOTNTPOFF:
04152 case UNSPEC_NTPOFF:
04153 return 1;
04154 default:
04155 break;
04156 }
04157 if (GET_CODE (XEXP (value, 0)) == PLUS)
04158 {
04159 rtx op1 = XEXP (XEXP (value, 0), 0);
04160 rtx op2 = XEXP (XEXP (value, 0), 1);
04161 HOST_WIDE_INT offset;
04162
04163 if (ix86_cmodel == CM_LARGE)
04164 return 0;
04165 if (GET_CODE (op2) != CONST_INT)
04166 return 0;
04167 offset = trunc_int_for_mode (INTVAL (op2), DImode);
04168 switch (GET_CODE (op1))
04169 {
04170 case SYMBOL_REF:
04171
04172
04173
04174
04175 if (ix86_cmodel == CM_SMALL
04176 && offset < 16*1024*1024
04177 && trunc_int_for_mode (offset, SImode) == offset)
04178 return 1;
04179
04180
04181
04182
04183 if (ix86_cmodel == CM_KERNEL
04184 && offset > 0
04185 && trunc_int_for_mode (offset, SImode) == offset)
04186 return 1;
04187 break;
04188 case LABEL_REF:
04189
04190
04191 if ((ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM)
04192 && offset < 16*1024*1024
04193 && trunc_int_for_mode (offset, SImode) == offset)
04194 return 1;
04195 if (ix86_cmodel == CM_KERNEL
04196 && offset > 0
04197 && trunc_int_for_mode (offset, SImode) == offset)
04198 return 1;
04199 break;
04200 case UNSPEC:
04201 switch (XINT (op1, 1))
04202 {
04203 case UNSPEC_DTPOFF:
04204 case UNSPEC_NTPOFF:
04205 if (offset > 0
04206 && trunc_int_for_mode (offset, SImode) == offset)
04207 return 1;
04208 }
04209 break;
04210 default:
04211 return 0;
04212 }
04213 }
04214 return 0;
04215 default:
04216 return 0;
04217 }
04218 }
04219
04220
04221 int
04222 x86_64_zero_extended_value (value)
04223 rtx value;
04224 {
04225 switch (GET_CODE (value))
04226 {
04227 case CONST_DOUBLE:
04228 if (HOST_BITS_PER_WIDE_INT == 32)
04229 return (GET_MODE (value) == VOIDmode
04230 && !CONST_DOUBLE_HIGH (value));
04231 else
04232 return 0;
04233 case CONST_INT:
04234 if (HOST_BITS_PER_WIDE_INT == 32)
04235 return INTVAL (value) >= 0;
04236 else
04237 return !(INTVAL (value) & ~(HOST_WIDE_INT) 0xffffffff);
04238 break;
04239
04240
04241
04242 case SYMBOL_REF:
04243 return (ix86_cmodel == CM_SMALL
04244 && !tls_symbolic_operand (value, GET_MODE (value)));
04245
04246
04247 case LABEL_REF:
04248 return ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM;
04249
04250
04251
04252 case CONST:
04253 if (GET_CODE (XEXP (value, 0)) == PLUS)
04254 {
04255 rtx op1 = XEXP (XEXP (value, 0), 0);
04256 rtx op2 = XEXP (XEXP (value, 0), 1);
04257
04258 if (ix86_cmodel == CM_LARGE)
04259 return 0;
04260 switch (GET_CODE (op1))
04261 {
04262 case SYMBOL_REF:
04263 return 0;
04264
04265
04266
04267
04268 if (ix86_cmodel == CM_SMALL
04269 && GET_CODE (op2) == CONST_INT
04270 && trunc_int_for_mode (INTVAL (op2), DImode) > -0x10000
04271 && (trunc_int_for_mode (INTVAL (op2), SImode)
04272 == INTVAL (op2)))
04273 return 1;
04274
04275
04276
04277
04278 break;
04279 case LABEL_REF:
04280
04281
04282 if ((ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM)
04283 && GET_CODE (op2) == CONST_INT
04284 && trunc_int_for_mode (INTVAL (op2), DImode) > -0x10000
04285 && (trunc_int_for_mode (INTVAL (op2), SImode)
04286 == INTVAL (op2)))
04287 return 1;
04288 break;
04289 default:
04290 return 0;
04291 }
04292 }
04293 return 0;
04294 default:
04295 return 0;
04296 }
04297 }
04298
04299
04300
04301
04302
04303 int
04304 ix86_frame_pointer_required ()
04305 {
04306
04307
04308 if (cfun->machine->accesses_prev_frame)
04309 return 1;
04310
04311
04312
04313 if (SUBTARGET_FRAME_POINTER_REQUIRED)
04314 return 1;
04315
04316
04317
04318
04319 if (TARGET_OMIT_LEAF_FRAME_POINTER
04320 && (!current_function_is_leaf))
04321 return 1;
04322
04323 if (current_function_profile)
04324 return 1;
04325
04326 return 0;
04327 }
04328
04329
04330
04331 void
04332 ix86_setup_frame_addresses ()
04333 {
04334 cfun->machine->accesses_prev_frame = 1;
04335 }
04336
04337 #if defined(HAVE_GAS_HIDDEN) && (defined(SUPPORTS_ONE_ONLY) && SUPPORTS_ONE_ONLY)
04338 # define USE_HIDDEN_LINKONCE 1
04339 #else
04340 # define USE_HIDDEN_LINKONCE 0
04341 #endif
04342
04343 static int pic_labels_used;
04344
04345
04346
04347
04348 static void
04349 get_pc_thunk_name (name, regno)
04350 char name[32];
04351 unsigned int regno;
04352 {
04353 if (USE_HIDDEN_LINKONCE)
04354 sprintf (name, "__i686.get_pc_thunk.%s", reg_names[regno]);
04355 else
04356 ASM_GENERATE_INTERNAL_LABEL (name, "LPR", regno);
04357 }
04358
04359
04360
04361
04362
04363 void
04364 ix86_asm_file_end (file)
04365 FILE *file;
04366 {
04367 rtx xops[2];
04368 int regno;
04369
04370 for (regno = 0; regno < 8; ++regno)
04371 {
04372 char name[32];
04373
04374 if (! ((pic_labels_used >> regno) & 1))
04375 continue;
04376
04377 get_pc_thunk_name (name, regno);
04378
04379 if (USE_HIDDEN_LINKONCE)
04380 {
04381 tree decl;
04382
04383 decl = build_decl (FUNCTION_DECL, get_identifier (name),
04384 error_mark_node);
04385 TREE_PUBLIC (decl) = 1;
04386 TREE_STATIC (decl) = 1;
04387 DECL_ONE_ONLY (decl) = 1;
04388
04389 (*targetm.asm_out.unique_section) (decl, 0);
04390 named_section (decl, NULL, 0);
04391
04392 (*targetm.asm_out.globalize_label) (file, name);
04393 fputs ("\t.hidden\t", file);
04394 assemble_name (file, name);
04395 fputc ('\n', file);
04396 ASM_DECLARE_FUNCTION_NAME (file, name, decl);
04397 }
04398 else
04399 {
04400 text_section ();
04401 ASM_OUTPUT_LABEL (file, name);
04402 }
04403
04404 xops[0] = gen_rtx_REG (SImode, regno);
04405 xops[1] = gen_rtx_MEM (SImode, stack_pointer_rtx);
04406 output_asm_insn ("mov{l}\t{%1, %0|%0, %1}", xops);
04407 output_asm_insn ("ret", xops);
04408 }
04409
04410 #ifdef SUBTARGET_FILE_END
04411 SUBTARGET_FILE_END (file);
04412 #endif
04413 }
04414
04415
04416
04417 const char *
04418 output_set_got (dest)
04419 rtx dest;
04420 {
04421 rtx xops[3];
04422
04423 xops[0] = dest;
04424 xops[1] = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
04425
04426 if (! TARGET_DEEP_BRANCH_PREDICTION || !flag_pic)
04427 {
04428 xops[2] = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
04429
04430 if (!flag_pic)
04431 output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops);
04432 else
04433 output_asm_insn ("call\t%a2", xops);
04434
04435 #if TARGET_MACHO
04436
04437
04438 ASM_OUTPUT_LABEL (asm_out_file, machopic_function_base_name ());
04439 #endif
04440 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
04441 CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
04442
04443 if (flag_pic)
04444 output_asm_insn ("pop{l}\t%0", xops);
04445 }
04446 else
04447 {
04448 char name[32];
04449 get_pc_thunk_name (name, REGNO (dest));
04450 pic_labels_used |= 1 << REGNO (dest);
04451
04452 xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
04453 xops[2] = gen_rtx_MEM (QImode, xops[2]);
04454 output_asm_insn ("call\t%X2", xops);
04455 }
04456
04457 if (!flag_pic || TARGET_DEEP_BRANCH_PREDICTION)
04458 output_asm_insn ("add{l}\t{%1, %0|%0, %1}", xops);
04459 else if (!TARGET_MACHO)
04460 output_asm_insn ("add{l}\t{%1+[.-%a2], %0|%0, %a1+(.-%a2)}", xops);
04461
04462 return "";
04463 }
04464
04465
04466
04467 static rtx
04468 gen_push (arg)
04469 rtx arg;
04470 {
04471 return gen_rtx_SET (VOIDmode,
04472 gen_rtx_MEM (Pmode,
04473 gen_rtx_PRE_DEC (Pmode,
04474 stack_pointer_rtx)),
04475 arg);
04476 }
04477
04478
04479
04480
04481 static unsigned int
04482 ix86_select_alt_pic_regnum ()
04483 {
04484 if (current_function_is_leaf && !current_function_profile)
04485 {
04486 int i;
04487 for (i = 2; i >= 0; --i)
04488 if (!regs_ever_live[i])
04489 return i;
04490 }
04491
04492 return INVALID_REGNUM;
04493 }
04494
04495
04496 static int
04497 ix86_save_reg (regno, maybe_eh_return)
04498 unsigned int regno;
04499 int maybe_eh_return;
04500 {
04501 if (pic_offset_table_rtx
04502 && regno == REAL_PIC_OFFSET_TABLE_REGNUM
04503 && (regs_ever_live[REAL_PIC_OFFSET_TABLE_REGNUM]
04504 || current_function_profile
04505 || current_function_calls_eh_return
04506 || current_function_uses_const_pool))
04507 {
04508 if (ix86_select_alt_pic_regnum () != INVALID_REGNUM)
04509 return 0;
04510 return 1;
04511 }
04512
04513 if (current_function_calls_eh_return && maybe_eh_return)
04514 {
04515 unsigned i;
04516 for (i = 0; ; i++)
04517 {
04518 unsigned test = EH_RETURN_DATA_REGNO (i);
04519 if (test == INVALID_REGNUM)
04520 break;
04521 if (test == regno)
04522 return 1;
04523 }
04524 }
04525
04526 return (regs_ever_live[regno]
04527 && !call_used_regs[regno]
04528 && !fixed_regs[regno]
04529 && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed));
04530 }
04531
04532
04533
04534 static int
04535 ix86_nsaved_regs ()
04536 {
04537 int nregs = 0;
04538 int regno;
04539
04540 for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
04541 if (ix86_save_reg (regno, true))
04542 nregs++;
04543 return nregs;
04544 }
04545
04546
04547
04548
04549 HOST_WIDE_INT
04550 ix86_initial_elimination_offset (from, to)
04551 int from;
04552 int to;
04553 {
04554 struct ix86_frame frame;
04555 ix86_compute_frame_layout (&frame);
04556
04557 if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
04558 return frame.hard_frame_pointer_offset;
04559 else if (from == FRAME_POINTER_REGNUM
04560 && to == HARD_FRAME_POINTER_REGNUM)
04561 return frame.hard_frame_pointer_offset - frame.frame_pointer_offset;
04562 else
04563 {
04564 if (to != STACK_POINTER_REGNUM)
04565 abort ();
04566 else if (from == ARG_POINTER_REGNUM)
04567 return frame.stack_pointer_offset;
04568 else if (from != FRAME_POINTER_REGNUM)
04569 abort ();
04570 else
04571 return frame.stack_pointer_offset - frame.frame_pointer_offset;
04572 }
04573 }
04574
04575
04576
04577 static void
04578 ix86_compute_frame_layout (frame)
04579 struct ix86_frame *frame;
04580 {
04581 HOST_WIDE_INT total_size;
04582 int stack_alignment_needed = cfun->stack_alignment_needed / BITS_PER_UNIT;
04583 int offset;
04584 int preferred_alignment = cfun->preferred_stack_boundary / BITS_PER_UNIT;
04585 HOST_WIDE_INT size = get_frame_size ();
04586
04587 frame->nregs = ix86_nsaved_regs ();
04588 total_size = size;
04589
04590
04591 offset = frame_pointer_needed ? UNITS_PER_WORD * 2 : UNITS_PER_WORD;
04592
04593 frame->hard_frame_pointer_offset = offset;
04594
04595
04596
04597
04598
04599 if (size && !stack_alignment_needed)
04600 abort ();
04601 if (preferred_alignment < STACK_BOUNDARY / BITS_PER_UNIT)
04602 abort ();
04603 if (preferred_alignment > PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
04604 abort ();
04605 if (stack_alignment_needed > PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
04606 abort ();
04607
04608 if (stack_alignment_needed < STACK_BOUNDARY / BITS_PER_UNIT)
04609 stack_alignment_needed = STACK_BOUNDARY / BITS_PER_UNIT;
04610
04611
04612 offset += frame->nregs * UNITS_PER_WORD;
04613
04614
04615 if (ix86_save_varrargs_registers)
04616 {
04617 offset += X86_64_VARARGS_SIZE;
04618 frame->va_arg_size = X86_64_VARARGS_SIZE;
04619 }
04620 else
04621 frame->va_arg_size = 0;
04622
04623
04624 frame->padding1 = ((offset + stack_alignment_needed - 1)
04625 & -stack_alignment_needed) - offset;
04626
04627 offset += frame->padding1;
04628
04629
04630 frame->frame_pointer_offset = offset;
04631
04632 offset += size;
04633
04634
04635
04636 if (ACCUMULATE_OUTGOING_ARGS && !current_function_is_leaf)
04637 {
04638 offset += current_function_outgoing_args_size;
04639 frame->outgoing_arguments_size = current_function_outgoing_args_size;
04640 }
04641 else
04642 frame->outgoing_arguments_size = 0;
04643
04644
04645
04646 if (!current_function_is_leaf || current_function_calls_alloca)
04647 frame->padding2 = ((offset + preferred_alignment - 1)
04648 & -preferred_alignment) - offset;
04649 else
04650 frame->padding2 = 0;
04651
04652 offset += frame->padding2;
04653
04654
04655 frame->stack_pointer_offset = offset;
04656
04657
04658 frame->to_allocate =
04659 (size + frame->padding1 + frame->padding2
04660 + frame->outgoing_arguments_size + frame->va_arg_size);
04661
04662 if (TARGET_64BIT && TARGET_RED_ZONE && current_function_sp_is_unchanging
04663 && current_function_is_leaf)
04664 {
04665 frame->red_zone_size = frame->to_allocate;
04666 if (frame->red_zone_size > RED_ZONE_SIZE - RED_ZONE_RESERVE)
04667 frame->red_zone_size = RED_ZONE_SIZE - RED_ZONE_RESERVE;
04668 }
04669 else
04670 frame->red_zone_size = 0;
04671 frame->to_allocate -= frame->red_zone_size;
04672 frame->stack_pointer_offset -= frame->red_zone_size;
04673 #if 0
04674 fprintf (stderr, "nregs: %i\n", frame->nregs);
04675 fprintf (stderr, "size: %i\n", size);
04676 fprintf (stderr, "alignment1: %i\n", stack_alignment_needed);
04677 fprintf (stderr, "padding1: %i\n", frame->padding1);
04678 fprintf (stderr, "va_arg: %i\n", frame->va_arg_size);
04679 fprintf (stderr, "padding2: %i\n", frame->padding2);
04680 fprintf (stderr, "to_allocate: %i\n", frame->to_allocate);
04681 fprintf (stderr, "red_zone_size: %i\n", frame->red_zone_size);
04682 fprintf (stderr, "frame_pointer_offset: %i\n", frame->frame_pointer_offset);
04683 fprintf (stderr, "hard_frame_pointer_offset: %i\n",
04684 frame->hard_frame_pointer_offset);
04685 fprintf (stderr, "stack_pointer_offset: %i\n", frame->stack_pointer_offset);
04686 #endif
04687 }
04688
04689
04690
04691 static void
04692 ix86_emit_save_regs ()
04693 {
04694 register int regno;
04695 rtx insn;
04696
04697 for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
04698 if (ix86_save_reg (regno, true))
04699 {
04700 insn = emit_insn (gen_push (gen_rtx_REG (Pmode, regno)));
04701 RTX_FRAME_RELATED_P (insn) = 1;
04702 }
04703 }
04704
04705
04706
04707 static void
04708 ix86_emit_save_regs_using_mov (pointer, offset)
04709 rtx pointer;
04710 HOST_WIDE_INT offset;
04711 {
04712 int regno;
04713 rtx insn;
04714
04715 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
04716 if (ix86_save_reg (regno, true))
04717 {
04718 insn = emit_move_insn (adjust_address (gen_rtx_MEM (Pmode, pointer),
04719 Pmode, offset),
04720 gen_rtx_REG (Pmode, regno));
04721 RTX_FRAME_RELATED_P (insn) = 1;
04722 offset += UNITS_PER_WORD;
04723 }
04724 }
04725
04726
04727
04728 void
04729 ix86_expand_prologue ()
04730 {
04731 rtx insn;
04732 bool pic_reg_used;
04733 struct ix86_frame frame;
04734 int use_mov = 0;
04735 HOST_WIDE_INT allocate;
04736
04737 if (!optimize_size)
04738 {
04739 use_fast_prologue_epilogue
04740 = !expensive_function_p (FAST_PROLOGUE_INSN_COUNT);
04741 if (TARGET_PROLOGUE_USING_MOVE)
04742 use_mov = use_fast_prologue_epilogue;
04743 }
04744 ix86_compute_frame_layout (&frame);
04745
04746
04747
04748
04749 if (frame_pointer_needed)
04750 {
04751 insn = emit_insn (gen_push (hard_frame_pointer_rtx));
04752 RTX_FRAME_RELATED_P (insn) = 1;
04753
04754 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
04755 RTX_FRAME_RELATED_P (insn) = 1;
04756 }
04757
04758 allocate = frame.to_allocate;
04759
04760
04761 if (allocate == 0 && frame.nregs <= 1)
04762 use_mov = 0;
04763
04764 if (!use_mov)
04765 ix86_emit_save_regs ();
04766 else
04767 allocate += frame.nregs * UNITS_PER_WORD;
04768
04769 if (allocate == 0)
04770 ;
04771 else if (! TARGET_STACK_PROBE || allocate < CHECK_STACK_LIMIT)
04772 {
04773 insn = emit_insn (gen_pro_epilogue_adjust_stack
04774 (stack_pointer_rtx, stack_pointer_rtx,
04775 GEN_INT (-allocate)));
04776 RTX_FRAME_RELATED_P (insn) = 1;
04777 }
04778 else
04779 {
04780
04781
04782 rtx arg0, sym;
04783
04784 if (TARGET_64BIT)
04785 abort ();
04786
04787 arg0 = gen_rtx_REG (SImode, 0);
04788 emit_move_insn (arg0, GEN_INT (allocate));
04789
04790 sym = gen_rtx_MEM (FUNCTION_MODE,
04791 gen_rtx_SYMBOL_REF (Pmode, "_alloca"));
04792 insn = emit_call_insn (gen_call (sym, const0_rtx, constm1_rtx));
04793
04794 CALL_INSN_FUNCTION_USAGE (insn)
04795 = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, arg0),
04796 CALL_INSN_FUNCTION_USAGE (insn));
04797
04798
04799
04800 emit_insn (gen_blockage (const0_rtx));
04801 }
04802 if (use_mov)
04803 {
04804 if (!frame_pointer_needed || !frame.to_allocate)
04805 ix86_emit_save_regs_using_mov (stack_pointer_rtx, frame.to_allocate);
04806 else
04807 ix86_emit_save_regs_using_mov (hard_frame_pointer_rtx,
04808 -frame.nregs * UNITS_PER_WORD);
04809 }
04810
04811 #ifdef SUBTARGET_PROLOGUE
04812 SUBTARGET_PROLOGUE;
04813 #endif
04814
04815 pic_reg_used = false;
04816 if (pic_offset_table_rtx
04817 && (regs_ever_live[REAL_PIC_OFFSET_TABLE_REGNUM]
04818 || current_function_profile))
04819 {
04820 unsigned int alt_pic_reg_used = ix86_select_alt_pic_regnum ();
04821
04822 if (alt_pic_reg_used != INVALID_REGNUM)
04823 REGNO (pic_offset_table_rtx) = alt_pic_reg_used;
04824
04825 pic_reg_used = true;
04826 }
04827
04828 if (pic_reg_used)
04829 {
04830 insn = emit_insn (gen_set_got (pic_offset_table_rtx));
04831
04832
04833
04834
04835
04836
04837
04838 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx, NULL);
04839 }
04840
04841
04842
04843 if (current_function_profile)
04844 emit_insn (gen_blockage (pic_reg_used ? pic_offset_table_rtx : const0_rtx));
04845 }
04846
04847
04848
04849 static void
04850 ix86_emit_restore_regs_using_mov (pointer, offset, maybe_eh_return)
04851 rtx pointer;
04852 int offset;
04853 int maybe_eh_return;
04854 {
04855 int regno;
04856
04857 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
04858 if (ix86_save_reg (regno, maybe_eh_return))
04859 {
04860 emit_move_insn (gen_rtx_REG (Pmode, regno),
04861 adjust_address (gen_rtx_MEM (Pmode, pointer),
04862 Pmode, offset));
04863 offset += UNITS_PER_WORD;
04864 }
04865 }
04866
04867
04868
04869 void
04870 ix86_expand_epilogue (style)
04871 int style;
04872 {
04873 int regno;
04874 int sp_valid = !frame_pointer_needed || current_function_sp_is_unchanging;
04875 struct ix86_frame frame;
04876 HOST_WIDE_INT offset;
04877
04878 ix86_compute_frame_layout (&frame);
04879
04880
04881
04882
04883
04884 offset = frame.nregs;
04885 if (current_function_calls_eh_return && style != 2)
04886 offset -= 2;
04887 offset *= -UNITS_PER_WORD;
04888
04889
04890
04891
04892
04893
04894
04895
04896
04897
04898
04899 if ((!sp_valid && frame.nregs <= 1)
04900 || (TARGET_EPILOGUE_USING_MOVE
04901 && use_fast_prologue_epilogue
04902 && (frame.nregs > 1 || frame.to_allocate))
04903 || (frame_pointer_needed && !frame.nregs && frame.to_allocate)
04904 || (frame_pointer_needed && TARGET_USE_LEAVE
04905 && use_fast_prologue_epilogue && frame.nregs == 1)
04906 || current_function_calls_eh_return)
04907 {
04908
04909
04910
04911
04912
04913
04914 if (!frame_pointer_needed || (sp_valid && !frame.to_allocate))
04915 ix86_emit_restore_regs_using_mov (stack_pointer_rtx,
04916 frame.to_allocate, style == 2);
04917 else
04918 ix86_emit_restore_regs_using_mov (hard_frame_pointer_rtx,
04919 offset, style == 2);
04920
04921
04922 if (style == 2)
04923 {
04924 rtx tmp, sa = EH_RETURN_STACKADJ_RTX;
04925
04926 if (frame_pointer_needed)
04927 {
04928 tmp = gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, sa);
04929 tmp = plus_constant (tmp, UNITS_PER_WORD);
04930 emit_insn (gen_rtx_SET (VOIDmode, sa, tmp));
04931
04932 tmp = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
04933 emit_move_insn (hard_frame_pointer_rtx, tmp);
04934
04935 emit_insn (gen_pro_epilogue_adjust_stack
04936 (stack_pointer_rtx, sa, const0_rtx));
04937 }
04938 else
04939 {
04940 tmp = gen_rtx_PLUS (Pmode, stack_pointer_rtx, sa);
04941 tmp = plus_constant (tmp, (frame.to_allocate
04942 + frame.nregs * UNITS_PER_WORD));
04943 emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx, tmp));
04944 }
04945 }
04946 else if (!frame_pointer_needed)
04947 emit_insn (gen_pro_epilogue_adjust_stack
04948 (stack_pointer_rtx, stack_pointer_rtx,
04949 GEN_INT (frame.to_allocate
04950 + frame.nregs * UNITS_PER_WORD)));
04951
04952 else if (TARGET_USE_LEAVE || optimize_size || !use_fast_prologue_epilogue)
04953 emit_insn (TARGET_64BIT ? gen_leave_rex64 () : gen_leave ());
04954 else
04955 {
04956 emit_insn (gen_pro_epilogue_adjust_stack (stack_pointer_rtx,
04957 hard_frame_pointer_rtx,
04958 const0_rtx));
04959 if (TARGET_64BIT)
04960 emit_insn (gen_popdi1 (hard_frame_pointer_rtx));
04961 else
04962 emit_insn (gen_popsi1 (hard_frame_pointer_rtx));
04963 }
04964 }
04965 else
04966 {
04967
04968
04969 if (!sp_valid)
04970 {
04971 if (!frame_pointer_needed)
04972 abort ();
04973 emit_insn (gen_pro_epilogue_adjust_stack (stack_pointer_rtx,
04974 hard_frame_pointer_rtx,
04975 GEN_INT (offset)));
04976 }
04977 else if (frame.to_allocate)
04978 emit_insn (gen_pro_epilogue_adjust_stack
04979 (stack_pointer_rtx, stack_pointer_rtx,
04980 GEN_INT (frame.to_allocate)));
04981
04982 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
04983 if (ix86_save_reg (regno, false))
04984 {
04985 if (TARGET_64BIT)
04986 emit_insn (gen_popdi1 (gen_rtx_REG (Pmode, regno)));
04987 else
04988 emit_insn (gen_popsi1 (gen_rtx_REG (Pmode, regno)));
04989 }
04990 if (frame_pointer_needed)
04991 {
04992
04993
04994 if (TARGET_USE_LEAVE)
04995 emit_insn (TARGET_64BIT ? gen_leave_rex64 () : gen_leave ());
04996 else if (TARGET_64BIT)
04997 emit_insn (gen_popdi1 (hard_frame_pointer_rtx));
04998 else
04999 emit_insn (gen_popsi1 (hard_frame_pointer_rtx));
05000 }
05001 }
05002
05003
05004 if (style == 0)
05005 return;
05006
05007 if (current_function_pops_args && current_function_args_size)
05008 {
05009 rtx popc = GEN_INT (current_function_pops_args);
05010
05011
05012
05013
05014
05015 if (current_function_pops_args >= 65536)
05016 {
05017 rtx ecx = gen_rtx_REG (SImode, 2);
05018
05019
05020 if (TARGET_64BIT)
05021 abort ();
05022
05023 emit_insn (gen_popsi1 (ecx));
05024 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, popc));
05025 emit_jump_insn (gen_return_indirect_internal (ecx));
05026 }
05027 else
05028 emit_jump_insn (gen_return_pop_internal (popc));
05029 }
05030 else
05031 emit_jump_insn (gen_return_internal ());
05032 }
05033
05034
05035
05036 static void
05037 ix86_output_function_epilogue (file, size)
05038 FILE *file ATTRIBUTE_UNUSED;
05039 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
05040 {
05041 if (pic_offset_table_rtx)
05042 REGNO (pic_offset_table_rtx) = REAL_PIC_OFFSET_TABLE_REGNUM;
05043 }
05044
05045
05046
05047
05048
05049
05050 static int
05051 ix86_decompose_address (addr, out)
05052 register rtx addr;
05053 struct ix86_address *out;
05054 {
05055 rtx base = NULL_RTX;
05056 rtx index = NULL_RTX;
05057 rtx disp = NULL_RTX;
05058 HOST_WIDE_INT scale = 1;
05059 rtx scale_rtx = NULL_RTX;
05060 int retval = 1;
05061 enum ix86_address_seg seg = SEG_DEFAULT;
05062
05063 if (REG_P (addr) || GET_CODE (addr) == SUBREG)
05064 base = addr;
05065 else if (GET_CODE (addr) == PLUS)
05066 {
05067 rtx addends[4], op;
05068 int n = 0, i;
05069
05070 op = addr;
05071 do
05072 {
05073 if (n >= 4)
05074 return 0;
05075 addends[n++] = XEXP (op, 1);
05076 op = XEXP (op, 0);
05077 }
05078 while (GET_CODE (op) == PLUS);
05079 if (n >= 4)
05080 return 0;
05081 addends[n] = op;
05082
05083 for (i = 0; i <= n; ++i)
05084 {
05085 op = addends[i];
05086 switch (GET_CODE (op))
05087 {
05088 case MULT:
05089 if (index)
05090 return 0;
05091 index = XEXP (op, 0);
05092 scale_rtx = XEXP (op, 1);
05093 break;
05094
05095 case UNSPEC:
05096 if (XINT (op, 1) == UNSPEC_TP
05097 && TARGET_TLS_DIRECT_SEG_REFS
05098 && seg == SEG_DEFAULT)
05099 seg = TARGET_64BIT ? SEG_FS : SEG_GS;
05100 else
05101 return 0;
05102 break;
05103
05104 case REG:
05105 case SUBREG:
05106 if (!base)
05107 base = op;
05108 else if (!index)
05109 index = op;
05110 else
05111 return 0;
05112 break;
05113
05114 case CONST:
05115 case CONST_INT:
05116 case SYMBOL_REF:
05117 case LABEL_REF:
05118 if (disp)
05119 return 0;
05120 disp = op;
05121 break;
05122
05123 default:
05124 return 0;
05125 }
05126 }
05127 }
05128 else if (GET_CODE (addr) == MULT)
05129 {
05130 index = XEXP (addr, 0);
05131 scale_rtx = XEXP (addr, 1);
05132 }
05133 else if (GET_CODE (addr) == ASHIFT)
05134 {
05135 rtx tmp;
05136
05137
05138 index = XEXP (addr, 0);
05139 tmp = XEXP (addr, 1);
05140 if (GET_CODE (tmp) != CONST_INT)
05141 return 0;
05142 scale = INTVAL (tmp);
05143 if ((unsigned HOST_WIDE_INT) scale > 3)
05144 return 0;
05145 scale = 1 << scale;
05146 retval = -1;
05147 }
05148 else if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_TP_MEM)
05149 {
05150 if (seg != SEG_DEFAULT)
05151 return 0;
05152 seg = TARGET_64BIT ? SEG_FS : SEG_GS;
05153 disp = const0_rtx;
05154 }
05155 else
05156 disp = addr;
05157
05158
05159 if (scale_rtx)
05160 {
05161 if (GET_CODE (scale_rtx) != CONST_INT)
05162 return 0;
05163 scale = INTVAL (scale_rtx);
05164 }
05165
05166
05167 if (base && index && scale == 1
05168 && (index == arg_pointer_rtx || index == frame_pointer_rtx
05169 || index == stack_pointer_rtx))
05170 {
05171 rtx tmp = base;
05172 base = index;
05173 index = tmp;
05174 }
05175
05176
05177 if ((base == hard_frame_pointer_rtx
05178 || base == frame_pointer_rtx
05179 || base == arg_pointer_rtx) && !disp)
05180 disp = const0_rtx;
05181
05182
05183
05184 if (ix86_cpu == PROCESSOR_K6 && !optimize_size
05185 && base && !index && !disp
05186 && REG_P (base)
05187 && REGNO_REG_CLASS (REGNO (base)) == SIREG)
05188 disp = const0_rtx;
05189
05190
05191 if (!base && index && scale && scale == 2)
05192 base = index, scale = 1;
05193
05194
05195 if (!base && !disp && index && scale != 1)
05196 disp = const0_rtx;
05197
05198 out->base = base;
05199 out->index = index;
05200 out->disp = disp;
05201 out->scale = scale;
05202 out->seg = seg;
05203
05204 return retval;
05205 }
05206
05207
05208
05209
05210
05211
05212 int
05213 ix86_address_cost (x)
05214 rtx x;
05215 {
05216 struct ix86_address parts;
05217 int cost = 1;
05218
05219 if (!ix86_decompose_address (x, &parts))
05220 abort ();
05221
05222 if (parts.base && GET_CODE (parts.base) == SUBREG)
05223 parts.base = SUBREG_REG (parts.base);
05224 if (parts.index && GET_CODE (parts.index) == SUBREG)
05225 parts.index = SUBREG_REG (parts.index);
05226
05227
05228 if (parts.disp && parts.disp != const0_rtx)
05229 cost--;
05230 if (parts.seg != SEG_DEFAULT)
05231 cost--;
05232
05233
05234 if ((parts.base
05235 && (!REG_P (parts.base) || REGNO (parts.base) >= FIRST_PSEUDO_REGISTER))
05236 || (parts.index
05237 && (!REG_P (parts.index)
05238 || REGNO (parts.index) >= FIRST_PSEUDO_REGISTER)))
05239 cost++;
05240
05241 if (parts.base
05242 && (!REG_P (parts.base) || REGNO (parts.base) >= FIRST_PSEUDO_REGISTER)
05243 && parts.index
05244 && (!REG_P (parts.index) || REGNO (parts.index) >= FIRST_PSEUDO_REGISTER)
05245 && parts.base != parts.index)
05246 cost++;
05247
05248
05249
05250
05251
05252
05253
05254
05255
05256
05257
05258
05259
05260
05261
05262
05263 if (TARGET_K6
05264 && ((!parts.disp && parts.base && parts.index && parts.scale != 1)
05265 || (parts.disp && !parts.base && parts.index && parts.scale != 1)
05266 || (!parts.disp && parts.base && parts.index && parts.scale == 1)))
05267 cost += 10;
05268
05269 return cost;
05270 }
05271
05272
05273
05274
05275
05276 rtx
05277 ix86_find_base_term (x)
05278 rtx x;
05279 {
05280 rtx term;
05281
05282 if (TARGET_64BIT)
05283 {
05284 if (GET_CODE (x) != CONST)
05285 return x;
05286 term = XEXP (x, 0);
05287 if (GET_CODE (term) == PLUS
05288 && (GET_CODE (XEXP (term, 1)) == CONST_INT
05289 || GET_CODE (XEXP (term, 1)) == CONST_DOUBLE))
05290 term = XEXP (term, 0);
05291 if (GET_CODE (term) != UNSPEC
05292 || XINT (term, 1) != UNSPEC_GOTPCREL)
05293 return x;
05294
05295 term = XVECEXP (term, 0, 0);
05296
05297 if (GET_CODE (term) != SYMBOL_REF
05298 && GET_CODE (term) != LABEL_REF)
05299 return x;
05300
05301 return term;
05302 }
05303
05304 if (GET_CODE (x) != PLUS
05305 || XEXP (x, 0) != pic_offset_table_rtx
05306 || GET_CODE (XEXP (x, 1)) != CONST)
05307 return x;
05308
05309 term = XEXP (XEXP (x, 1), 0);
05310
05311 if (GET_CODE (term) == PLUS && GET_CODE (XEXP (term, 1)) == CONST_INT)
05312 term = XEXP (term, 0);
05313
05314 if (GET_CODE (term) != UNSPEC
05315 || XINT (term, 1) != UNSPEC_GOTOFF)
05316 return x;
05317
05318 term = XVECEXP (term, 0, 0);
05319
05320 if (GET_CODE (term) != SYMBOL_REF
05321 && GET_CODE (term) != LABEL_REF)
05322 return x;
05323
05324 return term;
05325 }
05326
05327
05328
05329
05330 bool
05331 legitimate_constant_p (x)
05332 rtx x;
05333 {
05334 rtx inner;
05335
05336 switch (GET_CODE (x))
05337 {
05338 case SYMBOL_REF:
05339
05340 if (tls_symbolic_operand (x, Pmode))
05341 return false;
05342 break;
05343
05344 case CONST:
05345 inner = XEXP (x, 0);
05346
05347
05348
05349 if (GET_CODE (inner) == PLUS
05350 && tls_symbolic_operand (XEXP (inner, 0), Pmode))
05351 return false;
05352
05353
05354 if (GET_CODE (inner) == UNSPEC)
05355 switch (XINT (inner, 1))
05356 {
05357 case UNSPEC_TPOFF:
05358 return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
05359 default:
05360 return false;
05361 }
05362 break;
05363
05364 default:
05365 break;
05366 }
05367
05368
05369 return true;
05370 }
05371
05372
05373
05374
05375
05376 static bool
05377 ix86_cannot_force_const_mem (x)
05378 rtx x;
05379 {
05380 return !legitimate_constant_p (x);
05381 }
05382
05383
05384
05385 bool
05386 constant_address_p (x)
05387 rtx x;
05388 {
05389 switch (GET_CODE (x))
05390 {
05391 case LABEL_REF:
05392 case CONST_INT:
05393 return true;
05394
05395 case CONST_DOUBLE:
05396 return TARGET_64BIT;
05397
05398 case CONST:
05399
05400 if (TARGET_MACHO)
05401 return true;
05402
05403 case SYMBOL_REF:
05404 return !flag_pic && legitimate_constant_p (x);
05405
05406 default:
05407 return false;
05408 }
05409 }
05410
05411
05412
05413
05414
05415 bool
05416 legitimate_pic_operand_p (x)
05417 rtx x;
05418 {
05419 rtx inner;
05420
05421 switch (GET_CODE (x))
05422 {
05423 case CONST:
05424 inner = XEXP (x, 0);
05425
05426
05427 if (GET_CODE (inner) == UNSPEC)
05428 switch (XINT (inner, 1))
05429 {
05430 case UNSPEC_TPOFF:
05431 return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
05432 default:
05433 return false;
05434 }
05435
05436
05437 case SYMBOL_REF:
05438 case LABEL_REF:
05439 return legitimate_pic_address_disp_p (x);
05440
05441 default:
05442 return true;
05443 }
05444 }
05445
05446
05447
05448
05449 int
05450 legitimate_pic_address_disp_p (disp)
05451 register rtx disp;
05452 {
05453 bool saw_plus;
05454
05455
05456
05457 if (TARGET_64BIT)
05458 {
05459
05460 if (tls_symbolic_operand (disp, GET_MODE (disp)))
05461 return 0;
05462 if (GET_CODE (disp) == SYMBOL_REF
05463 && ix86_cmodel == CM_SMALL_PIC
05464 && (CONSTANT_POOL_ADDRESS_P (disp)
05465 || SYMBOL_REF_FLAG (disp)))
05466 return 1;
05467 if (GET_CODE (disp) == LABEL_REF)
05468 return 1;
05469 if (GET_CODE (disp) == CONST
05470 && GET_CODE (XEXP (disp, 0)) == PLUS)
05471 {
05472 rtx op0 = XEXP (XEXP (disp, 0), 0);
05473 rtx op1 = XEXP (XEXP (disp, 0), 1);
05474
05475
05476 if (tls_symbolic_operand (op0, GET_MODE (op0)))
05477 return 0;
05478
05479 if (((GET_CODE (op0) == SYMBOL_REF
05480 && ix86_cmodel == CM_SMALL_PIC
05481 && (CONSTANT_POOL_ADDRESS_P (op0)
05482 || SYMBOL_REF_FLAG (op0)))
05483 || GET_CODE (op0) == LABEL_REF)
05484 && GET_CODE (op1) == CONST_INT
05485 && INTVAL (op1) < 16*1024*1024
05486 && INTVAL (op1) >= -16*1024*1024)
05487 return 1;
05488 }
05489 }
05490 if (GET_CODE (disp) != CONST)
05491 return 0;
05492 disp = XEXP (disp, 0);
05493
05494 if (TARGET_64BIT)
05495 {
05496
05497
05498 if (GET_CODE (disp) != UNSPEC
05499 || XINT (disp, 1) != UNSPEC_GOTPCREL)
05500 return 0;
05501
05502 if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
05503 && GET_CODE (XVECEXP (disp, 0, 0)) != LABEL_REF)
05504 return 0;
05505 return 1;
05506 }
05507
05508 saw_plus = false;
05509 if (GET_CODE (disp) == PLUS)
05510 {
05511 if (GET_CODE (XEXP (disp, 1)) != CONST_INT)
05512 return 0;
05513 disp = XEXP (disp, 0);
05514 saw_plus = true;
05515 }
05516
05517
05518 if (TARGET_MACHO && GET_CODE (disp) == MINUS)
05519 {
05520 if (GET_CODE (XEXP (disp, 0)) == LABEL_REF
05521 || GET_CODE (XEXP (disp, 0)) == SYMBOL_REF)
05522 if (GET_CODE (XEXP (disp, 1)) == SYMBOL_REF)
05523 {
05524 const char *sym_name = XSTR (XEXP (disp, 1), 0);
05525 if (strstr (sym_name, "$pb") != 0)
05526 return 1;
05527 }
05528 }
05529
05530 if (GET_CODE (disp) != UNSPEC)
05531 return 0;
05532
05533 switch (XINT (disp, 1))
05534 {
05535 case UNSPEC_GOT:
05536 if (saw_plus)
05537 return false;
05538 return GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF;
05539 case UNSPEC_GOTOFF:
05540 return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
05541 case UNSPEC_GOTTPOFF:
05542 case UNSPEC_GOTNTPOFF:
05543 case UNSPEC_INDNTPOFF:
05544 if (saw_plus)
05545 return false;
05546 return initial_exec_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
05547 case UNSPEC_NTPOFF:
05548 return local_exec_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
05549 case UNSPEC_DTPOFF:
05550 return local_dynamic_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
05551 }
05552
05553 return 0;
05554 }
05555
05556
05557
05558
05559
05560
05561
05562
05563
05564 int
05565 legitimate_address_p (mode, addr, strict)
05566 enum machine_mode mode;
05567 register rtx addr;
05568 int strict;
05569 {
05570 struct ix86_address parts;
05571 rtx base, index, disp;
05572 HOST_WIDE_INT scale;
05573 const char *reason = NULL;
05574 rtx reason_rtx = NULL_RTX;
05575
05576 if (TARGET_DEBUG_ADDR)
05577 {
05578 fprintf (stderr,
05579 "\n======\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
05580 GET_MODE_NAME (mode), strict);
05581 debug_rtx (addr);
05582 }
05583
05584 if (ix86_decompose_address (addr, &parts) <= 0)
05585 {
05586 reason = "decomposition failed";
05587 goto report_error;
05588 }
05589
05590 base = parts.base;
05591 index = parts.index;
05592 disp = parts.disp;
05593 scale = parts.scale;
05594
05595
05596
05597
05598
05599
05600
05601 if (base)
05602 {
05603 rtx reg;
05604 reason_rtx = base;
05605
05606 if (GET_CODE (base) == SUBREG)
05607 reg = SUBREG_REG (base);
05608 else
05609 reg = base;
05610
05611 if (GET_CODE (reg) != REG)
05612 {
05613 reason = "base is not a register";
05614 goto report_error;
05615 }
05616
05617 if (GET_MODE (base) != Pmode)
05618 {
05619 reason = "base is not in Pmode";
05620 goto report_error;
05621 }
05622
05623 if ((strict && ! REG_OK_FOR_BASE_STRICT_P (reg))
05624 || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (reg)))
05625 {
05626 reason = "base is not valid";
05627 goto report_error;
05628 }
05629 }
05630
05631
05632
05633
05634
05635
05636
05637 if (index)
05638 {
05639 rtx reg;
05640 reason_rtx = index;
05641
05642 if (GET_CODE (index) == SUBREG)
05643 reg = SUBREG_REG (index);
05644 else
05645 reg = index;
05646
05647 if (GET_CODE (reg) != REG)
05648 {
05649 reason = "index is not a register";
05650 goto report_error;
05651 }
05652
05653 if (GET_MODE (index) != Pmode)
05654 {
05655 reason = "index is not in Pmode";
05656 goto report_error;
05657 }
05658
05659 if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (reg))
05660 || (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (reg)))
05661 {
05662 reason = "index is not valid";
05663 goto report_error;
05664 }
05665 }
05666
05667
05668 if (scale != 1)
05669 {
05670 reason_rtx = GEN_INT (scale);
05671 if (!index)
05672 {
05673 reason = "scale without index";
05674 goto report_error;
05675 }
05676
05677 if (scale != 2 && scale != 4 && scale != 8)
05678 {
05679 reason = "scale is not a valid multiplier";
05680 goto report_error;
05681 }
05682 }
05683
05684
05685 if (disp)
05686 {
05687 reason_rtx = disp;
05688
05689 if (GET_CODE (disp) == CONST
05690 && GET_CODE (XEXP (disp, 0)) == UNSPEC)
05691 switch (XINT (XEXP (disp, 0), 1))
05692 {
05693 case UNSPEC_GOT:
05694 case UNSPEC_GOTOFF:
05695 case UNSPEC_GOTPCREL:
05696 if (!flag_pic)
05697 abort ();
05698 goto is_legitimate_pic;
05699
05700 case UNSPEC_GOTTPOFF:
05701 case UNSPEC_GOTNTPOFF:
05702 case UNSPEC_INDNTPOFF:
05703 case UNSPEC_NTPOFF:
05704 case UNSPEC_DTPOFF:
05705 break;
05706
05707 default:
05708 reason = "invalid address unspec";
05709 goto report_error;
05710 }
05711
05712 else if (flag_pic && (SYMBOLIC_CONST (disp)
05713 #if TARGET_MACHO
05714 && !machopic_operand_p (disp)
05715 #endif
05716 ))
05717 {
05718 is_legitimate_pic:
05719 if (TARGET_64BIT && (index || base))
05720 {
05721
05722 if (GET_CODE (disp) != CONST
05723 || GET_CODE (XEXP (disp, 0)) != PLUS
05724 || GET_CODE (XEXP (XEXP (disp, 0), 0)) != UNSPEC
05725 || GET_CODE (XEXP (XEXP (disp, 0), 1)) != CONST_INT
05726 || (XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_DTPOFF
05727 && XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_NTPOFF))
05728 {
05729 reason = "non-constant pic memory reference";
05730 goto report_error;
05731 }
05732 }
05733 else if (! legitimate_pic_address_disp_p (disp))
05734 {
05735 reason = "displacement is an invalid pic construct";
05736 goto report_error;
05737 }
05738
05739
05740
05741
05742
05743
05744
05745
05746
05747
05748
05749
05750
05751
05752
05753
05754
05755
05756
05757
05758
05759
05760 }
05761 else if (!CONSTANT_ADDRESS_P (disp))
05762 {
05763 reason = "displacement is not constant";
05764 goto report_error;
05765 }
05766 else if (TARGET_64BIT && !x86_64_sign_extended_value (disp))
05767 {
05768 reason = "displacement is out of range";
05769 goto report_error;
05770 }
05771 else if (!TARGET_64BIT && GET_CODE (disp) == CONST_DOUBLE)
05772 {
05773 reason = "displacement is a const_double";
05774 goto report_error;
05775 }
05776 }
05777
05778
05779 if (TARGET_DEBUG_ADDR)
05780 fprintf (stderr, "Success.\n");
05781 return TRUE;
05782
05783 report_error:
05784 if (TARGET_DEBUG_ADDR)
05785 {
05786 fprintf (stderr, "Error: %s\n", reason);
05787 debug_rtx (reason_rtx);
05788 }
05789 return FALSE;
05790 }
05791
05792
05793
05794 static HOST_WIDE_INT
05795 ix86_GOT_alias_set ()
05796 {
05797 static HOST_WIDE_INT set = -1;
05798 if (set == -1)
05799 set = new_alias_set ();
05800 return set;
05801 }
05802
05803
05804
05805
05806
05807
05808
05809
05810
05811
05812
05813
05814
05815
05816
05817
05818
05819
05820
05821 rtx
05822 legitimize_pic_address (orig, reg)
05823 rtx orig;
05824 rtx reg;
05825 {
05826 rtx addr = orig;
05827 rtx new = orig;
05828 rtx base;
05829
05830 #if TARGET_MACHO
05831 if (reg == 0)
05832 reg = gen_reg_rtx (Pmode);
05833
05834 return machopic_legitimize_pic_address (orig, GET_MODE (orig), reg);
05835 #endif
05836
05837 if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
05838 new = addr;
05839 else if (!TARGET_64BIT && local_symbolic_operand (addr, Pmode))
05840 {
05841
05842
05843
05844 if (reload_in_progress)
05845 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
05846 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
05847 new = gen_rtx_CONST (Pmode, new);
05848 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
05849
05850 if (reg != 0)
05851 {
05852 emit_move_insn (reg, new);
05853 new = reg;
05854 }
05855 }
05856 else if (GET_CODE (addr) == SYMBOL_REF)
05857 {
05858 if (TARGET_64BIT)
05859 {
05860 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTPCREL);
05861 new = gen_rtx_CONST (Pmode, new);
05862 new = gen_rtx_MEM (Pmode, new);
05863 RTX_UNCHANGING_P (new) = 1;
05864 set_mem_alias_set (new, ix86_GOT_alias_set ());
05865
05866 if (reg == 0)
05867 reg = gen_reg_rtx (Pmode);
05868
05869
05870
05871 emit_insn (gen_movsi (reg, new));
05872 new = reg;
05873 }
05874 else
05875 {
05876
05877
05878
05879 if (reload_in_progress)
05880 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
05881 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
05882 new = gen_rtx_CONST (Pmode, new);
05883 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
05884 new = gen_rtx_MEM (Pmode, new);
05885 RTX_UNCHANGING_P (new) = 1;
05886 set_mem_alias_set (new, ix86_GOT_alias_set ());
05887
05888 if (reg == 0)
05889 reg = gen_reg_rtx (Pmode);
05890 emit_move_insn (reg, new);
05891 new = reg;
05892 }
05893 }
05894 else
05895 {
05896 if (GET_CODE (addr) == CONST)
05897 {
05898 addr = XEXP (addr, 0);
05899
05900
05901
05902
05903 if (GET_CODE (addr) == UNSPEC
05904 || (GET_CODE (addr) == PLUS
05905 && GET_CODE (XEXP (addr, 0)) == UNSPEC))
05906 return orig;
05907 if (GET_CODE (addr) != PLUS)
05908 abort ();
05909 }
05910 if (GET_CODE (addr) == PLUS)
05911 {
05912 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
05913
05914
05915
05916 if (local_symbolic_operand (op0, Pmode)
05917 && GET_CODE (op1) == CONST_INT)
05918 {
05919 if (!TARGET_64BIT)
05920 {
05921 if (reload_in_progress)
05922 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
05923 new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
05924 UNSPEC_GOTOFF);
05925 new = gen_rtx_PLUS (Pmode, new, op1);
05926 new = gen_rtx_CONST (Pmode, new);
05927 new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
05928
05929 if (reg != 0)
05930 {
05931 emit_move_insn (reg, new);
05932 new = reg;
05933 }
05934 }
05935 else
05936 {
05937 if (INTVAL (op1) < -16*1024*1024
05938 || INTVAL (op1) >= 16*1024*1024)
05939 new = gen_rtx_PLUS (Pmode, op0, force_reg (Pmode, op1));
05940 }
05941 }
05942 else
05943 {
05944 base = legitimize_pic_address (XEXP (addr, 0), reg);
05945 new = legitimize_pic_address (XEXP (addr, 1),
05946 base == reg ? NULL_RTX : reg);
05947
05948 if (GET_CODE (new) == CONST_INT)
05949 new = plus_constant (base, INTVAL (new));
05950 else
05951 {
05952 if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1)))
05953 {
05954 base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0));
05955 new = XEXP (new, 1);
05956 }
05957 new = gen_rtx_PLUS (Pmode, base, new);
05958 }
05959 }
05960 }
05961 }
05962 return new;
05963 }
05964
05965 static void
05966 ix86_encode_section_info (decl, first)
05967 tree decl;
05968 int first ATTRIBUTE_UNUSED;
05969 {
05970 bool local_p = (*targetm.binds_local_p) (decl);
05971 rtx rtl, symbol;
05972
05973 rtl = DECL_P (decl) ? DECL_RTL (decl) : TREE_CST_RTL (decl);
05974 if (GET_CODE (rtl) != MEM)
05975 return;
05976 symbol = XEXP (rtl, 0);
05977 if (GET_CODE (symbol) != SYMBOL_REF)
05978 return;
05979
05980
05981
05982
05983 if (flag_pic)
05984 SYMBOL_REF_FLAG (symbol) = local_p;
05985
05986
05987
05988
05989
05990 if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
05991 {
05992 const char *symbol_str;
05993 char *newstr;
05994 size_t len;
05995 enum tls_model kind = decl_tls_model (decl);
05996
05997 if (TARGET_64BIT && ! flag_pic)
05998 {
05999
06000
06001 switch (kind)
06002 {
06003 case TLS_MODEL_GLOBAL_DYNAMIC:
06004 kind = TLS_MODEL_INITIAL_EXEC; break;
06005 case TLS_MODEL_LOCAL_DYNAMIC:
06006 kind = TLS_MODEL_LOCAL_EXEC; break;
06007 default:
06008 break;
06009 }
06010 }
06011
06012 symbol_str = XSTR (symbol, 0);
06013
06014 if (symbol_str[0] == '%')
06015 {
06016 if (symbol_str[1] == tls_model_chars[kind])
06017 return;
06018 symbol_str += 2;
06019 }
06020 len = strlen (symbol_str) + 1;
06021 newstr = alloca (len + 2);
06022
06023 newstr[0] = '%';
06024 newstr[1] = tls_model_chars[kind];
06025 memcpy (newstr + 2, symbol_str, len);
06026
06027 XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2 - 1);
06028 }
06029 }
06030
06031
06032
06033 static const char *
06034 ix86_strip_name_encoding (str)
06035 const char *str;
06036 {
06037 if (str[0] == '%')
06038 str += 2;
06039 if (str [0] == '*')
06040 str += 1;
06041 return str;
06042 }
06043
06044
06045
06046 static rtx
06047 get_thread_pointer (to_reg)
06048 int to_reg;
06049 {
06050 rtx tp, reg, insn;
06051
06052 tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
06053 if (!to_reg)
06054 return tp;
06055
06056 reg = gen_reg_rtx (Pmode);
06057 insn = gen_rtx_SET (VOIDmode, reg, tp);
06058 insn = emit_insn (insn);
06059
06060 #if 0
06061
06062
06063
06064 if (flag_peephole2)
06065 {
06066 tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP_MEM);
06067 tp = gen_rtx_MEM (Pmode, tp);
06068 RTX_UNCHANGING_P (tp) = 1;
06069 set_mem_alias_set (tp, ix86_GOT_alias_set ());
06070 set_unique_reg_note (insn, REG_EQUAL, tp);
06071 }
06072 #endif
06073
06074 return reg;
06075 }
06076
06077
06078
06079
06080
06081 static rtx
06082 legitimize_tls_address (x, model, for_mov)
06083 rtx x;
06084 enum tls_model model;
06085 int for_mov;
06086 {
06087 rtx dest, base, off, pic;
06088 int type;
06089
06090 switch (model)
06091 {
06092 case TLS_MODEL_GLOBAL_DYNAMIC:
06093 dest = gen_reg_rtx (Pmode);
06094 if (TARGET_64BIT)
06095 {
06096 rtx rax = gen_rtx_REG (Pmode, 0), insns;
06097
06098 start_sequence ();
06099 emit_call_insn (gen_tls_global_dynamic_64 (rax, x));
06100 insns = get_insns ();
06101 end_sequence ();
06102
06103 emit_libcall_block (insns, dest, rax, x);
06104 }
06105 else
06106 emit_insn (gen_tls_global_dynamic_32 (dest, x));
06107 break;
06108
06109 case TLS_MODEL_LOCAL_DYNAMIC:
06110 base = gen_reg_rtx (Pmode);
06111 if (TARGET_64BIT)
06112 {
06113 rtx rax = gen_rtx_REG (Pmode, 0), insns, note;
06114
06115 start_sequence ();
06116 emit_call_insn (gen_tls_local_dynamic_base_64 (rax));
06117 insns = get_insns ();
06118 end_sequence ();
06119
06120 note = gen_rtx_EXPR_LIST (VOIDmode, const0_rtx, NULL);
06121 note = gen_rtx_EXPR_LIST (VOIDmode, ix86_tls_get_addr (), note);
06122 emit_libcall_block (insns, base, rax, note);
06123 }
06124 else
06125 emit_insn (gen_tls_local_dynamic_base_32 (base));
06126
06127 off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
06128 off = gen_rtx_CONST (Pmode, off);
06129
06130 return gen_rtx_PLUS (Pmode, base, off);
06131
06132 case TLS_MODEL_INITIAL_EXEC:
06133 if (TARGET_64BIT)
06134 {
06135 pic = NULL;
06136 type = UNSPEC_GOTNTPOFF;
06137 }
06138 else if (flag_pic)
06139 {
06140 if (reload_in_progress)
06141 regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
06142 pic = pic_offset_table_rtx;
06143 type = TARGET_GNU_TLS ? UNSPEC_GOTNTPOFF : UNSPEC_GOTTPOFF;
06144 }
06145 else if (!TARGET_GNU_TLS)
06146 {
06147 pic = gen_reg_rtx (Pmode);
06148 emit_insn (gen_set_got (pic));
06149 type = UNSPEC_GOTTPOFF;
06150 }
06151 else
06152 {
06153 pic = NULL;
06154 type = UNSPEC_INDNTPOFF;
06155 }
06156
06157 off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), type);
06158 off = gen_rtx_CONST (Pmode, off);
06159 if (pic)
06160 off = gen_rtx_PLUS (Pmode, pic, off);
06161 off = gen_rtx_MEM (Pmode, off);
06162 RTX_UNCHANGING_P (off) = 1;
06163 set_mem_alias_set (off, ix86_GOT_alias_set ());
06164
06165 if (TARGET_64BIT || TARGET_GNU_TLS)
06166 {
06167 base = get_thread_pointer (for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
06168 off = force_reg (Pmode, off);
06169 return gen_rtx_PLUS (Pmode, base, off);
06170 }
06171 else
06172 {
06173 base = get_thread_pointer (true);
06174 dest = gen_reg_rtx (Pmode);
06175 emit_insn (gen_subsi3 (dest, base, off));
06176 }
06177 break;
06178
06179 case TLS_MODEL_LOCAL_EXEC:
06180 off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
06181 (TARGET_64BIT || TARGET_GNU_TLS
06182 ? UNSPEC_NTPOFF : UNSPEC_TPOFF));
06183 off = gen_rtx_CONST (Pmode, off);
06184
06185 if (TARGET_64BIT || TARGET_GNU_TLS)
06186 {
06187 base = get_thread_pointer (for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
06188 return gen_rtx_PLUS (Pmode, base, off);
06189 }
06190 else
06191 {
06192 base = get_thread_pointer (true);
06193 dest = gen_reg_rtx (Pmode);
06194 emit_insn (gen_subsi3 (dest, base, off));
06195 }
06196 break;
06197
06198 default:
06199 abort ();
06200 }
06201
06202 return dest;
06203 }
06204
06205
06206
06207
06208
06209
06210
06211
06212
06213
06214
06215
06216
06217
06218
06219
06220
06221
06222
06223
06224
06225
06226 rtx
06227 legitimize_address (x, oldx, mode)
06228 register rtx x;
06229 register rtx oldx ATTRIBUTE_UNUSED;
06230 enum machine_mode mode;
06231 {
06232 int changed = 0;
06233 unsigned log;
06234
06235 if (TARGET_DEBUG_ADDR)
06236 {
06237 fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n",
06238 GET_MODE_NAME (mode));
06239 debug_rtx (x);
06240 }
06241
06242 log = tls_symbolic_operand (x, mode);
06243 if (log)
06244 return legitimize_tls_address (x, log, false);
06245
06246 if (flag_pic && SYMBOLIC_CONST (x))
06247 return legitimize_pic_address (x, 0);
06248
06249
06250 if (GET_CODE (x) == ASHIFT
06251 && GET_CODE (XEXP (x, 1)) == CONST_INT
06252 && (log = (unsigned) exact_log2 (INTVAL (XEXP (x, 1)))) < 4)
06253 {
06254 changed = 1;
06255 x = gen_rtx_MULT (Pmode, force_reg (Pmode, XEXP (x, 0)),
06256 GEN_INT (1 << log));
06257 }
06258
06259 if (GET_CODE (x) == PLUS)
06260 {
06261
06262
06263 if (GET_CODE (XEXP (x, 0)) == ASHIFT
06264 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
06265 && (log = (unsigned) exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4)
06266 {
06267 changed = 1;
06268 XEXP (x, 0) = gen_rtx_MULT (Pmode,
06269 force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
06270 GEN_INT (1 << log));
06271 }
06272
06273 if (GET_CODE (XEXP (x, 1)) == ASHIFT
06274 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
06275 && (log = (unsigned) exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4)
06276 {
06277 changed = 1;
06278 XEXP (x, 1) = gen_rtx_MULT (Pmode,
06279 force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
06280 GEN_INT (1 << log));
06281 }
06282
06283
06284 if (GET_CODE (XEXP (x, 1)) == MULT)
06285 {
06286 rtx tmp = XEXP (x, 0);
06287 XEXP (x, 0) = XEXP (x, 1);
06288 XEXP (x, 1) = tmp;
06289 changed = 1;
06290 }
06291
06292
06293
06294
06295
06296 if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
06297 {
06298 changed = 1;
06299 x = gen_rtx_PLUS (Pmode,
06300 gen_rtx_PLUS (Pmode, XEXP (x, 0),
06301 XEXP (XEXP (x, 1), 0)),
06302 XEXP (XEXP (x, 1), 1));
06303 }
06304
06305
06306
06307
06308 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
06309 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
06310 && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
06311 && CONSTANT_P (XEXP (x, 1)))
06312 {
06313 rtx constant;
06314 rtx other = NULL_RTX;
06315
06316 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
06317 {
06318 constant = XEXP (x, 1);
06319 other = XEXP (XEXP (XEXP (x, 0), 1), 1);
06320 }
06321 else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
06322 {
06323 constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
06324 other = XEXP (x, 1);
06325 }
06326 else
06327 constant = 0;
06328
06329 if (constant)
06330 {
06331 changed = 1;
06332 x = gen_rtx_PLUS (Pmode,
06333 gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 0),
06334 XEXP (XEXP (XEXP (x, 0), 1), 0)),
06335 plus_constant (other, INTVAL (constant)));
06336 }
06337 }
06338
06339 if (changed && legitimate_address_p (mode, x, FALSE))
06340 return x;
06341
06342 if (GET_CODE (XEXP (x, 0)) == MULT)
06343 {
06344 changed = 1;
06345 XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
06346 }
06347
06348 if (GET_CODE (XEXP (x, 1)) == MULT)
06349 {
06350 changed = 1;
06351 XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
06352 }
06353
06354 if (changed
06355 && GET_CODE (XEXP (x, 1)) == REG
06356 && GET_CODE (XEXP (x, 0)) == REG)
06357 return x;
06358
06359 if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
06360 {
06361 changed = 1;
06362 x = legitimize_pic_address (x, 0);
06363 }
06364
06365 if (changed && legitimate_address_p (mode, x, FALSE))
06366 return x;
06367
06368 if (GET_CODE (XEXP (x, 0)) == REG)
06369 {
06370 register rtx temp = gen_reg_rtx (Pmode);
06371 register rtx val = force_operand (XEXP (x, 1), temp);
06372 if (val != temp)
06373 emit_move_insn (temp, val);
06374
06375 XEXP (x, 1) = temp;
06376 return x;
06377 }
06378
06379 else if (GET_CODE (XEXP (x, 1)) == REG)
06380 {
06381 register rtx temp = gen_reg_rtx (Pmode);
06382 register rtx val = force_operand (XEXP (x, 0), temp);
06383 if (val != temp)
06384 emit_move_insn (temp, val);
06385
06386 XEXP (x, 0) = temp;
06387 return x;
06388 }
06389 }
06390
06391 return x;
06392 }
06393
06394
06395
06396
06397
06398
06399 static void
06400 output_pic_addr_const (file, x, code)
06401 FILE *file;
06402 rtx x;
06403 int code;
06404 {
06405 char buf[256];
06406
06407 switch (GET_CODE (x))
06408 {
06409 case PC:
06410 if (flag_pic)
06411 putc ('.', file);
06412 else
06413 abort ();
06414 break;
06415
06416 case SYMBOL_REF:
06417 assemble_name (file, XSTR (x, 0));
06418 if (!TARGET_MACHO && code == 'P' && ! SYMBOL_REF_FLAG (x))
06419 fputs ("@PLT", file);
06420 break;
06421
06422 case LABEL_REF:
06423 x = XEXP (x, 0);
06424
06425 case CODE_LABEL:
06426 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
06427 assemble_name (asm_out_file, buf);
06428 break;
06429
06430 case CONST_INT:
06431 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
06432 break;
06433
06434 case CONST:
06435
06436
06437 output_pic_addr_const (file, XEXP (x, 0), code);
06438 break;
06439
06440 case CONST_DOUBLE:
06441 if (GET_MODE (x) == VOIDmode)
06442 {
06443
06444 if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
06445 fprintf (file, "0x%lx%08lx",
06446 (unsigned long) CONST_DOUBLE_HIGH (x),
06447 (unsigned long) CONST_DOUBLE_LOW (x));
06448 else
06449 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
06450 }
06451 else
06452
06453
06454 output_operand_lossage ("floating constant misused");
06455 break;
06456
06457 case PLUS:
06458
06459 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
06460 {
06461 output_pic_addr_const (file, XEXP (x, 0), code);
06462 putc ('+', file);
06463 output_pic_addr_const (file, XEXP (x, 1), code);
06464 }
06465 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
06466 {
06467 output_pic_addr_const (file, XEXP (x, 1), code);
06468 putc ('+', file);
06469 output_pic_addr_const (file, XEXP (x, 0), code);
06470 }
06471 else
06472 abort ();
06473 break;
06474
06475 case MINUS:
06476 if (!TARGET_MACHO)
06477 putc (ASSEMBLER_DIALECT == ASM_INTEL ? '(' : '[', file);
06478 output_pic_addr_const (file, XEXP (x, 0), code);
06479 putc ('-', file);
06480 output_pic_addr_const (file, XEXP (x, 1), code);
06481 if (!TARGET_MACHO)
06482 putc (ASSEMBLER_DIALECT == ASM_INTEL ? ')' : ']', file);
06483 break;
06484
06485 case UNSPEC:
06486 if (XVECLEN (x, 0) != 1)
06487 abort ();
06488 output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
06489 switch (XINT (x, 1))
06490 {
06491 case UNSPEC_GOT:
06492 fputs ("@GOT", file);
06493 break;
06494 case UNSPEC_GOTOFF:
06495 fputs ("@GOTOFF", file);
06496 break;
06497 case UNSPEC_GOTPCREL:
06498 fputs ("@GOTPCREL(%rip)", file);
06499 break;
06500 case UNSPEC_GOTTPOFF:
06501
06502 fputs ("@GOTTPOFF", file);
06503 break;
06504 case UNSPEC_TPOFF:
06505 fputs ("@TPOFF", file);
06506 break;
06507 case UNSPEC_NTPOFF:
06508 if (TARGET_64BIT)
06509 fputs ("@TPOFF", file);
06510 else
06511 fputs ("@NTPOFF", file);
06512 break;
06513 case UNSPEC_DTPOFF:
06514 fputs ("@DTPOFF", file);
06515 break;
06516 case UNSPEC_GOTNTPOFF:
06517 if (TARGET_64BIT)
06518 fputs ("@GOTTPOFF(%rip)", file);
06519 else
06520 fputs ("@GOTNTPOFF", file);
06521 break;
06522 case UNSPEC_INDNTPOFF:
06523 fputs ("@INDNTPOFF", file);
06524 break;
06525 default:
06526 output_operand_lossage ("invalid UNSPEC as operand");
06527 break;
06528 }
06529 break;
06530
06531 default:
06532 output_operand_lossage ("invalid expression as operand");
06533 }
06534 }
06535
06536
06537
06538
06539 void
06540 i386_dwarf_output_addr_const (file, x)
06541 FILE *file;
06542 rtx x;
06543 {
06544 #ifdef ASM_QUAD
06545 fprintf (file, "%s", TARGET_64BIT ? ASM_QUAD : ASM_LONG);
06546 #else
06547 if (TARGET_64BIT)
06548 abort ();
06549 fprintf (file, "%s", ASM_LONG);
06550 #endif
06551 if (flag_pic)
06552 output_pic_addr_const (file, x, '\0');
06553 else
06554 output_addr_const (file, x);
06555 fputc ('\n', file);
06556 }
06557
06558
06559
06560
06561 void
06562 i386_output_dwarf_dtprel (file, size, x)
06563 FILE *file;
06564 int size;
06565 rtx x;
06566 {
06567 fputs (ASM_LONG, file);
06568 output_addr_const (file, x);
06569 fputs ("@DTPOFF", file);
06570 switch (size)
06571 {
06572 case 4:
06573 break;
06574 case 8:
06575 fputs (", 0", file);
06576 break;
06577 default:
06578 abort ();
06579 }
06580 }
06581
06582
06583
06584
06585
06586 rtx
06587 i386_simplify_dwarf_addr (orig_x)
06588 rtx orig_x;
06589 {
06590 rtx x = orig_x, y;
06591
06592 if (GET_CODE (x) == MEM)
06593 x = XEXP (x, 0);
06594
06595 if (TARGET_64BIT)
06596 {
06597 if (GET_CODE (x) != CONST
06598 || GET_CODE (XEXP (x, 0)) != UNSPEC
06599 || XINT (XEXP (x, 0), 1) != UNSPEC_GOTPCREL
06600 || GET_CODE (orig_x) != MEM)
06601 return orig_x;
06602 return XVECEXP (XEXP (x, 0), 0, 0);
06603 }
06604
06605 if (GET_CODE (x) != PLUS
06606 || GET_CODE (XEXP (x, 1)) != CONST)
06607 return orig_x;
06608
06609 if (GET_CODE (XEXP (x, 0)) == REG
06610 && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM)
06611
06612 y = NULL;
06613 else if (GET_CODE (XEXP (x, 0)) == PLUS)
06614 {
06615
06616 y = XEXP (x, 0);
06617 if (GET_CODE (XEXP (y, 0)) == REG
06618 && REGNO (XEXP (y, 0)) == PIC_OFFSET_TABLE_REGNUM)
06619 y = XEXP (y, 1);
06620 else if (GET_CODE (XEXP (y, 1)) == REG
06621 && REGNO (XEXP (y, 1)) == PIC_OFFSET_TABLE_REGNUM)
06622 y = XEXP (y, 0);
06623 else
06624 return orig_x;
06625 if (GET_CODE (y) != REG
06626 && GET_CODE (y) != MULT
06627 && GET_CODE (y) != ASHIFT)
06628 return orig_x;
06629 }
06630 else
06631 return orig_x;
06632
06633 x = XEXP (XEXP (x, 1), 0);
06634 if (GET_CODE (x) == UNSPEC
06635 && ((XINT (x, 1) == UNSPEC_GOT && GET_CODE (orig_x) == MEM)
06636 || (XINT (x, 1) == UNSPEC_GOTOFF && GET_CODE (orig_x) != MEM)))
06637 {
06638 if (y)
06639 return gen_rtx_PLUS (Pmode, y, XVECEXP (x, 0, 0));
06640 return XVECEXP (x, 0, 0);
06641 }
06642
06643 if (GET_CODE (x) == PLUS
06644 && GET_CODE (XEXP (x, 0)) == UNSPEC
06645 && GET_CODE (XEXP (x, 1)) == CONST_INT
06646 && ((XINT (XEXP (x, 0), 1) == UNSPEC_GOT && GET_CODE (orig_x) == MEM)
06647 || (XINT (XEXP (x, 0), 1) == UNSPEC_GOTOFF
06648 && GET_CODE (orig_x) != MEM)))
06649 {
06650 x = gen_rtx_PLUS (VOIDmode, XVECEXP (XEXP (x, 0), 0, 0), XEXP (x, 1));
06651 if (y)
06652 return gen_rtx_PLUS (Pmode, y, x);
06653 return x;
06654 }
06655
06656 return orig_x;
06657 }
06658
06659 static void
06660 put_condition_code (code, mode, reverse, fp, file)
06661 enum rtx_code code;
06662 enum machine_mode mode;
06663 int reverse, fp;
06664 FILE *file;
06665 {
06666 const char *suffix;
06667
06668 if (mode == CCFPmode || mode == CCFPUmode)
06669 {
06670 enum rtx_code second_code, bypass_code;
06671 ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
06672 if (bypass_code != NIL || second_code != NIL)
06673 abort ();
06674 code = ix86_fp_compare_code_to_integer (code);
06675 mode = CCmode;
06676 }
06677 if (reverse)
06678 code = reverse_condition (code);
06679
06680 switch (code)
06681 {
06682 case EQ:
06683 suffix = "e";
06684 break;
06685 case NE:
06686 suffix = "ne";
06687 break;
06688 case GT:
06689 if (mode != CCmode && mode != CCNOmode && mode != CCGCmode)
06690 abort ();
06691 suffix = "g";
06692 break;
06693 case GTU:
06694
06695
06696 if (mode != CCmode)
06697 abort ();
06698 suffix = fp ? "nbe" : "a";
06699 break;
06700 case LT:
06701 if (mode == CCNOmode || mode == CCGOCmode)
06702 suffix = "s";
06703 else if (mode == CCmode || mode == CCGCmode)
06704 suffix = "l";
06705 else
06706 abort ();
06707 break;
06708 case LTU:
06709 if (mode != CCmode)
06710 abort ();
06711 suffix = "b";
06712 break;
06713 case GE:
06714 if (mode == CCNOmode || mode == CCGOCmode)
06715 suffix = "ns";
06716 else if (mode == CCmode || mode == CCGCmode)
06717 suffix = "ge";
06718 else
06719 abort ();
06720 break;
06721 case GEU:
06722
06723 if (mode != CCmode)
06724 abort ();
06725 suffix = fp ? "nb" : "ae";
06726 break;
06727 case LE:
06728 if (mode != CCmode && mode != CCGCmode && mode != CCNOmode)
06729 abort ();
06730 suffix = "le";
06731 break;
06732 case LEU:
06733 if (mode != CCmode)
06734 abort ();
06735 suffix = "be";
06736 break;
06737 case UNORDERED:
06738 suffix = fp ? "u" : "p";
06739 break;
06740 case ORDERED:
06741 suffix = fp ? "nu" : "np";
06742 break;
06743 default:
06744 abort ();
06745 }
06746 fputs (suffix, file);
06747 }
06748
06749 void
06750 print_reg (x, code, file)
06751 rtx x;
06752 int code;
06753 FILE *file;
06754 {
06755 if (REGNO (x) == ARG_POINTER_REGNUM
06756 || REGNO (x) == FRAME_POINTER_REGNUM
06757 || REGNO (x) == FLAGS_REG
06758 || REGNO (x) == FPSR_REG)
06759 abort ();
06760
06761 if (ASSEMBLER_DIALECT == ASM_ATT || USER_LABEL_PREFIX[0] == 0)
06762 putc ('%', file);
06763
06764 if (code == 'w' || MMX_REG_P (x))
06765 code = 2;
06766 else if (code == 'b')
06767 code = 1;
06768 else if (code == 'k')
06769 code = 4;
06770 else if (code == 'q')
06771 code = 8;
06772 else if (code == 'y')
06773 code = 3;
06774 else if (code == 'h')
06775 code = 0;
06776 else
06777 code = GET_MODE_SIZE (GET_MODE (x));
06778
06779
06780
06781 if (REX_INT_REG_P (x))
06782 {
06783 if (!TARGET_64BIT)
06784 abort ();
06785 switch (code)
06786 {
06787 case 0:
06788 error ("extended registers have no high halves");
06789 break;
06790 case 1:
06791 fprintf (file, "r%ib", REGNO (x) - FIRST_REX_INT_REG + 8);
06792 break;
06793 case 2:
06794 fprintf (file, "r%iw", REGNO (x) - FIRST_REX_INT_REG + 8);
06795 break;
06796 case 4:
06797 fprintf (file, "r%id", REGNO (x) - FIRST_REX_INT_REG + 8);
06798 break;
06799 case 8:
06800 fprintf (file, "r%i", REGNO (x) - FIRST_REX_INT_REG + 8);
06801 break;
06802 default:
06803 error ("unsupported operand size for extended register");
06804 break;
06805 }
06806 return;
06807 }
06808 switch (code)
06809 {
06810 case 3:
06811 if (STACK_TOP_P (x))
06812 {
06813 fputs ("st(0)", file);
06814 break;
06815 }
06816
06817 case 8:
06818 case 4:
06819 case 12:
06820 if (! ANY_FP_REG_P (x))
06821 putc (code == 8 && TARGET_64BIT ? 'r' : 'e', file);
06822
06823 case 16:
06824 case 2:
06825 fputs (hi_reg_name[REGNO (x)], file);
06826 break;
06827 case 1:
06828 fputs (qi_reg_name[REGNO (x)], file);
06829 break;
06830 case 0:
06831 fputs (qi_high_reg_name[REGNO (x)], file);
06832 break;
06833 default:
06834 abort ();
06835 }
06836 }
06837
06838
06839
06840
06841
06842 static const char *
06843 get_some_local_dynamic_name ()
06844 {
06845 rtx insn;
06846
06847 if (cfun->machine->some_ld_name)
06848 return cfun->machine->some_ld_name;
06849
06850 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
06851 if (INSN_P (insn)
06852 && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
06853 return cfun->machine->some_ld_name;
06854
06855 abort ();
06856 }
06857
06858 static int
06859 get_some_local_dynamic_name_1 (px, data)
06860 rtx *px;
06861 void *data ATTRIBUTE_UNUSED;
06862 {
06863 rtx x = *px;
06864
06865 if (GET_CODE (x) == SYMBOL_REF
06866 && local_dynamic_symbolic_operand (x, Pmode))
06867 {
06868 cfun->machine->some_ld_name = XSTR (x, 0);
06869 return 1;
06870 }
06871
06872 return 0;
06873 }
06874
06875
06876
06877
06878
06879
06880
06881
06882
06883
06884
06885
06886
06887
06888
06889
06890
06891
06892
06893
06894
06895
06896
06897
06898
06899
06900
06901
06902 void
06903 print_operand (file, x, code)
06904 FILE *file;
06905 rtx x;
06906 int code;
06907 {
06908 if (code)
06909 {
06910 switch (code)
06911 {
06912 case '*':
06913 if (ASSEMBLER_DIALECT == ASM_ATT)
06914 putc ('*', file);
06915 return;
06916
06917 case '&':
06918 assemble_name (file, get_some_local_dynamic_name ());
06919 return;
06920
06921 case 'A':
06922 if (ASSEMBLER_DIALECT == ASM_ATT)
06923 putc ('*', file);
06924 else if (ASSEMBLER_DIALECT == ASM_INTEL)
06925 {
06926
06927
06928 if (GET_CODE (x) != REG)
06929 {
06930 putc ('[', file);
06931 PRINT_OPERAND (file, x, 0);
06932 putc (']', file);
06933 return;
06934 }
06935 }
06936 else
06937 abort ();
06938
06939 PRINT_OPERAND (file, x, 0);
06940 return;
06941
06942
06943 case 'L':
06944 if (ASSEMBLER_DIALECT == ASM_ATT)
06945 putc ('l', file);
06946 return;
06947
06948 case 'W':
06949 if (ASSEMBLER_DIALECT == ASM_ATT)
06950 putc ('w', file);
06951 return;
06952
06953 case 'B':
06954 if (ASSEMBLER_DIALECT == ASM_ATT)
06955 putc ('b', file);
06956 return;
06957
06958 case 'Q':
06959 if (ASSEMBLER_DIALECT == ASM_ATT)
06960 putc ('l', file);
06961 return;
06962
06963 case 'S':
06964 if (ASSEMBLER_DIALECT == ASM_ATT)
06965 putc ('s', file);
06966 return;
06967
06968 case 'T':
06969 if (ASSEMBLER_DIALECT == ASM_ATT)
06970 putc ('t', file);
06971 return;
06972
06973 case 'z':
06974
06975
06976 if (STACK_REG_P (x))
06977 return;
06978
06979
06980 if (ASSEMBLER_DIALECT == ASM_INTEL)
06981 return;
06982
06983
06984 switch (GET_MODE_SIZE (GET_MODE (x)))
06985 {
06986 case 2:
06987 #ifdef HAVE_GAS_FILDS_FISTS
06988 putc ('s', file);
06989 #endif
06990 return;
06991
06992 case 4:
06993 if (GET_MODE (x) == SFmode)
06994 {
06995 putc ('s', file);
06996 return;
06997 }
06998 else
06999 putc ('l', file);
07000 return;
07001
07002 case 12:
07003 case 16:
07004 putc ('t', file);
07005 return;
07006
07007 case 8:
07008 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
07009 {
07010 #ifdef GAS_MNEMONICS
07011 putc ('q', file);
07012 #else
07013 putc ('l', file);
07014 putc ('l', file);
07015 #endif
07016 }
07017 else
07018 putc ('l', file);
07019 return;
07020
07021 default:
07022 abort ();
07023 }
07024
07025 case 'b':
07026 case 'w':
07027 case 'k':
07028 case 'q':
07029 case 'h':
07030 case 'y':
07031 case 'X':
07032 case 'P':
07033 break;
07034
07035 case 's':
07036 if (GET_CODE (x) == CONST_INT || ! SHIFT_DOUBLE_OMITS_COUNT)
07037 {
07038 PRINT_OPERAND (file, x, 0);
07039 putc (',', file);
07040 }
07041 return;
07042
07043 case 'D':
07044
07045
07046
07047 switch (GET_CODE (x))
07048 {
07049 case EQ:
07050 case UNEQ:
07051 fputs ("eq", file);
07052 break;
07053 case LT:
07054 case UNLT:
07055 fputs ("lt", file);
07056 break;
07057 case LE:
07058 case UNLE:
07059 fputs ("le", file);
07060 break;
07061 case UNORDERED:
07062 fputs ("unord", file);
07063 break;
07064 case NE:
07065 case LTGT:
07066 fputs ("neq", file);
07067 break;
07068 case UNGE:
07069 case GE:
07070 fputs ("nlt", file);
07071 break;
07072 case UNGT:
07073 case GT:
07074 fputs ("nle", file);
07075 break;
07076 case ORDERED:
07077 fputs ("ord", file);
07078 break;
07079 default:
07080 abort ();
07081 break;
07082 }
07083 return;
07084 case 'O':
07085 #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
07086 if (ASSEMBLER_DIALECT == ASM_ATT)
07087 {
07088 switch (GET_MODE (x))
07089 {
07090 case HImode: putc ('w', file); break;
07091 case SImode:
07092 case SFmode: putc ('l', file); break;
07093 case DImode:
07094 case DFmode: putc ('q', file); break;
07095 default: abort ();
07096 }
07097 putc ('.', file);
07098 }
07099 #endif
07100 return;
07101 case 'C':
07102 put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 0, 0, file);
07103 return;
07104 case 'F':
07105 #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
07106 if (ASSEMBLER_DIALECT == ASM_ATT)
07107 putc ('.', file);
07108 #endif
07109 put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 0, 1, file);
07110 return;
07111
07112
07113 case 'c':
07114
07115
07116 if (GET_RTX_CLASS (GET_CODE (x)) != '<')
07117 {
07118 output_operand_lossage ("operand is neither a constant nor a condition code, invalid operand code 'c'");
07119 return;
07120 }
07121 put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 1, 0, file);
07122 return;
07123 case 'f':
07124 #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
07125 if (ASSEMBLER_DIALECT == ASM_ATT)
07126 putc ('.', file);
07127 #endif
07128 put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 1, 1, file);
07129 return;
07130 case '+':
07131 {
07132 rtx x;
07133
07134 if (!optimize || optimize_size || !TARGET_BRANCH_PREDICTION_HINTS)
07135 return;
07136
07137 x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
07138 if (x)
07139 {
07140 int pred_val = INTVAL (XEXP (x, 0));
07141
07142 if (pred_val < REG_BR_PROB_BASE * 45 / 100
07143 || pred_val > REG_BR_PROB_BASE * 55 / 100)
07144 {
07145 int taken = pred_val > REG_BR_PROB_BASE / 2;
07146 int cputaken = final_forward_branch_p (current_output_insn) == 0;
07147
07148
07149
07150 if (taken != cputaken)
07151 {
07152
07153
07154 if (taken)
07155 fputs ("ds ; ", file);
07156 else
07157 fputs ("cs ; ", file);
07158 }
07159 }
07160 }
07161 return;
07162 }
07163 default:
07164 output_operand_lossage ("invalid operand code `%c'", code);
07165 }
07166 }
07167
07168 if (GET_CODE (x) == REG)
07169 {
07170 PRINT_REG (x, code, file);
07171 }
07172
07173 else if (GET_CODE (x) == MEM)
07174 {
07175
07176 if (ASSEMBLER_DIALECT == ASM_INTEL && code != 'X' && code != 'P')
07177 {
07178 const char * size;
07179 switch (GET_MODE_SIZE (GET_MODE (x)))
07180 {
07181 case 1: size = "BYTE"; break;
07182 case 2: size = "WORD"; break;
07183 case 4: size = "DWORD"; break;
07184 case 8: size = "QWORD"; break;
07185 case 12: size = "XWORD"; break;
07186 case 16: size = "XMMWORD"; break;
07187 default:
07188 abort ();
07189 }
07190
07191
07192 if (code == 'b')
07193 size = "BYTE";
07194 else if (code == 'w')
07195 size = "WORD";
07196 else if (code == 'k')
07197 size = "DWORD";
07198
07199 fputs (size, file);
07200 fputs (" PTR ", file);
07201 }
07202
07203 x = XEXP (x, 0);
07204 if (flag_pic && CONSTANT_ADDRESS_P (x))
07205 output_pic_addr_const (file, x, code);
07206
07207 else if (CONSTANT_ADDRESS_P (x) && code == 'P'
07208 && GET_CODE (x) != CONST_INT)
07209 output_addr_const (file, x);
07210 else if (this_is_asm_operands && ! address_operand (x, VOIDmode))
07211 output_operand_lossage ("invalid constraints for operand");
07212 else
07213 output_address (x);
07214 }
07215
07216 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
07217 {
07218 REAL_VALUE_TYPE r;
07219 long l;
07220
07221 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
07222 REAL_VALUE_TO_TARGET_SINGLE (r, l);
07223
07224 if (ASSEMBLER_DIALECT == ASM_ATT)
07225 putc ('$', file);
07226 fprintf (file, "0x%lx", l);
07227 }
07228
07229
07230 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
07231 {
07232 char dstr[30];
07233
07234 real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x), sizeof (dstr), 0, 1);
07235 fprintf (file, "%s", dstr);
07236 }
07237
07238 else if (GET_CODE (x) == CONST_DOUBLE
07239 && (GET_MODE (x) == XFmode || GET_MODE (x) == TFmode))
07240 {
07241 char dstr[30];
07242
07243 real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x), sizeof (dstr), 0, 1);
07244 fprintf (file, "%s", dstr);
07245 }
07246
07247 else
07248 {
07249 if (code != 'P')
07250 {
07251 if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
07252 {
07253 if (ASSEMBLER_DIALECT == ASM_ATT)
07254 putc ('$', file);
07255 }
07256 else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
07257 || GET_CODE (x) == LABEL_REF)
07258 {
07259 if (ASSEMBLER_DIALECT == ASM_ATT)
07260 putc ('$', file);
07261 else
07262 fputs ("OFFSET FLAT:", file);
07263 }
07264 }
07265 if (GET_CODE (x) == CONST_INT)
07266 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
07267 else if (flag_pic)
07268 output_pic_addr_const (file, x, code);
07269 else
07270 output_addr_const (file, x);
07271 }
07272 }
07273
07274
07275
07276 void
07277 print_operand_address (file, addr)
07278 FILE *file;
07279 register rtx addr;
07280 {
07281 struct ix86_address parts;
07282 rtx base, index, disp;
07283 int scale;
07284
07285 if (! ix86_decompose_address (addr, &parts))
07286 abort ();
07287
07288 base = parts.base;
07289 index = parts.index;
07290 disp = parts.disp;
07291 scale = parts.scale;
07292
07293 switch (parts.seg)
07294 {
07295 case SEG_DEFAULT:
07296 break;
07297 case SEG_FS:
07298 if (USER_LABEL_PREFIX[0] == 0)
07299 putc ('%', file);
07300 fputs ("fs:", file);
07301 break;
07302 case SEG_GS:
07303 if (USER_LABEL_PREFIX[0] == 0)
07304 putc ('%', file);
07305 fputs ("gs:", file);
07306 break;
07307 default:
07308 abort ();
07309 }
07310
07311 if (!base && !index)
07312 {
07313
07314
07315 if (GET_CODE (disp) == CONST_INT)
07316 {
07317 if (ASSEMBLER_DIALECT == ASM_INTEL && parts.seg == SEG_DEFAULT)
07318 {
07319 if (USER_LABEL_PREFIX[0] == 0)
07320 putc ('%', file);
07321 fputs ("ds:", file);
07322 }
07323 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (disp));
07324 }
07325 else if (flag_pic)
07326 output_pic_addr_const (file, disp, 0);
07327 else
07328 output_addr_const (file, disp);
07329
07330
07331 if (TARGET_64BIT
07332 && ((GET_CODE (disp) == SYMBOL_REF
07333 && ! tls_symbolic_operand (disp, GET_MODE (disp)))
07334 || GET_CODE (disp) == LABEL_REF
07335 || (GET_CODE (disp) == CONST
07336 && GET_CODE (XEXP (disp, 0)) == PLUS
07337 && (GET_CODE (XEXP (XEXP (disp, 0), 0)) == SYMBOL_REF
07338 || GET_CODE (XEXP (XEXP (disp, 0), 0)) == LABEL_REF)
07339 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)))
07340 fputs ("(%rip)", file);
07341 }
07342 else
07343 {
07344 if (ASSEMBLER_DIALECT == ASM_ATT)
07345 {
07346 if (disp)
07347 {
07348 if (flag_pic)
07349 output_pic_addr_const (file, disp, 0);
07350 else if (GET_CODE (disp) == LABEL_REF)
07351 output_asm_label (disp);
07352 else
07353 output_addr_const (file, disp);
07354 }
07355
07356 putc ('(', file);
07357 if (base)
07358 PRINT_REG (base, 0, file);
07359 if (index)
07360 {
07361 putc (',', file);
07362 PRINT_REG (index, 0, file);
07363 if (scale != 1)
07364 fprintf (file, ",%d", scale);
07365 }
07366 putc (')', file);
07367 }
07368 else
07369 {
07370 rtx offset = NULL_RTX;
07371
07372 if (disp)
07373 {
07374
07375 if (GET_CODE (disp) == CONST
07376 && GET_CODE (XEXP (disp, 0)) == PLUS
07377 && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)
07378 {
07379 offset = XEXP (XEXP (disp, 0), 1);
07380 disp = gen_rtx_CONST (VOIDmode,
07381 XEXP (XEXP (disp, 0), 0));
07382 }
07383
07384 if (flag_pic)
07385 output_pic_addr_const (file, disp, 0);
07386 else if (GET_CODE (disp) == LABEL_REF)
07387 output_asm_label (disp);
07388 else if (GET_CODE (disp) == CONST_INT)
07389 offset = disp;
07390 else
07391 output_addr_const (file, disp);
07392 }
07393
07394 putc ('[', file);
07395 if (base)
07396 {
07397 PRINT_REG (base, 0, file);
07398 if (offset)
07399 {
07400 if (INTVAL (offset) >= 0)
07401 putc ('+', file);
07402 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
07403 }
07404 }
07405 else if (offset)
07406 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
07407 else
07408 putc ('0', file);
07409
07410 if (index)
07411 {
07412 putc ('+', file);
07413 PRINT_REG (index, 0, file);
07414 if (scale != 1)
07415 fprintf (file, "*%d", scale);
07416 }
07417 putc (']', file);
07418 }
07419 }
07420 }
07421
07422 bool
07423 output_addr_const_extra (file, x)
07424 FILE *file;
07425 rtx x;
07426 {
07427 rtx op;
07428
07429 if (GET_CODE (x) != UNSPEC)
07430 return false;
07431
07432 op = XVECEXP (x, 0, 0);
07433 switch (XINT (x, 1))
07434 {
07435 case UNSPEC_GOTTPOFF:
07436 output_addr_const (file, op);
07437
07438 fputs ("@GOTTPOFF", file);
07439 break;
07440 case UNSPEC_TPOFF:
07441 output_addr_const (file, op);
07442 fputs ("@TPOFF", file);
07443 break;
07444 case UNSPEC_NTPOFF:
07445 output_addr_const (file, op);
07446 if (TARGET_64BIT)
07447 fputs ("@TPOFF", file);
07448 else
07449 fputs ("@NTPOFF", file);
07450 break;
07451 case UNSPEC_DTPOFF:
07452 output_addr_const (file, op);
07453 fputs ("@DTPOFF", file);
07454 break;
07455 case UNSPEC_GOTNTPOFF:
07456 output_addr_const (file, op);
07457 if (TARGET_64BIT)
07458 fputs ("@GOTTPOFF(%rip)", file);
07459 else
07460 fputs ("@GOTNTPOFF", file);
07461 break;
07462 case UNSPEC_INDNTPOFF:
07463 output_addr_const (file, op);
07464 fputs ("@INDNTPOFF", file);
07465 break;
07466
07467 default:
07468 return false;
07469 }
07470
07471 return true;
07472 }
07473
07474
07475
07476
07477
07478
07479
07480 void
07481 split_di (operands, num, lo_half, hi_half)
07482 rtx operands[];
07483 int num;
07484 rtx lo_half[], hi_half[];
07485 {
07486 while (num--)
07487 {
07488 rtx op = operands[num];
07489
07490
07491
07492 if (GET_CODE (op) == MEM)
07493 {
07494 lo_half[num] = adjust_address (op, SImode, 0);
07495 hi_half[num] = adjust_address (op, SImode, 4);
07496 }
07497 else
07498 {
07499 lo_half[num] = simplify_gen_subreg (SImode, op,
07500 GET_MODE (op) == VOIDmode
07501 ? DImode : GET_MODE (op), 0);
07502 hi_half[num] = simplify_gen_subreg (SImode, op,
07503 GET_MODE (op) == VOIDmode
07504 ? DImode : GET_MODE (op), 4);
07505 }
07506 }
07507 }
07508
07509
07510
07511
07512
07513
07514 void
07515 split_ti (operands, num, lo_half, hi_half)
07516 rtx operands[];
07517 int num;
07518 rtx lo_half[], hi_half[];
07519 {
07520 while (num--)
07521 {
07522 rtx op = operands[num];
07523
07524
07525
07526 if (GET_CODE (op) == MEM)
07527 {
07528 lo_half[num] = adjust_address (op, DImode, 0);
07529 hi_half[num] = adjust_address (op, DImode, 8);
07530 }
07531 else
07532 {
07533 lo_half[num] = simplify_gen_subreg (DImode, op, TImode, 0);
07534 hi_half[num] = simplify_gen_subreg (DImode, op, TImode, 8);
07535 }
07536 }
07537 }
07538
07539
07540
07541
07542
07543
07544
07545
07546
07547 #ifndef SYSV386_COMPAT
07548
07549
07550
07551
07552
07553 #define SYSV386_COMPAT 1
07554 #endif
07555
07556 const char *
07557 output_387_binary_op (insn, operands)
07558 rtx insn;
07559 rtx *operands;
07560 {
07561 static char buf[30];
07562 const char *p;
07563 const char *ssep;
07564 int is_sse = SSE_REG_P (operands[0]) | SSE_REG_P (operands[1]) | SSE_REG_P (operands[2]);
07565
07566 #ifdef ENABLE_CHECKING
07567
07568
07569 if (STACK_REG_P (operands[0])
07570 && ((REG_P (operands[1])
07571 && REGNO (operands[0]) == REGNO (operands[1])
07572 && (STACK_REG_P (operands[2]) || GET_CODE (operands[2]) == MEM))
07573 || (REG_P (operands[2])
07574 && REGNO (operands[0]) == REGNO (operands[2])
07575 && (STACK_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)))
07576 && (STACK_TOP_P (operands[1]) || STACK_TOP_P (operands[2])))
07577 ;
07578 else if (!is_sse)
07579 abort ();
07580 #endif
07581
07582 switch (GET_CODE (operands[3]))
07583 {
07584 case PLUS:
07585 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
07586 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
07587 p = "fiadd";
07588 else
07589 p = "fadd";
07590 ssep = "add";
07591 break;
07592
07593 case MINUS:
07594 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
07595 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
07596 p = "fisub";
07597 else
07598 p = "fsub";
07599 ssep = "sub";
07600 break;
07601
07602 case MULT:
07603 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
07604 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
07605 p = "fimul";
07606 else
07607 p = "fmul";
07608 ssep = "mul";
07609 break;
07610
07611 case DIV:
07612 if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
07613 || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
07614 p = "fidiv";
07615 else
07616 p = "fdiv";
07617 ssep = "div";
07618 break;
07619
07620 default:
07621 abort ();
07622 }
07623
07624 if (is_sse)
07625 {
07626 strcpy (buf, ssep);
07627 if (GET_MODE (operands[0]) == SFmode)
07628 strcat (buf, "ss\t{%2, %0|%0, %2}");
07629 else
07630 strcat (buf, "sd\t{%2, %0|%0, %2}");
07631 return buf;
07632 }
07633 strcpy (buf, p);
07634
07635 switch (GET_CODE (operands[3]))
07636 {
07637 case MULT:
07638 case PLUS:
07639 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
07640 {
07641 rtx temp = operands[2];
07642 operands[2] = operands[1];
07643 operands[1] = temp;
07644 }
07645
07646
07647
07648 if (GET_CODE (operands[2]) == MEM)
07649 {
07650 p = "%z2\t%2";
07651 break;
07652 }
07653
07654 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
07655 {
07656 if (STACK_TOP_P (operands[0]))
07657
07658
07659
07660
07661
07662
07663
07664 p = "p\t{%0, %2|%2, %0}";
07665 else
07666 p = "p\t{%2, %0|%0, %2}";
07667 break;
07668 }
07669
07670 if (STACK_TOP_P (operands[0]))
07671 p = "\t{%y2, %0|%0, %y2}";
07672 else
07673 p = "\t{%2, %0|%0, %2}";
07674 break;
07675
07676 case MINUS:
07677 case DIV:
07678 if (GET_CODE (operands[1]) == MEM)
07679 {
07680 p = "r%z1\t%1";
07681 break;
07682 }
07683
07684 if (GET_CODE (operands[2]) == MEM)
07685 {
07686 p = "%z2\t%2";
07687 break;
07688 }
07689
07690 if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
07691 {
07692 #if SYSV386_COMPAT
07693
07694
07695
07696
07697
07698
07699 if (STACK_TOP_P (operands[0]))
07700 p = "{p\t%0, %2|rp\t%2, %0}";
07701 else
07702 p = "{rp\t%2, %0|p\t%0, %2}";
07703 #else
07704 if (STACK_TOP_P (operands[0]))
07705
07706 p = "rp\t{%0, %2|%2, %0}";
07707 else
07708 p = "p\t{%2, %0|%0, %2}";
07709 #endif
07710 break;
07711 }
07712
07713 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
07714 {
07715 #if SYSV386_COMPAT
07716 if (STACK_TOP_P (operands[0]))
07717 p = "{rp\t%0, %1|p\t%1, %0}";
07718 else
07719 p = "{p\t%1, %0|rp\t%0, %1}";
07720 #else
07721 if (STACK_TOP_P (operands[0]))
07722 p = "p\t{%0, %1|%1, %0}";
07723 else
07724 p = "rp\t{%1, %0|%0, %1}";
07725 #endif
07726 break;
07727 }
07728
07729 if (STACK_TOP_P (operands[0]))
07730 {
07731 if (STACK_TOP_P (operands[1]))
07732 p = "\t{%y2, %0|%0, %y2}";
07733 else
07734 p = "r\t{%y1, %0|%0, %y1}";
07735 break;
07736 }
07737 else if (STACK_TOP_P (operands[1]))
07738 {
07739 #if SYSV386_COMPAT
07740 p = "{\t%1, %0|r\t%0, %1}";
07741 #else
07742 p = "r\t{%1, %0|%0, %1}";
07743 #endif
07744 }
07745 else
07746 {
07747 #if SYSV386_COMPAT
07748 p = "{r\t%2, %0|\t%0, %2}";
07749 #else
07750 p = "\t{%2, %0|%0, %2}";
07751 #endif
07752 }
07753 break;
07754
07755 default:
07756 abort ();
07757 }
07758
07759 strcat (buf, p);
07760 return buf;
07761 }
07762
07763
07764
07765
07766 void
07767 emit_i387_cw_initialization (normal, round_down)
07768 rtx normal, round_down;
07769 {
07770 rtx reg = gen_reg_rtx (HImode);
07771
07772 emit_insn (gen_x86_fnstcw_1 (normal));
07773 emit_move_insn (reg, normal);
07774 if (!TARGET_PARTIAL_REG_STALL && !optimize_size
07775 && !TARGET_64BIT)
07776 emit_insn (gen_movsi_insv_1 (reg, GEN_INT (0xc)));
07777 else
07778 emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0xc00)));
07779 emit_move_insn (round_down, reg);
07780 }
07781
07782
07783
07784
07785
07786 const char *
07787 output_fix_trunc (insn, operands)
07788 rtx insn;
07789 rtx *operands;
07790 {
07791 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
07792 int dimode_p = GET_MODE (operands[0]) == DImode;
07793
07794
07795
07796
07797 if (dimode_p && !stack_top_dies)
07798 output_asm_insn ("fld\t%y1", operands);
07799
07800 if (!STACK_TOP_P (operands[1]))
07801 abort ();
07802
07803 if (GET_CODE (operands[0]) != MEM)
07804 abort ();
07805
07806 output_asm_insn ("fldcw\t%3", operands);
07807 if (stack_top_dies || dimode_p)
07808 output_asm_insn ("fistp%z0\t%0", operands);
07809 else
07810 output_asm_insn ("fist%z0\t%0", operands);
07811 output_asm_insn ("fldcw\t%2", operands);
07812
07813 return "";
07814 }
07815
07816
07817
07818
07819
07820 const char *
07821 output_fp_compare (insn, operands, eflags_p, unordered_p)
07822 rtx insn;
07823 rtx *operands;
07824 int eflags_p, unordered_p;
07825 {
07826 int stack_top_dies;
07827 rtx cmp_op0 = operands[0];
07828 rtx cmp_op1 = operands[1];
07829 int is_sse = SSE_REG_P (operands[0]) | SSE_REG_P (operands[1]);
07830
07831 if (eflags_p == 2)
07832 {
07833 cmp_op0 = cmp_op1;
07834 cmp_op1 = operands[2];
07835 }
07836 if (is_sse)
07837 {
07838 if (GET_MODE (operands[0]) == SFmode)
07839 if (unordered_p)
07840 return "ucomiss\t{%1, %0|%0, %1}";
07841 else
07842 return "comiss\t{%1, %0|%0, %1}";
07843 else
07844 if (unordered_p)
07845 return "ucomisd\t{%1, %0|%0, %1}";
07846 else
07847 return "comisd\t{%1, %0|%0, %1}";
07848 }
07849
07850 if (! STACK_TOP_P (cmp_op0))
07851 abort ();
07852
07853 stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
07854
07855 if (STACK_REG_P (cmp_op1)
07856 && stack_top_dies
07857 && find_regno_note (insn, REG_DEAD, REGNO (cmp_op1))
07858 && REGNO (cmp_op1) != FIRST_STACK_REG)
07859 {
07860
07861
07862
07863
07864 if (eflags_p == 1)
07865 {
07866
07867
07868 if (unordered_p)
07869 output_asm_insn ("fucomip\t{%y1, %0|%0, %y1}", operands);
07870 else
07871 output_asm_insn ("fcomip\t{%y1, %0|%0, %y1}", operands);
07872 return "fstp\t%y0";
07873 }
07874 else
07875 {
07876 if (eflags_p == 2)
07877 {
07878 if (unordered_p)
07879 return "fucompp\n\tfnstsw\t%0";
07880 else
07881 return "fcompp\n\tfnstsw\t%0";
07882 }
07883 else
07884 {
07885 if (unordered_p)
07886 return "fucompp";
07887 else
07888 return "fcompp";
07889 }
07890 }
07891 }
07892 else
07893 {
07894
07895
07896 static const char * const alt[24] =
07897 {
07898 "fcom%z1\t%y1",
07899 "fcomp%z1\t%y1",
07900 "fucom%z1\t%y1",
07901 "fucomp%z1\t%y1",
07902
07903 "ficom%z1\t%y1",
07904 "ficomp%z1\t%y1",
07905 NULL,
07906 NULL,
07907
07908 "fcomi\t{%y1, %0|%0, %y1}",
07909 "fcomip\t{%y1, %0|%0, %y1}",
07910 "fucomi\t{%y1, %0|%0, %y1}",
07911 "fucomip\t{%y1, %0|%0, %y1}",
07912
07913 NULL,
07914 NULL,
07915 NULL,
07916 NULL,
07917
07918 "fcom%z2\t%y2\n\tfnstsw\t%0",
07919 "fcomp%z2\t%y2\n\tfnstsw\t%0",
07920 "fucom%z2\t%y2\n\tfnstsw\t%0",
07921 "fucomp%z2\t%y2\n\tfnstsw\t%0",
07922
07923 "ficom%z2\t%y2\n\tfnstsw\t%0",
07924 "ficomp%z2\t%y2\n\tfnstsw\t%0",
07925 NULL,
07926 NULL
07927 };
07928
07929 int mask;
07930 const char *ret;
07931
07932 mask = eflags_p << 3;
07933 mask |= (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT) << 2;
07934 mask |= unordered_p << 1;
07935 mask |= stack_top_dies;
07936
07937 if (mask >= 24)
07938 abort ();
07939 ret = alt[mask];
07940 if (ret == NULL)
07941 abort ();
07942
07943 return ret;
07944 }
07945 }
07946
07947 void
07948 ix86_output_addr_vec_elt (file, value)
07949 FILE *file;
07950 int value;
07951 {
07952 const char *directive = ASM_LONG;
07953
07954 if (TARGET_64BIT)
07955 {
07956 #ifdef ASM_QUAD
07957 directive = ASM_QUAD;
07958 #else
07959 abort ();
07960 #endif
07961 }
07962
07963 fprintf (file, "%s%s%d\n", directive, LPREFIX, value);
07964 }
07965
07966 void
07967 ix86_output_addr_diff_elt (file, value, rel)
07968 FILE *file;
07969 int value, rel;
07970 {
07971 if (TARGET_64BIT)
07972 fprintf (file, "%s%s%d-%s%d\n",
07973 ASM_LONG, LPREFIX, value, LPREFIX, rel);
07974 else if (HAVE_AS_GOTOFF_IN_DATA)
07975 fprintf (file, "%s%s%d@GOTOFF\n", ASM_LONG, LPREFIX, value);
07976 #if TARGET_MACHO
07977 else if (TARGET_MACHO)
07978 fprintf (file, "%s%s%d-%s\n", ASM_LONG, LPREFIX, value,
07979 machopic_function_base_name () + 1);
07980 #endif
07981 else
07982 asm_fprintf (file, "%s%U%s+[.-%s%d]\n",
07983 ASM_LONG, GOT_SYMBOL_NAME, LPREFIX, value);
07984 }
07985
07986
07987
07988
07989 void
07990 ix86_expand_clear (dest)
07991 rtx dest;
07992 {
07993 rtx tmp;
07994
07995
07996 if (!reload_completed)
07997 abort ();
07998
07999
08000 if (GET_MODE_SIZE (GET_MODE (dest)) < 4)
08001 dest = gen_rtx_REG (SImode, REGNO (dest));
08002
08003 tmp = gen_rtx_SET (VOIDmode, dest, const0_rtx);
08004
08005
08006 if (reload_completed && (!TARGET_USE_MOV0 || optimize_size))
08007 {
08008 rtx clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, 17));
08009 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
08010 }
08011
08012 emit_insn (tmp);
08013 }
08014
08015
08016
08017
08018 static rtx
08019 maybe_get_pool_constant (x)
08020 rtx x;
08021 {
08022 x = XEXP (x, 0);
08023
08024 if (flag_pic && ! TARGET_64BIT)
08025 {
08026 if (GET_CODE (x) != PLUS)
08027 return NULL_RTX;
08028 if (XEXP (x, 0) != pic_offset_table_rtx)
08029 return NULL_RTX;
08030 x = XEXP (x, 1);
08031 if (GET_CODE (x) != CONST)
08032 return NULL_RTX;
08033 x = XEXP (x, 0);
08034 if (GET_CODE (x) != UNSPEC)
08035 return NULL_RTX;
08036 if (XINT (x, 1) != UNSPEC_GOTOFF)
08037 return NULL_RTX;
08038 x = XVECEXP (x, 0, 0);
08039 }
08040
08041 if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
08042 return get_pool_constant (x);
08043
08044 return NULL_RTX;
08045 }
08046
08047 void
08048 ix86_expand_move (mode, operands)
08049 enum machine_mode mode;
08050 rtx operands[];
08051 {
08052 int strict = (reload_in_progress || reload_completed);
08053 rtx op0, op1;
08054 enum tls_model model;
08055
08056 op0 = operands[0];
08057 op1 = operands[1];
08058
08059 model = tls_symbolic_operand (op1, Pmode);
08060 if (model)
08061 {
08062 op1 = legitimize_tls_address (op1, model, true);
08063 op1 = force_operand (op1, op0);
08064 if (op1 == op0)
08065 return;
08066 }
08067
08068 if (flag_pic && mode == Pmode && symbolic_operand (op1, Pmode))
08069 {
08070 #if TARGET_MACHO
08071 if (MACHOPIC_PURE)
08072 {
08073 rtx temp = ((reload_in_progress
08074 || ((op0 && GET_CODE (op0) == REG)
08075 && mode == Pmode))
08076 ? op0 : gen_reg_rtx (Pmode));
08077 op1 = machopic_indirect_data_reference (op1, temp);
08078 op1 = machopic_legitimize_pic_address (op1, mode,
08079 temp == op1 ? 0 : temp);
08080 }
08081 else
08082 {
08083 if (MACHOPIC_INDIRECT)
08084 op1 = machopic_indirect_data_reference (op1, 0);
08085 }
08086 if (op0 != op1)
08087 {
08088 insn = gen_rtx_SET (VOIDmode, op0, op1);
08089 emit_insn (insn);
08090 }
08091 return;
08092 #endif
08093 if (GET_CODE (op0) == MEM)
08094 op1 = force_reg (Pmode, op1);
08095 else
08096 {
08097 rtx temp = op0;
08098 if (GET_CODE (temp) != REG)
08099 temp = gen_reg_rtx (Pmode);
08100 temp = legitimize_pic_address (op1, temp);
08101 if (temp == op0)
08102 return;
08103 op1 = temp;
08104 }
08105 }
08106 else
08107 {
08108 if (GET_CODE (op0) == MEM
08109 && (PUSH_ROUNDING (GET_MODE_SIZE (mode)) != GET_MODE_SIZE (mode)
08110 || !push_operand (op0, mode))
08111 && GET_CODE (op1) == MEM)
08112 op1 = force_reg (mode, op1);
08113
08114 if (push_operand (op0, mode)
08115 && ! general_no_elim_operand (op1, mode))
08116 op1 = copy_to_mode_reg (mode, op1);
08117
08118
08119
08120 if (TARGET_64BIT && mode == DImode
08121 && immediate_operand (op1, mode)
08122 && !x86_64_zero_extended_value (op1)
08123 && !register_operand (op0, mode)
08124 && optimize && !reload_completed && !reload_in_progress)
08125 op1 = copy_to_mode_reg (mode, op1);
08126
08127 if (FLOAT_MODE_P (mode))
08128 {
08129
08130
08131
08132
08133 if (strict)
08134 ;
08135 else if (GET_CODE (op1) == CONST_DOUBLE)
08136 {
08137 op1 = validize_mem (force_const_mem (mode, op1));
08138 if (!register_operand (op0, mode))
08139 {
08140 rtx temp = gen_reg_rtx (mode);
08141 emit_insn (gen_rtx_SET (VOIDmode, temp, op1));
08142 emit_move_insn (op0, temp);
08143 return;
08144 }
08145 }
08146 }
08147 }
08148
08149 emit_insn (gen_rtx_SET (VOIDmode, op0, op1));
08150 }
08151
08152 void
08153 ix86_expand_vector_move (mode, operands)
08154 enum machine_mode mode;
08155 rtx operands[];
08156 {
08157
08158
08159
08160
08161 if ((reload_in_progress | reload_completed) == 0
08162 && register_operand (operands[0], mode)
08163 && CONSTANT_P (operands[1]) && operands[1] != CONST0_RTX (mode))
08164 {
08165 operands[1] = force_const_mem (mode, operands[1]);
08166 emit_move_insn (operands[0], operands[1]);
08167 return;
08168 }
08169
08170
08171 if (!no_new_pseudos
08172 && !register_operand (operands[0], mode)
08173 && !register_operand (operands[1], mode))
08174 {
08175 rtx temp = force_reg (GET_MODE (operands[1]), operands[1]);
08176 emit_move_insn (operands[0], temp);
08177 return;
08178 }
08179
08180 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
08181 }
08182
08183
08184
08185
08186
08187 void
08188 ix86_expand_binary_operator (code, mode, operands)
08189 enum rtx_code code;
08190 enum machine_mode mode;
08191 rtx operands[];
08192 {
08193 int matching_memory;
08194 rtx src1, src2, dst, op, clob;
08195
08196 dst = operands[0];
08197 src1 = operands[1];
08198 src2 = operands[2];
08199
08200
08201 if (GET_RTX_CLASS (code) == 'c'
08202 && (rtx_equal_p (dst, src2)
08203 || immediate_operand (src1, mode)))
08204 {
08205 rtx temp = src1;
08206 src1 = src2;
08207 src2 = temp;
08208 }
08209
08210
08211
08212 matching_memory = 0;
08213 if (GET_CODE (dst) == MEM)
08214 {
08215 if (rtx_equal_p (dst, src1))
08216 matching_memory = 1;
08217 else if (GET_RTX_CLASS (code) == 'c'
08218 && rtx_equal_p (dst, src2))
08219 matching_memory = 2;
08220 else
08221 dst = gen_reg_rtx (mode);
08222 }
08223
08224
08225 if (GET_CODE (src1) == MEM && GET_CODE (src2) == MEM)
08226 {
08227 if (matching_memory != 2)
08228 src2 = force_reg (mode, src2);
08229 else
08230 src1 = force_reg (mode, src1);
08231 }
08232
08233
08234
08235 if ((CONSTANT_P (src1)
08236 || (!matching_memory && GET_CODE (src1) == MEM))
08237 && GET_RTX_CLASS (code) != 'c')
08238 src1 = force_reg (mode, src1);
08239
08240
08241 if (optimize && ! no_new_pseudos)
08242 {
08243 if (GET_CODE (dst) == MEM)
08244 dst = gen_reg_rtx (mode);
08245 if (GET_CODE (src1) == MEM)
08246 src1 = force_reg (mode, src1);
08247 if (GET_CODE (src2) == MEM)
08248 src2 = force_reg (mode, src2);
08249 }
08250
08251
08252
08253 op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_ee (code, mode, src1, src2));
08254 if (reload_in_progress)
08255 {
08256
08257
08258 if (code != PLUS)
08259 abort ();
08260 emit_insn (op);
08261 }
08262 else
08263 {
08264 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
08265 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
08266 }
08267
08268
08269 if (dst != operands[0])
08270 emit_move_insn (operands[0], dst);
08271 }
08272
08273
08274
08275
08276 int
08277 ix86_binary_operator_ok (code, mode, operands)
08278 enum rtx_code code;
08279 enum machine_mode mode ATTRIBUTE_UNUSED;
08280 rtx operands[3];
08281 {
08282
08283 if (GET_CODE (operands[1]) == MEM && GET_CODE (operands[2]) == MEM)
08284 return 0;
08285
08286 if (CONSTANT_P (operands[1]) && GET_RTX_CLASS (code) != 'c')
08287 return 0;
08288
08289 if (GET_CODE (operands[0]) == MEM
08290 && ! (rtx_equal_p (operands[0], operands[1])
08291 || (GET_RTX_CLASS (code) == 'c'
08292 && rtx_equal_p (operands[0], operands[2]))))
08293 return 0;
08294
08295
08296 if (GET_CODE (operands[1]) == MEM
08297 && GET_RTX_CLASS (code) != 'c'
08298 && ! rtx_equal_p (operands[0], operands[1]))
08299 return 0;
08300 return 1;
08301 }
08302
08303
08304
08305
08306
08307 void
08308 ix86_expand_unary_operator (code, mode, operands)
08309 enum rtx_code code;
08310 enum machine_mode mode;
08311 rtx operands[];
08312 {
08313 int matching_memory;
08314 rtx src, dst, op, clob;
08315
08316 dst = operands[0];
08317 src = operands[1];
08318
08319
08320
08321 matching_memory = 0;
08322 if (GET_CODE (dst) == MEM)
08323 {
08324 if (rtx_equal_p (dst, src))
08325 matching_memory = 1;
08326 else
08327 dst = gen_reg_rtx (mode);
08328 }
08329
08330
08331 if (!matching_memory && GET_CODE (src) == MEM)
08332 src = force_reg (mode, src);
08333
08334
08335 if (optimize && ! no_new_pseudos)
08336 {
08337 if (GET_CODE (dst) == MEM)
08338 dst = gen_reg_rtx (mode);
08339 if (GET_CODE (src) == MEM)
08340 src = force_reg (mode, src);
08341 }
08342
08343
08344
08345 op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_e (code, mode, src));
08346 if (reload_in_progress || code == NOT)
08347 {
08348
08349
08350 if (code != NOT)
08351 abort ();
08352 emit_insn (op);
08353 }
08354 else
08355 {
08356 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
08357 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
08358 }
08359
08360
08361 if (dst != operands[0])
08362 emit_move_insn (operands[0], dst);
08363 }
08364
08365
08366
08367
08368 int
08369 ix86_unary_operator_ok (code, mode, operands)
08370 enum rtx_code code ATTRIBUTE_UNUSED;
08371 enum machine_mode mode ATTRIBUTE_UNUSED;
08372 rtx operands[2] ATTRIBUTE_UNUSED;
08373 {
08374
08375 if ((GET_CODE (operands[0]) == MEM
08376 || GET_CODE (operands[1]) == MEM)
08377 && ! rtx_equal_p (operands[0], operands[1]))
08378 return FALSE;
08379 return TRUE;
08380 }
08381
08382
08383
08384
08385
08386 int
08387 ix86_match_ccmode (insn, req_mode)
08388 rtx insn;
08389 enum machine_mode req_mode;
08390 {
08391 rtx set;
08392 enum machine_mode set_mode;
08393
08394 set = PATTERN (insn);
08395 if (GET_CODE (set) == PARALLEL)
08396 set = XVECEXP (set, 0, 0);
08397 if (GET_CODE (set) != SET)
08398 abort ();
08399 if (GET_CODE (SET_SRC (set)) != COMPARE)
08400 abort ();
08401
08402 set_mode = GET_MODE (SET_DEST (set));
08403 switch (set_mode)
08404 {
08405 case CCNOmode:
08406 if (req_mode != CCNOmode
08407 && (req_mode != CCmode
08408 || XEXP (SET_SRC (set), 1) != const0_rtx))
08409 return 0;
08410 break;
08411 case CCmode:
08412 if (req_mode == CCGCmode)
08413 return 0;
08414
08415 case CCGCmode:
08416 if (req_mode == CCGOCmode || req_mode == CCNOmode)
08417 return 0;
08418
08419 case CCGOCmode:
08420 if (req_mode == CCZmode)
08421 return 0;
08422
08423 case CCZmode:
08424 break;
08425
08426 default:
08427 abort ();
08428 }
08429
08430 return (GET_MODE (SET_SRC (set)) == set_mode);
08431 }
08432
08433
08434
08435 static rtx
08436 ix86_expand_int_compare (code, op0, op1)
08437 enum rtx_code code;
08438 rtx op0, op1;
08439 {
08440 enum machine_mode cmpmode;
08441 rtx tmp, flags;
08442
08443 cmpmode = SELECT_CC_MODE (code, op0, op1);
08444 flags = gen_rtx_REG (cmpmode, FLAGS_REG);
08445
08446
08447
08448 tmp = gen_rtx_COMPARE (cmpmode, op0, op1);
08449 emit_insn (gen_rtx_SET (VOIDmode, flags, tmp));
08450
08451
08452
08453 return gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
08454 }
08455
08456
08457
08458
08459 enum machine_mode
08460 ix86_fp_compare_mode (code)
08461 enum rtx_code code ATTRIBUTE_UNUSED;
08462 {
08463
08464
08465
08466
08467
08468 return TARGET_IEEE_FP ? CCFPUmode : CCFPmode;
08469 }
08470
08471 enum machine_mode
08472 ix86_cc_mode (code, op0, op1)
08473 enum rtx_code code;
08474 rtx op0, op1;
08475 {
08476 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
08477 return ix86_fp_compare_mode (code);
08478 switch (code)
08479 {
08480
08481 case EQ:
08482 case NE:
08483 return CCZmode;
08484
08485 case GEU:
08486 case GTU:
08487 case LTU:
08488 case LEU:
08489 return CCmode;
08490
08491
08492 case GE:
08493 case LT:
08494 if (op1 == const0_rtx)
08495 return CCGOCmode;
08496 else
08497
08498 return CCGCmode;
08499
08500
08501
08502
08503 case GT:
08504 case LE:
08505 if (op1 == const0_rtx)
08506 return CCNOmode;
08507 else
08508 return CCGCmode;
08509
08510
08511 case USE:
08512 return CCmode;
08513 default:
08514 abort ();
08515 }
08516 }
08517
08518
08519
08520 int
08521 ix86_use_fcomi_compare (code)
08522 enum rtx_code code ATTRIBUTE_UNUSED;
08523 {
08524 enum rtx_code swapped_code = swap_condition (code);
08525 return ((ix86_fp_comparison_cost (code) == ix86_fp_comparison_fcomi_cost (code))
08526 || (ix86_fp_comparison_cost (swapped_code)
08527 == ix86_fp_comparison_fcomi_cost (swapped_code)));
08528 }
08529
08530
08531
08532
08533
08534 static enum rtx_code
08535 ix86_prepare_fp_compare_args (code, pop0, pop1)
08536 enum rtx_code code;
08537 rtx *pop0, *pop1;
08538 {
08539 enum machine_mode fpcmp_mode = ix86_fp_compare_mode (code);
08540 rtx op0 = *pop0, op1 = *pop1;
08541 enum machine_mode op_mode = GET_MODE (op0);
08542 int is_sse = SSE_REG_P (op0) | SSE_REG_P (op1);
08543
08544
08545
08546
08547
08548 if (!is_sse
08549 && (fpcmp_mode == CCFPUmode
08550 || op_mode == XFmode
08551 || op_mode == TFmode
08552 || ix86_use_fcomi_compare (code)))
08553 {
08554 op0 = force_reg (op_mode, op0);
08555 op1 = force_reg (op_mode, op1);
08556 }
08557 else
08558 {
08559
08560
08561
08562
08563 if (standard_80387_constant_p (op0) == 0
08564 || (GET_CODE (op0) == MEM
08565 && ! (standard_80387_constant_p (op1) == 0
08566 || GET_CODE (op1) == MEM)))
08567 {
08568 rtx tmp;
08569 tmp = op0, op0 = op1, op1 = tmp;
08570 code = swap_condition (code);
08571 }
08572
08573 if (GET_CODE (op0) != REG)
08574 op0 = force_reg (op_mode, op0);
08575
08576 if (CONSTANT_P (op1))
08577 {
08578 if (standard_80387_constant_p (op1))
08579 op1 = force_reg (op_mode, op1);
08580 else
08581 op1 = validize_mem (force_const_mem (op_mode, op1));
08582 }
08583 }
08584
08585
08586 if (ix86_fp_comparison_cost (code)
08587 > ix86_fp_comparison_cost (swap_condition (code))
08588 && (GET_CODE (op1) == REG || !no_new_pseudos))
08589 {
08590 rtx tmp;
08591 tmp = op0, op0 = op1, op1 = tmp;
08592 code = swap_condition (code);
08593 if (GET_CODE (op0) != REG)
08594 op0 = force_reg (op_mode, op0);
08595 }
08596
08597 *pop0 = op0;
08598 *pop1 = op1;
08599 return code;
08600 }
08601
08602
08603
08604
08605 static enum rtx_code
08606 ix86_fp_compare_code_to_integer (code)
08607 enum rtx_code code;
08608 {
08609 switch (code)
08610 {
08611 case GT:
08612 return GTU;
08613 case GE:
08614 return GEU;
08615 case ORDERED:
08616 case UNORDERED:
08617 return code;
08618 break;
08619 case UNEQ:
08620 return EQ;
08621 break;
08622 case UNLT:
08623 return LTU;
08624 break;
08625 case UNLE:
08626 return LEU;
08627 break;
08628 case LTGT:
08629 return NE;
08630 break;
08631 default:
08632 return UNKNOWN;
08633 }
08634 }
08635
08636
08637
08638
08639
08640
08641 static void
08642 ix86_fp_comparison_codes (code, bypass_code, first_code, second_code)
08643 enum rtx_code code, *bypass_code, *first_code, *second_code;
08644 {
08645 *first_code = code;
08646 *bypass_code = NIL;
08647 *second_code = NIL;
08648
08649
08650
08651
08652
08653
08654
08655
08656
08657 switch (code)
08658 {
08659 case GT:
08660 case GE:
08661 case ORDERED:
08662 case UNORDERED:
08663 case UNEQ:
08664 case UNLT:
08665 case UNLE:
08666 case LTGT:
08667 break;
08668 case LT:
08669 *first_code = UNLT;
08670 *bypass_code = UNORDERED;
08671 break;
08672 case LE:
08673 *first_code = UNLE;
08674 *bypass_code = UNORDERED;
08675 break;
08676 case EQ:
08677 *first_code = UNEQ;
08678 *bypass_code = UNORDERED;
08679 break;
08680 case NE:
08681 *first_code = LTGT;
08682 *second_code = UNORDERED;
08683 break;
08684 case UNGE:
08685 *first_code = GE;
08686 *second_code = UNORDERED;
08687 break;
08688 case UNGT:
08689 *first_code = GT;
08690 *second_code = UNORDERED;
08691 break;
08692 default:
08693 abort ();
08694 }
08695 if (!TARGET_IEEE_FP)
08696 {
08697 *second_code = NIL;
08698 *bypass_code = NIL;
08699 }
08700 }
08701
08702
08703
08704
08705
08706 static int
08707 ix86_fp_comparison_arithmetics_cost (code)
08708 enum rtx_code code;
08709 {
08710 if (!TARGET_IEEE_FP)
08711 return 4;
08712
08713 switch (code)
08714 {
08715 case UNLE:
08716 case UNLT:
08717 case LTGT:
08718 case GT:
08719 case GE:
08720 case UNORDERED:
08721 case ORDERED:
08722 case UNEQ:
08723 return 4;
08724 break;
08725 case LT:
08726 case NE:
08727 case EQ:
08728 case UNGE:
08729 return 5;
08730 break;
08731 case LE:
08732 case UNGT:
08733 return 6;
08734 break;
08735 default:
08736 abort ();
08737 }
08738 }
08739
08740
08741
08742 static int
08743 ix86_fp_comparison_fcomi_cost (code)
08744 enum rtx_code code;
08745 {
08746 enum rtx_code bypass_code, first_code, second_code;
08747
08748
08749 if (!TARGET_CMOVE)
08750 return 1024;
08751 ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
08752 return (bypass_code != NIL || second_code != NIL) + 2;
08753 }
08754
08755
08756
08757 static int
08758 ix86_fp_comparison_sahf_cost (code)
08759 enum rtx_code code;
08760 {
08761 enum rtx_code bypass_code, first_code, second_code;
08762
08763
08764 if (!TARGET_USE_SAHF && !optimize_size)
08765 return 1024;
08766 ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
08767 return (bypass_code != NIL || second_code != NIL) + 3;
08768 }
08769
08770
08771
08772 static int
08773 ix86_fp_comparison_cost (code)
08774 enum rtx_code code;
08775 {
08776 int fcomi_cost, sahf_cost, arithmetics_cost = 1024;
08777 int min;
08778
08779 fcomi_cost = ix86_fp_comparison_fcomi_cost (code);
08780 sahf_cost = ix86_fp_comparison_sahf_cost (code);
08781
08782 min = arithmetics_cost = ix86_fp_comparison_arithmetics_cost (code);
08783 if (min > sahf_cost)
08784 min = sahf_cost;
08785 if (min > fcomi_cost)
08786 min = fcomi_cost;
08787 return min;
08788 }
08789
08790
08791
08792 static rtx
08793 ix86_expand_fp_compare (code, op0, op1, scratch, second_test, bypass_test)
08794 enum rtx_code code;
08795 rtx op0, op1, scratch;
08796 rtx *second_test;
08797 rtx *bypass_test;
08798 {
08799 enum machine_mode fpcmp_mode, intcmp_mode;
08800 rtx tmp, tmp2;
08801 int cost = ix86_fp_comparison_cost (code);
08802 enum rtx_code bypass_code, first_code, second_code;
08803
08804 fpcmp_mode = ix86_fp_compare_mode (code);
08805 code = ix86_prepare_fp_compare_args (code, &op0, &op1);
08806
08807 if (second_test)
08808 *second_test = NULL_RTX;
08809 if (bypass_test)
08810 *bypass_test = NULL_RTX;
08811
08812 ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
08813
08814
08815 if ((bypass_code == NIL || bypass_test)
08816 && (second_code == NIL || second_test)
08817 && ix86_fp_comparison_arithmetics_cost (code) > cost)
08818 {
08819 if (TARGET_CMOVE)
08820 {
08821 tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
08822 tmp = gen_rtx_SET (VOIDmode, gen_rtx_REG (fpcmp_mode, FLAGS_REG),
08823 tmp);
08824 emit_insn (tmp);
08825 }
08826 else
08827 {
08828 tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
08829 tmp2 = gen_rtx_UNSPEC (HImode, gen_rtvec (1, tmp), UNSPEC_FNSTSW);
08830 if (!scratch)
08831 scratch = gen_reg_rtx (HImode);
08832 emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp2));
08833 emit_insn (gen_x86_sahf_1 (scratch));
08834 }
08835
08836
08837 intcmp_mode = fpcmp_mode;
08838 code = first_code;
08839 if (bypass_code != NIL)
08840 *bypass_test = gen_rtx_fmt_ee (bypass_code, VOIDmode,
08841 gen_rtx_REG (intcmp_mode, FLAGS_REG),
08842 const0_rtx);
08843 if (second_code != NIL)
08844 *second_test = gen_rtx_fmt_ee (second_code, VOIDmode,
08845 gen_rtx_REG (intcmp_mode, FLAGS_REG),
08846 const0_rtx);
08847 }
08848 else
08849 {
08850
08851 tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
08852 tmp2 = gen_rtx_UNSPEC (HImode, gen_rtvec (1, tmp), UNSPEC_FNSTSW);
08853 if (!scratch)
08854 scratch = gen_reg_rtx (HImode);
08855 emit_insn (gen_rtx_SET (VOIDmode, scratch, tmp2));
08856
08857
08858
08859
08860
08861
08862 intcmp_mode = CCNOmode;
08863 switch (code)
08864 {
08865 case GT:
08866 case UNGT:
08867 if (code == GT || !TARGET_IEEE_FP)
08868 {
08869 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x45)));
08870 code = EQ;
08871 }
08872 else
08873 {
08874 emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
08875 emit_insn (gen_addqi_ext_1 (scratch, scratch, constm1_rtx));
08876 emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x44)));
08877 intcmp_mode = CCmode;
08878 code = GEU;
08879 }
08880 break;
08881 case LT:
08882 case UNLT:
08883 if (code == LT && TARGET_IEEE_FP)
08884 {
08885 emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
08886 emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x01)));
08887 intcmp_mode = CCmode;
08888 code = EQ;
08889 }
08890 else
08891 {
08892 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x01)));
08893 code = NE;
08894 }
08895 break;
08896 case GE:
08897 case UNGE:
08898 if (code == GE || !TARGET_IEEE_FP)
08899 {
08900 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x05)));
08901 code = EQ;
08902 }
08903 else
08904 {
08905 emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
08906 emit_insn (gen_xorqi_cc_ext_1 (scratch, scratch,
08907 GEN_INT (0x01)));
08908 code = NE;
08909 }
08910 break;
08911 case LE:
08912 case UNLE:
08913 if (code == LE && TARGET_IEEE_FP)
08914 {
08915 emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
08916 emit_insn (gen_addqi_ext_1 (scratch, scratch, constm1_rtx));
08917 emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x40)));
08918 intcmp_mode = CCmode;
08919 code = LTU;
08920 }
08921 else
08922 {
08923 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x45)));
08924 code = NE;
08925 }
08926 break;
08927 case EQ:
08928 case UNEQ:
08929 if (code == EQ && TARGET_IEEE_FP)
08930 {
08931 emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
08932 emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x40)));
08933 intcmp_mode = CCmode;
08934 code = EQ;
08935 }
08936 else
08937 {
08938 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x40)));
08939 code = NE;
08940 break;
08941 }
08942 break;
08943 case NE:
08944 case LTGT:
08945 if (code == NE && TARGET_IEEE_FP)
08946 {
08947 emit_insn (gen_andqi_ext_0 (scratch, scratch, GEN_INT (0x45)));
08948 emit_insn (gen_xorqi_cc_ext_1 (scratch, scratch,
08949 GEN_INT (0x40)));
08950 code = NE;
08951 }
08952 else
08953 {
08954 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x40)));
08955 code = EQ;
08956 }
08957 break;
08958
08959 case UNORDERED:
08960 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x04)));
08961 code = NE;
08962 break;
08963 case ORDERED:
08964 emit_insn (gen_testqi_ext_ccno_0 (scratch, GEN_INT (0x04)));
08965 code = EQ;
08966 break;
08967
08968 default:
08969 abort ();
08970 }
08971 }
08972
08973
08974
08975 return gen_rtx_fmt_ee (code, VOIDmode,
08976 gen_rtx_REG (intcmp_mode, FLAGS_REG),
08977 const0_rtx);
08978 }
08979
08980 rtx
08981 ix86_expand_compare (code, second_test, bypass_test)
08982 enum rtx_code code;
08983 rtx *second_test, *bypass_test;
08984 {
08985 rtx op0, op1, ret;
08986 op0 = ix86_compare_op0;
08987 op1 = ix86_compare_op1;
08988
08989 if (second_test)
08990 *second_test = NULL_RTX;
08991 if (bypass_test)
08992 *bypass_test = NULL_RTX;
08993
08994 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
08995 ret = ix86_expand_fp_compare (code, op0, op1, NULL_RTX,
08996 second_test, bypass_test);
08997 else
08998 ret = ix86_expand_int_compare (code, op0, op1);
08999
09000 return ret;
09001 }
09002
09003
09004 bool
09005 ix86_fp_jump_nontrivial_p (code)
09006 enum rtx_code code;
09007 {
09008 enum rtx_code bypass_code, first_code, second_code;
09009 if (!TARGET_CMOVE)
09010 return true;
09011 ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
09012 return bypass_code != NIL || second_code != NIL;
09013 }
09014
09015 void
09016 ix86_expand_branch (code, label)
09017 enum rtx_code code;
09018 rtx label;
09019 {
09020 rtx tmp;
09021
09022 switch (GET_MODE (ix86_compare_op0))
09023 {
09024 case QImode:
09025 case HImode:
09026 case SImode:
09027 simple:
09028 tmp = ix86_expand_compare (code, NULL, NULL);
09029 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
09030 gen_rtx_LABEL_REF (VOIDmode, label),
09031 pc_rtx);
09032 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
09033 return;
09034
09035 case SFmode:
09036 case DFmode:
09037 case XFmode:
09038 case TFmode:
09039 {
09040 rtvec vec;
09041 int use_fcomi;
09042 enum rtx_code bypass_code, first_code, second_code;
09043
09044 code = ix86_prepare_fp_compare_args (code, &ix86_compare_op0,
09045 &ix86_compare_op1);
09046
09047 ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
09048
09049
09050
09051
09052 if (bypass_code == NIL && second_code == NIL
09053 && TARGET_CMOVE)
09054 {
09055 ix86_split_fp_branch (code, ix86_compare_op0, ix86_compare_op1,
09056 gen_rtx_LABEL_REF (VOIDmode, label),
09057 pc_rtx, NULL_RTX);
09058 }
09059 else
09060 {
09061 tmp = gen_rtx_fmt_ee (code, VOIDmode,
09062 ix86_compare_op0, ix86_compare_op1);
09063 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
09064 gen_rtx_LABEL_REF (VOIDmode, label),
09065 pc_rtx);
09066 tmp = gen_rtx_SET (VOIDmode, pc_rtx, tmp);
09067
09068 use_fcomi = ix86_use_fcomi_compare (code);
09069 vec = rtvec_alloc (3 + !use_fcomi);
09070 RTVEC_ELT (vec, 0) = tmp;
09071 RTVEC_ELT (vec, 1)
09072 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, 18));
09073 RTVEC_ELT (vec, 2)
09074 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, 17));
09075 if (! use_fcomi)
09076 RTVEC_ELT (vec, 3)
09077 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (HImode));
09078
09079 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, vec));
09080 }
09081 return;
09082 }
09083
09084 case DImode:
09085 if (TARGET_64BIT)
09086 goto simple;
09087
09088 {
09089 rtx lo[2], hi[2], label2;
09090 enum rtx_code code1, code2, code3;
09091
09092 if (CONSTANT_P (ix86_compare_op0) && ! CONSTANT_P (ix86_compare_op1))
09093 {
09094 tmp = ix86_compare_op0;
09095 ix86_compare_op0 = ix86_compare_op1;
09096 ix86_compare_op1 = tmp;
09097 code = swap_condition (code);
09098 }
09099 split_di (&ix86_compare_op0, 1, lo+0, hi+0);
09100 split_di (&ix86_compare_op1, 1, lo+1, hi+1);
09101
09102
09103
09104
09105
09106 if ((code == EQ || code == NE)
09107 && (!optimize_size
09108 || hi[1] == const0_rtx || lo[1] == const0_rtx))
09109 {
09110 rtx xor0, xor1;
09111
09112 xor1 = hi[0];
09113 if (hi[1] != const0_rtx)
09114 xor1 = expand_binop (SImode, xor_optab, xor1, hi[1],
09115 NULL_RTX, 0, OPTAB_WIDEN);
09116
09117 xor0 = lo[0];
09118 if (lo[1] != const0_rtx)
09119 xor0 = expand_binop (SImode, xor_optab, xor0, lo[1],
09120 NULL_RTX, 0, OPTAB_WIDEN);
09121
09122 tmp = expand_binop (SImode, ior_optab, xor1, xor0,
09123 NULL_RTX, 0, OPTAB_WIDEN);
09124
09125 ix86_compare_op0 = tmp;
09126 ix86_compare_op1 = const0_rtx;
09127 ix86_expand_branch (code, label);
09128 return;
09129 }
09130
09131
09132
09133
09134
09135 if (GET_CODE (hi[1]) == CONST_INT && lo[1] == const0_rtx)
09136 switch (code)
09137 {
09138 case LT: case LTU: case GE: case GEU:
09139 ix86_compare_op0 = hi[0];
09140 ix86_compare_op1 = hi[1];
09141 ix86_expand_branch (code, label);
09142 return;
09143 default:
09144 break;
09145 }
09146
09147
09148
09149 label2 = gen_label_rtx ();
09150
09151 code1 = code;
09152 code2 = swap_condition (code);
09153 code3 = unsigned_condition (code);
09154
09155 switch (code)
09156 {
09157 case LT: case GT: case LTU: case GTU:
09158 break;
09159
09160 case LE: code1 = LT; code2 = GT; break;
09161 case GE: code1 = GT; code2 = LT; break;
09162 case LEU: code1 = LTU; code2 = GTU; break;
09163 case GEU: code1 = GTU; code2 = LTU; break;
09164
09165 case EQ: code1 = NIL; code2 = NE; break;
09166 case NE: code2 = NIL; break;
09167
09168 default:
09169 abort ();
09170 }
09171
09172
09173
09174
09175
09176
09177
09178
09179
09180 ix86_compare_op0 = hi[0];
09181 ix86_compare_op1 = hi[1];
09182
09183 if (code1 != NIL)
09184 ix86_expand_branch (code1, label);
09185 if (code2 != NIL)
09186 ix86_expand_branch (code2, label2);
09187
09188 ix86_compare_op0 = lo[0];
09189 ix86_compare_op1 = lo[1];
09190 ix86_expand_branch (code3, label);
09191
09192 if (code2 != NIL)
09193 emit_label (label2);
09194 return;
09195 }
09196
09197 default:
09198 abort ();
09199 }
09200 }
09201
09202
09203 void
09204 ix86_split_fp_branch (code, op1, op2, target1, target2, tmp)
09205 enum rtx_code code;
09206 rtx op1, op2, target1, target2, tmp;
09207 {
09208 rtx second, bypass;
09209 rtx label = NULL_RTX;
09210 rtx condition;
09211 int bypass_probability = -1, second_probability = -1, probability = -1;
09212 rtx i;
09213
09214 if (target2 != pc_rtx)
09215 {
09216 rtx tmp = target2;
09217 code = reverse_condition_maybe_unordered (code);
09218 target2 = target1;
09219 target1 = tmp;
09220 }
09221
09222 condition = ix86_expand_fp_compare (code, op1, op2,
09223 tmp, &second, &bypass);
09224
09225 if (split_branch_probability >= 0)
09226 {
09227
09228
09229
09230 probability = split_branch_probability;
09231
09232
09233
09234
09235 if (bypass)
09236 bypass_probability = 1;
09237 if (second)
09238 second_probability = 1;
09239 }
09240 if (bypass != NULL_RTX)
09241 {
09242 label = gen_label_rtx ();
09243 i = emit_jump_insn (gen_rtx_SET
09244 (VOIDmode, pc_rtx,
09245 gen_rtx_IF_THEN_ELSE (VOIDmode,
09246 bypass,
09247 gen_rtx_LABEL_REF (VOIDmode,
09248 label),
09249 pc_rtx)));
09250 if (bypass_probability >= 0)
09251 REG_NOTES (i)
09252 = gen_rtx_EXPR_LIST (REG_BR_PROB,
09253 GEN_INT (bypass_probability),
09254 REG_NOTES (i));
09255 }
09256 i = emit_jump_insn (gen_rtx_SET
09257 (VOIDmode, pc_rtx,
09258 gen_rtx_IF_THEN_ELSE (VOIDmode,
09259 condition, target1, target2)));
09260 if (probability >= 0)
09261 REG_NOTES (i)
09262 = gen_rtx_EXPR_LIST (REG_BR_PROB,
09263 GEN_INT (probability),
09264 REG_NOTES (i));
09265 if (second != NULL_RTX)
09266 {
09267 i = emit_jump_insn (gen_rtx_SET
09268 (VOIDmode, pc_rtx,
09269 gen_rtx_IF_THEN_ELSE (VOIDmode, second, target1,
09270 target2)));
09271 if (second_probability >= 0)
09272 REG_NOTES (i)
09273 = gen_rtx_EXPR_LIST (REG_BR_PROB,
09274 GEN_INT (second_probability),
09275 REG_NOTES (i));
09276 }
09277 if (label != NULL_RTX)
09278 emit_label (label);
09279 }
09280
09281 int
09282 ix86_expand_setcc (code, dest)
09283 enum rtx_code code;
09284 rtx dest;
09285 {
09286 rtx ret, tmp, tmpreg;
09287 rtx second_test, bypass_test;
09288
09289 if (GET_MODE (ix86_compare_op0) == DImode
09290 && !TARGET_64BIT)
09291 return 0;
09292
09293 if (GET_MODE (dest) != QImode)
09294 abort ();
09295
09296 ret = ix86_expand_compare (code, &second_test, &bypass_test);
09297 PUT_MODE (ret, QImode);
09298
09299 tmp = dest;
09300 tmpreg = dest;
09301
09302 emit_insn (gen_rtx_SET (VOIDmode, tmp, ret));
09303 if (bypass_test || second_test)
09304 {
09305 rtx test = second_test;
09306 int bypass = 0;
09307 rtx tmp2 = gen_reg_rtx (QImode);
09308 if (bypass_test)
09309 {
09310 if (second_test)
09311 abort ();
09312 test = bypass_test;
09313 bypass = 1;
09314 PUT_CODE (test, reverse_condition_maybe_unordered (GET_CODE (test)));
09315 }
09316 PUT_MODE (test, QImode);
09317 emit_insn (gen_rtx_SET (VOIDmode, tmp2, test));
09318
09319 if (bypass)
09320 emit_insn (gen_andqi3 (tmp, tmpreg, tmp2));
09321 else
09322 emit_insn (gen_iorqi3 (tmp, tmpreg, tmp2));
09323 }
09324
09325 return 1;
09326 }
09327
09328 int
09329 ix86_expand_int_movcc (operands)
09330 rtx operands[];
09331 {
09332 enum rtx_code code = GET_CODE (operands[1]), compare_code;
09333 rtx compare_seq, compare_op;
09334 rtx second_test, bypass_test;
09335 enum machine_mode mode = GET_MODE (operands[0]);
09336
09337
09338
09339
09340
09341 if ((code == LEU || code == GTU)
09342 && GET_CODE (ix86_compare_op1) == CONST_INT
09343 && mode != HImode
09344 && INTVAL (ix86_compare_op1) != -1
09345
09346
09347 && (!TARGET_64BIT
09348 || GET_MODE (ix86_compare_op0) != DImode
09349 || INTVAL (ix86_compare_op1) != 0x7fffffff)
09350 && GET_CODE (operands[2]) == CONST_INT
09351 && GET_CODE (operands[3]) == CONST_INT)
09352 {
09353 if (code == LEU)
09354 code = LTU;
09355 else
09356 code = GEU;
09357 ix86_compare_op1 = gen_int_mode (INTVAL (ix86_compare_op1) + 1,
09358 GET_MODE (ix86_compare_op0));
09359 }
09360
09361 start_sequence ();
09362 compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
09363 compare_seq = get_insns ();
09364 end_sequence ();
09365
09366 compare_code = GET_CODE (compare_op);
09367
09368
09369
09370
09371 if (mode != HImode
09372 && (mode != DImode || TARGET_64BIT)
09373 && GET_CODE (operands[2]) == CONST_INT
09374 && GET_CODE (operands[3]) == CONST_INT)
09375 {
09376 rtx out = operands[0];
09377 HOST_WIDE_INT ct = INTVAL (operands[2]);
09378 HOST_WIDE_INT cf = INTVAL (operands[3]);
09379 HOST_WIDE_INT diff;
09380
09381 if ((compare_code == LTU || compare_code == GEU)
09382 && !second_test && !bypass_test)
09383 {
09384
09385 rtx tmp = out;
09386
09387
09388 if (compare_code == LTU)
09389 {
09390 HOST_WIDE_INT tmp = ct;
09391 ct = cf;
09392 cf = tmp;
09393 compare_code = reverse_condition (compare_code);
09394 code = reverse_condition (code);
09395 }
09396 diff = ct - cf;
09397
09398 if (reg_overlap_mentioned_p (out, ix86_compare_op0)
09399 || reg_overlap_mentioned_p (out, ix86_compare_op1))
09400 tmp = gen_reg_rtx (mode);
09401
09402 emit_insn (compare_seq);
09403 if (mode == DImode)
09404 emit_insn (gen_x86_movdicc_0_m1_rex64 (tmp));
09405 else
09406 emit_insn (gen_x86_movsicc_0_m1 (tmp));
09407
09408 if (diff == 1)
09409 {
09410
09411
09412
09413
09414
09415
09416
09417 if (ct)
09418 tmp = expand_simple_binop (mode, PLUS,
09419 tmp, GEN_INT (ct),
09420 tmp, 1, OPTAB_DIRECT);
09421 }
09422 else if (cf == -1)
09423 {
09424
09425
09426
09427
09428
09429
09430
09431 tmp = expand_simple_binop (mode, IOR,
09432 tmp, GEN_INT (ct),
09433 tmp, 1, OPTAB_DIRECT);
09434 }
09435 else if (diff == -1 && ct)
09436 {
09437
09438
09439
09440
09441
09442
09443
09444
09445 tmp = expand_simple_unop (mode, NOT, tmp, tmp, 1);
09446 if (cf)
09447 tmp = expand_simple_binop (mode, PLUS,
09448 tmp, GEN_INT (cf),
09449 tmp, 1, OPTAB_DIRECT);
09450 }
09451 else
09452 {
09453
09454
09455
09456
09457
09458
09459
09460
09461
09462
09463 if (cf == 0)
09464 {
09465 cf = ct;
09466 ct = 0;
09467 tmp = expand_simple_unop (mode, NOT, tmp, tmp, 1);
09468 }
09469
09470 tmp = expand_simple_binop (mode, AND,
09471 tmp,
09472 gen_int_mode (cf - ct, mode),
09473 tmp, 1, OPTAB_DIRECT);
09474 if (ct)
09475 tmp = expand_simple_binop (mode, PLUS,
09476 tmp, GEN_INT (ct),
09477 tmp, 1, OPTAB_DIRECT);
09478 }
09479
09480 if (tmp != out)
09481 emit_move_insn (out, tmp);
09482
09483 return 1;
09484 }
09485
09486 diff = ct - cf;
09487 if (diff < 0)
09488 {
09489 HOST_WIDE_INT tmp;
09490 tmp = ct, ct = cf, cf = tmp;
09491 diff = -diff;
09492 if (FLOAT_MODE_P (GET_MODE (ix86_compare_op0)))
09493 {
09494
09495
09496
09497
09498 compare_code = reverse_condition_maybe_unordered (compare_code);
09499 code = reverse_condition_maybe_unordered (code);
09500 }
09501 else
09502 {
09503 compare_code = reverse_condition (compare_code);
09504 code = reverse_condition (code);
09505 }
09506 }
09507
09508 compare_code = NIL;
09509 if (GET_MODE_CLASS (GET_MODE (ix86_compare_op0)) == MODE_INT
09510 && GET_CODE (ix86_compare_op1) == CONST_INT)
09511 {
09512 if (ix86_compare_op1 == const0_rtx
09513 && (code == LT || code == GE))
09514 compare_code = code;
09515 else if (ix86_compare_op1 == constm1_rtx)
09516 {
09517 if (code == LE)
09518 compare_code = LT;
09519 else if (code == GT)
09520 compare_code = GE;
09521 }
09522 }
09523
09524
09525 if (compare_code != NIL
09526 && GET_MODE (ix86_compare_op0) == GET_MODE (out)
09527 && (cf == -1 || ct == -1))
09528 {
09529
09530
09531
09532 if (! (diff == 1 || diff == 2 || diff == 4 || diff == 8
09533 || diff == 3 || diff == 5 || diff == 9)
09534 || (compare_code == LT && ct == -1)
09535 || (compare_code == GE && cf == -1))
09536 {
09537
09538
09539
09540
09541
09542 if (ct != -1)
09543 {
09544 cf = ct;
09545 ct = -1;
09546 code = reverse_condition (code);
09547 }
09548
09549 out = emit_store_flag (out, code, ix86_compare_op0,
09550 ix86_compare_op1, VOIDmode, 0, -1);
09551
09552 out = expand_simple_binop (mode, IOR,
09553 out, GEN_INT (cf),
09554 out, 1, OPTAB_DIRECT);
09555 if (out != operands[0])
09556 emit_move_insn (operands[0], out);
09557
09558 return 1;
09559 }
09560 }
09561
09562 if ((diff == 1 || diff == 2 || diff == 4 || diff == 8
09563 || diff == 3 || diff == 5 || diff == 9)
09564 && (mode != DImode || x86_64_sign_extended_value (GEN_INT (cf))))
09565 {
09566
09567
09568
09569
09570
09571
09572
09573
09574
09575
09576
09577 rtx tmp;
09578 int nops;
09579
09580 out = emit_store_flag (out, code, ix86_compare_op0,
09581 ix86_compare_op1, VOIDmode, 0, 1);
09582
09583 nops = 0;
09584
09585
09586 if (diff == 1)
09587 tmp = copy_rtx (out);
09588 else
09589 {
09590 rtx out1;
09591 out1 = copy_rtx (out);
09592 tmp = gen_rtx_MULT (mode, out1, GEN_INT (diff & ~1));
09593 nops++;
09594 if (diff & 1)
09595 {
09596 tmp = gen_rtx_PLUS (mode, tmp, out1);
09597 nops++;
09598 }
09599 }
09600 if (cf != 0)
09601 {
09602 tmp = gen_rtx_PLUS (mode, tmp, GEN_INT (cf));
09603 nops++;
09604 }
09605 if (tmp != out
09606 && (GET_CODE (tmp) != SUBREG || SUBREG_REG (tmp) != out))
09607 {
09608 if (nops == 1)
09609 out = force_operand (tmp, copy_rtx (out));
09610 else
09611 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (out), copy_rtx (tmp)));
09612 }
09613 if (out != operands[0])
09614 emit_move_insn (operands[0], copy_rtx (out));
09615
09616 return 1;
09617 }
09618
09619
09620
09621
09622
09623
09624
09625
09626
09627
09628
09629
09630
09631
09632
09633
09634
09635
09636
09637
09638 if (!optimize_size && !TARGET_CMOVE)
09639 {
09640 if (cf == 0)
09641 {
09642 cf = ct;
09643 ct = 0;
09644 if (FLOAT_MODE_P (GET_MODE (ix86_compare_op0)))
09645
09646
09647
09648
09649 code = reverse_condition_maybe_unordered (code);
09650 else
09651 {
09652 code = reverse_condition (code);
09653 if (compare_code != NIL)
09654 compare_code = reverse_condition (compare_code);
09655 }
09656 }
09657
09658 if (compare_code != NIL)
09659 {
09660
09661
09662
09663
09664
09665
09666
09667
09668
09669
09670
09671
09672 if (compare_code == GE || !cf)
09673 {
09674 code = reverse_condition (code);
09675 compare_code = LT;
09676 }
09677 else
09678 {
09679 HOST_WIDE_INT tmp = cf;
09680 cf = ct;
09681 ct = tmp;
09682 }
09683
09684 out = emit_store_flag (out, code, ix86_compare_op0,
09685 ix86_compare_op1, VOIDmode, 0, -1);
09686 }
09687 else
09688 {
09689 out = emit_store_flag (out, code, ix86_compare_op0,
09690 ix86_compare_op1, VOIDmode, 0, 1);
09691
09692 out = expand_simple_binop (mode, PLUS, out, constm1_rtx,
09693 out, 1, OPTAB_DIRECT);
09694 }
09695
09696 out = expand_simple_binop (mode, AND, out,
09697 gen_int_mode (cf - ct, mode),
09698 out, 1, OPTAB_DIRECT);
09699 if (ct)
09700 out = expand_simple_binop (mode, PLUS, out, GEN_INT (ct),
09701 out, 1, OPTAB_DIRECT);
09702 if (out != operands[0])
09703 emit_move_insn (operands[0], out);
09704
09705 return 1;
09706 }
09707 }
09708
09709 if (!TARGET_CMOVE)
09710 {
09711
09712
09713 optab op;
09714 rtx var, orig_out, out, tmp;
09715
09716 if (optimize_size)
09717 return 0;
09718
09719
09720
09721
09722 if (GET_CODE (operands[2]) == CONST_INT)
09723 {
09724 var = operands[3];
09725 if (INTVAL (operands[2]) == 0)
09726 operands[3] = constm1_rtx, op = and_optab;
09727 else if (INTVAL (operands[2]) == -1)
09728 operands[3] = const0_rtx, op = ior_optab;
09729 else
09730 return 0;
09731 }
09732 else if (GET_CODE (operands[3]) == CONST_INT)
09733 {
09734 var = operands[2];
09735 if (INTVAL (operands[3]) == 0)
09736 operands[2] = constm1_rtx, op = and_optab;
09737 else if (INTVAL (operands[3]) == -1)
09738 operands[2] = const0_rtx, op = ior_optab;
09739 else
09740 return 0;
09741 }
09742 else
09743 return 0;
09744
09745 orig_out = operands[0];
09746 tmp = gen_reg_rtx (mode);
09747 operands[0] = tmp;
09748
09749
09750 if (ix86_expand_int_movcc (operands) == 0)
09751 return 0;
09752
09753
09754 out = expand_binop (mode, op, var, tmp, orig_out, 0,
09755 OPTAB_WIDEN);
09756 if (out != orig_out)
09757 emit_move_insn (orig_out, out);
09758
09759 return 1;
09760 }
09761
09762
09763
09764
09765
09766
09767
09768
09769
09770
09771
09772
09773 if (! nonimmediate_operand (operands[2], mode))
09774 operands[2] = force_reg (mode, operands[2]);
09775 if (! nonimmediate_operand (operands[3], mode))
09776 operands[3] = force_reg (mode, operands[3]);
09777
09778 if (bypass_test && reg_overlap_mentioned_p (operands[0], operands[3]))
09779 {
09780 rtx tmp = gen_reg_rtx (mode);
09781 emit_move_insn (tmp, operands[3]);
09782 operands[3] = tmp;
09783 }
09784 if (second_test && reg_overlap_mentioned_p (operands[0], operands[2]))
09785 {
09786 rtx tmp = gen_reg_rtx (mode);
09787 emit_move_insn (tmp, operands[2]);
09788 operands[2] = tmp;
09789 }
09790 if (! register_operand (operands[2], VOIDmode)
09791 && ! register_operand (operands[3], VOIDmode))
09792 operands[2] = force_reg (mode, operands[2]);
09793
09794 emit_insn (compare_seq);
09795 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
09796 gen_rtx_IF_THEN_ELSE (mode,
09797 compare_op, operands[2],
09798 operands[3])));
09799 if (bypass_test)
09800 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
09801 gen_rtx_IF_THEN_ELSE (mode,
09802 bypass_test,
09803 operands[3],
09804 operands[0])));
09805 if (second_test)
09806 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
09807 gen_rtx_IF_THEN_ELSE (mode,
09808 second_test,
09809 operands[2],
09810 operands[0])));
09811
09812 return 1;
09813 }
09814
09815 int
09816 ix86_expand_fp_movcc (operands)
09817 rtx operands[];
09818 {
09819 enum rtx_code code;
09820 rtx tmp;
09821 rtx compare_op, second_test, bypass_test;
09822
09823
09824
09825 if (((TARGET_SSE_MATH && GET_MODE (operands[0]) == SFmode)
09826 || (TARGET_SSE2 && TARGET_SSE_MATH && GET_MODE (operands[0]) == DFmode))
09827 && GET_MODE (ix86_compare_op0) == GET_MODE (operands[0])
09828
09829 && (!TARGET_IEEE_FP
09830 || (GET_CODE (operands[1]) != LTGT && GET_CODE (operands[1]) != UNEQ))
09831
09832 && (!REG_P (operands[0])
09833 || SSE_REG_P (operands[0])
09834 || REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
09835 {
09836 rtx op0 = ix86_compare_op0, op1 = ix86_compare_op1;
09837 code = GET_CODE (operands[1]);
09838
09839
09840
09841 if (rtx_equal_p (operands[2], op1))
09842 {
09843 rtx tmp = op0;
09844 op0 = op1;
09845 op1 = tmp;
09846 code = reverse_condition_maybe_unordered (code);
09847 }
09848 if (rtx_equal_p (operands[2], op0) && rtx_equal_p (operands[3], op1))
09849 {
09850
09851 if (code == LT)
09852 {
09853 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
09854 if (memory_operand (op0, VOIDmode))
09855 op0 = force_reg (GET_MODE (operands[0]), op0);
09856 if (GET_MODE (operands[0]) == SFmode)
09857 emit_insn (gen_minsf3 (operands[0], op0, op1));
09858 else
09859 emit_insn (gen_mindf3 (operands[0], op0, op1));
09860 return 1;
09861 }
09862
09863 if (code == GT)
09864 {
09865 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
09866 if (memory_operand (op0, VOIDmode))
09867 op0 = force_reg (GET_MODE (operands[0]), op0);
09868 if (GET_MODE (operands[0]) == SFmode)
09869 emit_insn (gen_maxsf3 (operands[0], op0, op1));
09870 else
09871 emit_insn (gen_maxdf3 (operands[0], op0, op1));
09872 return 1;
09873 }
09874 }
09875
09876
09877
09878
09879 if (!sse_comparison_operator (operands[1], VOIDmode)
09880 || (rtx_equal_p (operands[0], ix86_compare_op1) && !TARGET_IEEE_FP))
09881 {
09882 rtx tmp = ix86_compare_op0;
09883 ix86_compare_op0 = ix86_compare_op1;
09884 ix86_compare_op1 = tmp;
09885 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
09886 VOIDmode, ix86_compare_op0,
09887 ix86_compare_op1);
09888 }
09889
09890
09891
09892 if ((rtx_equal_p (operands[0], operands[3])
09893 && (!TARGET_IEEE_FP || GET_CODE (operands[1]) != EQ))
09894 || (GET_CODE (operands[1]) == NE && TARGET_IEEE_FP))
09895 {
09896 rtx tmp = operands[2];
09897 operands[2] = operands[3];
09898 operands[3] = tmp;
09899 operands[1] = gen_rtx_fmt_ee (reverse_condition_maybe_unordered
09900 (GET_CODE (operands[1])),
09901 VOIDmode, ix86_compare_op0,
09902 ix86_compare_op1);
09903 }
09904 if (GET_MODE (operands[0]) == SFmode)
09905 emit_insn (gen_sse_movsfcc (operands[0], operands[1],
09906 operands[2], operands[3],
09907 ix86_compare_op0, ix86_compare_op1));
09908 else
09909 emit_insn (gen_sse_movdfcc (operands[0], operands[1],
09910 operands[2], operands[3],
09911 ix86_compare_op0, ix86_compare_op1));
09912 return 1;
09913 }
09914
09915
09916
09917
09918 code = GET_CODE (operands[1]);
09919 compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
09920
09921
09922
09923
09924 if (!fcmov_comparison_operator (compare_op, VOIDmode))
09925 {
09926 if (second_test != NULL || bypass_test != NULL)
09927 abort ();
09928 tmp = gen_reg_rtx (QImode);
09929 ix86_expand_setcc (code, tmp);
09930 code = NE;
09931 ix86_compare_op0 = tmp;
09932 ix86_compare_op1 = const0_rtx;
09933 compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
09934 }
09935 if (bypass_test && reg_overlap_mentioned_p (operands[0], operands[3]))
09936 {
09937 tmp = gen_reg_rtx (GET_MODE (operands[0]));
09938 emit_move_insn (tmp, operands[3]);
09939 operands[3] = tmp;
09940 }
09941 if (second_test && reg_overlap_mentioned_p (operands[0], operands[2]))
09942 {
09943 tmp = gen_reg_rtx (GET_MODE (operands[0]));
09944 emit_move_insn (tmp, operands[2]);
09945 operands[2] = tmp;
09946 }
09947
09948 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
09949 gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
09950 compare_op,
09951 operands[2],
09952 operands[3])));
09953 if (bypass_test)
09954 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
09955 gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
09956 bypass_test,
09957 operands[3],
09958 operands[0])));
09959 if (second_test)
09960 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
09961 gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
09962 second_test,
09963 operands[2],
09964 operands[0])));
09965
09966 return 1;
09967 }
09968
09969
09970
09971
09972
09973
09974 static int
09975 ix86_split_to_parts (operand, parts, mode)
09976 rtx operand;
09977 rtx *parts;
09978 enum machine_mode mode;
09979 {
09980 int size;
09981
09982 if (!TARGET_64BIT)
09983 size = mode == TFmode ? 3 : (GET_MODE_SIZE (mode) / 4);
09984 else
09985 size = (GET_MODE_SIZE (mode) + 4) / 8;
09986
09987 if (GET_CODE (operand) == REG && MMX_REGNO_P (REGNO (operand)))
09988 abort ();
09989 if (size < 2 || size > 3)
09990 abort ();
09991
09992
09993
09994 if (GET_CODE (operand) == MEM && RTX_UNCHANGING_P (operand))
09995 {
09996 rtx tmp = maybe_get_pool_constant (operand);
09997 if (tmp)
09998 operand = tmp;
09999 }
10000
10001 if (GET_CODE (operand) == MEM && !offsettable_memref_p (operand))
10002 {
10003
10004 if (! push_operand (operand, VOIDmode))
10005 abort ();
10006
10007 operand = copy_rtx (operand);
10008 PUT_MODE (operand, Pmode);
10009 parts[0] = parts[1] = parts[2] = operand;
10010 }
10011 else if (!TARGET_64BIT)
10012 {
10013 if (mode == DImode)
10014 split_di (&operand, 1, &parts[0], &parts[1]);
10015 else
10016 {
10017 if (REG_P (operand))
10018 {
10019 if (!reload_completed)
10020 abort ();
10021 parts[0] = gen_rtx_REG (SImode, REGNO (operand) + 0);
10022 parts[1] = gen_rtx_REG (SImode, REGNO (operand) + 1);
10023 if (size == 3)
10024 parts[2] = gen_rtx_REG (SImode, REGNO (operand) + 2);
10025 }
10026 else if (offsettable_memref_p (operand))
10027 {
10028 operand = adjust_address (operand, SImode, 0);
10029 parts[0] = operand;
10030 parts[1] = adjust_address (operand, SImode, 4);
10031 if (size == 3)
10032 parts[2] = adjust_address (operand, SImode, 8);
10033 }
10034 else if (GET_CODE (operand) == CONST_DOUBLE)
10035 {
10036 REAL_VALUE_TYPE r;
10037 long l[4];
10038
10039 REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
10040 switch (mode)
10041 {
10042 case XFmode:
10043 case TFmode:
10044 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
10045 parts[2] = gen_int_mode (l[2], SImode);
10046 break;
10047 case DFmode:
10048 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
10049 break;
10050 default:
10051 abort ();
10052 }
10053 parts[1] = gen_int_mode (l[1], SImode);
10054 parts[0] = gen_int_mode (l[0], SImode);
10055 }
10056 else
10057 abort ();
10058 }
10059 }
10060 else
10061 {
10062 if (mode == TImode)
10063 split_ti (&operand, 1, &parts[0], &parts[1]);
10064 if (mode == XFmode || mode == TFmode)
10065 {
10066 if (REG_P (operand))
10067 {
10068 if (!reload_completed)
10069 abort ();
10070 parts[0] = gen_rtx_REG (DImode, REGNO (operand) + 0);
10071 parts[1] = gen_rtx_REG (SImode, REGNO (operand) + 1);
10072 }
10073 else if (offsettable_memref_p (operand))
10074 {
10075 operand = adjust_address (operand, DImode, 0);
10076 parts[0] = operand;
10077 parts[1] = adjust_address (operand, SImode, 8);
10078 }
10079 else if (GET_CODE (operand) == CONST_DOUBLE)
10080 {
10081 REAL_VALUE_TYPE r;
10082 long l[3];
10083
10084 REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
10085 REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
10086
10087 if (HOST_BITS_PER_WIDE_INT >= 64)
10088 parts[0]
10089 = gen_int_mode
10090 ((l[0] & (((HOST_WIDE_INT) 2 << 31) - 1))
10091 + ((((HOST_WIDE_INT) l[1]) << 31) << 1),
10092 DImode);
10093 else
10094 parts[0] = immed_double_const (l[0], l[1], DImode);
10095 parts[1] = gen_int_mode (l[2], SImode);
10096 }
10097 else
10098 abort ();
10099 }
10100 }
10101
10102 return size;
10103 }
10104
10105
10106
10107
10108
10109
10110 void
10111 ix86_split_long_move (operands)
10112 rtx operands[];
10113 {
10114 rtx part[2][3];
10115 int nparts;
10116 int push = 0;
10117 int collisions = 0;
10118 enum machine_mode mode = GET_MODE (operands[0]);
10119
10120
10121
10122
10123 if (GET_MODE_SIZE (GET_MODE (operands[0])) == 8 && TARGET_64BIT)
10124 {
10125
10126
10127
10128 if (GET_CODE (operands[1]) == MEM
10129 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
10130 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
10131 operands[1] = get_pool_constant (XEXP (operands[1], 0));
10132 if (push_operand (operands[0], VOIDmode))
10133 {
10134 operands[0] = copy_rtx (operands[0]);
10135 PUT_MODE (operands[0], Pmode);
10136 }
10137 else
10138 operands[0] = gen_lowpart (DImode, operands[0]);
10139 operands[1] = gen_lowpart (DImode, operands[1]);
10140 emit_move_insn (operands[0], operands[1]);
10141 return;
10142 }
10143
10144
10145 if (push_operand (operands[0], VOIDmode))
10146 push = 1;
10147 else if (GET_CODE (operands[0]) == MEM
10148 && ! offsettable_memref_p (operands[0]))
10149 abort ();
10150
10151 nparts = ix86_split_to_parts (operands[1], part[1], GET_MODE (operands[0]));
10152 ix86_split_to_parts (operands[0], part[0], GET_MODE (operands[0]));
10153
10154
10155 if (push && GET_CODE (operands[1]) == MEM
10156 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
10157 {
10158 if (nparts == 3)
10159 part[1][1] = change_address (part[1][1], GET_MODE (part[1][1]),
10160 XEXP (part[1][2], 0));
10161 part[1][0] = change_address (part[1][0], GET_MODE (part[1][0]),
10162 XEXP (part[1][1], 0));
10163 }
10164
10165
10166
10167 if (REG_P (part[0][0]) && GET_CODE (part[1][0]) == MEM)
10168 {
10169 if (reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0)))
10170 collisions++;
10171 if (reg_overlap_mentioned_p (part[0][1], XEXP (part[1][0], 0)))
10172 collisions++;
10173 if (nparts == 3
10174 && reg_overlap_mentioned_p (part[0][2], XEXP (part[1][0], 0)))
10175 collisions++;
10176
10177
10178 if (collisions == 1 && nparts == 3
10179 && reg_overlap_mentioned_p (part[0][1], XEXP (part[1][0], 0)))
10180 {
10181 rtx tmp;
10182 tmp = part[0][1]; part[0][1] = part[0][2]; part[0][2] = tmp;
10183 tmp = part[1][1]; part[1][1] = part[1][2]; part[1][2] = tmp;
10184 }
10185
10186
10187
10188 else if (collisions > 1)
10189 {
10190 rtx base;
10191
10192 collisions = 1;
10193
10194 base = part[0][nparts - 1];
10195
10196
10197
10198 if (GET_MODE (base) != Pmode)
10199 base = gen_rtx_REG (Pmode, REGNO (base));
10200
10201 emit_insn (gen_rtx_SET (VOIDmode, base, XEXP (part[1][0], 0)));
10202 part[1][0] = replace_equiv_address (part[1][0], base);
10203 part[1][1] = replace_equiv_address (part[1][1],
10204 plus_constant (base, UNITS_PER_WORD));
10205 if (nparts == 3)
10206 part[1][2] = replace_equiv_address (part[1][2],
10207 plus_constant (base, 8));
10208 }
10209 }
10210
10211 if (push)
10212 {
10213 if (!TARGET_64BIT)
10214 {
10215 if (nparts == 3)
10216 {
10217
10218
10219
10220 if (mode == TFmode && !TARGET_64BIT)
10221 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
10222 GEN_INT (-4)));
10223 emit_move_insn (part[0][2], part[1][2]);
10224 }
10225 }
10226 else
10227 {
10228
10229
10230
10231
10232 if (GET_MODE (part[1][1]) == SImode)
10233 {
10234 if (GET_CODE (part[1][1]) == MEM)
10235 part[1][1] = adjust_address (part[1][1], DImode, 0);
10236 else if (REG_P (part[1][1]))
10237 part[1][1] = gen_rtx_REG (DImode, REGNO (part[1][1]));
10238 else
10239 abort ();
10240 if (GET_MODE (part[1][0]) == SImode)
10241 part[1][0] = part[1][1];
10242 }
10243 }
10244 emit_move_insn (part[0][1], part[1][1]);
10245 emit_move_insn (part[0][0], part[1][0]);
10246 return;
10247 }
10248
10249
10250 if ((REG_P (part[0][0])
10251 && REG_P (part[1][1])
10252 && (REGNO (part[0][0]) == REGNO (part[1][1])
10253 || (nparts == 3
10254 && REGNO (part[0][0]) == REGNO (part[1][2]))))
10255 || (collisions > 0
10256 && reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0))))
10257 {
10258 if (nparts == 3)
10259 {
10260 operands[2] = part[0][2];
10261 operands[3] = part[0][1];
10262 operands[4] = part[0][0];
10263 operands[5] = part[1][2];
10264 operands[6] = part[1][1];
10265 operands[7] = part[1][0];
10266 }
10267 else
10268 {
10269 operands[2] = part[0][1];
10270 operands[3] = part[0][0];
10271 operands[5] = part[1][1];
10272 operands[6] = part[1][0];
10273 }
10274 }
10275 else
10276 {
10277 if (nparts == 3)
10278 {
10279 operands[2] = part[0][0];
10280 operands[3] = part[0][1];
10281 operands[4] = part[0][2];
10282 operands[5] = part[1][0];
10283 operands[6] = part[1][1];
10284 operands[7] = part[1][2];
10285 }
10286 else
10287 {
10288 operands[2] = part[0][0];
10289 operands[3] = part[0][1];
10290 operands[5] = part[1][0];
10291 operands[6] = part[1][1];
10292 }
10293 }
10294 emit_move_insn (operands[2], operands[5]);
10295 emit_move_insn (operands[3], operands[6]);
10296 if (nparts == 3)
10297 emit_move_insn (operands[4], operands[7]);
10298
10299 return;
10300 }
10301
10302 void
10303 ix86_split_ashldi (operands, scratch)
10304 rtx *operands, scratch;
10305 {
10306 rtx low[2], high[2];
10307 int count;
10308
10309 if (GET_CODE (operands[2]) == CONST_INT)
10310 {
10311 split_di (operands, 2, low, high);
10312 count = INTVAL (operands[2]) & 63;
10313
10314 if (count >= 32)
10315 {
10316 emit_move_insn (high[0], low[1]);
10317 emit_move_insn (low[0], const0_rtx);
10318
10319 if (count > 32)
10320 emit_insn (gen_ashlsi3 (high[0], high[0], GEN_INT (count - 32)));
10321 }
10322 else
10323 {
10324 if (!rtx_equal_p (operands[0], operands[1]))
10325 emit_move_insn (operands[0], operands[1]);
10326 emit_insn (gen_x86_shld_1 (high[0], low[0], GEN_INT (count)));
10327 emit_insn (gen_ashlsi3 (low[0], low[0], GEN_INT (count)));
10328 }
10329 }
10330 else
10331 {
10332 if (!rtx_equal_p (operands[0], operands[1]))
10333 emit_move_insn (operands[0], operands[1]);
10334
10335 split_di (operands, 1, low, high);
10336
10337 emit_insn (gen_x86_shld_1 (high[0], low[0], operands[2]));
10338 emit_insn (gen_ashlsi3 (low[0], low[0], operands[2]));
10339
10340 if (TARGET_CMOVE && (! no_new_pseudos || scratch))
10341 {
10342 if (! no_new_pseudos)
10343 scratch = force_reg (SImode, const0_rtx);
10344 else
10345 emit_move_insn (scratch, const0_rtx);
10346
10347 emit_insn (gen_x86_shift_adj_1 (high[0], low[0], operands[2],
10348 scratch));
10349 }
10350 else
10351 emit_insn (gen_x86_shift_adj_2 (high[0], low[0], operands[2]));
10352 }
10353 }
10354
10355 void
10356 ix86_split_ashrdi (operands, scratch)
10357 rtx *operands, scratch;
10358 {
10359 rtx low[2], high[2];
10360 int count;
10361
10362 if (GET_CODE (operands[2]) == CONST_INT)
10363 {
10364 split_di (operands, 2, low, high);
10365 count = INTVAL (operands[2]) & 63;
10366
10367 if (count >= 32)
10368 {
10369 emit_move_insn (low[0], high[1]);
10370
10371 if (! reload_completed)
10372 emit_insn (gen_ashrsi3 (high[0], low[0], GEN_INT (31)));
10373 else
10374 {
10375 emit_move_insn (high[0], low[0]);
10376 emit_insn (gen_ashrsi3 (high[0], high[0], GEN_INT (31)));
10377 }
10378
10379 if (count > 32)
10380 emit_insn (gen_ashrsi3 (low[0], low[0], GEN_INT (count - 32)));
10381 }
10382 else
10383 {
10384 if (!rtx_equal_p (operands[0], operands[1]))
10385 emit_move_insn (operands[0], operands[1]);
10386 emit_insn (gen_x86_shrd_1 (low[0], high[0], GEN_INT (count)));
10387 emit_insn (gen_ashrsi3 (high[0], high[0], GEN_INT (count)));
10388 }
10389 }
10390 else
10391 {
10392 if (!rtx_equal_p (operands[0], operands[1]))
10393 emit_move_insn (operands[0], operands[1]);
10394
10395 split_di (operands, 1, low, high);
10396
10397 emit_insn (gen_x86_shrd_1 (low[0], high[0], operands[2]));
10398 emit_insn (gen_ashrsi3 (high[0], high[0], operands[2]));
10399
10400 if (TARGET_CMOVE && (! no_new_pseudos || scratch))
10401 {
10402 if (! no_new_pseudos)
10403 scratch = gen_reg_rtx (SImode);
10404 emit_move_insn (scratch, high[0]);
10405 emit_insn (gen_ashrsi3 (scratch, scratch, GEN_INT (31)));
10406 emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2],
10407 scratch));
10408 }
10409 else
10410 emit_insn (gen_x86_shift_adj_3 (low[0], high[0], operands[2]));
10411 }
10412 }
10413
10414 void
10415 ix86_split_lshrdi (operands, scratch)
10416 rtx *operands, scratch;
10417 {
10418 rtx low[2], high[2];
10419 int count;
10420
10421 if (GET_CODE (operands[2]) == CONST_INT)
10422 {
10423 split_di (operands, 2, low, high);
10424 count = INTVAL (operands[2]) & 63;
10425
10426 if (count >= 32)
10427 {
10428 emit_move_insn (low[0], high[1]);
10429 emit_move_insn (high[0], const0_rtx);
10430
10431 if (count > 32)
10432 emit_insn (gen_lshrsi3 (low[0], low[0], GEN_INT (count - 32)));
10433 }
10434 else
10435 {
10436 if (!rtx_equal_p (operands[0], operands[1]))
10437 emit_move_insn (operands[0], operands[1]);
10438 emit_insn (gen_x86_shrd_1 (low[0], high[0], GEN_INT (count)));
10439 emit_insn (gen_lshrsi3 (high[0], high[0], GEN_INT (count)));
10440 }
10441 }
10442 else
10443 {
10444 if (!rtx_equal_p (operands[0], operands[1]))
10445 emit_move_insn (operands[0], operands[1]);
10446
10447 split_di (operands, 1, low, high);
10448
10449 emit_insn (gen_x86_shrd_1 (low[0], high[0], operands[2]));
10450 emit_insn (gen_lshrsi3 (high[0], high[0], operands[2]));
10451
10452
10453 if (TARGET_CMOVE && (! no_new_pseudos || scratch))
10454 {
10455 if (! no_new_pseudos)
10456 scratch = force_reg (SImode, const0_rtx);
10457 else
10458 emit_move_insn (scratch, const0_rtx);
10459
10460 emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2],
10461 scratch));
10462 }
10463 else
10464 emit_insn (gen_x86_shift_adj_2 (low[0], high[0], operands[2]));
10465 }
10466 }
10467
10468
10469
10470 static rtx
10471 ix86_expand_aligntest (variable, value)
10472 rtx variable;
10473 int value;
10474 {
10475 rtx label = gen_label_rtx ();
10476 rtx tmpcount = gen_reg_rtx (GET_MODE (variable));
10477 if (GET_MODE (variable) == DImode)
10478 emit_insn (gen_anddi3 (tmpcount, variable, GEN_INT (value)));
10479 else
10480 emit_insn (gen_andsi3 (tmpcount, variable, GEN_INT (value)));
10481 emit_cmp_and_jump_insns (tmpcount, const0_rtx, EQ, 0, GET_MODE (variable),
10482 1, label);
10483 return label;
10484 }
10485
10486
10487 static void
10488 ix86_adjust_counter (countreg, value)
10489 rtx countreg;
10490 HOST_WIDE_INT value;
10491 {
10492 if (GET_MODE (countreg) == DImode)
10493 emit_insn (gen_adddi3 (countreg, countreg, GEN_INT (-value)));
10494 else
10495 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-value)));
10496 }
10497
10498
10499 rtx
10500 ix86_zero_extend_to_Pmode (exp)
10501 rtx exp;
10502 {
10503 rtx r;
10504 if (GET_MODE (exp) == VOIDmode)
10505 return force_reg (Pmode, exp);
10506 if (GET_MODE (exp) == Pmode)
10507 return copy_to_mode_reg (Pmode, exp);
10508 r = gen_reg_rtx (Pmode);
10509 emit_insn (gen_zero_extendsidi2 (r, exp));
10510 return r;
10511 }
10512
10513
10514
10515 int
10516 ix86_expand_movstr (dst, src, count_exp, align_exp)
10517 rtx dst, src, count_exp, align_exp;
10518 {
10519 rtx srcreg, destreg, countreg;
10520 enum machine_mode counter_mode;
10521 HOST_WIDE_INT align = 0;
10522 unsigned HOST_WIDE_INT count = 0;
10523 rtx insns;
10524
10525 start_sequence ();
10526
10527 if (GET_CODE (align_exp) == CONST_INT)
10528 align = INTVAL (align_exp);
10529
10530
10531 if (!TARGET_ALIGN_STRINGOPS)
10532 align = 64;
10533
10534 if (GET_CODE (count_exp) == CONST_INT)
10535 count = INTVAL (count_exp);
10536
10537
10538
10539
10540 if (!TARGET_64BIT || GET_MODE (count_exp) == SImode
10541 || x86_64_zero_extended_value (count_exp))
10542 counter_mode = SImode;
10543 else
10544 counter_mode = DImode;
10545
10546 if (counter_mode != SImode && counter_mode != DImode)
10547 abort ();
10548
10549 destreg = copy_to_mode_reg (Pmode, XEXP (dst, 0));
10550 srcreg = copy_to_mode_reg (Pmode, XEXP (src, 0));
10551
10552 emit_insn (gen_cld ());
10553
10554
10555
10556
10557 if ((!optimize || optimize_size) && (count == 0 || (count & 0x03)))
10558 {
10559 countreg = ix86_zero_extend_to_Pmode (count_exp);
10560 if (TARGET_64BIT)
10561 emit_insn (gen_rep_movqi_rex64 (destreg, srcreg, countreg,
10562 destreg, srcreg, countreg));
10563 else
10564 emit_insn (gen_rep_movqi (destreg, srcreg, countreg,
10565 destreg, srcreg, countreg));
10566 }
10567
10568
10569
10570
10571
10572 else if (count != 0
10573 && (align >= 8
10574 || (!TARGET_PENTIUMPRO && !TARGET_64BIT && align >= 4)
10575 || optimize_size || count < (unsigned int) 64))
10576 {
10577 int size = TARGET_64BIT && !optimize_size ? 8 : 4;
10578 if (count & ~(size - 1))
10579 {
10580 countreg = copy_to_mode_reg (counter_mode,
10581 GEN_INT ((count >> (size == 4 ? 2 : 3))
10582 & (TARGET_64BIT ? -1 : 0x3fffffff)));
10583 countreg = ix86_zero_extend_to_Pmode (countreg);
10584 if (size == 4)
10585 {
10586 if (TARGET_64BIT)
10587 emit_insn (gen_rep_movsi_rex64 (destreg, srcreg, countreg,
10588 destreg, srcreg, countreg));
10589 else
10590 emit_insn (gen_rep_movsi (destreg, srcreg, countreg,
10591 destreg, srcreg, countreg));
10592 }
10593 else
10594 emit_insn (gen_rep_movdi_rex64 (destreg, srcreg, countreg,
10595 destreg, srcreg, countreg));
10596 }
10597 if (size == 8 && (count & 0x04))
10598 emit_insn (gen_strmovsi (destreg, srcreg));
10599 if (count & 0x02)
10600 emit_insn (gen_strmovhi (destreg, srcreg));
10601 if (count & 0x01)
10602 emit_insn (gen_strmovqi (destreg, srcreg));
10603 }
10604
10605
10606
10607
10608
10609 else
10610 {
10611 rtx countreg2;
10612 rtx label = NULL;
10613 int desired_alignment = (TARGET_PENTIUMPRO
10614 && (count == 0 || count >= (unsigned int) 260)
10615 ? 8 : UNITS_PER_WORD);
10616
10617
10618
10619
10620 if (!TARGET_INLINE_ALL_STRINGOPS && align < UNITS_PER_WORD)
10621 {
10622 end_sequence ();
10623 return 0;
10624 }
10625
10626 if (TARGET_SINGLE_STRINGOP)
10627 emit_insn (gen_cld ());
10628
10629 countreg2 = gen_reg_rtx (Pmode);
10630 countreg = copy_to_mode_reg (counter_mode, count_exp);
10631
10632
10633
10634
10635
10636
10637
10638
10639
10640
10641
10642
10643
10644
10645 if (count == 0 && align < desired_alignment)
10646 {
10647 label = gen_label_rtx ();
10648 emit_cmp_and_jump_insns (countreg, GEN_INT (desired_alignment - 1),
10649 LEU, 0, counter_mode, 1, label);
10650 }
10651 if (align <= 1)
10652 {
10653 rtx label = ix86_expand_aligntest (destreg, 1);
10654 emit_insn (gen_strmovqi (destreg, srcreg));
10655 ix86_adjust_counter (countreg, 1);
10656 emit_label (label);
10657 LABEL_NUSES (label) = 1;
10658 }
10659 if (align <= 2)
10660 {
10661 rtx label = ix86_expand_aligntest (destreg, 2);
10662 emit_insn (gen_strmovhi (destreg, srcreg));
10663 ix86_adjust_counter (countreg, 2);
10664 emit_label (label);
10665 LABEL_NUSES (label) = 1;
10666 }
10667 if (align <= 4 && desired_alignment > 4)
10668 {
10669 rtx label = ix86_expand_aligntest (destreg, 4);
10670 emit_insn (gen_strmovsi (destreg, srcreg));
10671 ix86_adjust_counter (countreg, 4);
10672 emit_label (label);
10673 LABEL_NUSES (label) = 1;
10674 }
10675
10676 if (label && desired_alignment > 4 && !TARGET_64BIT)
10677 {
10678 emit_label (label);
10679 LABEL_NUSES (label) = 1;
10680 label = NULL_RTX;
10681 }
10682 if (!TARGET_SINGLE_STRINGOP)
10683 emit_insn (gen_cld ());
10684 if (TARGET_64BIT)
10685 {
10686 emit_insn (gen_lshrdi3 (countreg2, ix86_zero_extend_to_Pmode (countreg),
10687 GEN_INT (3)));
10688 emit_insn (gen_rep_movdi_rex64 (destreg, srcreg, countreg2,
10689 destreg, srcreg, countreg2));
10690 }
10691 else
10692 {
10693 emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
10694 emit_insn (gen_rep_movsi (destreg, srcreg, countreg2,
10695 destreg, srcreg, countreg2));
10696 }
10697
10698 if (label)
10699 {
10700 emit_label (label);
10701 LABEL_NUSES (label) = 1;
10702 }
10703 if (TARGET_64BIT && align > 4 && count != 0 && (count & 4))
10704 emit_insn (gen_strmovsi (destreg, srcreg));
10705 if ((align <= 4 || count == 0) && TARGET_64BIT)
10706 {
10707 rtx label = ix86_expand_aligntest (countreg, 4);
10708 emit_insn (gen_strmovsi (destreg, srcreg));
10709 emit_label (label);
10710 LABEL_NUSES (label) = 1;
10711 }
10712 if (align > 2 && count != 0 && (count & 2))
10713 emit_insn (gen_strmovhi (destreg, srcreg));
10714 if (align <= 2 || count == 0)
10715 {
10716 rtx label = ix86_expand_aligntest (countreg, 2);
10717 emit_insn (gen_strmovhi (destreg, srcreg));
10718 emit_label (label);
10719 LABEL_NUSES (label) = 1;
10720 }
10721 if (align > 1 && count != 0 && (count & 1))
10722 emit_insn (gen_strmovqi (destreg, srcreg));
10723 if (align <= 1 || count == 0)
10724 {
10725 rtx label = ix86_expand_aligntest (countreg, 1);
10726 emit_insn (gen_strmovqi (destreg, srcreg));
10727 emit_label (label);
10728 LABEL_NUSES (label) = 1;
10729 }
10730 }
10731
10732 insns = get_insns ();
10733 end_sequence ();
10734
10735 ix86_set_move_mem_attrs (insns, dst, src, destreg, srcreg);
10736 emit_insn (insns);
10737 return 1;
10738 }
10739
10740
10741
10742 int
10743 ix86_expand_clrstr (src, count_exp, align_exp)
10744 rtx src, count_exp, align_exp;
10745 {
10746 rtx destreg, zeroreg, countreg;
10747 enum machine_mode counter_mode;
10748 HOST_WIDE_INT align = 0;
10749 unsigned HOST_WIDE_INT count = 0;
10750
10751 if (GET_CODE (align_exp) == CONST_INT)
10752 align = INTVAL (align_exp);
10753
10754
10755 if (!TARGET_ALIGN_STRINGOPS)
10756 align = 32;
10757
10758 if (GET_CODE (count_exp) == CONST_INT)
10759 count = INTVAL (count_exp);
10760
10761
10762
10763 if (!TARGET_64BIT || GET_MODE (count_exp) == SImode
10764 || x86_64_zero_extended_value (count_exp))
10765 counter_mode = SImode;
10766 else
10767 counter_mode = DImode;
10768
10769 destreg = copy_to_mode_reg (Pmode, XEXP (src, 0));
10770
10771 emit_insn (gen_cld ());
10772
10773
10774
10775
10776 if ((!optimize || optimize_size) && (count == 0 || (count & 0x03)))
10777 {
10778 countreg = ix86_zero_extend_to_Pmode (count_exp);
10779 zeroreg = copy_to_mode_reg (QImode, const0_rtx);
10780 if (TARGET_64BIT)
10781 emit_insn (gen_rep_stosqi_rex64 (destreg, countreg, zeroreg,
10782 destreg, countreg));
10783 else
10784 emit_insn (gen_rep_stosqi (destreg, countreg, zeroreg,
10785 destreg, countreg));
10786 }
10787 else if (count != 0
10788 && (align >= 8
10789 || (!TARGET_PENTIUMPRO && !TARGET_64BIT && align >= 4)
10790 || optimize_size || count < (unsigned int) 64))
10791 {
10792 int size = TARGET_64BIT && !optimize_size ? 8 : 4;
10793 zeroreg = copy_to_mode_reg (size == 4 ? SImode : DImode, const0_rtx);
10794 if (count & ~(size - 1))
10795 {
10796 countreg = copy_to_mode_reg (counter_mode,
10797 GEN_INT ((count >> (size == 4 ? 2 : 3))
10798 & (TARGET_64BIT ? -1 : 0x3fffffff)));
10799 countreg = ix86_zero_extend_to_Pmode (countreg);
10800 if (size == 4)
10801 {
10802 if (TARGET_64BIT)
10803 emit_insn (gen_rep_stossi_rex64 (destreg, countreg, zeroreg,
10804 destreg, countreg));
10805 else
10806 emit_insn (gen_rep_stossi (destreg, countreg, zeroreg,
10807 destreg, countreg));
10808 }
10809 else
10810 emit_insn (gen_rep_stosdi_rex64 (destreg, countreg, zeroreg,
10811 destreg, countreg));
10812 }
10813 if (size == 8 && (count & 0x04))
10814 emit_insn (gen_strsetsi (destreg,
10815 gen_rtx_SUBREG (SImode, zeroreg, 0)));
10816 if (count & 0x02)
10817 emit_insn (gen_strsethi (destreg,
10818 gen_rtx_SUBREG (HImode, zeroreg, 0)));
10819 if (count & 0x01)
10820 emit_insn (gen_strsetqi (destreg,
10821 gen_rtx_SUBREG (QImode, zeroreg, 0)));
10822 }
10823 else
10824 {
10825 rtx countreg2;
10826 rtx label = NULL;
10827
10828 int desired_alignment = (TARGET_PENTIUMPRO
10829 && (count == 0 || count >= (unsigned int) 260)
10830 ? 8 : UNITS_PER_WORD);
10831
10832
10833
10834
10835 if (!TARGET_INLINE_ALL_STRINGOPS && align < UNITS_PER_WORD)
10836 return 0;
10837
10838 if (TARGET_SINGLE_STRINGOP)
10839 emit_insn (gen_cld ());
10840
10841 countreg2 = gen_reg_rtx (Pmode);
10842 countreg = copy_to_mode_reg (counter_mode, count_exp);
10843 zeroreg = copy_to_mode_reg (Pmode, const0_rtx);
10844
10845 if (count == 0 && align < desired_alignment)
10846 {
10847 label = gen_label_rtx ();
10848 emit_cmp_and_jump_insns (countreg, GEN_INT (desired_alignment - 1),
10849 LEU, 0, counter_mode, 1, label);
10850 }
10851 if (align <= 1)
10852 {
10853 rtx label = ix86_expand_aligntest (destreg, 1);
10854 emit_insn (gen_strsetqi (destreg,
10855 gen_rtx_SUBREG (QImode, zeroreg, 0)));
10856 ix86_adjust_counter (countreg, 1);
10857 emit_label (label);
10858 LABEL_NUSES (label) = 1;
10859 }
10860 if (align <= 2)
10861 {
10862 rtx label = ix86_expand_aligntest (destreg, 2);
10863 emit_insn (gen_strsethi (destreg,
10864 gen_rtx_SUBREG (HImode, zeroreg, 0)));
10865 ix86_adjust_counter (countreg, 2);
10866 emit_label (label);
10867 LABEL_NUSES (label) = 1;
10868 }
10869 if (align <= 4 && desired_alignment > 4)
10870 {
10871 rtx label = ix86_expand_aligntest (destreg, 4);
10872 emit_insn (gen_strsetsi (destreg, (TARGET_64BIT
10873 ? gen_rtx_SUBREG (SImode, zeroreg, 0)
10874 : zeroreg)));
10875 ix86_adjust_counter (countreg, 4);
10876 emit_label (label);
10877 LABEL_NUSES (label) = 1;
10878 }
10879
10880 if (label && desired_alignment > 4 && !TARGET_64BIT)
10881 {
10882 emit_label (label);
10883 LABEL_NUSES (label) = 1;
10884 label = NULL_RTX;
10885 }
10886
10887 if (!TARGET_SINGLE_STRINGOP)
10888 emit_insn (gen_cld ());
10889 if (TARGET_64BIT)
10890 {
10891 emit_insn (gen_lshrdi3 (countreg2, ix86_zero_extend_to_Pmode (countreg),
10892 GEN_INT (3)));
10893 emit_insn (gen_rep_stosdi_rex64 (destreg, countreg2, zeroreg,
10894 destreg, countreg2));
10895 }
10896 else
10897 {
10898 emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
10899 emit_insn (gen_rep_stossi (destreg, countreg2, zeroreg,
10900 destreg, countreg2));
10901 }
10902 if (label)
10903 {
10904 emit_label (label);
10905 LABEL_NUSES (label) = 1;
10906 }
10907
10908 if (TARGET_64BIT && align > 4 && count != 0 && (count & 4))
10909 emit_insn (gen_strsetsi (destreg,
10910 gen_rtx_SUBREG (SImode, zeroreg, 0)));
10911 if (TARGET_64BIT && (align <= 4 || count == 0))
10912 {
10913 rtx label = ix86_expand_aligntest (countreg, 4);
10914 emit_insn (gen_strsetsi (destreg,
10915 gen_rtx_SUBREG (SImode, zeroreg, 0)));
10916 emit_label (label);
10917 LABEL_NUSES (label) = 1;
10918 }
10919 if (align > 2 && count != 0 && (count & 2))
10920 emit_insn (gen_strsethi (destreg,
10921 gen_rtx_SUBREG (HImode, zeroreg, 0)));
10922 if (align <= 2 || count == 0)
10923 {
10924 rtx label = ix86_expand_aligntest (countreg, 2);
10925 emit_insn (gen_strsethi (destreg,
10926 gen_rtx_SUBREG (HImode, zeroreg, 0)));
10927 emit_label (label);
10928 LABEL_NUSES (label) = 1;
10929 }
10930 if (align > 1 && count != 0 && (count & 1))
10931 emit_insn (gen_strsetqi (destreg,
10932 gen_rtx_SUBREG (QImode, zeroreg, 0)));
10933 if (align <= 1 || count == 0)
10934 {
10935 rtx label = ix86_expand_aligntest (countreg, 1);
10936 emit_insn (gen_strsetqi (destreg,
10937 gen_rtx_SUBREG (QImode, zeroreg, 0)));
10938 emit_label (label);
10939 LABEL_NUSES (label) = 1;
10940 }
10941 }
10942 return 1;
10943 }
10944
10945 int
10946 ix86_expand_strlen (out, src, eoschar, align)
10947 rtx out, src, eoschar, align;
10948 {
10949 rtx addr, scratch1, scratch2, scratch3, scratch4;
10950
10951
10952
10953
10954 if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
10955 && !TARGET_INLINE_ALL_STRINGOPS
10956 && !optimize_size
10957 && (GET_CODE (align) != CONST_INT || INTVAL (align) < 4))
10958 return 0;
10959
10960 addr = force_reg (Pmode, XEXP (src, 0));
10961 scratch1 = gen_reg_rtx (Pmode);
10962
10963 if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
10964 && !optimize_size)
10965 {
10966
10967
10968
10969
10970
10971
10972
10973
10974 emit_move_insn (out, addr);
10975
10976 ix86_expand_strlensi_unroll_1 (out, align);
10977
10978
10979
10980
10981 if (TARGET_64BIT)
10982 emit_insn (gen_subdi3 (out, out, addr));
10983 else
10984 emit_insn (gen_subsi3 (out, out, addr));
10985 }
10986 else
10987 {
10988 scratch2 = gen_reg_rtx (Pmode);
10989 scratch3 = gen_reg_rtx (Pmode);
10990 scratch4 = force_reg (Pmode, constm1_rtx);
10991
10992 emit_move_insn (scratch3, addr);
10993 eoschar = force_reg (QImode, eoschar);
10994
10995 emit_insn (gen_cld ());
10996 if (TARGET_64BIT)
10997 {
10998 emit_insn (gen_strlenqi_rex_1 (scratch1, scratch3, eoschar,
10999 align, scratch4, scratch3));
11000 emit_insn (gen_one_cmpldi2 (scratch2, scratch1));
11001 emit_insn (gen_adddi3 (out, scratch2, constm1_rtx));
11002 }
11003 else
11004 {
11005 emit_insn (gen_strlenqi_1 (scratch1, scratch3, eoschar,
11006 align, scratch4, scratch3));
11007 emit_insn (gen_one_cmplsi2 (scratch2, scratch1));
11008 emit_insn (gen_addsi3 (out, scratch2, constm1_rtx));
11009 }
11010 }
11011 return 1;
11012 }
11013
11014
11015
11016
11017
11018
11019
11020
11021
11022
11023
11024
11025 static void
11026 ix86_expand_strlensi_unroll_1 (out, align_rtx)
11027 rtx out, align_rtx;
11028 {
11029 int align;
11030 rtx tmp;
11031 rtx align_2_label = NULL_RTX;
11032 rtx align_3_label = NULL_RTX;
11033 rtx align_4_label = gen_label_rtx ();
11034 rtx end_0_label = gen_label_rtx ();
11035 rtx mem;
11036 rtx tmpreg = gen_reg_rtx (SImode);
11037 rtx scratch = gen_reg_rtx (SImode);
11038
11039 align = 0;
11040 if (GET_CODE (align_rtx) == CONST_INT)
11041 align = INTVAL (align_rtx);
11042
11043
11044
11045
11046 if (align < 4)
11047 {
11048 rtx scratch1 = gen_reg_rtx (Pmode);
11049 emit_move_insn (scratch1, out);
11050
11051 if (align != 2)
11052 {
11053 align_3_label = gen_label_rtx ();
11054 align_2_label = gen_label_rtx ();
11055
11056
11057 align_rtx = expand_binop (Pmode, and_optab, scratch1, GEN_INT (3),
11058 NULL_RTX, 0, OPTAB_WIDEN);
11059
11060 emit_cmp_and_jump_insns (align_rtx, const0_rtx, EQ, NULL,
11061 Pmode, 1, align_4_label);
11062 emit_cmp_and_jump_insns (align_rtx, GEN_INT (2), EQ, NULL,
11063 Pmode, 1, align_2_label);
11064 emit_cmp_and_jump_insns (align_rtx, GEN_INT (2), GTU, NULL,
11065 Pmode, 1, align_3_label);
11066 }
11067 else
11068 {
11069
11070
11071
11072 align_rtx = expand_binop (Pmode, and_optab, scratch1, GEN_INT (2),
11073 NULL_RTX, 0, OPTAB_WIDEN);
11074
11075 emit_cmp_and_jump_insns (align_rtx, const0_rtx, EQ, NULL,
11076 Pmode, 1, align_4_label);
11077 }
11078
11079 mem = gen_rtx_MEM (QImode, out);
11080
11081
11082
11083
11084 emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL,
11085 QImode, 1, end_0_label);
11086
11087
11088 if (TARGET_64BIT)
11089 emit_insn (gen_adddi3 (out, out, const1_rtx));
11090 else
11091 emit_insn (gen_addsi3 (out, out, const1_rtx));
11092
11093
11094 if (align != 2)
11095 {
11096 emit_label (align_2_label);
11097
11098 emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL, QImode, 1,
11099 end_0_label);
11100
11101 if (TARGET_64BIT)
11102 emit_insn (gen_adddi3 (out, out, const1_rtx));
11103 else
11104 emit_insn (gen_addsi3 (out, out, const1_rtx));
11105
11106 emit_label (align_3_label);
11107 }
11108
11109 emit_cmp_and_jump_insns (mem, const0_rtx, EQ, NULL, QImode, 1,
11110 end_0_label);
11111
11112 if (TARGET_64BIT)
11113 emit_insn (gen_adddi3 (out, out, const1_rtx));
11114 else
11115 emit_insn (gen_addsi3 (out, out, const1_rtx));
11116 }
11117
11118
11119
11120
11121 emit_label (align_4_label);
11122
11123 mem = gen_rtx_MEM (SImode, out);
11124 emit_move_insn (scratch, mem);
11125 if (TARGET_64BIT)
11126 emit_insn (gen_adddi3 (out, out, GEN_INT (4)));
11127 else
11128 emit_insn (gen_addsi3 (out, out, GEN_INT (4)));
11129
11130
11131
11132
11133 emit_insn (gen_addsi3 (tmpreg, scratch, GEN_INT (-0x01010101)));
11134 emit_insn (gen_one_cmplsi2 (scratch, scratch));
11135 emit_insn (gen_andsi3 (tmpreg, tmpreg, scratch));
11136 emit_insn (gen_andsi3 (tmpreg, tmpreg,
11137 gen_int_mode (0x80808080, SImode)));
11138 emit_cmp_and_jump_insns (tmpreg, const0_rtx, EQ, 0, SImode, 1,
11139 align_4_label);
11140
11141 if (TARGET_CMOVE)
11142 {
11143 rtx reg = gen_reg_rtx (SImode);
11144 rtx reg2 = gen_reg_rtx (Pmode);
11145 emit_move_insn (reg, tmpreg);
11146 emit_insn (gen_lshrsi3 (reg, reg, GEN_INT (16)));
11147
11148
11149 emit_insn (gen_testsi_ccno_1 (tmpreg, GEN_INT (0x8080)));
11150 tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
11151 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11152 emit_insn (gen_rtx_SET (VOIDmode, tmpreg,
11153 gen_rtx_IF_THEN_ELSE (SImode, tmp,
11154 reg,
11155 tmpreg)));
11156
11157 emit_insn (gen_rtx_SET (SImode, reg2,
11158 gen_rtx_PLUS (Pmode, out, GEN_INT (2))));
11159
11160 tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
11161 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11162 emit_insn (gen_rtx_SET (VOIDmode, out,
11163 gen_rtx_IF_THEN_ELSE (Pmode, tmp,
11164 reg2,
11165 out)));
11166
11167 }
11168 else
11169 {
11170 rtx end_2_label = gen_label_rtx ();
11171
11172
11173 emit_insn (gen_testsi_ccno_1 (tmpreg, GEN_INT (0x8080)));
11174 tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
11175 tmp = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
11176 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11177 gen_rtx_LABEL_REF (VOIDmode, end_2_label),
11178 pc_rtx);
11179 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11180 JUMP_LABEL (tmp) = end_2_label;
11181
11182
11183 emit_insn (gen_lshrsi3 (tmpreg, tmpreg, GEN_INT (16)));
11184 if (TARGET_64BIT)
11185 emit_insn (gen_adddi3 (out, out, GEN_INT (2)));
11186 else
11187 emit_insn (gen_addsi3 (out, out, GEN_INT (2)));
11188
11189 emit_label (end_2_label);
11190
11191 }
11192
11193
11194 tmpreg = gen_lowpart (QImode, tmpreg);
11195 emit_insn (gen_addqi3_cc (tmpreg, tmpreg, tmpreg));
11196 if (TARGET_64BIT)
11197 emit_insn (gen_subdi3_carry_rex64 (out, out, GEN_INT (3)));
11198 else
11199 emit_insn (gen_subsi3_carry (out, out, GEN_INT (3)));
11200
11201 emit_label (end_0_label);
11202 }
11203
11204 void
11205 ix86_expand_call (retval, fnaddr, callarg1, callarg2, pop)
11206 rtx retval, fnaddr, callarg1, callarg2, pop;
11207 {
11208 rtx use = NULL, call;
11209
11210 if (pop == const0_rtx)
11211 pop = NULL;
11212 if (TARGET_64BIT && pop)
11213 abort ();
11214
11215 #if TARGET_MACHO
11216 if (flag_pic && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF)
11217 fnaddr = machopic_indirect_call_target (fnaddr);
11218 #else
11219
11220 if (! TARGET_64BIT && flag_pic
11221 && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
11222 && ! SYMBOL_REF_FLAG (XEXP (fnaddr, 0)))
11223 use_reg (&use, pic_offset_table_rtx);
11224
11225 if (TARGET_64BIT && INTVAL (callarg2) >= 0)
11226 {
11227 rtx al = gen_rtx_REG (QImode, 0);
11228 emit_move_insn (al, callarg2);
11229 use_reg (&use, al);
11230 }
11231 #endif
11232
11233 if (! call_insn_operand (XEXP (fnaddr, 0), Pmode))
11234 {
11235 fnaddr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
11236 fnaddr = gen_rtx_MEM (QImode, fnaddr);
11237 }
11238
11239 call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
11240 if (retval)
11241 call = gen_rtx_SET (VOIDmode, retval, call);
11242 if (pop)
11243 {
11244 pop = gen_rtx_PLUS (Pmode, stack_pointer_rtx, pop);
11245 pop = gen_rtx_SET (VOIDmode, stack_pointer_rtx, pop);
11246 call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, call, pop));
11247 }
11248
11249 call = emit_call_insn (call);
11250 if (use)
11251 CALL_INSN_FUNCTION_USAGE (call) = use;
11252 }
11253
11254
11255
11256
11257
11258
11259 static struct machine_function *
11260 ix86_init_machine_status ()
11261 {
11262 return ggc_alloc_cleared (sizeof (struct machine_function));
11263 }
11264
11265
11266
11267
11268
11269
11270
11271 rtx
11272 assign_386_stack_local (mode, n)
11273 enum machine_mode mode;
11274 int n;
11275 {
11276 if (n < 0 || n >= MAX_386_STACK_LOCALS)
11277 abort ();
11278
11279 if (ix86_stack_locals[(int) mode][n] == NULL_RTX)
11280 ix86_stack_locals[(int) mode][n]
11281 = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
11282
11283 return ix86_stack_locals[(int) mode][n];
11284 }
11285
11286
11287
11288 static GTY(()) rtx ix86_tls_symbol;
11289 rtx
11290 ix86_tls_get_addr ()
11291 {
11292
11293 if (!ix86_tls_symbol)
11294 {
11295 ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode,
11296 (TARGET_GNU_TLS && !TARGET_64BIT)
11297 ? "___tls_get_addr"
11298 : "__tls_get_addr");
11299 }
11300
11301 return ix86_tls_symbol;
11302 }
11303
11304
11305
11306
11307 static int
11308 memory_address_length (addr)
11309 rtx addr;
11310 {
11311 struct ix86_address parts;
11312 rtx base, index, disp;
11313 int len;
11314
11315 if (GET_CODE (addr) == PRE_DEC
11316 || GET_CODE (addr) == POST_INC
11317 || GET_CODE (addr) == PRE_MODIFY
11318 || GET_CODE (addr) == POST_MODIFY)
11319 return 0;
11320
11321 if (! ix86_decompose_address (addr, &parts))
11322 abort ();
11323
11324 base = parts.base;
11325 index = parts.index;
11326 disp = parts.disp;
11327 len = 0;
11328
11329
11330
11331
11332
11333
11334 if (base && !index && !disp)
11335 {
11336
11337
11338 if (addr == stack_pointer_rtx
11339 || addr == arg_pointer_rtx
11340 || addr == frame_pointer_rtx
11341 || addr == hard_frame_pointer_rtx)
11342 len = 1;
11343 }
11344
11345
11346 else if (disp && !base && !index)
11347 len = 4;
11348
11349 else
11350 {
11351
11352 if (disp)
11353 {
11354 if (GET_CODE (disp) == CONST_INT
11355 && CONST_OK_FOR_LETTER_P (INTVAL (disp), 'K')
11356 && base)
11357 len = 1;
11358 else
11359 len = 4;
11360 }
11361
11362 else if (base == hard_frame_pointer_rtx)
11363 len = 1;
11364
11365
11366 if (index
11367
11368 || base == stack_pointer_rtx
11369 || base == arg_pointer_rtx
11370 || base == frame_pointer_rtx)
11371 len += 1;
11372 }
11373
11374 return len;
11375 }
11376
11377
11378
11379 int
11380 ix86_attr_length_immediate_default (insn, shortform)
11381 rtx insn;
11382 int shortform;
11383 {
11384 int len = 0;
11385 int i;
11386 extract_insn_cached (insn);
11387 for (i = recog_data.n_operands - 1; i >= 0; --i)
11388 if (CONSTANT_P (recog_data.operand[i]))
11389 {
11390 if (len)
11391 abort ();
11392 if (shortform
11393 && GET_CODE (recog_data.operand[i]) == CONST_INT
11394 && CONST_OK_FOR_LETTER_P (INTVAL (recog_data.operand[i]), 'K'))
11395 len = 1;
11396 else
11397 {
11398 switch (get_attr_mode (insn))
11399 {
11400 case MODE_QI:
11401 len+=1;
11402 break;
11403 case MODE_HI:
11404 len+=2;
11405 break;
11406 case MODE_SI:
11407 len+=4;
11408 break;
11409
11410 case MODE_DI:
11411 len+=4;
11412 break;
11413 default:
11414 fatal_insn ("unknown insn mode", insn);
11415 }
11416 }
11417 }
11418 return len;
11419 }
11420
11421 int
11422 ix86_attr_length_address_default (insn)
11423 rtx insn;
11424 {
11425 int i;
11426
11427 if (get_attr_type (insn) == TYPE_LEA)
11428 {
11429 rtx set = PATTERN (insn);
11430 if (GET_CODE (set) == SET)
11431 ;
11432 else if (GET_CODE (set) == PARALLEL
11433 && GET_CODE (XVECEXP (set, 0, 0)) == SET)
11434 set = XVECEXP (set, 0, 0);
11435 else
11436 {
11437 #ifdef ENABLE_CHECKING
11438 abort ();
11439 #endif
11440 return 0;
11441 }
11442
11443 return memory_address_length (SET_SRC (set));
11444 }
11445
11446 extract_insn_cached (insn);
11447 for (i = recog_data.n_operands - 1; i >= 0; --i)
11448 if (GET_CODE (recog_data.operand[i]) == MEM)
11449 {
11450 return memory_address_length (XEXP (recog_data.operand[i], 0));
11451 break;
11452 }
11453 return 0;
11454 }
11455
11456
11457
11458 static int
11459 ix86_issue_rate ()
11460 {
11461 switch (ix86_cpu)
11462 {
11463 case PROCESSOR_PENTIUM:
11464 case PROCESSOR_K6:
11465 return 2;
11466
11467 case PROCESSOR_PENTIUMPRO:
11468 case PROCESSOR_PENTIUM4:
11469 case PROCESSOR_ATHLON:
11470 return 3;
11471
11472 default:
11473 return 1;
11474 }
11475 }
11476
11477
11478
11479
11480 static int
11481 ix86_flags_dependant (insn, dep_insn, insn_type)
11482 rtx insn, dep_insn;
11483 enum attr_type insn_type;
11484 {
11485 rtx set, set2;
11486
11487
11488 if (insn_type != TYPE_SETCC
11489 && insn_type != TYPE_ICMOV
11490 && insn_type != TYPE_FCMOV
11491 && insn_type != TYPE_IBR)
11492 return 0;
11493
11494 if ((set = single_set (dep_insn)) != 0)
11495 {
11496 set = SET_DEST (set);
11497 set2 = NULL_RTX;
11498 }
11499 else if (GET_CODE (PATTERN (dep_insn)) == PARALLEL
11500 && XVECLEN (PATTERN (dep_insn), 0) == 2
11501 && GET_CODE (XVECEXP (PATTERN (dep_insn), 0, 0)) == SET
11502 && GET_CODE (XVECEXP (PATTERN (dep_insn), 0, 1)) == SET)
11503 {
11504 set = SET_DEST (XVECEXP (PATTERN (dep_insn), 0, 0));
11505 set2 = SET_DEST (XVECEXP (PATTERN (dep_insn), 0, 0));
11506 }
11507 else
11508 return 0;
11509
11510 if (GET_CODE (set) != REG || REGNO (set) != FLAGS_REG)
11511 return 0;
11512
11513
11514
11515 if (!reg_overlap_mentioned_p (set, PATTERN (insn)))
11516 return 0;
11517
11518 if (set2 && reg_overlap_mentioned_p (set2, PATTERN (insn)))
11519 return 0;
11520
11521 return 1;
11522 }
11523
11524
11525
11526
11527 static int
11528 ix86_agi_dependant (insn, dep_insn, insn_type)
11529 rtx insn, dep_insn;
11530 enum attr_type insn_type;
11531 {
11532 rtx addr;
11533
11534 if (insn_type == TYPE_LEA
11535 && TARGET_PENTIUM)
11536 {
11537 addr = PATTERN (insn);
11538 if (GET_CODE (addr) == SET)
11539 ;
11540 else if (GET_CODE (addr) == PARALLEL
11541 && GET_CODE (XVECEXP (addr, 0, 0)) == SET)
11542 addr = XVECEXP (addr, 0, 0);
11543 else
11544 abort ();
11545 addr = SET_SRC (addr);
11546 }
11547 else
11548 {
11549 int i;
11550 extract_insn_cached (insn);
11551 for (i = recog_data.n_operands - 1; i >= 0; --i)
11552 if (GET_CODE (recog_data.operand[i]) == MEM)
11553 {
11554 addr = XEXP (recog_data.operand[i], 0);
11555 goto found;
11556 }
11557 return 0;
11558 found:;
11559 }
11560
11561 return modified_in_p (addr, dep_insn);
11562 }
11563
11564 static int
11565 ix86_adjust_cost (insn, link, dep_insn, cost)
11566 rtx insn, link, dep_insn;
11567 int cost;
11568 {
11569 enum attr_type insn_type, dep_insn_type;
11570 enum attr_memory memory, dep_memory;
11571 rtx set, set2;
11572 int dep_insn_code_number;
11573
11574
11575 if (REG_NOTE_KIND (link) != 0)
11576 return 0;
11577
11578 dep_insn_code_number = recog_memoized (dep_insn);
11579
11580
11581 if (dep_insn_code_number < 0 || recog_memoized (insn) < 0)
11582 return cost;
11583
11584 insn_type = get_attr_type (insn);
11585 dep_insn_type = get_attr_type (dep_insn);
11586
11587 switch (ix86_cpu)
11588 {
11589 case PROCESSOR_PENTIUM:
11590
11591 if (ix86_agi_dependant (insn, dep_insn, insn_type))
11592 cost += 1;
11593
11594
11595 if (ix86_flags_dependant (insn, dep_insn, insn_type))
11596 cost = 0;
11597
11598
11599 if (insn_type == TYPE_FMOV
11600 && get_attr_memory (insn) == MEMORY_STORE
11601 && !ix86_agi_dependant (insn, dep_insn, insn_type))
11602 cost += 1;
11603 break;
11604
11605 case PROCESSOR_PENTIUMPRO:
11606 memory = get_attr_memory (insn);
11607 dep_memory = get_attr_memory (dep_insn);
11608
11609
11610
11611 if (dep_insn_type != TYPE_IMOV
11612 && dep_insn_type != TYPE_FMOV
11613 && (dep_memory == MEMORY_LOAD || dep_memory == MEMORY_BOTH))
11614 cost += 1;
11615
11616
11617 if (get_attr_fp_int_src (dep_insn))
11618 cost += 5;
11619
11620
11621 if (insn_type == TYPE_FMOV
11622 && (set = single_set (dep_insn)) != NULL_RTX
11623 && (set2 = single_set (insn)) != NULL_RTX
11624 && rtx_equal_p (SET_DEST (set), SET_SRC (set2))
11625 && GET_CODE (SET_DEST (set2)) == MEM)
11626 cost += 1;
11627
11628
11629
11630
11631 if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
11632 && !ix86_agi_dependant (insn, dep_insn, insn_type))
11633 {
11634
11635
11636 if (dep_insn_type == TYPE_IMOV
11637 || dep_insn_type == TYPE_FMOV)
11638 cost = 1;
11639 else if (cost > 1)
11640 cost--;
11641 }
11642 break;
11643
11644 case PROCESSOR_K6:
11645 memory = get_attr_memory (insn);
11646 dep_memory = get_attr_memory (dep_insn);
11647
11648
11649 if ((insn_type == TYPE_PUSH || insn_type == TYPE_POP)
11650 && (dep_insn_type == TYPE_PUSH || dep_insn_type == TYPE_POP))
11651 return 1;
11652
11653
11654
11655 if (dep_memory == MEMORY_LOAD || dep_memory == MEMORY_BOTH)
11656 cost += (dep_insn_type != TYPE_IMOV) ? 2 : 1;
11657
11658
11659 if (get_attr_fp_int_src (dep_insn))
11660 cost += 5;
11661
11662
11663
11664
11665 if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
11666 && !ix86_agi_dependant (insn, dep_insn, insn_type))
11667 {
11668
11669
11670 if (dep_insn_type == TYPE_IMOV
11671 || dep_insn_type == TYPE_FMOV)
11672 cost = 1;
11673 else if (cost > 2)
11674 cost -= 2;
11675 else
11676 cost = 1;
11677 }
11678 break;
11679
11680 case PROCESSOR_ATHLON:
11681 memory = get_attr_memory (insn);
11682 dep_memory = get_attr_memory (dep_insn);
11683
11684 if (dep_memory == MEMORY_LOAD || dep_memory == MEMORY_BOTH)
11685 {
11686 if (dep_insn_type == TYPE_IMOV || dep_insn_type == TYPE_FMOV)
11687 cost += 2;
11688 else
11689 cost += 3;
11690 }
11691
11692
11693
11694 if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
11695 && !ix86_agi_dependant (insn, dep_insn, insn_type))
11696 {
11697
11698
11699 if (dep_insn_type == TYPE_IMOV
11700 || dep_insn_type == TYPE_FMOV)
11701 cost = 0;
11702 else if (cost >= 3)
11703 cost -= 3;
11704 else
11705 cost = 0;
11706 }
11707
11708 default:
11709 break;
11710 }
11711
11712 return cost;
11713 }
11714
11715 static union
11716 {
11717 struct ppro_sched_data
11718 {
11719 rtx decode[3];
11720 int issued_this_cycle;
11721 } ppro;
11722 } ix86_sched_data;
11723
11724 static enum attr_ppro_uops
11725 ix86_safe_ppro_uops (insn)
11726 rtx insn;
11727 {
11728 if (recog_memoized (insn) >= 0)
11729 return get_attr_ppro_uops (insn);
11730 else
11731 return PPRO_UOPS_MANY;
11732 }
11733
11734 static void
11735 ix86_dump_ppro_packet (dump)
11736 FILE *dump;
11737 {
11738 if (ix86_sched_data.ppro.decode[0])
11739 {
11740 fprintf (dump, "PPRO packet: %d",
11741 INSN_UID (ix86_sched_data.ppro.decode[0]));
11742 if (ix86_sched_data.ppro.decode[1])
11743 fprintf (dump, " %d", INSN_UID (ix86_sched_data.ppro.decode[1]));
11744 if (ix86_sched_data.ppro.decode[2])
11745 fprintf (dump, " %d", INSN_UID (ix86_sched_data.ppro.decode[2]));
11746 fputc ('\n', dump);
11747 }
11748 }
11749
11750
11751
11752 static void
11753 ix86_sched_init (dump, sched_verbose, veclen)
11754 FILE *dump ATTRIBUTE_UNUSED;
11755 int sched_verbose ATTRIBUTE_UNUSED;
11756 int veclen ATTRIBUTE_UNUSED;
11757 {
11758 memset (&ix86_sched_data, 0, sizeof (ix86_sched_data));
11759 }
11760
11761
11762
11763 static void
11764 ix86_reorder_insn (insnp, slot)
11765 rtx *insnp, *slot;
11766 {
11767 if (insnp != slot)
11768 {
11769 rtx insn = *insnp;
11770 do
11771 insnp[0] = insnp[1];
11772 while (++insnp != slot);
11773 *insnp = insn;
11774 }
11775 }
11776
11777 static void
11778 ix86_sched_reorder_ppro (ready, e_ready)
11779 rtx *ready;
11780 rtx *e_ready;
11781 {
11782 rtx decode[3];
11783 enum attr_ppro_uops cur_uops;
11784 int issued_this_cycle;
11785 rtx *insnp;
11786 int i;
11787
11788
11789
11790
11791
11792
11793
11794 memcpy (decode, ix86_sched_data.ppro.decode, sizeof (decode));
11795 issued_this_cycle = 0;
11796
11797 insnp = e_ready;
11798 cur_uops = ix86_safe_ppro_uops (*insnp);
11799
11800
11801
11802 if (decode[0] == NULL)
11803 {
11804 if (cur_uops == PPRO_UOPS_MANY)
11805 {
11806 decode[0] = *insnp;
11807 goto ppro_done;
11808 }
11809
11810
11811 while (cur_uops != PPRO_UOPS_FEW)
11812 {
11813 if (insnp == ready)
11814 break;
11815 cur_uops = ix86_safe_ppro_uops (*--insnp);
11816 }
11817
11818
11819 if (cur_uops == PPRO_UOPS_FEW)
11820 ix86_reorder_insn (insnp, e_ready);
11821
11822
11823 issued_this_cycle = 1;
11824 decode[0] = *e_ready--;
11825 }
11826
11827
11828 for (i = 1; i < 3; ++i)
11829 if (decode[i] == NULL)
11830 {
11831 if (ready > e_ready)
11832 goto ppro_done;
11833
11834 insnp = e_ready;
11835 cur_uops = ix86_safe_ppro_uops (*insnp);
11836 while (cur_uops != PPRO_UOPS_ONE)
11837 {
11838 if (insnp == ready)
11839 break;
11840 cur_uops = ix86_safe_ppro_uops (*--insnp);
11841 }
11842
11843
11844 if (cur_uops == PPRO_UOPS_ONE)
11845 {
11846 ix86_reorder_insn (insnp, e_ready);
11847 decode[i] = *e_ready--;
11848 issued_this_cycle++;
11849 continue;
11850 }
11851
11852
11853
11854 }
11855
11856 ppro_done:
11857 if (issued_this_cycle == 0)
11858 issued_this_cycle = 1;
11859 ix86_sched_data.ppro.issued_this_cycle = issued_this_cycle;
11860 }
11861
11862
11863
11864 static int
11865 ix86_sched_reorder (dump, sched_verbose, ready, n_readyp, clock_var)
11866 FILE *dump ATTRIBUTE_UNUSED;
11867 int sched_verbose ATTRIBUTE_UNUSED;
11868 rtx *ready;
11869 int *n_readyp;
11870 int clock_var ATTRIBUTE_UNUSED;
11871 {
11872 int n_ready = *n_readyp;
11873 rtx *e_ready = ready + n_ready - 1;
11874
11875
11876
11877
11878 if (n_ready < 2)
11879 {
11880 ix86_sched_data.ppro.issued_this_cycle = 1;
11881 goto out;
11882 }
11883
11884 switch (ix86_cpu)
11885 {
11886 default:
11887 break;
11888
11889 case PROCESSOR_PENTIUMPRO:
11890 ix86_sched_reorder_ppro (ready, e_ready);
11891 break;
11892 }
11893
11894 out:
11895 return ix86_issue_rate ();
11896 }
11897
11898
11899
11900
11901 static int
11902 ix86_variable_issue (dump, sched_verbose, insn, can_issue_more)
11903 FILE *dump;
11904 int sched_verbose;
11905 rtx insn;
11906 int can_issue_more;
11907 {
11908 int i;
11909 switch (ix86_cpu)
11910 {
11911 default:
11912 return can_issue_more - 1;
11913
11914 case PROCESSOR_PENTIUMPRO:
11915 {
11916 enum attr_ppro_uops uops = ix86_safe_ppro_uops (insn);
11917
11918 if (uops == PPRO_UOPS_MANY)
11919 {
11920 if (sched_verbose)
11921 ix86_dump_ppro_packet (dump);
11922 ix86_sched_data.ppro.decode[0] = insn;
11923 ix86_sched_data.ppro.decode[1] = NULL;
11924 ix86_sched_data.ppro.decode[2] = NULL;
11925 if (sched_verbose)
11926 ix86_dump_ppro_packet (dump);
11927 ix86_sched_data.ppro.decode[0] = NULL;
11928 }
11929 else if (uops == PPRO_UOPS_FEW)
11930 {
11931 if (sched_verbose)
11932 ix86_dump_ppro_packet (dump);
11933 ix86_sched_data.ppro.decode[0] = insn;
11934 ix86_sched_data.ppro.decode[1] = NULL;
11935 ix86_sched_data.ppro.decode[2] = NULL;
11936 }
11937 else
11938 {
11939 for (i = 0; i < 3; ++i)
11940 if (ix86_sched_data.ppro.decode[i] == NULL)
11941 {
11942 ix86_sched_data.ppro.decode[i] = insn;
11943 break;
11944 }
11945 if (i == 3)
11946 abort ();
11947 if (i == 2)
11948 {
11949 if (sched_verbose)
11950 ix86_dump_ppro_packet (dump);
11951 ix86_sched_data.ppro.decode[0] = NULL;
11952 ix86_sched_data.ppro.decode[1] = NULL;
11953 ix86_sched_data.ppro.decode[2] = NULL;
11954 }
11955 }
11956 }
11957 return --ix86_sched_data.ppro.issued_this_cycle;
11958 }
11959 }
11960
11961 static int
11962 ia32_use_dfa_pipeline_interface ()
11963 {
11964 if (ix86_cpu == PROCESSOR_PENTIUM)
11965 return 1;
11966 return 0;
11967 }
11968
11969
11970
11971
11972
11973 static int
11974 ia32_multipass_dfa_lookahead ()
11975 {
11976 if (ix86_cpu == PROCESSOR_PENTIUM)
11977 return 2;
11978 else
11979 return 0;
11980 }
11981
11982
11983
11984
11985
11986
11987 void
11988 ix86_set_move_mem_attrs (insns, dstref, srcref, dstreg, srcreg)
11989 rtx insns;
11990 rtx dstref, srcref, dstreg, srcreg;
11991 {
11992 rtx insn;
11993
11994 for (insn = insns; insn != 0 ; insn = NEXT_INSN (insn))
11995 if (INSN_P (insn))
11996 ix86_set_move_mem_attrs_1 (PATTERN (insn), dstref, srcref,
11997 dstreg, srcreg);
11998 }
11999
12000
12001
12002
12003 static void
12004 ix86_set_move_mem_attrs_1 (x, dstref, srcref, dstreg, srcreg)
12005 rtx x;
12006 rtx dstref, srcref, dstreg, srcreg;
12007 {
12008 enum rtx_code code = GET_CODE (x);
12009 const char *format_ptr = GET_RTX_FORMAT (code);
12010 int i, j;
12011
12012 if (code == MEM && XEXP (x, 0) == dstreg)
12013 MEM_COPY_ATTRIBUTES (x, dstref);
12014 else if (code == MEM && XEXP (x, 0) == srcreg)
12015 MEM_COPY_ATTRIBUTES (x, srcref);
12016
12017 for (i = 0; i < GET_RTX_LENGTH (code); i++, format_ptr++)
12018 {
12019 if (*format_ptr == 'e')
12020 ix86_set_move_mem_attrs_1 (XEXP (x, i), dstref, srcref,
12021 dstreg, srcreg);
12022 else if (*format_ptr == 'E')
12023 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
12024 ix86_set_move_mem_attrs_1 (XVECEXP (x, i, j), dstref, srcref,
12025 dstreg, srcreg);
12026 }
12027 }
12028
12029
12030
12031
12032
12033
12034
12035 int
12036 ix86_constant_alignment (exp, align)
12037 tree exp;
12038 int align;
12039 {
12040 if (TREE_CODE (exp) == REAL_CST)
12041 {
12042 if (TYPE_MODE (TREE_TYPE (exp)) == DFmode && align < 64)
12043 return 64;
12044 else if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (exp))) && align < 128)
12045 return 128;
12046 }
12047 else if (TREE_CODE (exp) == STRING_CST && TREE_STRING_LENGTH (exp) >= 31
12048 && align < 256)
12049 return 256;
12050
12051 return align;
12052 }
12053
12054
12055
12056
12057
12058
12059 int
12060 ix86_data_alignment (type, align)
12061 tree type;
12062 int align;
12063 {
12064 if (AGGREGATE_TYPE_P (type)
12065 && TYPE_SIZE (type)
12066 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
12067 && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 256
12068 || TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 256)
12069 return 256;
12070
12071
12072
12073 if (TARGET_64BIT)
12074 {
12075 if (AGGREGATE_TYPE_P (type)
12076 && TYPE_SIZE (type)
12077 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
12078 && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 128
12079 || TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 128)
12080 return 128;
12081 }
12082
12083 if (TREE_CODE (type) == ARRAY_TYPE)
12084 {
12085 if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
12086 return 64;
12087 if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
12088 return 128;
12089 }
12090 else if (TREE_CODE (type) == COMPLEX_TYPE)
12091 {
12092
12093 if (TYPE_MODE (type) == DCmode && align < 64)
12094 return 64;
12095 if (TYPE_MODE (type) == XCmode && align < 128)
12096 return 128;
12097 }
12098 else if ((TREE_CODE (type) == RECORD_TYPE
12099 || TREE_CODE (type) == UNION_TYPE
12100 || TREE_CODE (type) == QUAL_UNION_TYPE)
12101 && TYPE_FIELDS (type))
12102 {
12103 if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
12104 return 64;
12105 if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
12106 return 128;
12107 }
12108 else if (TREE_CODE (type) == REAL_TYPE || TREE_CODE (type) == VECTOR_TYPE
12109 || TREE_CODE (type) == INTEGER_TYPE)
12110 {
12111 if (TYPE_MODE (type) == DFmode && align < 64)
12112 return 64;
12113 if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
12114 return 128;
12115 }
12116
12117 return align;
12118 }
12119
12120
12121
12122
12123
12124
12125 int
12126 ix86_local_alignment (type, align)
12127 tree type;
12128 int align;
12129 {
12130
12131
12132 if (TARGET_64BIT)
12133 {
12134 if (AGGREGATE_TYPE_P (type)
12135 && TYPE_SIZE (type)
12136 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
12137 && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 16
12138 || TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 128)
12139 return 128;
12140 }
12141 if (TREE_CODE (type) == ARRAY_TYPE)
12142 {
12143 if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
12144 return 64;
12145 if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
12146 return 128;
12147 }
12148 else if (TREE_CODE (type) == COMPLEX_TYPE)
12149 {
12150 if (TYPE_MODE (type) == DCmode && align < 64)
12151 return 64;
12152 if (TYPE_MODE (type) == XCmode && align < 128)
12153 return 128;
12154 }
12155 else if ((TREE_CODE (type) == RECORD_TYPE
12156 || TREE_CODE (type) == UNION_TYPE
12157 || TREE_CODE (type) == QUAL_UNION_TYPE)
12158 && TYPE_FIELDS (type))
12159 {
12160 if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
12161 return 64;
12162 if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
12163 return 128;
12164 }
12165 else if (TREE_CODE (type) == REAL_TYPE || TREE_CODE (type) == VECTOR_TYPE
12166 || TREE_CODE (type) == INTEGER_TYPE)
12167 {
12168
12169 if (TYPE_MODE (type) == DFmode && align < 64)
12170 return 64;
12171 if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
12172 return 128;
12173 }
12174 return align;
12175 }
12176
12177
12178
12179
12180 void
12181 x86_initialize_trampoline (tramp, fnaddr, cxt)
12182 rtx tramp, fnaddr, cxt;
12183 {
12184 if (!TARGET_64BIT)
12185 {
12186
12187 rtx disp = expand_binop (SImode, sub_optab, fnaddr,
12188 plus_constant (tramp, 10),
12189 NULL_RTX, 1, OPTAB_DIRECT);
12190 emit_move_insn (gen_rtx_MEM (QImode, tramp),
12191 gen_int_mode (0xb9, QImode));
12192 emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 1)), cxt);
12193 emit_move_insn (gen_rtx_MEM (QImode, plus_constant (tramp, 5)),
12194 gen_int_mode (0xe9, QImode));
12195 emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 6)), disp);
12196 }
12197 else
12198 {
12199 int offset = 0;
12200
12201
12202
12203 if (x86_64_zero_extended_value (fnaddr))
12204 {
12205 fnaddr = copy_to_mode_reg (DImode, fnaddr);
12206 emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, offset)),
12207 gen_int_mode (0xbb41, HImode));
12208 emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, offset + 2)),
12209 gen_lowpart (SImode, fnaddr));
12210 offset += 6;
12211 }
12212 else
12213 {
12214 emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, offset)),
12215 gen_int_mode (0xbb49, HImode));
12216 emit_move_insn (gen_rtx_MEM (DImode, plus_constant (tramp, offset + 2)),
12217 fnaddr);
12218 offset += 10;
12219 }
12220
12221 emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, offset)),
12222 gen_int_mode (0xba49, HImode));
12223 emit_move_insn (gen_rtx_MEM (DImode, plus_constant (tramp, offset + 2)),
12224 cxt);
12225 offset += 10;
12226
12227 emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, offset)),
12228 gen_int_mode (0xff49, HImode));
12229 emit_move_insn (gen_rtx_MEM (QImode, plus_constant (tramp, offset+2)),
12230 gen_int_mode (0xe3, QImode));
12231 offset += 3;
12232 if (offset > TRAMPOLINE_SIZE)
12233 abort ();
12234 }
12235
12236 #ifdef TRANSFER_FROM_TRAMPOLINE
12237 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
12238 LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
12239 #endif
12240 }
12241
12242 #define def_builtin(MASK, NAME, TYPE, CODE) \
12243 do { \
12244 if ((MASK) & target_flags \
12245 && (!((MASK) & MASK_64BIT) || TARGET_64BIT)) \
12246 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
12247 NULL, NULL_TREE); \
12248 } while (0)
12249
12250 struct builtin_description
12251 {
12252 const unsigned int mask;
12253 const enum insn_code icode;
12254 const char *const name;
12255 const enum ix86_builtins code;
12256 const enum rtx_code comparison;
12257 const unsigned int flag;
12258 };
12259
12260 static const struct builtin_description bdesc_comi[] =
12261 {
12262 { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comieq", IX86_BUILTIN_COMIEQSS, UNEQ, 0 },
12263 { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comilt", IX86_BUILTIN_COMILTSS, UNLT, 0 },
12264 { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comile", IX86_BUILTIN_COMILESS, UNLE, 0 },
12265 { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comigt", IX86_BUILTIN_COMIGTSS, GT, 0 },
12266 { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comige", IX86_BUILTIN_COMIGESS, GE, 0 },
12267 { MASK_SSE, CODE_FOR_sse_comi, "__builtin_ia32_comineq", IX86_BUILTIN_COMINEQSS, LTGT, 0 },
12268 { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomieq", IX86_BUILTIN_UCOMIEQSS, UNEQ, 0 },
12269 { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomilt", IX86_BUILTIN_UCOMILTSS, UNLT, 0 },
12270 { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomile", IX86_BUILTIN_UCOMILESS, UNLE, 0 },
12271 { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomigt", IX86_BUILTIN_UCOMIGTSS, GT, 0 },
12272 { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomige", IX86_BUILTIN_UCOMIGESS, GE, 0 },
12273 { MASK_SSE, CODE_FOR_sse_ucomi, "__builtin_ia32_ucomineq", IX86_BUILTIN_UCOMINEQSS, LTGT, 0 },
12274 { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdeq", IX86_BUILTIN_COMIEQSD, UNEQ, 0 },
12275 { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdlt", IX86_BUILTIN_COMILTSD, UNLT, 0 },
12276 { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdle", IX86_BUILTIN_COMILESD, UNLE, 0 },
12277 { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdgt", IX86_BUILTIN_COMIGTSD, GT, 0 },
12278 { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdge", IX86_BUILTIN_COMIGESD, GE, 0 },
12279 { MASK_SSE2, CODE_FOR_sse2_comi, "__builtin_ia32_comisdneq", IX86_BUILTIN_COMINEQSD, LTGT, 0 },
12280 { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdeq", IX86_BUILTIN_UCOMIEQSD, UNEQ, 0 },
12281 { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdlt", IX86_BUILTIN_UCOMILTSD, UNLT, 0 },
12282 { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdle", IX86_BUILTIN_UCOMILESD, UNLE, 0 },
12283 { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdgt", IX86_BUILTIN_UCOMIGTSD, GT, 0 },
12284 { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdge", IX86_BUILTIN_UCOMIGESD, GE, 0 },
12285 { MASK_SSE2, CODE_FOR_sse2_ucomi, "__builtin_ia32_ucomisdneq", IX86_BUILTIN_UCOMINEQSD, LTGT, 0 },
12286 };
12287
12288 static const struct builtin_description bdesc_2arg[] =
12289 {
12290
12291 { MASK_SSE, CODE_FOR_addv4sf3, "__builtin_ia32_addps", IX86_BUILTIN_ADDPS, 0, 0 },
12292 { MASK_SSE, CODE_FOR_subv4sf3, "__builtin_ia32_subps", IX86_BUILTIN_SUBPS, 0, 0 },
12293 { MASK_SSE, CODE_FOR_mulv4sf3, "__builtin_ia32_mulps", IX86_BUILTIN_MULPS, 0, 0 },
12294 { MASK_SSE, CODE_FOR_divv4sf3, "__builtin_ia32_divps", IX86_BUILTIN_DIVPS, 0, 0 },
12295 { MASK_SSE, CODE_FOR_vmaddv4sf3, "__builtin_ia32_addss", IX86_BUILTIN_ADDSS, 0, 0 },
12296 { MASK_SSE, CODE_FOR_vmsubv4sf3, "__builtin_ia32_subss", IX86_BUILTIN_SUBSS, 0, 0 },
12297 { MASK_SSE, CODE_FOR_vmmulv4sf3, "__builtin_ia32_mulss", IX86_BUILTIN_MULSS, 0, 0 },
12298 { MASK_SSE, CODE_FOR_vmdivv4sf3, "__builtin_ia32_divss", IX86_BUILTIN_DIVSS, 0, 0 },
12299
12300 { MASK_SSE, CODE_FOR_maskcmpv4sf3, "__builtin_ia32_cmpeqps", IX86_BUILTIN_CMPEQPS, EQ, 0 },
12301 { MASK_SSE, CODE_FOR_maskcmpv4sf3, "__builtin_ia32_cmpltps", IX86_BUILTIN_CMPLTPS, LT, 0 },
12302 { MASK_SSE, CODE_FOR_maskcmpv4sf3, "__builtin_ia32_cmpleps", IX86_BUILTIN_CMPLEPS, LE, 0 },
12303 { MASK_SSE, CODE_FOR_maskcmpv4sf3, "__builtin_ia32_cmpgtps", IX86_BUILTIN_CMPGTPS, LT, 1 },
12304 { MASK_SSE, CODE_FOR_maskcmpv4sf3, "__builtin_ia32_cmpgeps", IX86_BUILTIN_CMPGEPS, LE, 1 },
12305 { MASK_SSE, CODE_FOR_maskcmpv4sf3, "__builtin_ia32_cmpunordps", IX86_BUILTIN_CMPUNORDPS, UNORDERED, 0 },
12306 { MASK_SSE, CODE_FOR_maskncmpv4sf3, "__builtin_ia32_cmpneqps", IX86_BUILTIN_CMPNEQPS, EQ, 0 },
12307 { MASK_SSE, CODE_FOR_maskncmpv4sf3, "__builtin_ia32_cmpnltps", IX86_BUILTIN_CMPNLTPS, LT, 0 },
12308 { MASK_SSE, CODE_FOR_maskncmpv4sf3, "__builtin_ia32_cmpnleps", IX86_BUILTIN_CMPNLEPS, LE, 0 },
12309 { MASK_SSE, CODE_FOR_maskncmpv4sf3, "__builtin_ia32_cmpngtps", IX86_BUILTIN_CMPNGTPS, LT, 1 },
12310 { MASK_SSE, CODE_FOR_maskncmpv4sf3, "__builtin_ia32_cmpngeps", IX86_BUILTIN_CMPNGEPS, LE, 1 },
12311 { MASK_SSE, CODE_FOR_maskncmpv4sf3, "__builtin_ia32_cmpordps", IX86_BUILTIN_CMPORDPS, UNORDERED, 0 },
12312 { MASK_SSE, CODE_FOR_vmmaskcmpv4sf3, "__builtin_ia32_cmpeqss", IX86_BUILTIN_CMPEQSS, EQ, 0 },
12313 { MASK_SSE, CODE_FOR_vmmaskcmpv4sf3, "__builtin_ia32_cmpltss", IX86_BUILTIN_CMPLTSS, LT, 0 },
12314 { MASK_SSE, CODE_FOR_vmmaskcmpv4sf3, "__builtin_ia32_cmpless", IX86_BUILTIN_CMPLESS, LE, 0 },
12315 { MASK_SSE, CODE_FOR_vmmaskcmpv4sf3, "__builtin_ia32_cmpunordss", IX86_BUILTIN_CMPUNORDSS, UNORDERED, 0 },
12316 { MASK_SSE, CODE_FOR_vmmaskncmpv4sf3, "__builtin_ia32_cmpneqss", IX86_BUILTIN_CMPNEQSS, EQ, 0 },
12317 { MASK_SSE, CODE_FOR_vmmaskncmpv4sf3, "__builtin_ia32_cmpnltss", IX86_BUILTIN_CMPNLTSS, LT, 0 },
12318 { MASK_SSE, CODE_FOR_vmmaskncmpv4sf3, "__builtin_ia32_cmpnless", IX86_BUILTIN_CMPNLESS, LE, 0 },
12319 { MASK_SSE, CODE_FOR_vmmaskncmpv4sf3, "__builtin_ia32_cmpordss", IX86_BUILTIN_CMPORDSS, UNORDERED, 0 },
12320
12321 { MASK_SSE, CODE_FOR_sminv4sf3, "__builtin_ia32_minps", IX86_BUILTIN_MINPS, 0, 0 },
12322 { MASK_SSE, CODE_FOR_smaxv4sf3, "__builtin_ia32_maxps", IX86_BUILTIN_MAXPS, 0, 0 },
12323 { MASK_SSE, CODE_FOR_vmsminv4sf3, "__builtin_ia32_minss", IX86_BUILTIN_MINSS, 0, 0 },
12324 { MASK_SSE, CODE_FOR_vmsmaxv4sf3, "__builtin_ia32_maxss", IX86_BUILTIN_MAXSS, 0, 0 },
12325
12326 { MASK_SSE, CODE_FOR_sse_andv4sf3, "__builtin_ia32_andps", IX86_BUILTIN_ANDPS, 0, 0 },
12327 { MASK_SSE, CODE_FOR_sse_nandv4sf3, "__builtin_ia32_andnps", IX86_BUILTIN_ANDNPS, 0, 0 },
12328 { MASK_SSE, CODE_FOR_sse_iorv4sf3, "__builtin_ia32_orps", IX86_BUILTIN_ORPS, 0, 0 },
12329 { MASK_SSE, CODE_FOR_sse_xorv4sf3, "__builtin_ia32_xorps", IX86_BUILTIN_XORPS, 0, 0 },
12330
12331 { MASK_SSE, CODE_FOR_sse_movss, "__builtin_ia32_movss", IX86_BUILTIN_MOVSS, 0, 0 },
12332 { MASK_SSE, CODE_FOR_sse_movhlps, "__builtin_ia32_movhlps", IX86_BUILTIN_MOVHLPS, 0, 0 },
12333 { MASK_SSE, CODE_FOR_sse_movlhps, "__builtin_ia32_movlhps", IX86_BUILTIN_MOVLHPS, 0, 0 },
12334 { MASK_SSE, CODE_FOR_sse_unpckhps, "__builtin_ia32_unpckhps", IX86_BUILTIN_UNPCKHPS, 0, 0 },
12335 { MASK_SSE, CODE_FOR_sse_unpcklps, "__builtin_ia32_unpcklps", IX86_BUILTIN_UNPCKLPS, 0, 0 },
12336
12337
12338 { MASK_MMX, CODE_FOR_addv8qi3, "__builtin_ia32_paddb", IX86_BUILTIN_PADDB, 0, 0 },
12339 { MASK_MMX, CODE_FOR_addv4hi3, "__builtin_ia32_paddw", IX86_BUILTIN_PADDW, 0, 0 },
12340 { MASK_MMX, CODE_FOR_addv2si3, "__builtin_ia32_paddd", IX86_BUILTIN_PADDD, 0, 0 },
12341 { MASK_MMX, CODE_FOR_mmx_adddi3, "__builtin_ia32_paddq", IX86_BUILTIN_PADDQ, 0, 0 },
12342 { MASK_MMX, CODE_FOR_subv8qi3, "__builtin_ia32_psubb", IX86_BUILTIN_PSUBB, 0, 0 },
12343 { MASK_MMX, CODE_FOR_subv4hi3, "__builtin_ia32_psubw", IX86_BUILTIN_PSUBW, 0, 0 },
12344 { MASK_MMX, CODE_FOR_subv2si3, "__builtin_ia32_psubd", IX86_BUILTIN_PSUBD, 0, 0 },
12345 { MASK_MMX, CODE_FOR_mmx_subdi3, "__builtin_ia32_psubq", IX86_BUILTIN_PSUBQ, 0, 0 },
12346
12347 { MASK_MMX, CODE_FOR_ssaddv8qi3, "__builtin_ia32_paddsb", IX86_BUILTIN_PADDSB, 0, 0 },
12348 { MASK_MMX, CODE_FOR_ssaddv4hi3, "__builtin_ia32_paddsw", IX86_BUILTIN_PADDSW, 0, 0 },
12349 { MASK_MMX, CODE_FOR_sssubv8qi3, "__builtin_ia32_psubsb", IX86_BUILTIN_PSUBSB, 0, 0 },
12350 { MASK_MMX, CODE_FOR_sssubv4hi3, "__builtin_ia32_psubsw", IX86_BUILTIN_PSUBSW, 0, 0 },
12351 { MASK_MMX, CODE_FOR_usaddv8qi3, "__builtin_ia32_paddusb", IX86_BUILTIN_PADDUSB, 0, 0 },
12352 { MASK_MMX, CODE_FOR_usaddv4hi3, "__builtin_ia32_paddusw", IX86_BUILTIN_PADDUSW, 0, 0 },
12353 { MASK_MMX, CODE_FOR_ussubv8qi3, "__builtin_ia32_psubusb", IX86_BUILTIN_PSUBUSB, 0, 0 },
12354 { MASK_MMX, CODE_FOR_ussubv4hi3, "__builtin_ia32_psubusw", IX86_BUILTIN_PSUBUSW, 0, 0 },
12355
12356 { MASK_MMX, CODE_FOR_mulv4hi3, "__builtin_ia32_pmullw", IX86_BUILTIN_PMULLW, 0, 0 },
12357 { MASK_MMX, CODE_FOR_smulv4hi3_highpart, "__builtin_ia32_pmulhw", IX86_BUILTIN_PMULHW, 0, 0 },
12358 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_umulv4hi3_highpart, "__builtin_ia32_pmulhuw", IX86_BUILTIN_PMULHUW, 0, 0 },
12359
12360 { MASK_MMX, CODE_FOR_mmx_anddi3, "__builtin_ia32_pand", IX86_BUILTIN_PAND, 0, 0 },
12361 { MASK_MMX, CODE_FOR_mmx_nanddi3, "__builtin_ia32_pandn", IX86_BUILTIN_PANDN, 0, 0 },
12362 { MASK_MMX, CODE_FOR_mmx_iordi3, "__builtin_ia32_por", IX86_BUILTIN_POR, 0, 0 },
12363 { MASK_MMX, CODE_FOR_mmx_xordi3, "__builtin_ia32_pxor", IX86_BUILTIN_PXOR, 0, 0 },
12364
12365 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_mmx_uavgv8qi3, "__builtin_ia32_pavgb", IX86_BUILTIN_PAVGB, 0, 0 },
12366 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_mmx_uavgv4hi3, "__builtin_ia32_pavgw", IX86_BUILTIN_PAVGW, 0, 0 },
12367
12368 { MASK_MMX, CODE_FOR_eqv8qi3, "__builtin_ia32_pcmpeqb", IX86_BUILTIN_PCMPEQB, 0, 0 },
12369 { MASK_MMX, CODE_FOR_eqv4hi3, "__builtin_ia32_pcmpeqw", IX86_BUILTIN_PCMPEQW, 0, 0 },
12370 { MASK_MMX, CODE_FOR_eqv2si3, "__builtin_ia32_pcmpeqd", IX86_BUILTIN_PCMPEQD, 0, 0 },
12371 { MASK_MMX, CODE_FOR_gtv8qi3, "__builtin_ia32_pcmpgtb", IX86_BUILTIN_PCMPGTB, 0, 0 },
12372 { MASK_MMX, CODE_FOR_gtv4hi3, "__builtin_ia32_pcmpgtw", IX86_BUILTIN_PCMPGTW, 0, 0 },
12373 { MASK_MMX, CODE_FOR_gtv2si3, "__builtin_ia32_pcmpgtd", IX86_BUILTIN_PCMPGTD, 0, 0 },
12374
12375 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_umaxv8qi3, "__builtin_ia32_pmaxub", IX86_BUILTIN_PMAXUB, 0, 0 },
12376 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_smaxv4hi3, "__builtin_ia32_pmaxsw", IX86_BUILTIN_PMAXSW, 0, 0 },
12377 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_uminv8qi3, "__builtin_ia32_pminub", IX86_BUILTIN_PMINUB, 0, 0 },
12378 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_sminv4hi3, "__builtin_ia32_pminsw", IX86_BUILTIN_PMINSW, 0, 0 },
12379
12380 { MASK_MMX, CODE_FOR_mmx_punpckhbw, "__builtin_ia32_punpckhbw", IX86_BUILTIN_PUNPCKHBW, 0, 0 },
12381 { MASK_MMX, CODE_FOR_mmx_punpckhwd, "__builtin_ia32_punpckhwd", IX86_BUILTIN_PUNPCKHWD, 0, 0 },
12382 { MASK_MMX, CODE_FOR_mmx_punpckhdq, "__builtin_ia32_punpckhdq", IX86_BUILTIN_PUNPCKHDQ, 0, 0 },
12383 { MASK_MMX, CODE_FOR_mmx_punpcklbw, "__builtin_ia32_punpcklbw", IX86_BUILTIN_PUNPCKLBW, 0, 0 },
12384 { MASK_MMX, CODE_FOR_mmx_punpcklwd, "__builtin_ia32_punpcklwd", IX86_BUILTIN_PUNPCKLWD, 0, 0 },
12385 { MASK_MMX, CODE_FOR_mmx_punpckldq, "__builtin_ia32_punpckldq", IX86_BUILTIN_PUNPCKLDQ, 0, 0 },
12386
12387
12388 { MASK_MMX, CODE_FOR_mmx_packsswb, 0, IX86_BUILTIN_PACKSSWB, 0, 0 },
12389 { MASK_MMX, CODE_FOR_mmx_packssdw, 0, IX86_BUILTIN_PACKSSDW, 0, 0 },
12390 { MASK_MMX, CODE_FOR_mmx_packuswb, 0, IX86_BUILTIN_PACKUSWB, 0, 0 },
12391
12392 { MASK_SSE, CODE_FOR_cvtpi2ps, 0, IX86_BUILTIN_CVTPI2PS, 0, 0 },
12393 { MASK_SSE, CODE_FOR_cvtsi2ss, 0, IX86_BUILTIN_CVTSI2SS, 0, 0 },
12394 { MASK_SSE | MASK_64BIT, CODE_FOR_cvtsi2ssq, 0, IX86_BUILTIN_CVTSI642SS, 0, 0 },
12395
12396 { MASK_MMX, CODE_FOR_ashlv4hi3, 0, IX86_BUILTIN_PSLLW, 0, 0 },
12397 { MASK_MMX, CODE_FOR_ashlv4hi3, 0, IX86_BUILTIN_PSLLWI, 0, 0 },
12398 { MASK_MMX, CODE_FOR_ashlv2si3, 0, IX86_BUILTIN_PSLLD, 0, 0 },
12399 { MASK_MMX, CODE_FOR_ashlv2si3, 0, IX86_BUILTIN_PSLLDI, 0, 0 },
12400 { MASK_MMX, CODE_FOR_mmx_ashldi3, 0, IX86_BUILTIN_PSLLQ, 0, 0 },
12401 { MASK_MMX, CODE_FOR_mmx_ashldi3, 0, IX86_BUILTIN_PSLLQI, 0, 0 },
12402
12403 { MASK_MMX, CODE_FOR_lshrv4hi3, 0, IX86_BUILTIN_PSRLW, 0, 0 },
12404 { MASK_MMX, CODE_FOR_lshrv4hi3, 0, IX86_BUILTIN_PSRLWI, 0, 0 },
12405 { MASK_MMX, CODE_FOR_lshrv2si3, 0, IX86_BUILTIN_PSRLD, 0, 0 },
12406 { MASK_MMX, CODE_FOR_lshrv2si3, 0, IX86_BUILTIN_PSRLDI, 0, 0 },
12407 { MASK_MMX, CODE_FOR_mmx_lshrdi3, 0, IX86_BUILTIN_PSRLQ, 0, 0 },
12408 { MASK_MMX, CODE_FOR_mmx_lshrdi3, 0, IX86_BUILTIN_PSRLQI, 0, 0 },
12409
12410 { MASK_MMX, CODE_FOR_ashrv4hi3, 0, IX86_BUILTIN_PSRAW, 0, 0 },
12411 { MASK_MMX, CODE_FOR_ashrv4hi3, 0, IX86_BUILTIN_PSRAWI, 0, 0 },
12412 { MASK_MMX, CODE_FOR_ashrv2si3, 0, IX86_BUILTIN_PSRAD, 0, 0 },
12413 { MASK_MMX, CODE_FOR_ashrv2si3, 0, IX86_BUILTIN_PSRADI, 0, 0 },
12414
12415 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_mmx_psadbw, 0, IX86_BUILTIN_PSADBW, 0, 0 },
12416 { MASK_MMX, CODE_FOR_mmx_pmaddwd, 0, IX86_BUILTIN_PMADDWD, 0, 0 },
12417
12418
12419 { MASK_SSE2, CODE_FOR_addv2df3, "__builtin_ia32_addpd", IX86_BUILTIN_ADDPD, 0, 0 },
12420 { MASK_SSE2, CODE_FOR_subv2df3, "__builtin_ia32_subpd", IX86_BUILTIN_SUBPD, 0, 0 },
12421 { MASK_SSE2, CODE_FOR_mulv2df3, "__builtin_ia32_mulpd", IX86_BUILTIN_MULPD, 0, 0 },
12422 { MASK_SSE2, CODE_FOR_divv2df3, "__builtin_ia32_divpd", IX86_BUILTIN_DIVPD, 0, 0 },
12423 { MASK_SSE2, CODE_FOR_vmaddv2df3, "__builtin_ia32_addsd", IX86_BUILTIN_ADDSD, 0, 0 },
12424 { MASK_SSE2, CODE_FOR_vmsubv2df3, "__builtin_ia32_subsd", IX86_BUILTIN_SUBSD, 0, 0 },
12425 { MASK_SSE2, CODE_FOR_vmmulv2df3, "__builtin_ia32_mulsd", IX86_BUILTIN_MULSD, 0, 0 },
12426 { MASK_SSE2, CODE_FOR_vmdivv2df3, "__builtin_ia32_divsd", IX86_BUILTIN_DIVSD, 0, 0 },
12427
12428 { MASK_SSE2, CODE_FOR_maskcmpv2df3, "__builtin_ia32_cmpeqpd", IX86_BUILTIN_CMPEQPD, EQ, 0 },
12429 { MASK_SSE2, CODE_FOR_maskcmpv2df3, "__builtin_ia32_cmpltpd", IX86_BUILTIN_CMPLTPD, LT, 0 },
12430 { MASK_SSE2, CODE_FOR_maskcmpv2df3, "__builtin_ia32_cmplepd", IX86_BUILTIN_CMPLEPD, LE, 0 },
12431 { MASK_SSE2, CODE_FOR_maskcmpv2df3, "__builtin_ia32_cmpgtpd", IX86_BUILTIN_CMPGTPD, LT, 1 },
12432 { MASK_SSE2, CODE_FOR_maskcmpv2df3, "__builtin_ia32_cmpgepd", IX86_BUILTIN_CMPGEPD, LE, 1 },
12433 { MASK_SSE2, CODE_FOR_maskcmpv2df3, "__builtin_ia32_cmpunordpd", IX86_BUILTIN_CMPUNORDPD, UNORDERED, 0 },
12434 { MASK_SSE2, CODE_FOR_maskncmpv2df3, "__builtin_ia32_cmpneqpd", IX86_BUILTIN_CMPNEQPD, EQ, 0 },
12435 { MASK_SSE2, CODE_FOR_maskncmpv2df3, "__builtin_ia32_cmpnltpd", IX86_BUILTIN_CMPNLTPD, LT, 0 },
12436 { MASK_SSE2, CODE_FOR_maskncmpv2df3, "__builtin_ia32_cmpnlepd", IX86_BUILTIN_CMPNLEPD, LE, 0 },
12437 { MASK_SSE2, CODE_FOR_maskncmpv2df3, "__builtin_ia32_cmpngtpd", IX86_BUILTIN_CMPNGTPD, LT, 1 },
12438 { MASK_SSE2, CODE_FOR_maskncmpv2df3, "__builtin_ia32_cmpngepd", IX86_BUILTIN_CMPNGEPD, LE, 1 },
12439 { MASK_SSE2, CODE_FOR_maskncmpv2df3, "__builtin_ia32_cmpordpd", IX86_BUILTIN_CMPORDPD, UNORDERED, 0 },
12440 { MASK_SSE2, CODE_FOR_vmmaskcmpv2df3, "__builtin_ia32_cmpeqsd", IX86_BUILTIN_CMPEQSD, EQ, 0 },
12441 { MASK_SSE2, CODE_FOR_vmmaskcmpv2df3, "__builtin_ia32_cmpltsd", IX86_BUILTIN_CMPLTSD, LT, 0 },
12442 { MASK_SSE2, CODE_FOR_vmmaskcmpv2df3, "__builtin_ia32_cmplesd", IX86_BUILTIN_CMPLESD, LE, 0 },
12443 { MASK_SSE2, CODE_FOR_vmmaskcmpv2df3, "__builtin_ia32_cmpunordsd", IX86_BUILTIN_CMPUNORDSD, UNORDERED, 0 },
12444 { MASK_SSE2, CODE_FOR_vmmaskncmpv2df3, "__builtin_ia32_cmpneqsd", IX86_BUILTIN_CMPNEQSD, EQ, 0 },
12445 { MASK_SSE2, CODE_FOR_vmmaskncmpv2df3, "__builtin_ia32_cmpnltsd", IX86_BUILTIN_CMPNLTSD, LT, 0 },
12446 { MASK_SSE2, CODE_FOR_vmmaskncmpv2df3, "__builtin_ia32_cmpnlesd", IX86_BUILTIN_CMPNLESD, LE, 0 },
12447 { MASK_SSE2, CODE_FOR_vmmaskncmpv2df3, "__builtin_ia32_cmpordsd", IX86_BUILTIN_CMPORDSD, UNORDERED, 0 },
12448
12449 { MASK_SSE2, CODE_FOR_sminv2df3, "__builtin_ia32_minpd", IX86_BUILTIN_MINPD, 0, 0 },
12450 { MASK_SSE2, CODE_FOR_smaxv2df3, "__builtin_ia32_maxpd", IX86_BUILTIN_MAXPD, 0, 0 },
12451 { MASK_SSE2, CODE_FOR_vmsminv2df3, "__builtin_ia32_minsd", IX86_BUILTIN_MINSD, 0, 0 },
12452 { MASK_SSE2, CODE_FOR_vmsmaxv2df3, "__builtin_ia32_maxsd", IX86_BUILTIN_MAXSD, 0, 0 },
12453
12454 { MASK_SSE2, CODE_FOR_sse2_andv2df3, "__builtin_ia32_andpd", IX86_BUILTIN_ANDPD, 0, 0 },
12455 { MASK_SSE2, CODE_FOR_sse2_nandv2df3, "__builtin_ia32_andnpd", IX86_BUILTIN_ANDNPD, 0, 0 },
12456 { MASK_SSE2, CODE_FOR_sse2_iorv2df3, "__builtin_ia32_orpd", IX86_BUILTIN_ORPD, 0, 0 },
12457 { MASK_SSE2, CODE_FOR_sse2_xorv2df3, "__builtin_ia32_xorpd", IX86_BUILTIN_XORPD, 0, 0 },
12458
12459 { MASK_SSE2, CODE_FOR_sse2_movsd, "__builtin_ia32_movsd", IX86_BUILTIN_MOVSD, 0, 0 },
12460 { MASK_SSE2, CODE_FOR_sse2_unpckhpd, "__builtin_ia32_unpckhpd", IX86_BUILTIN_UNPCKHPD, 0, 0 },
12461 { MASK_SSE2, CODE_FOR_sse2_unpcklpd, "__builtin_ia32_unpcklpd", IX86_BUILTIN_UNPCKLPD, 0, 0 },
12462
12463
12464 { MASK_SSE2, CODE_FOR_addv16qi3, "__builtin_ia32_paddb128", IX86_BUILTIN_PADDB128, 0, 0 },
12465 { MASK_SSE2, CODE_FOR_addv8hi3, "__builtin_ia32_paddw128", IX86_BUILTIN_PADDW128, 0, 0 },
12466 { MASK_SSE2, CODE_FOR_addv4si3, "__builtin_ia32_paddd128", IX86_BUILTIN_PADDD128, 0, 0 },
12467 { MASK_SSE2, CODE_FOR_addv2di3, "__builtin_ia32_paddq128", IX86_BUILTIN_PADDQ128, 0, 0 },
12468 { MASK_SSE2, CODE_FOR_subv16qi3, "__builtin_ia32_psubb128", IX86_BUILTIN_PSUBB128, 0, 0 },
12469 { MASK_SSE2, CODE_FOR_subv8hi3, "__builtin_ia32_psubw128", IX86_BUILTIN_PSUBW128, 0, 0 },
12470 { MASK_SSE2, CODE_FOR_subv4si3, "__builtin_ia32_psubd128", IX86_BUILTIN_PSUBD128, 0, 0 },
12471 { MASK_SSE2, CODE_FOR_subv2di3, "__builtin_ia32_psubq128", IX86_BUILTIN_PSUBQ128, 0, 0 },
12472
12473 { MASK_MMX, CODE_FOR_ssaddv16qi3, "__builtin_ia32_paddsb128", IX86_BUILTIN_PADDSB128, 0, 0 },
12474 { MASK_MMX, CODE_FOR_ssaddv8hi3, "__builtin_ia32_paddsw128", IX86_BUILTIN_PADDSW128, 0, 0 },
12475 { MASK_MMX, CODE_FOR_sssubv16qi3, "__builtin_ia32_psubsb128", IX86_BUILTIN_PSUBSB128, 0, 0 },
12476 { MASK_MMX, CODE_FOR_sssubv8hi3, "__builtin_ia32_psubsw128", IX86_BUILTIN_PSUBSW128, 0, 0 },
12477 { MASK_MMX, CODE_FOR_usaddv16qi3, "__builtin_ia32_paddusb128", IX86_BUILTIN_PADDUSB128, 0, 0 },
12478 { MASK_MMX, CODE_FOR_usaddv8hi3, "__builtin_ia32_paddusw128", IX86_BUILTIN_PADDUSW128, 0, 0 },
12479 { MASK_MMX, CODE_FOR_ussubv16qi3, "__builtin_ia32_psubusb128", IX86_BUILTIN_PSUBUSB128, 0, 0 },
12480 { MASK_MMX, CODE_FOR_ussubv8hi3, "__builtin_ia32_psubusw128", IX86_BUILTIN_PSUBUSW128, 0, 0 },
12481
12482 { MASK_SSE2, CODE_FOR_mulv8hi3, "__builtin_ia32_pmullw128", IX86_BUILTIN_PMULLW128, 0, 0 },
12483 { MASK_SSE2, CODE_FOR_smulv8hi3_highpart, "__builtin_ia32_pmulhw128", IX86_BUILTIN_PMULHW128, 0, 0 },
12484 { MASK_SSE2, CODE_FOR_sse2_umulsidi3, "__builtin_ia32_pmuludq", IX86_BUILTIN_PMULUDQ, 0, 0 },
12485 { MASK_SSE2, CODE_FOR_sse2_umulv2siv2di3, "__builtin_ia32_pmuludq128", IX86_BUILTIN_PMULUDQ128, 0, 0 },
12486
12487 { MASK_SSE2, CODE_FOR_sse2_andv2di3, "__builtin_ia32_pand128", IX86_BUILTIN_PAND128, 0, 0 },
12488 { MASK_SSE2, CODE_FOR_sse2_nandv2di3, "__builtin_ia32_pandn128", IX86_BUILTIN_PANDN128, 0, 0 },
12489 { MASK_SSE2, CODE_FOR_sse2_iorv2di3, "__builtin_ia32_por128", IX86_BUILTIN_POR128, 0, 0 },
12490 { MASK_SSE2, CODE_FOR_sse2_xorv2di3, "__builtin_ia32_pxor128", IX86_BUILTIN_PXOR128, 0, 0 },
12491
12492 { MASK_SSE2, CODE_FOR_sse2_uavgv16qi3, "__builtin_ia32_pavgb128", IX86_BUILTIN_PAVGB128, 0, 0 },
12493 { MASK_SSE2, CODE_FOR_sse2_uavgv8hi3, "__builtin_ia32_pavgw128", IX86_BUILTIN_PAVGW128, 0, 0 },
12494
12495 { MASK_SSE2, CODE_FOR_eqv16qi3, "__builtin_ia32_pcmpeqb128", IX86_BUILTIN_PCMPEQB128, 0, 0 },
12496 { MASK_SSE2, CODE_FOR_eqv8hi3, "__builtin_ia32_pcmpeqw128", IX86_BUILTIN_PCMPEQW128, 0, 0 },
12497 { MASK_SSE2, CODE_FOR_eqv4si3, "__builtin_ia32_pcmpeqd128", IX86_BUILTIN_PCMPEQD128, 0, 0 },
12498 { MASK_SSE2, CODE_FOR_gtv16qi3, "__builtin_ia32_pcmpgtb128", IX86_BUILTIN_PCMPGTB128, 0, 0 },
12499 { MASK_SSE2, CODE_FOR_gtv8hi3, "__builtin_ia32_pcmpgtw128", IX86_BUILTIN_PCMPGTW128, 0, 0 },
12500 { MASK_SSE2, CODE_FOR_gtv4si3, "__builtin_ia32_pcmpgtd128", IX86_BUILTIN_PCMPGTD128, 0, 0 },
12501
12502 { MASK_SSE2, CODE_FOR_umaxv16qi3, "__builtin_ia32_pmaxub128", IX86_BUILTIN_PMAXUB128, 0, 0 },
12503 { MASK_SSE2, CODE_FOR_smaxv8hi3, "__builtin_ia32_pmaxsw128", IX86_BUILTIN_PMAXSW128, 0, 0 },
12504 { MASK_SSE2, CODE_FOR_uminv16qi3, "__builtin_ia32_pminub128", IX86_BUILTIN_PMINUB128, 0, 0 },
12505 { MASK_SSE2, CODE_FOR_sminv8hi3, "__builtin_ia32_pminsw128", IX86_BUILTIN_PMINSW128, 0, 0 },
12506
12507 { MASK_SSE2, CODE_FOR_sse2_punpckhbw, "__builtin_ia32_punpckhbw128", IX86_BUILTIN_PUNPCKHBW128, 0, 0 },
12508 { MASK_SSE2, CODE_FOR_sse2_punpckhwd, "__builtin_ia32_punpckhwd128", IX86_BUILTIN_PUNPCKHWD128, 0, 0 },
12509 { MASK_SSE2, CODE_FOR_sse2_punpckhdq, "__builtin_ia32_punpckhdq128", IX86_BUILTIN_PUNPCKHDQ128, 0, 0 },
12510 { MASK_SSE2, CODE_FOR_sse2_punpckhqdq, "__builtin_ia32_punpckhqdq128", IX86_BUILTIN_PUNPCKHQDQ128, 0, 0 },
12511 { MASK_SSE2, CODE_FOR_sse2_punpcklbw, "__builtin_ia32_punpcklbw128", IX86_BUILTIN_PUNPCKLBW128, 0, 0 },
12512 { MASK_SSE2, CODE_FOR_sse2_punpcklwd, "__builtin_ia32_punpcklwd128", IX86_BUILTIN_PUNPCKLWD128, 0, 0 },
12513 { MASK_SSE2, CODE_FOR_sse2_punpckldq, "__builtin_ia32_punpckldq128", IX86_BUILTIN_PUNPCKLDQ128, 0, 0 },
12514 { MASK_SSE2, CODE_FOR_sse2_punpcklqdq, "__builtin_ia32_punpcklqdq128", IX86_BUILTIN_PUNPCKLQDQ128, 0, 0 },
12515
12516 { MASK_SSE2, CODE_FOR_sse2_packsswb, "__builtin_ia32_packsswb128", IX86_BUILTIN_PACKSSWB128, 0, 0 },
12517 { MASK_SSE2, CODE_FOR_sse2_packssdw, "__builtin_ia32_packssdw128", IX86_BUILTIN_PACKSSDW128, 0, 0 },
12518 { MASK_SSE2, CODE_FOR_sse2_packuswb, "__builtin_ia32_packuswb128", IX86_BUILTIN_PACKUSWB128, 0, 0 },
12519
12520 { MASK_SSE2, CODE_FOR_umulv8hi3_highpart, "__builtin_ia32_pmulhuw128", IX86_BUILTIN_PMULHUW128, 0, 0 },
12521 { MASK_SSE2, CODE_FOR_sse2_psadbw, 0, IX86_BUILTIN_PSADBW128, 0, 0 },
12522
12523 { MASK_SSE2, CODE_FOR_ashlv8hi3_ti, 0, IX86_BUILTIN_PSLLW128, 0, 0 },
12524 { MASK_SSE2, CODE_FOR_ashlv8hi3, 0, IX86_BUILTIN_PSLLWI128, 0, 0 },
12525 { MASK_SSE2, CODE_FOR_ashlv4si3_ti, 0, IX86_BUILTIN_PSLLD128, 0, 0 },
12526 { MASK_SSE2, CODE_FOR_ashlv4si3, 0, IX86_BUILTIN_PSLLDI128, 0, 0 },
12527 { MASK_SSE2, CODE_FOR_ashlv2di3_ti, 0, IX86_BUILTIN_PSLLQ128, 0, 0 },
12528 { MASK_SSE2, CODE_FOR_ashlv2di3, 0, IX86_BUILTIN_PSLLQI128, 0, 0 },
12529
12530 { MASK_SSE2, CODE_FOR_lshrv8hi3_ti, 0, IX86_BUILTIN_PSRLW128, 0, 0 },
12531 { MASK_SSE2, CODE_FOR_lshrv8hi3, 0, IX86_BUILTIN_PSRLWI128, 0, 0 },
12532 { MASK_SSE2, CODE_FOR_lshrv4si3_ti, 0, IX86_BUILTIN_PSRLD128, 0, 0 },
12533 { MASK_SSE2, CODE_FOR_lshrv4si3, 0, IX86_BUILTIN_PSRLDI128, 0, 0 },
12534 { MASK_SSE2, CODE_FOR_lshrv2di3_ti, 0, IX86_BUILTIN_PSRLQ128, 0, 0 },
12535 { MASK_SSE2, CODE_FOR_lshrv2di3, 0, IX86_BUILTIN_PSRLQI128, 0, 0 },
12536
12537 { MASK_SSE2, CODE_FOR_ashrv8hi3_ti, 0, IX86_BUILTIN_PSRAW128, 0, 0 },
12538 { MASK_SSE2, CODE_FOR_ashrv8hi3, 0, IX86_BUILTIN_PSRAWI128, 0, 0 },
12539 { MASK_SSE2, CODE_FOR_ashrv4si3_ti, 0, IX86_BUILTIN_PSRAD128, 0, 0 },
12540 { MASK_SSE2, CODE_FOR_ashrv4si3, 0, IX86_BUILTIN_PSRADI128, 0, 0 },
12541
12542 { MASK_SSE2, CODE_FOR_sse2_pmaddwd, 0, IX86_BUILTIN_PMADDWD128, 0, 0 },
12543
12544 { MASK_SSE2, CODE_FOR_cvtsi2sd, 0, IX86_BUILTIN_CVTSI2SD, 0, 0 },
12545 { MASK_SSE2 | MASK_64BIT, CODE_FOR_cvtsi2sdq, 0, IX86_BUILTIN_CVTSI642SD, 0, 0 },
12546 { MASK_SSE2, CODE_FOR_cvtsd2ss, 0, IX86_BUILTIN_CVTSD2SS, 0, 0 },
12547 { MASK_SSE2, CODE_FOR_cvtss2sd, 0, IX86_BUILTIN_CVTSS2SD, 0, 0 },
12548
12549
12550 { MASK_PNI, CODE_FOR_addsubv4sf3, "__builtin_ia32_addsubps", IX86_BUILTIN_ADDSUBPS, 0, 0 },
12551 { MASK_PNI, CODE_FOR_addsubv2df3, "__builtin_ia32_addsubpd", IX86_BUILTIN_ADDSUBPD, 0, 0 },
12552 { MASK_PNI, CODE_FOR_haddv4sf3, "__builtin_ia32_haddps", IX86_BUILTIN_HADDPS, 0, 0 },
12553 { MASK_PNI, CODE_FOR_haddv2df3, "__builtin_ia32_haddpd", IX86_BUILTIN_HADDPD, 0, 0 },
12554 { MASK_PNI, CODE_FOR_hsubv4sf3, "__builtin_ia32_hsubps", IX86_BUILTIN_HSUBPS, 0, 0 },
12555 { MASK_PNI, CODE_FOR_hsubv2df3, "__builtin_ia32_hsubpd", IX86_BUILTIN_HSUBPD, 0, 0 }
12556 };
12557
12558 static const struct builtin_description bdesc_1arg[] =
12559 {
12560 { MASK_SSE | MASK_3DNOW_A, CODE_FOR_mmx_pmovmskb, 0, IX86_BUILTIN_PMOVMSKB, 0, 0 },
12561 { MASK_SSE, CODE_FOR_sse_movmskps, 0, IX86_BUILTIN_MOVMSKPS, 0, 0 },
12562
12563 { MASK_SSE, CODE_FOR_sqrtv4sf2, 0, IX86_BUILTIN_SQRTPS, 0, 0 },
12564 { MASK_SSE, CODE_FOR_rsqrtv4sf2, 0, IX86_BUILTIN_RSQRTPS, 0, 0 },
12565 { MASK_SSE, CODE_FOR_rcpv4sf2, 0, IX86_BUILTIN_RCPPS, 0, 0 },
12566
12567 { MASK_SSE, CODE_FOR_cvtps2pi, 0, IX86_BUILTIN_CVTPS2PI, 0, 0 },
12568 { MASK_SSE, CODE_FOR_cvtss2si, 0, IX86_BUILTIN_CVTSS2SI, 0, 0 },
12569 { MASK_SSE | MASK_64BIT, CODE_FOR_cvtss2siq, 0, IX86_BUILTIN_CVTSS2SI64, 0, 0 },
12570 { MASK_SSE, CODE_FOR_cvttps2pi, 0, IX86_BUILTIN_CVTTPS2PI, 0, 0 },
12571 { MASK_SSE, CODE_FOR_cvttss2si, 0, IX86_BUILTIN_CVTTSS2SI, 0, 0 },
12572 { MASK_SSE | MASK_64BIT, CODE_FOR_cvttss2siq, 0, IX86_BUILTIN_CVTTSS2SI64, 0, 0 },
12573
12574 { MASK_SSE2, CODE_FOR_sse2_pmovmskb, 0, IX86_BUILTIN_PMOVMSKB128, 0, 0 },
12575 { MASK_SSE2, CODE_FOR_sse2_movmskpd, 0, IX86_BUILTIN_MOVMSKPD, 0, 0 },
12576 { MASK_SSE2, CODE_FOR_sse2_movq2dq, 0, IX86_BUILTIN_MOVQ2DQ, 0, 0 },
12577 { MASK_SSE2, CODE_FOR_sse2_movdq2q, 0, IX86_BUILTIN_MOVDQ2Q, 0, 0 },
12578
12579 { MASK_SSE2, CODE_FOR_sqrtv2df2, 0, IX86_BUILTIN_SQRTPD, 0, 0 },
12580
12581 { MASK_SSE2, CODE_FOR_cvtdq2pd, 0, IX86_BUILTIN_CVTDQ2PD, 0, 0 },
12582 { MASK_SSE2, CODE_FOR_cvtdq2ps, 0, IX86_BUILTIN_CVTDQ2PS, 0, 0 },
12583
12584 { MASK_SSE2, CODE_FOR_cvtpd2dq, 0, IX86_BUILTIN_CVTPD2DQ, 0, 0 },
12585 { MASK_SSE2, CODE_FOR_cvtpd2pi, 0, IX86_BUILTIN_CVTPD2PI, 0, 0 },
12586 { MASK_SSE2, CODE_FOR_cvtpd2ps, 0, IX86_BUILTIN_CVTPD2PS, 0, 0 },
12587 { MASK_SSE2, CODE_FOR_cvttpd2dq, 0, IX86_BUILTIN_CVTTPD2DQ, 0, 0 },
12588 { MASK_SSE2, CODE_FOR_cvttpd2pi, 0, IX86_BUILTIN_CVTTPD2PI, 0, 0 },
12589
12590 { MASK_SSE2, CODE_FOR_cvtpi2pd, 0, IX86_BUILTIN_CVTPI2PD, 0, 0 },
12591
12592 { MASK_SSE2, CODE_FOR_cvtsd2si, 0, IX86_BUILTIN_CVTSD2SI, 0, 0 },
12593 { MASK_SSE2, CODE_FOR_cvttsd2si, 0, IX86_BUILTIN_CVTTSD2SI, 0, 0 },
12594 { MASK_SSE2 | MASK_64BIT, CODE_FOR_cvtsd2siq, 0, IX86_BUILTIN_CVTSD2SI64, 0, 0 },
12595 { MASK_SSE2 | MASK_64BIT, CODE_FOR_cvttsd2siq, 0, IX86_BUILTIN_CVTTSD2SI64, 0, 0 },
12596
12597 { MASK_SSE2, CODE_FOR_cvtps2dq, 0, IX86_BUILTIN_CVTPS2DQ, 0, 0 },
12598 { MASK_SSE2, CODE_FOR_cvtps2pd, 0, IX86_BUILTIN_CVTPS2PD, 0, 0 },
12599 { MASK_SSE2, CODE_FOR_cvttps2dq, 0, IX86_BUILTIN_CVTTPS2DQ, 0, 0 },
12600
12601 { MASK_SSE2, CODE_FOR_sse2_movq, 0, IX86_BUILTIN_MOVQ, 0, 0 },
12602
12603
12604 { MASK_PNI, CODE_FOR_movshdup, 0, IX86_BUILTIN_MOVSHDUP, 0, 0 },
12605 { MASK_PNI, CODE_FOR_movsldup, 0, IX86_BUILTIN_MOVSLDUP, 0, 0 },
12606 { MASK_PNI, CODE_FOR_movddup, 0, IX86_BUILTIN_MOVDDUP, 0, 0 }
12607 };
12608
12609 void
12610 ix86_init_builtins ()
12611 {
12612 if (TARGET_MMX)
12613 ix86_init_mmx_sse_builtins ();
12614 }
12615
12616
12617
12618
12619 static void
12620 ix86_init_mmx_sse_builtins ()
12621 {
12622 const struct builtin_description * d;
12623 size_t i;
12624
12625 tree pchar_type_node = build_pointer_type (char_type_node);
12626 tree pcchar_type_node = build_pointer_type (
12627 build_type_variant (char_type_node, 1, 0));
12628 tree pfloat_type_node = build_pointer_type (float_type_node);
12629 tree pcfloat_type_node = build_pointer_type (
12630 build_type_variant (float_type_node, 1, 0));
12631 tree pv2si_type_node = build_pointer_type (V2SI_type_node);
12632 tree pv2di_type_node = build_pointer_type (V2DI_type_node);
12633 tree pdi_type_node = build_pointer_type (long_long_unsigned_type_node);
12634
12635
12636 tree int_ftype_v4sf_v4sf
12637 = build_function_type_list (integer_type_node,
12638 V4SF_type_node, V4SF_type_node, NULL_TREE);
12639 tree v4si_ftype_v4sf_v4sf
12640 = build_function_type_list (V4SI_type_node,
12641 V4SF_type_node, V4SF_type_node, NULL_TREE);
12642
12643 tree int_ftype_v4sf
12644 = build_function_type_list (integer_type_node,
12645 V4SF_type_node, NULL_TREE);
12646 tree int64_ftype_v4sf
12647 = build_function_type_list (long_long_integer_type_node,
12648 V4SF_type_node, NULL_TREE);
12649 tree int_ftype_v8qi
12650 = build_function_type_list (integer_type_node, V8QI_type_node, NULL_TREE);
12651 tree v4sf_ftype_v4sf_int
12652 = build_function_type_list (V4SF_type_node,
12653 V4SF_type_node, integer_type_node, NULL_TREE);
12654 tree v4sf_ftype_v4sf_int64
12655 = build_function_type_list (V4SF_type_node,
12656 V4SF_type_node, long_long_integer_type_node,
12657 NULL_TREE);
12658 tree v4sf_ftype_v4sf_v2si
12659 = build_function_type_list (V4SF_type_node,
12660 V4SF_type_node, V2SI_type_node, NULL_TREE);
12661 tree int_ftype_v4hi_int
12662 = build_function_type_list (integer_type_node,
12663 V4HI_type_node, integer_type_node, NULL_TREE);
12664 tree v4hi_ftype_v4hi_int_int
12665 = build_function_type_list (V4HI_type_node, V4HI_type_node,
12666 integer_type_node, integer_type_node,
12667 NULL_TREE);
12668
12669 tree v8qi_ftype_v4hi_v4hi
12670 = build_function_type_list (V8QI_type_node,
12671 V4HI_type_node, V4HI_type_node, NULL_TREE);
12672 tree v4hi_ftype_v2si_v2si
12673 = build_function_type_list (V4HI_type_node,
12674 V2SI_type_node, V2SI_type_node, NULL_TREE);
12675 tree v4sf_ftype_v4sf_v4sf_int
12676 = build_function_type_list (V4SF_type_node,
12677 V4SF_type_node, V4SF_type_node,
12678 integer_type_node, NULL_TREE);
12679 tree v2si_ftype_v4hi_v4hi
12680 = build_function_type_list (V2SI_type_node,
12681 V4HI_type_node, V4HI_type_node, NULL_TREE);
12682 tree v4hi_ftype_v4hi_int
12683 = build_function_type_list (V4HI_type_node,
12684 V4HI_type_node, integer_type_node, NULL_TREE);
12685 tree v4hi_ftype_v4hi_di
12686 = build_function_type_list (V4HI_type_node,
12687 V4HI_type_node, long_long_unsigned_type_node,
12688 NULL_TREE);
12689 tree v2si_ftype_v2si_di
12690 = build_function_type_list (V2SI_type_node,
12691 V2SI_type_node, long_long_unsigned_type_node,
12692 NULL_TREE);
12693 tree void_ftype_void
12694 = build_function_type (void_type_node, void_list_node);
12695 tree void_ftype_unsigned
12696 = build_function_type_list (void_type_node, unsigned_type_node, NULL_TREE);
12697 tree void_ftype_unsigned_unsigned
12698 = build_function_type_list (void_type_node, unsigned_type_node,
12699 unsigned_type_node, NULL_TREE);
12700 tree void_ftype_pcvoid_unsigned_unsigned
12701 = build_function_type_list (void_type_node, const_ptr_type_node,
12702 unsigned_type_node, unsigned_type_node,
12703 NULL_TREE);
12704 tree unsigned_ftype_void
12705 = build_function_type (unsigned_type_node, void_list_node);
12706 tree di_ftype_void
12707 = build_function_type (long_long_unsigned_type_node, void_list_node);
12708 tree v4sf_ftype_void
12709 = build_function_type (V4SF_type_node, void_list_node);
12710 tree v2si_ftype_v4sf
12711 = build_function_type_list (V2SI_type_node, V4SF_type_node, NULL_TREE);
12712
12713 tree void_ftype_v8qi_v8qi_pchar
12714 = build_function_type_list (void_type_node,
12715 V8QI_type_node, V8QI_type_node,
12716 pchar_type_node, NULL_TREE);
12717 tree v4sf_ftype_pcfloat
12718 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12719
12720 tree v4sf_ftype_v4sf_pv2si
12721 = build_function_type_list (V4SF_type_node,
12722 V4SF_type_node, pv2si_type_node, NULL_TREE);
12723 tree void_ftype_pv2si_v4sf
12724 = build_function_type_list (void_type_node,
12725 pv2si_type_node, V4SF_type_node, NULL_TREE);
12726 tree void_ftype_pfloat_v4sf
12727 = build_function_type_list (void_type_node,
12728 pfloat_type_node, V4SF_type_node, NULL_TREE);
12729 tree void_ftype_pdi_di
12730 = build_function_type_list (void_type_node,
12731 pdi_type_node, long_long_unsigned_type_node,
12732 NULL_TREE);
12733 tree void_ftype_pv2di_v2di
12734 = build_function_type_list (void_type_node,
12735 pv2di_type_node, V2DI_type_node, NULL_TREE);
12736
12737 tree v4sf_ftype_v4sf
12738 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12739
12740
12741 tree v4sf_ftype_v4sf_v4sf
12742 = build_function_type_list (V4SF_type_node,
12743 V4SF_type_node, V4SF_type_node, NULL_TREE);
12744 tree v8qi_ftype_v8qi_v8qi
12745 = build_function_type_list (V8QI_type_node,
12746 V8QI_type_node, V8QI_type_node, NULL_TREE);
12747 tree v4hi_ftype_v4hi_v4hi
12748 = build_function_type_list (V4HI_type_node,
12749 V4HI_type_node, V4HI_type_node, NULL_TREE);
12750 tree v2si_ftype_v2si_v2si
12751 = build_function_type_list (V2SI_type_node,
12752 V2SI_type_node, V2SI_type_node, NULL_TREE);
12753 tree di_ftype_di_di
12754 = build_function_type_list (long_long_unsigned_type_node,
12755 long_long_unsigned_type_node,
12756 long_long_unsigned_type_node, NULL_TREE);
12757
12758 tree v2si_ftype_v2sf
12759 = build_function_type_list (V2SI_type_node, V2SF_type_node, NULL_TREE);
12760 tree v2sf_ftype_v2si
12761 = build_function_type_list (V2SF_type_node, V2SI_type_node, NULL_TREE);
12762 tree v2si_ftype_v2si
12763 = build_function_type_list (V2SI_type_node, V2SI_type_node, NULL_TREE);
12764 tree v2sf_ftype_v2sf
12765 = build_function_type_list (V2SF_type_node, V2SF_type_node, NULL_TREE);
12766 tree v2sf_ftype_v2sf_v2sf
12767 = build_function_type_list (V2SF_type_node,
12768 V2SF_type_node, V2SF_type_node, NULL_TREE);
12769 tree v2si_ftype_v2sf_v2sf
12770 = build_function_type_list (V2SI_type_node,
12771 V2SF_type_node, V2SF_type_node, NULL_TREE);
12772 tree pint_type_node = build_pointer_type (integer_type_node);
12773 tree pcint_type_node = build_pointer_type (
12774 build_type_variant (integer_type_node, 1, 0));
12775 tree pdouble_type_node = build_pointer_type (double_type_node);
12776 tree pcdouble_type_node = build_pointer_type (
12777 build_type_variant (double_type_node, 1, 0));
12778 tree int_ftype_v2df_v2df
12779 = build_function_type_list (integer_type_node,
12780 V2DF_type_node, V2DF_type_node, NULL_TREE);
12781
12782 tree ti_ftype_void
12783 = build_function_type (intTI_type_node, void_list_node);
12784 tree v2di_ftype_void
12785 = build_function_type (V2DI_type_node, void_list_node);
12786 tree ti_ftype_ti_ti
12787 = build_function_type_list (intTI_type_node,
12788 intTI_type_node, intTI_type_node, NULL_TREE);
12789 tree void_ftype_pcvoid
12790 = build_function_type_list (void_type_node, const_ptr_type_node, NULL_TREE);
12791 tree v2di_ftype_di
12792 = build_function_type_list (V2DI_type_node,
12793 long_long_unsigned_type_node, NULL_TREE);
12794 tree di_ftype_v2di
12795 = build_function_type_list (long_long_unsigned_type_node,
12796 V2DI_type_node, NULL_TREE);
12797 tree v4sf_ftype_v4si
12798 = build_function_type_list (V4SF_type_node, V4SI_type_node, NULL_TREE);
12799 tree v4si_ftype_v4sf
12800 = build_function_type_list (V4SI_type_node, V4SF_type_node, NULL_TREE);
12801 tree v2df_ftype_v4si
12802 = build_function_type_list (V2DF_type_node, V4SI_type_node, NULL_TREE);
12803 tree v4si_ftype_v2df
12804 = build_function_type_list (V4SI_type_node, V2DF_type_node, NULL_TREE);
12805 tree v2si_ftype_v2df
12806 = build_function_type_list (V2SI_type_node, V2DF_type_node, NULL_TREE);
12807 tree v4sf_ftype_v2df
12808 = build_function_type_list (V4SF_type_node, V2DF_type_node, NULL_TREE);
12809 tree v2df_ftype_v2si
12810 = build_function_type_list (V2DF_type_node, V2SI_type_node, NULL_TREE);
12811 tree v2df_ftype_v4sf
12812 = build_function_type_list (V2DF_type_node, V4SF_type_node, NULL_TREE);
12813 tree int_ftype_v2df
12814 = build_function_type_list (integer_type_node, V2DF_type_node, NULL_TREE);
12815 tree int64_ftype_v2df
12816 = build_function_type_list (long_long_integer_type_node,
12817 V2DF_type_node, NULL_TREE);
12818 tree v2df_ftype_v2df_int
12819 = build_function_type_list (V2DF_type_node,
12820 V2DF_type_node, integer_type_node, NULL_TREE);
12821 tree v2df_ftype_v2df_int64
12822 = build_function_type_list (V2DF_type_node,
12823 V2DF_type_node, long_long_integer_type_node,
12824 NULL_TREE);
12825 tree v4sf_ftype_v4sf_v2df
12826 = build_function_type_list (V4SF_type_node,
12827 V4SF_type_node, V2DF_type_node, NULL_TREE);
12828 tree v2df_ftype_v2df_v4sf
12829 = build_function_type_list (V2DF_type_node,
12830 V2DF_type_node, V4SF_type_node, NULL_TREE);
12831 tree v2df_ftype_v2df_v2df_int
12832 = build_function_type_list (V2DF_type_node,
12833 V2DF_type_node, V2DF_type_node,
12834 integer_type_node,
12835 NULL_TREE);
12836 tree v2df_ftype_v2df_pv2si
12837 = build_function_type_list (V2DF_type_node,
12838 V2DF_type_node, pv2si_type_node, NULL_TREE);
12839 tree void_ftype_pv2si_v2df
12840 = build_function_type_list (void_type_node,
12841 pv2si_type_node, V2DF_type_node, NULL_TREE);
12842 tree void_ftype_pdouble_v2df
12843 = build_function_type_list (void_type_node,
12844 pdouble_type_node, V2DF_type_node, NULL_TREE);
12845 tree void_ftype_pint_int
12846 = build_function_type_list (void_type_node,
12847 pint_type_node, integer_type_node, NULL_TREE);
12848 tree void_ftype_v16qi_v16qi_pchar
12849 = build_function_type_list (void_type_node,
12850 V16QI_type_node, V16QI_type_node,
12851 pchar_type_node, NULL_TREE);
12852 tree v2df_ftype_pcdouble
12853 = build_function_type_list (V2DF_type_node, pcdouble_type_node, NULL_TREE);
12854 tree v2df_ftype_v2df_v2df
12855 = build_function_type_list (V2DF_type_node,
12856 V2DF_type_node, V2DF_type_node, NULL_TREE);
12857 tree v16qi_ftype_v16qi_v16qi
12858 = build_function_type_list (V16QI_type_node,
12859 V16QI_type_node, V16QI_type_node, NULL_TREE);
12860 tree v8hi_ftype_v8hi_v8hi
12861 = build_function_type_list (V8HI_type_node,
12862 V8HI_type_node, V8HI_type_node, NULL_TREE);
12863 tree v4si_ftype_v4si_v4si
12864 = build_function_type_list (V4SI_type_node,
12865 V4SI_type_node, V4SI_type_node, NULL_TREE);
12866 tree v2di_ftype_v2di_v2di
12867 = build_function_type_list (V2DI_type_node,
12868 V2DI_type_node, V2DI_type_node, NULL_TREE);
12869 tree v2di_ftype_v2df_v2df
12870 = build_function_type_list (V2DI_type_node,
12871 V2DF_type_node, V2DF_type_node, NULL_TREE);
12872 tree v2df_ftype_v2df
12873 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12874 tree v2df_ftype_double
12875 = build_function_type_list (V2DF_type_node, double_type_node, NULL_TREE);
12876 tree v2df_ftype_double_double
12877 = build_function_type_list (V2DF_type_node,
12878 double_type_node, double_type_node, NULL_TREE);
12879 tree int_ftype_v8hi_int
12880 = build_function_type_list (integer_type_node,
12881 V8HI_type_node, integer_type_node, NULL_TREE);
12882 tree v8hi_ftype_v8hi_int_int
12883 = build_function_type_list (V8HI_type_node,
12884 V8HI_type_node, integer_type_node,
12885 integer_type_node, NULL_TREE);
12886 tree v2di_ftype_v2di_int
12887 = build_function_type_list (V2DI_type_node,
12888 V2DI_type_node, integer_type_node, NULL_TREE);
12889 tree v4si_ftype_v4si_int
12890 = build_function_type_list (V4SI_type_node,
12891 V4SI_type_node, integer_type_node, NULL_TREE);
12892 tree v8hi_ftype_v8hi_int
12893 = build_function_type_list (V8HI_type_node,
12894 V8HI_type_node, integer_type_node, NULL_TREE);
12895 tree v8hi_ftype_v8hi_v2di
12896 = build_function_type_list (V8HI_type_node,
12897 V8HI_type_node, V2DI_type_node, NULL_TREE);
12898 tree v4si_ftype_v4si_v2di
12899 = build_function_type_list (V4SI_type_node,
12900 V4SI_type_node, V2DI_type_node, NULL_TREE);
12901 tree v4si_ftype_v8hi_v8hi
12902 = build_function_type_list (V4SI_type_node,
12903 V8HI_type_node, V8HI_type_node, NULL_TREE);
12904 tree di_ftype_v8qi_v8qi
12905 = build_function_type_list (long_long_unsigned_type_node,
12906 V8QI_type_node, V8QI_type_node, NULL_TREE);
12907 tree v2di_ftype_v16qi_v16qi
12908 = build_function_type_list (V2DI_type_node,
12909 V16QI_type_node, V16QI_type_node, NULL_TREE);
12910 tree int_ftype_v16qi
12911 = build_function_type_list (integer_type_node, V16QI_type_node, NULL_TREE);
12912 tree v16qi_ftype_pcchar
12913 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12914 tree void_ftype_pchar_v16qi
12915 = build_function_type_list (void_type_node,
12916 pchar_type_node, V16QI_type_node, NULL_TREE);
12917 tree v4si_ftype_pcint
12918 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12919 tree void_ftype_pcint_v4si
12920 = build_function_type_list (void_type_node,
12921 pcint_type_node, V4SI_type_node, NULL_TREE);
12922 tree v2di_ftype_v2di
12923 = build_function_type_list (V2DI_type_node, V2DI_type_node, NULL_TREE);
12924
12925
12926
12927 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12928 {
12929
12930
12931 enum machine_mode mode;
12932 tree type;
12933
12934 if (d->name == 0)
12935 continue;
12936 mode = insn_data[d->icode].operand[1].mode;
12937
12938 switch (mode)
12939 {
12940 case V16QImode:
12941 type = v16qi_ftype_v16qi_v16qi;
12942 break;
12943 case V8HImode:
12944 type = v8hi_ftype_v8hi_v8hi;
12945 break;
12946 case V4SImode:
12947 type = v4si_ftype_v4si_v4si;
12948 break;
12949 case V2DImode:
12950 type = v2di_ftype_v2di_v2di;
12951 break;
12952 case V2DFmode:
12953 type = v2df_ftype_v2df_v2df;
12954 break;
12955 case TImode:
12956 type = ti_ftype_ti_ti;
12957 break;
12958 case V4SFmode:
12959 type = v4sf_ftype_v4sf_v4sf;
12960 break;
12961 case V8QImode:
12962 type = v8qi_ftype_v8qi_v8qi;
12963 break;
12964 case V4HImode:
12965 type = v4hi_ftype_v4hi_v4hi;
12966 break;
12967 case V2SImode:
12968 type = v2si_ftype_v2si_v2si;
12969 break;
12970 case DImode:
12971 type = di_ftype_di_di;
12972 break;
12973
12974 default:
12975 abort ();
12976 }
12977
12978
12979 if (d->icode == CODE_FOR_maskcmpv4sf3
12980 || d->icode == CODE_FOR_maskncmpv4sf3
12981 || d->icode == CODE_FOR_vmmaskcmpv4sf3
12982 || d->icode == CODE_FOR_vmmaskncmpv4sf3)
12983 type = v4si_ftype_v4sf_v4sf;
12984
12985 if (d->icode == CODE_FOR_maskcmpv2df3
12986 || d->icode == CODE_FOR_maskncmpv2df3
12987 || d->icode == CODE_FOR_vmmaskcmpv2df3
12988 || d->icode == CODE_FOR_vmmaskncmpv2df3)
12989 type = v2di_ftype_v2df_v2df;
12990
12991 def_builtin (d->mask, d->name, type, d->code);
12992 }
12993
12994
12995 def_builtin (MASK_MMX, "__builtin_ia32_mmx_zero", di_ftype_void, IX86_BUILTIN_MMX_ZERO);
12996 def_builtin (MASK_MMX, "__builtin_ia32_emms", void_ftype_void, IX86_BUILTIN_EMMS);
12997 def_builtin (MASK_MMX, "__builtin_ia32_psllw", v4hi_ftype_v4hi_di, IX86_BUILTIN_PSLLW);
12998 def_builtin (MASK_MMX, "__builtin_ia32_pslld", v2si_ftype_v2si_di, IX86_BUILTIN_PSLLD);
12999 def_builtin (MASK_MMX, "__builtin_ia32_psllq", di_ftype_di_di, IX86_BUILTIN_PSLLQ);
13000
13001 def_builtin (MASK_MMX, "__builtin_ia32_psrlw", v4hi_ftype_v4hi_di, IX86_BUILTIN_PSRLW);
13002 def_builtin (MASK_MMX, "__builtin_ia32_psrld", v2si_ftype_v2si_di, IX86_BUILTIN_PSRLD);
13003 def_builtin (MASK_MMX, "__builtin_ia32_psrlq", di_ftype_di_di, IX86_BUILTIN_PSRLQ);
13004
13005 def_builtin (MASK_MMX, "__builtin_ia32_psraw", v4hi_ftype_v4hi_di, IX86_BUILTIN_PSRAW);
13006 def_builtin (MASK_MMX, "__builtin_ia32_psrad", v2si_ftype_v2si_di, IX86_BUILTIN_PSRAD);
13007
13008 def_builtin (MASK_MMX, "__builtin_ia32_pshufw", v4hi_ftype_v4hi_int, IX86_BUILTIN_PSHUFW);
13009 def_builtin (MASK_MMX, "__builtin_ia32_pmaddwd", v2si_ftype_v4hi_v4hi, IX86_BUILTIN_PMADDWD);
13010
13011
13012 for (i = 0, d = bdesc_comi; i < ARRAY_SIZE (bdesc_comi); i++, d++)
13013 if (d->mask == MASK_SSE2)
13014 def_builtin (d->mask, d->name, int_ftype_v2df_v2df, d->code);
13015 else
13016 def_builtin (d->mask, d->name, int_ftype_v4sf_v4sf, d->code);
13017
13018 def_builtin (MASK_MMX, "__builtin_ia32_packsswb", v8qi_ftype_v4hi_v4hi, IX86_BUILTIN_PACKSSWB);
13019 def_builtin (MASK_MMX, "__builtin_ia32_packssdw", v4hi_ftype_v2si_v2si, IX86_BUILTIN_PACKSSDW);
13020 def_builtin (MASK_MMX, "__builtin_ia32_packuswb", v8qi_ftype_v4hi_v4hi, IX86_BUILTIN_PACKUSWB);
13021
13022 def_builtin (MASK_SSE, "__builtin_ia32_ldmxcsr", void_ftype_unsigned, IX86_BUILTIN_LDMXCSR);
13023 def_builtin (MASK_SSE, "__builtin_ia32_stmxcsr", unsigned_ftype_void, IX86_BUILTIN_STMXCSR);
13024 def_builtin (MASK_SSE, "__builtin_ia32_cvtpi2ps", v4sf_ftype_v4sf_v2si, IX86_BUILTIN_CVTPI2PS);
13025 def_builtin (MASK_SSE, "__builtin_ia32_cvtps2pi", v2si_ftype_v4sf, IX86_BUILTIN_CVTPS2PI);
13026 def_builtin (MASK_SSE, "__builtin_ia32_cvtsi2ss", v4sf_ftype_v4sf_int, IX86_BUILTIN_CVTSI2SS);
13027 def_builtin (MASK_SSE | MASK_64BIT, "__builtin_ia32_cvtsi642ss", v4sf_ftype_v4sf_int64, IX86_BUILTIN_CVTSI642SS);
13028 def_builtin (MASK_SSE, "__builtin_ia32_cvtss2si", int_ftype_v4sf, IX86_BUILTIN_CVTSS2SI);
13029 def_builtin (MASK_SSE | MASK_64BIT, "__builtin_ia32_cvtss2si64", int64_ftype_v4sf, IX86_BUILTIN_CVTSS2SI64);
13030 def_builtin (MASK_SSE, "__builtin_ia32_cvttps2pi", v2si_ftype_v4sf, IX86_BUILTIN_CVTTPS2PI);
13031 def_builtin (MASK_SSE, "__builtin_ia32_cvttss2si", int_ftype_v4sf, IX86_BUILTIN_CVTTSS2SI);
13032 def_builtin (MASK_SSE | MASK_64BIT, "__builtin_ia32_cvttss2si64", int64_ftype_v4sf, IX86_BUILTIN_CVTTSS2SI64);
13033
13034 def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_pextrw", int_ftype_v4hi_int, IX86_BUILTIN_PEXTRW);
13035 def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_pinsrw", v4hi_ftype_v4hi_int_int, IX86_BUILTIN_PINSRW);
13036
13037 def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_maskmovq", void_ftype_v8qi_v8qi_pchar, IX86_BUILTIN_MASKMOVQ);
13038
13039 def_builtin (MASK_SSE, "__builtin_ia32_loadaps", v4sf_ftype_pcfloat, IX86_BUILTIN_LOADAPS);
13040 def_builtin (MASK_SSE, "__builtin_ia32_loadups", v4sf_ftype_pcfloat, IX86_BUILTIN_LOADUPS);
13041 def_builtin (MASK_SSE, "__builtin_ia32_loadss", v4sf_ftype_pcfloat, IX86_BUILTIN_LOADSS);
13042 def_builtin (MASK_SSE, "__builtin_ia32_storeaps", void_ftype_pfloat_v4sf, IX86_BUILTIN_STOREAPS);
13043 def_builtin (MASK_SSE, "__builtin_ia32_storeups", void_ftype_pfloat_v4sf, IX86_BUILTIN_STOREUPS);
13044 def_builtin (MASK_SSE, "__builtin_ia32_storess", void_ftype_pfloat_v4sf, IX86_BUILTIN_STORESS);
13045
13046 def_builtin (MASK_SSE, "__builtin_ia32_loadhps", v4sf_ftype_v4sf_pv2si, IX86_BUILTIN_LOADHPS);
13047 def_builtin (MASK_SSE, "__builtin_ia32_loadlps", v4sf_ftype_v4sf_pv2si, IX86_BUILTIN_LOADLPS);
13048 def_builtin (MASK_SSE, "__builtin_ia32_storehps", void_ftype_pv2si_v4sf, IX86_BUILTIN_STOREHPS);
13049 def_builtin (MASK_SSE, "__builtin_ia32_storelps", void_ftype_pv2si_v4sf, IX86_BUILTIN_STORELPS);
13050
13051 def_builtin (MASK_SSE, "__builtin_ia32_movmskps", int_ftype_v4sf, IX86_BUILTIN_MOVMSKPS);
13052 def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_pmovmskb", int_ftype_v8qi, IX86_BUILTIN_PMOVMSKB);
13053 def_builtin (MASK_SSE, "__builtin_ia32_movntps", void_ftype_pfloat_v4sf, IX86_BUILTIN_MOVNTPS);
13054 def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_movntq", void_ftype_pdi_di, IX86_BUILTIN_MOVNTQ);
13055
13056 def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_sfence", void_ftype_void, IX86_BUILTIN_SFENCE);
13057
13058 def_builtin (MASK_SSE | MASK_3DNOW_A, "__builtin_ia32_psadbw", di_ftype_v8qi_v8qi, IX86_BUILTIN_PSADBW);
13059
13060 def_builtin (MASK_SSE, "__builtin_ia32_rcpps", v4sf_ftype_v4sf, IX86_BUILTIN_RCPPS);
13061 def_builtin (MASK_SSE, "__builtin_ia32_rcpss", v4sf_ftype_v4sf, IX86_BUILTIN_RCPSS);
13062 def_builtin (MASK_SSE, "__builtin_ia32_rsqrtps", v4sf_ftype_v4sf, IX86_BUILTIN_RSQRTPS);
13063 def_builtin (MASK_SSE, "__builtin_ia32_rsqrtss", v4sf_ftype_v4sf, IX86_BUILTIN_RSQRTSS);
13064 def_builtin (MASK_SSE, "__builtin_ia32_sqrtps", v4sf_ftype_v4sf, IX86_BUILTIN_SQRTPS);
13065 def_builtin (MASK_SSE, "__builtin_ia32_sqrtss", v4sf_ftype_v4sf, IX86_BUILTIN_SQRTSS);
13066
13067 def_builtin (MASK_SSE, "__builtin_ia32_shufps", v4sf_ftype_v4sf_v4sf_int, IX86_BUILTIN_SHUFPS);
13068
13069
13070 def_builtin (MASK_3DNOW, "__builtin_ia32_femms", void_ftype_void, IX86_BUILTIN_FEMMS);
13071 def_builtin (MASK_3DNOW, "__builtin_ia32_pavgusb", v8qi_ftype_v8qi_v8qi, IX86_BUILTIN_PAVGUSB);
13072 def_builtin (MASK_3DNOW, "__builtin_ia32_pf2id", v2si_ftype_v2sf, IX86_BUILTIN_PF2ID);
13073 def_builtin (MASK_3DNOW, "__builtin_ia32_pfacc", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFACC);
13074 def_builtin (MASK_3DNOW, "__builtin_ia32_pfadd", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFADD);
13075 def_builtin (MASK_3DNOW, "__builtin_ia32_pfcmpeq", v2si_ftype_v2sf_v2sf, IX86_BUILTIN_PFCMPEQ);
13076 def_builtin (MASK_3DNOW, "__builtin_ia32_pfcmpge", v2si_ftype_v2sf_v2sf, IX86_BUILTIN_PFCMPGE);
13077 def_builtin (MASK_3DNOW, "__builtin_ia32_pfcmpgt", v2si_ftype_v2sf_v2sf, IX86_BUILTIN_PFCMPGT);
13078 def_builtin (MASK_3DNOW, "__builtin_ia32_pfmax", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFMAX);
13079 def_builtin (MASK_3DNOW, "__builtin_ia32_pfmin", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFMIN);
13080 def_builtin (MASK_3DNOW, "__builtin_ia32_pfmul", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFMUL);
13081 def_builtin (MASK_3DNOW, "__builtin_ia32_pfrcp", v2sf_ftype_v2sf, IX86_BUILTIN_PFRCP);
13082 def_builtin (MASK_3DNOW, "__builtin_ia32_pfrcpit1", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFRCPIT1);
13083 def_builtin (MASK_3DNOW, "__builtin_ia32_pfrcpit2", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFRCPIT2);
13084 def_builtin (MASK_3DNOW, "__builtin_ia32_pfrsqrt", v2sf_ftype_v2sf, IX86_BUILTIN_PFRSQRT);
13085 def_builtin (MASK_3DNOW, "__builtin_ia32_pfrsqit1", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFRSQIT1);
13086 def_builtin (MASK_3DNOW, "__builtin_ia32_pfsub", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFSUB);
13087 def_builtin (MASK_3DNOW, "__builtin_ia32_pfsubr", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFSUBR);
13088 def_builtin (MASK_3DNOW, "__builtin_ia32_pi2fd", v2sf_ftype_v2si, IX86_BUILTIN_PI2FD);
13089 def_builtin (MASK_3DNOW, "__builtin_ia32_pmulhrw", v4hi_ftype_v4hi_v4hi, IX86_BUILTIN_PMULHRW);
13090
13091
13092 def_builtin (MASK_3DNOW_A, "__builtin_ia32_pf2iw", v2si_ftype_v2sf, IX86_BUILTIN_PF2IW);
13093 def_builtin (MASK_3DNOW_A, "__builtin_ia32_pfnacc", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFNACC);
13094 def_builtin (MASK_3DNOW_A, "__builtin_ia32_pfpnacc", v2sf_ftype_v2sf_v2sf, IX86_BUILTIN_PFPNACC);
13095 def_builtin (MASK_3DNOW_A, "__builtin_ia32_pi2fw", v2sf_ftype_v2si, IX86_BUILTIN_PI2FW);
13096 def_builtin (MASK_3DNOW_A, "__builtin_ia32_pswapdsf", v2sf_ftype_v2sf, IX86_BUILTIN_PSWAPDSF);
13097 def_builtin (MASK_3DNOW_A, "__builtin_ia32_pswapdsi", v2si_ftype_v2si, IX86_BUILTIN_PSWAPDSI);
13098
13099 def_builtin (MASK_SSE, "__builtin_ia32_setzerops", v4sf_ftype_void, IX86_BUILTIN_SSE_ZERO);
13100
13101
13102 def_builtin (MASK_SSE2, "__builtin_ia32_pextrw128", int_ftype_v8hi_int, IX86_BUILTIN_PEXTRW128);
13103 def_builtin (MASK_SSE2, "__builtin_ia32_pinsrw128", v8hi_ftype_v8hi_int_int, IX86_BUILTIN_PINSRW128);
13104
13105 def_builtin (MASK_SSE2, "__builtin_ia32_maskmovdqu", void_ftype_v16qi_v16qi_pchar, IX86_BUILTIN_MASKMOVDQU);
13106 def_builtin (MASK_SSE2, "__builtin_ia32_movq2dq", v2di_ftype_di, IX86_BUILTIN_MOVQ2DQ);
13107 def_builtin (MASK_SSE2, "__builtin_ia32_movdq2q", di_ftype_v2di, IX86_BUILTIN_MOVDQ2Q);
13108
13109 def_builtin (MASK_SSE2, "__builtin_ia32_loadapd", v2df_ftype_pcdouble, IX86_BUILTIN_LOADAPD);
13110 def_builtin (MASK_SSE2, "__builtin_ia32_loadupd", v2df_ftype_pcdouble, IX86_BUILTIN_LOADUPD);
13111 def_builtin (MASK_SSE2, "__builtin_ia32_loadsd", v2df_ftype_pcdouble, IX86_BUILTIN_LOADSD);
13112 def_builtin (MASK_SSE2, "__builtin_ia32_storeapd", void_ftype_pdouble_v2df, IX86_BUILTIN_STOREAPD);
13113 def_builtin (MASK_SSE2, "__builtin_ia32_storeupd", void_ftype_pdouble_v2df, IX86_BUILTIN_STOREUPD);
13114 def_builtin (MASK_SSE2, "__builtin_ia32_storesd", void_ftype_pdouble_v2df, IX86_BUILTIN_STORESD);
13115
13116 def_builtin (MASK_SSE2, "__builtin_ia32_loadhpd", v2df_ftype_v2df_pv2si, IX86_BUILTIN_LOADHPD);
13117 def_builtin (MASK_SSE2, "__builtin_ia32_loadlpd", v2df_ftype_v2df_pv2si, IX86_BUILTIN_LOADLPD);
13118 def_builtin (MASK_SSE2, "__builtin_ia32_storehpd", void_ftype_pv2si_v2df, IX86_BUILTIN_STOREHPD);
13119 def_builtin (MASK_SSE2, "__builtin_ia32_storelpd", void_ftype_pv2si_v2df, IX86_BUILTIN_STORELPD);
13120
13121 def_builtin (MASK_SSE2, "__builtin_ia32_movmskpd", int_ftype_v2df, IX86_BUILTIN_MOVMSKPD);
13122 def_builtin (MASK_SSE2, "__builtin_ia32_pmovmskb128", int_ftype_v16qi, IX86_BUILTIN_PMOVMSKB128);
13123 def_builtin (MASK_SSE2, "__builtin_ia32_movnti", void_ftype_pint_int, IX86_BUILTIN_MOVNTI);
13124 def_builtin (MASK_SSE2, "__builtin_ia32_movntpd", void_ftype_pdouble_v2df, IX86_BUILTIN_MOVNTPD);
13125 def_builtin (MASK_SSE2, "__builtin_ia32_movntdq", void_ftype_pv2di_v2di, IX86_BUILTIN_MOVNTDQ);
13126
13127 def_builtin (MASK_SSE2, "__builtin_ia32_pshufd", v4si_ftype_v4si_int, IX86_BUILTIN_PSHUFD);
13128 def_builtin (MASK_SSE2, "__builtin_ia32_pshuflw", v8hi_ftype_v8hi_int, IX86_BUILTIN_PSHUFLW);
13129 def_builtin (MASK_SSE2, "__builtin_ia32_pshufhw", v8hi_ftype_v8hi_int, IX86_BUILTIN_PSHUFHW);
13130 def_builtin (MASK_SSE2, "__builtin_ia32_psadbw128", v2di_ftype_v16qi_v16qi, IX86_BUILTIN_PSADBW128);
13131
13132 def_builtin (MASK_SSE2, "__builtin_ia32_sqrtpd", v2df_ftype_v2df, IX86_BUILTIN_SQRTPD);
13133 def_builtin (MASK_SSE2, "__builtin_ia32_sqrtsd", v2df_ftype_v2df, IX86_BUILTIN_SQRTSD);
13134
13135 def_builtin (MASK_SSE2, "__builtin_ia32_shufpd", v2df_ftype_v2df_v2df_int, IX86_BUILTIN_SHUFPD);
13136
13137 def_builtin (MASK_SSE2, "__builtin_ia32_cvtdq2pd", v2df_ftype_v4si, IX86_BUILTIN_CVTDQ2PD);
13138 def_builtin (MASK_SSE2, "__builtin_ia32_cvtdq2ps", v4sf_ftype_v4si, IX86_BUILTIN_CVTDQ2PS);
13139
13140 def_builtin (MASK_SSE2, "__builtin_ia32_cvtpd2dq", v4si_ftype_v2df, IX86_BUILTIN_CVTPD2DQ);
13141 def_builtin (MASK_SSE2, "__builtin_ia32_cvtpd2pi", v2si_ftype_v2df, IX86_BUILTIN_CVTPD2PI);
13142 def_builtin (MASK_SSE2, "__builtin_ia32_cvtpd2ps", v4sf_ftype_v2df, IX86_BUILTIN_CVTPD2PS);
13143 def_builtin (MASK_SSE2, "__builtin_ia32_cvttpd2dq", v4si_ftype_v2df, IX86_BUILTIN_CVTTPD2DQ);
13144 def_builtin (MASK_SSE2, "__builtin_ia32_cvttpd2pi", v2si_ftype_v2df, IX86_BUILTIN_CVTTPD2PI);
13145
13146 def_builtin (MASK_SSE2, "__builtin_ia32_cvtpi2pd", v2df_ftype_v2si, IX86_BUILTIN_CVTPI2PD);
13147
13148 def_builtin (MASK_SSE2, "__builtin_ia32_cvtsd2si", int_ftype_v2df, IX86_BUILTIN_CVTSD2SI);
13149 def_builtin (MASK_SSE2, "__builtin_ia32_cvttsd2si", int_ftype_v2df, IX86_BUILTIN_CVTTSD2SI);
13150 def_builtin (MASK_SSE2 | MASK_64BIT, "__builtin_ia32_cvtsd2si64", int64_ftype_v2df, IX86_BUILTIN_CVTSD2SI64);
13151 def_builtin (MASK_SSE2 | MASK_64BIT, "__builtin_ia32_cvttsd2si64", int64_ftype_v2df, IX86_BUILTIN_CVTTSD2SI64);
13152
13153 def_builtin (MASK_SSE2, "__builtin_ia32_cvtps2dq", v4si_ftype_v4sf, IX86_BUILTIN_CVTPS2DQ);
13154 def_builtin (MASK_SSE2, "__builtin_ia32_cvtps2pd", v2df_ftype_v4sf, IX86_BUILTIN_CVTPS2PD);
13155 def_builtin (MASK_SSE2, "__builtin_ia32_cvttps2dq", v4si_ftype_v4sf, IX86_BUILTIN_CVTTPS2DQ);
13156
13157 def_builtin (MASK_SSE2, "__builtin_ia32_cvtsi2sd", v2df_ftype_v2df_int, IX86_BUILTIN_CVTSI2SD);
13158 def_builtin (MASK_SSE2 | MASK_64BIT, "__builtin_ia32_cvtsi642sd", v2df_ftype_v2df_int64, IX86_BUILTIN_CVTSI642SD);
13159 def_builtin (MASK_SSE2, "__builtin_ia32_cvtsd2ss", v4sf_ftype_v4sf_v2df, IX86_BUILTIN_CVTSD2SS);
13160 def_builtin (MASK_SSE2, "__builtin_ia32_cvtss2sd", v2df_ftype_v2df_v4sf, IX86_BUILTIN_CVTSS2SD);
13161
13162 def_builtin (MASK_SSE2, "__builtin_ia32_setpd1", v2df_ftype_double, IX86_BUILTIN_SETPD1);
13163 def_builtin (MASK_SSE2, "__builtin_ia32_setpd", v2df_ftype_double_double, IX86_BUILTIN_SETPD);
13164 def_builtin (MASK_SSE2, "__builtin_ia32_setzeropd", ti_ftype_void, IX86_BUILTIN_CLRPD);
13165 def_builtin (MASK_SSE2, "__builtin_ia32_loadpd1", v2df_ftype_pcdouble, IX86_BUILTIN_LOADPD1);
13166 def_builtin (MASK_SSE2, "__builtin_ia32_loadrpd", v2df_ftype_pcdouble, IX86_BUILTIN_LOADRPD);
13167 def_builtin (MASK_SSE2, "__builtin_ia32_storepd1", void_ftype_pdouble_v2df, IX86_BUILTIN_STOREPD1);
13168 def_builtin (MASK_SSE2, "__builtin_ia32_storerpd", void_ftype_pdouble_v2df, IX86_BUILTIN_STORERPD);
13169
13170 def_builtin (MASK_SSE2, "__builtin_ia32_clflush", void_ftype_pcvoid, IX86_BUILTIN_CLFLUSH);
13171 def_builtin (MASK_SSE2, "__builtin_ia32_lfence", void_ftype_void, IX86_BUILTIN_LFENCE);
13172 def_builtin (MASK_SSE2, "__builtin_ia32_mfence", void_ftype_void, IX86_BUILTIN_MFENCE);
13173
13174 def_builtin (MASK_SSE2, "__builtin_ia32_loaddqa", v16qi_ftype_pcchar, IX86_BUILTIN_LOADDQA);
13175 def_builtin (MASK_SSE2, "__builtin_ia32_loaddqu", v16qi_ftype_pcchar, IX86_BUILTIN_LOADDQU);
13176 def_builtin (MASK_SSE2, "__builtin_ia32_loadd", v4si_ftype_pcint, IX86_BUILTIN_LOADD);
13177 def_builtin (MASK_SSE2, "__builtin_ia32_storedqa", void_ftype_pchar_v16qi, IX86_BUILTIN_STOREDQA);
13178 def_builtin (MASK_SSE2, "__builtin_ia32_storedqu", void_ftype_pchar_v16qi, IX86_BUILTIN_STOREDQU);
13179 def_builtin (MASK_SSE2, "__builtin_ia32_stored", void_ftype_pcint_v4si, IX86_BUILTIN_STORED);
13180 def_builtin (MASK_SSE2, "__builtin_ia32_movq", v2di_ftype_v2di, IX86_BUILTIN_MOVQ);
13181
13182 def_builtin (MASK_SSE, "__builtin_ia32_setzero128", v2di_ftype_void, IX86_BUILTIN_CLRTI);
13183
13184 def_builtin (MASK_SSE2, "__builtin_ia32_psllw128", v8hi_ftype_v8hi_v2di, IX86_BUILTIN_PSLLW128);
13185 def_builtin (MASK_SSE2, "__builtin_ia32_pslld128", v4si_ftype_v4si_v2di, IX86_BUILTIN_PSLLD128);
13186 def_builtin (MASK_SSE2, "__builtin_ia32_psllq128", v2di_ftype_v2di_v2di, IX86_BUILTIN_PSLLQ128);
13187
13188 def_builtin (MASK_SSE2, "__builtin_ia32_psrlw128", v8hi_ftype_v8hi_v2di, IX86_BUILTIN_PSRLW128);
13189 def_builtin (MASK_SSE2, "__builtin_ia32_psrld128", v4si_ftype_v4si_v2di, IX86_BUILTIN_PSRLD128);
13190 def_builtin (MASK_SSE2, "__builtin_ia32_psrlq128", v2di_ftype_v2di_v2di, IX86_BUILTIN_PSRLQ128);
13191
13192 def_builtin (MASK_SSE2, "__builtin_ia32_psraw128", v8hi_ftype_v8hi_v2di, IX86_BUILTIN_PSRAW128);
13193 def_builtin (MASK_SSE2, "__builtin_ia32_psrad128", v4si_ftype_v4si_v2di, IX86_BUILTIN_PSRAD128);
13194
13195 def_builtin (MASK_SSE2, "__builtin_ia32_pslldqi128", v2di_ftype_v2di_int, IX86_BUILTIN_PSLLDQI128);
13196 def_builtin (MASK_SSE2, "__builtin_ia32_psllwi128", v8hi_ftype_v8hi_int, IX86_BUILTIN_PSLLWI128);
13197 def_builtin (MASK_SSE2, "__builtin_ia32_pslldi128", v4si_ftype_v4si_int, IX86_BUILTIN_PSLLDI128);
13198 def_builtin (MASK_SSE2, "__builtin_ia32_psllqi128", v2di_ftype_v2di_int, IX86_BUILTIN_PSLLQI128);
13199
13200 def_builtin (MASK_SSE2, "__builtin_ia32_psrldqi128", v2di_ftype_v2di_int, IX86_BUILTIN_PSRLDQI128);
13201 def_builtin (MASK_SSE2, "__builtin_ia32_psrlwi128", v8hi_ftype_v8hi_int, IX86_BUILTIN_PSRLWI128);
13202 def_builtin (MASK_SSE2, "__builtin_ia32_psrldi128", v4si_ftype_v4si_int, IX86_BUILTIN_PSRLDI128);
13203 def_builtin (MASK_SSE2, "__builtin_ia32_psrlqi128", v2di_ftype_v2di_int, IX86_BUILTIN_PSRLQI128);
13204
13205 def_builtin (MASK_SSE2, "__builtin_ia32_psrawi128", v8hi_ftype_v8hi_int, IX86_BUILTIN_PSRAWI128);
13206 def_builtin (MASK_SSE2, "__builtin_ia32_psradi128", v4si_ftype_v4si_int, IX86_BUILTIN_PSRADI128);
13207
13208 def_builtin (MASK_SSE2, "__builtin_ia32_pmaddwd128", v4si_ftype_v8hi_v8hi, IX86_BUILTIN_PMADDWD128);
13209
13210
13211 def_builtin (MASK_PNI, "__builtin_ia32_monitor",
13212 void_ftype_pcvoid_unsigned_unsigned,
13213 IX86_BUILTIN_MONITOR);
13214 def_builtin (MASK_PNI, "__builtin_ia32_mwait",
13215 void_ftype_unsigned_unsigned,
13216 IX86_BUILTIN_MWAIT);
13217 def_builtin (MASK_PNI, "__builtin_ia32_movshdup",
13218 v4sf_ftype_v4sf,
13219 IX86_BUILTIN_MOVSHDUP);
13220 def_builtin (MASK_PNI, "__builtin_ia32_movsldup",
13221 v4sf_ftype_v4sf,
13222 IX86_BUILTIN_MOVSLDUP);
13223 def_builtin (MASK_PNI, "__builtin_ia32_lddqu",
13224 v16qi_ftype_pcchar, IX86_BUILTIN_LDDQU);
13225 def_builtin (MASK_PNI, "__builtin_ia32_loadddup",
13226 v2df_ftype_pcdouble, IX86_BUILTIN_LOADDDUP);
13227 def_builtin (MASK_PNI, "__builtin_ia32_movddup",
13228 v2df_ftype_v2df, IX86_BUILTIN_MOVDDUP);
13229 }
13230
13231
13232
13233
13234 static rtx
13235 safe_vector_operand (x, mode)
13236 rtx x;
13237 enum machine_mode mode;
13238 {
13239 if (x != const0_rtx)
13240 return x;
13241 x = gen_reg_rtx (mode);
13242
13243 if (VALID_MMX_REG_MODE (mode) || VALID_MMX_REG_MODE_3DNOW (mode))
13244 emit_insn (gen_mmx_clrdi (mode == DImode ? x
13245 : gen_rtx_SUBREG (DImode, x, 0)));
13246 else
13247 emit_insn (gen_sse_clrv4sf (mode == V4SFmode ? x
13248 : gen_rtx_SUBREG (V4SFmode, x, 0)));
13249 return x;
13250 }
13251
13252
13253
13254 static rtx
13255 ix86_expand_binop_builtin (icode, arglist, target)
13256 enum insn_code icode;
13257 tree arglist;
13258 rtx target;
13259 {
13260 rtx pat;
13261 tree arg0 = TREE_VALUE (arglist);
13262 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
13263 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
13264 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
13265 enum machine_mode tmode = insn_data[icode].operand[0].mode;
13266 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
13267 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
13268
13269 if (VECTOR_MODE_P (mode0))
13270 op0 = safe_vector_operand (op0, mode0);
13271 if (VECTOR_MODE_P (mode1))
13272 op1 = safe_vector_operand (op1, mode1);
13273
13274 if (! target
13275 || GET_MODE (target) != tmode
13276 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
13277 target = gen_reg_rtx (tmode);
13278
13279 if (GET_MODE (op1) == SImode && mode1 == TImode)
13280 {
13281 rtx x = gen_reg_rtx (V4SImode);
13282 emit_insn (gen_sse2_loadd (x, op1));
13283 op1 = gen_lowpart (TImode, x);
13284 }
13285
13286
13287
13288 if (GET_MODE (op0) != mode0 || GET_MODE (op1) != mode1)
13289 abort ();
13290
13291 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
13292 op0 = copy_to_mode_reg (mode0, op0);
13293 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
13294 op1 = copy_to_mode_reg (mode1, op1);
13295
13296
13297
13298
13299 if (GET_CODE (op0) == MEM && GET_CODE (op1) == MEM)
13300 op0 = copy_to_mode_reg (mode0, op0);
13301
13302 pat = GEN_FCN (icode) (target, op0, op1);
13303 if (! pat)
13304 return 0;
13305 emit_insn (pat);
13306 return target;
13307 }
13308
13309
13310
13311 static rtx
13312 ix86_expand_store_builtin (icode, arglist)
13313 enum insn_code icode;
13314 tree arglist;
13315 {
13316 rtx pat;
13317 tree arg0 = TREE_VALUE (arglist);
13318 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
13319 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
13320 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
13321 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
13322 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
13323
13324 if (VECTOR_MODE_P (mode1))
13325 op1 = safe_vector_operand (op1, mode1);
13326
13327 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
13328 op1 = copy_to_mode_reg (mode1, op1);
13329
13330 pat = GEN_FCN (icode) (op0, op1);
13331 if (pat)
13332 emit_insn (pat);
13333 return 0;
13334 }
13335
13336
13337
13338 static rtx
13339 ix86_expand_unop_builtin (icode, arglist, target, do_load)
13340 enum insn_code icode;
13341 tree arglist;
13342 rtx target;
13343 int do_load;
13344 {
13345 rtx pat;
13346 tree arg0 = TREE_VALUE (arglist);
13347 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
13348 enum machine_mode tmode = insn_data[icode].operand[0].mode;
13349 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
13350
13351 if (! target
13352 || GET_MODE (target) != tmode
13353 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
13354 target = gen_reg_rtx (tmode);
13355 if (do_load)
13356 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
13357 else
13358 {
13359 if (VECTOR_MODE_P (mode0))
13360 op0 = safe_vector_operand (op0, mode0);
13361
13362 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
13363 op0 = copy_to_mode_reg (mode0, op0);
13364 }
13365
13366 pat = GEN_FCN (icode) (target, op0);
13367 if (! pat)
13368 return 0;
13369 emit_insn (pat);
13370 return target;
13371 }
13372
13373
13374
13375
13376 static rtx
13377 ix86_expand_unop1_builtin (icode, arglist, target)
13378 enum insn_code icode;
13379 tree arglist;
13380 rtx target;
13381 {
13382 rtx pat;
13383 tree arg0 = TREE_VALUE (arglist);
13384 rtx op1, op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
13385 enum machine_mode tmode = insn_data[icode].operand[0].mode;
13386 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
13387
13388 if (! target
13389 || GET_MODE (target) != tmode
13390 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
13391 target = gen_reg_rtx (tmode);
13392
13393 if (VECTOR_MODE_P (mode0))
13394 op0 = safe_vector_operand (op0, mode0);
13395
13396 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
13397 op0 = copy_to_mode_reg (mode0, op0);
13398
13399 op1 = op0;
13400 if (! (*insn_data[icode].operand[2].predicate) (op1, mode0))
13401 op1 = copy_to_mode_reg (mode0, op1);
13402
13403 pat = GEN_FCN (icode) (target, op0, op1);
13404 if (! pat)
13405 return 0;
13406 emit_insn (pat);
13407 return target;
13408 }
13409
13410
13411
13412 static rtx
13413 ix86_expand_sse_compare (d, arglist, target)
13414 const struct builtin_description *d;
13415 tree arglist;
13416 rtx target;
13417 {
13418 rtx pat;
13419 tree arg0 = TREE_VALUE (arglist);
13420 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
13421 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
13422 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
13423 rtx op2;
13424 enum machine_mode tmode = insn_data[d->icode].operand[0].mode;
13425 enum machine_mode mode0 = insn_data[d->icode].operand[1].mode;
13426 enum machine_mode mode1 = insn_data[d->icode].operand[2].mode;
13427 enum rtx_code comparison = d->comparison;
13428
13429 if (VECTOR_MODE_P (mode0))
13430 op0 = safe_vector_operand (op0, mode0);
13431 if (VECTOR_MODE_P (mode1))
13432 op1 = safe_vector_operand (op1, mode1);
13433
13434
13435
13436 if (d->flag)
13437 {
13438 rtx tmp = gen_reg_rtx (mode1);
13439 emit_move_insn (tmp, op1);
13440 op1 = op0;
13441 op0 = tmp;
13442 }
13443
13444 if (! target
13445 || GET_MODE (target) != tmode
13446 || ! (*insn_data[d->icode].operand[0].predicate) (target, tmode))
13447 target = gen_reg_rtx (tmode);
13448
13449 if (! (*insn_data[d->icode].operand[1].predicate) (op0, mode0))
13450 op0 = copy_to_mode_reg (mode0, op0);
13451 if (! (*insn_data[d->icode].operand[2].predicate) (op1, mode1))
13452 op1 = copy_to_mode_reg (mode1, op1);
13453
13454 op2 = gen_rtx_fmt_ee (comparison, mode0, op0, op1);
13455 pat = GEN_FCN (d->icode) (target, op0, op1, op2);
13456 if (! pat)
13457 return 0;
13458 emit_insn (pat);
13459 return target;
13460 }
13461
13462
13463
13464 static rtx
13465 ix86_expand_sse_comi (d, arglist, target)
13466 const struct builtin_description *d;
13467 tree arglist;
13468 rtx target;
13469 {
13470 rtx pat;
13471 tree arg0 = TREE_VALUE (arglist);
13472 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
13473 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
13474 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
13475 rtx op2;
13476 enum machine_mode mode0 = insn_data[d->icode].operand[0].mode;
13477 enum machine_mode mode1 = insn_data[d->icode].operand[1].mode;
13478 enum rtx_code comparison = d->comparison;
13479
13480 if (VECTOR_MODE_P (mode0))
13481 op0 = safe_vector_operand (op0, mode0);
13482 if (VECTOR_MODE_P (mode1))
13483 op1 = safe_vector_operand (op1, mode1);
13484
13485
13486
13487 if (d->flag)
13488 {
13489 rtx tmp = op1;
13490 op1 = op0;
13491 op0 = tmp;
13492 }
13493
13494 target = gen_reg_rtx (SImode);
13495 emit_move_insn (target, const0_rtx);
13496 target = gen_rtx_SUBREG (QImode, target, 0);
13497
13498 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
13499 op0 = copy_to_mode_reg (mode0, op0);
13500 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
13501 op1 = copy_to_mode_reg (mode1, op1);
13502
13503 op2 = gen_rtx_fmt_ee (comparison, mode0, op0, op1);
13504 pat = GEN_FCN (d->icode) (op0, op1);
13505 if (! pat)
13506 return 0;
13507 emit_insn (pat);
13508 emit_insn (gen_rtx_SET (VOIDmode,
13509 gen_rtx_STRICT_LOW_PART (VOIDmode, target),
13510 gen_rtx_fmt_ee (comparison, QImode,
13511 SET_DEST (pat),
13512 const0_rtx)));
13513
13514 return SUBREG_REG (target);
13515 }
13516
13517
13518
13519
13520
13521
13522
13523 rtx
13524 ix86_expand_builtin (exp, target, subtarget, mode, ignore)
13525 tree exp;
13526 rtx target;
13527 rtx subtarget ATTRIBUTE_UNUSED;
13528 enum machine_mode mode ATTRIBUTE_UNUSED;
13529 int ignore ATTRIBUTE_UNUSED;
13530 {
13531 const struct builtin_description *d;
13532 size_t i;
13533 enum insn_code icode;
13534 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
13535 tree arglist = TREE_OPERAND (exp, 1);
13536 tree arg0, arg1, arg2;
13537 rtx op0, op1, op2, pat;
13538 enum machine_mode tmode, mode0, mode1, mode2;
13539 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
13540
13541 switch (fcode)
13542 {
13543 case IX86_BUILTIN_EMMS:
13544 emit_insn (gen_emms ());
13545 return 0;
13546
13547 case IX86_BUILTIN_SFENCE:
13548 emit_insn (gen_sfence ());
13549 return 0;
13550
13551 case IX86_BUILTIN_PEXTRW:
13552 case IX86_BUILTIN_PEXTRW128:
13553 icode = (fcode == IX86_BUILTIN_PEXTRW
13554 ? CODE_FOR_mmx_pextrw
13555 : CODE_FOR_sse2_pextrw);
13556 arg0 = TREE_VALUE (arglist);
13557 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
13558 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
13559 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
13560 tmode = insn_data[icode].operand[0].mode;
13561 mode0 = insn_data[icode].operand[1].mode;
13562 mode1 = insn_data[icode].operand[2].mode;
13563
13564 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
13565 op0 = copy_to_mode_reg (mode0, op0);
13566 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
13567 {
13568
13569 error ("selector must be an immediate");
13570 return gen_reg_rtx (tmode);
13571 }
13572 if (target == 0
13573 || GET_MODE (target) != tmode
13574 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
13575 target = gen_reg_rtx (tmode);
13576 pat = GEN_FCN (icode) (target, op0, op1);
13577 if (! pat)
13578 return 0;
13579 emit_insn (pat);
13580 return target;
13581
13582 case IX86_BUILTIN_PINSRW:
13583 case IX86_BUILTIN_PINSRW128:
13584 icode = (fcode == IX86_BUILTIN_PINSRW
13585 ? CODE_FOR_mmx_pinsrw
13586 : CODE_FOR_sse2_pinsrw);
13587 arg0 = TREE_VALUE (arglist);
13588 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
13589 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
13590 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
13591 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
13592 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
13593 tmode = insn_data[icode].operand[0].mode;
13594 mode0 = insn_data[icode].operand[1].mode;
13595 mode1 = insn_data[icode].operand[2].mode;
13596 mode2 = insn_data[icode].operand[3].mode;
13597
13598 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
13599 op0 = copy_to_mode_reg (mode0, op0);
13600 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
13601 op1 = copy_to_mode_reg (mode1, op1);
13602 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
13603 {
13604
13605 error ("selector must be an immediate");
13606 return const0_rtx;
13607 }
13608 if (target == 0
13609 || GET_MODE (target) != tmode
13610 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
13611 target = gen_reg_rtx (tmode);
13612 pat = GEN_FCN (icode) (target, op0, op1, op2);
13613 if (! pat)
13614 return 0;
13615 emit_insn (pat);
13616 return target;
13617
13618 case IX86_BUILTIN_MASKMOVQ:
13619 case IX86_BUILTIN_MASKMOVDQU:
13620 icode = (fcode == IX86_BUILTIN_MASKMOVQ
13621 ? (TARGET_64BIT ? CODE_FOR_mmx_maskmovq_rex : CODE_FOR_mmx_maskmovq)
13622 : (TARGET_64BIT ? CODE_FOR_sse2_maskmovdqu_rex64
13623 : CODE_FOR_sse2_maskmovdqu));
13624
13625 arg1 = TREE_VALUE (arglist);
13626 arg2 = TREE_VALUE (TREE_CHAIN (arglist));
13627 arg0 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
13628 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
13629 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
13630 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
13631 mode0 = insn_data[icode].operand[0].mode;
13632 mode1 = insn_data[icode].operand[1].mode;
13633 mode2 = insn_data[icode].operand[2].mode;
13634
13635 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
13636 op0 = copy_to_mode_reg (mode0, op0);
13637 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
13638 op1 = copy_to_mode_reg (mode1, op1);
13639 if (! (*insn_data[icode].operand[2].predicate) (op2, mode2))
13640 op2 = copy_to_mode_reg (mode2, op2);
13641 pat = GEN_FCN (icode) (op0, op1, op2);
13642 if (! pat)
13643 return 0;
13644 emit_insn (pat);
13645 return 0;
13646
13647 case IX86_BUILTIN_SQRTSS:
13648 return ix86_expand_unop1_builtin (CODE_FOR_vmsqrtv4sf2, arglist, target);
13649 case IX86_BUILTIN_RSQRTSS:
13650 return ix86_expand_unop1_builtin (CODE_FOR_vmrsqrtv4sf2, arglist, target);
13651 case IX86_BUILTIN_RCPSS:
13652 return ix86_expand_unop1_builtin (CODE_FOR_vmrcpv4sf2, arglist, target);
13653
13654 case IX86_BUILTIN_LOADAPS:
13655 return ix86_expand_unop_builtin (CODE_FOR_sse_movaps, arglist, target, 1);
13656
13657 case IX86_BUILTIN_LOADUPS:
13658 return ix86_expand_unop_builtin (CODE_FOR_sse_movups, arglist, target, 1);
13659
13660 case IX86_BUILTIN_STOREAPS:
13661 return ix86_expand_store_builtin (CODE_FOR_sse_movaps, arglist);
13662
13663 case IX86_BUILTIN_STOREUPS:
13664 return ix86_expand_store_builtin (CODE_FOR_sse_movups, arglist);
13665
13666 case IX86_BUILTIN_LOADSS:
13667 return ix86_expand_unop_builtin (CODE_FOR_sse_loadss, arglist, target, 1);
13668
13669 case IX86_BUILTIN_STORESS:
13670 return ix86_expand_store_builtin (CODE_FOR_sse_storess, arglist);
13671
13672 case IX86_BUILTIN_LOADHPS:
13673 case IX86_BUILTIN_LOADLPS:
13674 case IX86_BUILTIN_LOADHPD:
13675 case IX86_BUILTIN_LOADLPD:
13676 icode = (fcode == IX86_BUILTIN_LOADHPS ? CODE_FOR_sse_movhps
13677 : fcode == IX86_BUILTIN_LOADLPS ? CODE_FOR_sse_movlps
13678 : fcode == IX86_BUILTIN_LOADHPD ? CODE_FOR_sse2_movhpd
13679 : CODE_FOR_sse2_movlpd);
13680 arg0 = TREE_VALUE (arglist);
13681 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
13682 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
13683 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
13684 tmode = insn_data[icode].operand[0].mode;
13685 mode0 = insn_data[icode].operand[1].mode;
13686 mode1 = insn_data[icode].operand[2].mode;
13687
13688 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
13689 op0 = copy_to_mode_reg (mode0, op0);
13690 op1 = gen_rtx_MEM (mode1, copy_to_mode_reg (Pmode, op1));
13691 if (target == 0
13692 || GET_MODE (target) != tmode
13693 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
13694 target = gen_reg_rtx (tmode);
13695 pat = GEN_FCN (icode) (target, op0, op1);
13696 if (! pat)
13697 return 0;
13698 emit_insn (pat);
13699 return target;
13700
13701 case IX86_BUILTIN_STOREHPS:
13702 case IX86_BUILTIN_STORELPS:
13703 case IX86_BUILTIN_STOREHPD:
13704 case IX86_BUILTIN_STORELPD:
13705 icode = (fcode == IX86_BUILTIN_STOREHPS ? CODE_FOR_sse_movhps
13706 : fcode == IX86_BUILTIN_STORELPS ? CODE_FOR_sse_movlps
13707 : fcode == IX86_BUILTIN_STOREHPD ? CODE_FOR_sse2_movhpd
13708 : CODE_FOR_sse2_movlpd);
13709 arg0 = TREE_VALUE (arglist);
13710 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
13711 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
13712 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
13713 mode0 = insn_data[icode].operand[1].mode;
13714 mode1 = insn_data[icode].operand[2].mode;
13715
13716 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
13717 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
13718 op1 = copy_to_mode_reg (mode1, op1);
13719
13720 pat = GEN_FCN (icode) (op0, op0, op1);
13721 if (! pat)
13722 return 0;
13723 emit_insn (pat);
13724 return 0;
13725
13726 case IX86_BUILTIN_MOVNTPS:
13727 return ix86_expand_store_builtin (CODE_FOR_sse_movntv4sf, arglist);
13728 case IX86_BUILTIN_MOVNTQ:
13729 return ix86_expand_store_builtin (CODE_FOR_sse_movntdi, arglist);
13730
13731 case IX86_BUILTIN_LDMXCSR:
13732 op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
13733 target = assign_386_stack_local (SImode, 0);
13734 emit_move_insn (target, op0);
13735 emit_insn (gen_ldmxcsr (target));
13736 return 0;
13737
13738 case IX86_BUILTIN_STMXCSR:
13739 target = assign_386_stack_local (SImode, 0);
13740 emit_insn (gen_stmxcsr (target));
13741 return copy_to_mode_reg (SImode, target);
13742
13743 case IX86_BUILTIN_SHUFPS:
13744 case IX86_BUILTIN_SHUFPD:
13745 icode = (fcode == IX86_BUILTIN_SHUFPS
13746 ? CODE_FOR_sse_shufps
13747 : CODE_FOR_sse2_shufpd);
13748 arg0 = TREE_VALUE (arglist);
13749 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
13750 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
13751 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
13752 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
13753 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
13754 tmode = insn_data[icode].operand[0].mode;
13755 mode0 = insn_data[icode].operand[1].mode;
13756 mode1 = insn_data[icode].operand[2].mode;
13757 mode2 = insn_data[icode].operand[3].mode;
13758
13759 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
13760 op0 = copy_to_mode_reg (mode0, op0);
13761 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
13762 op1 = copy_to_mode_reg (mode1, op1);
13763 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
13764 {
13765
13766 error ("mask must be an immediate");
13767 return gen_reg_rtx (tmode);
13768 }
13769 if (target == 0
13770 || GET_MODE (target) != tmode
13771 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
13772 target = gen_reg_rtx (tmode);
13773 pat = GEN_FCN (icode) (target, op0, op1, op2);
13774 if (! pat)
13775 return 0;
13776 emit_insn (pat);
13777 return target;
13778
13779 case IX86_BUILTIN_PSHUFW:
13780 case IX86_BUILTIN_PSHUFD:
13781 case IX86_BUILTIN_PSHUFHW:
13782 case IX86_BUILTIN_PSHUFLW:
13783 icode = ( fcode == IX86_BUILTIN_PSHUFHW ? CODE_FOR_sse2_pshufhw
13784 : fcode == IX86_BUILTIN_PSHUFLW ? CODE_FOR_sse2_pshuflw
13785 : fcode == IX86_BUILTIN_PSHUFD ? CODE_FOR_sse2_pshufd
13786 : CODE_FOR_mmx_pshufw);
13787 arg0 = TREE_VALUE (arglist);
13788 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
13789 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
13790 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
13791 tmode = insn_data[icode].operand[0].mode;
13792 mode1 = insn_data[icode].operand[1].mode;
13793 mode2 = insn_data[icode].operand[2].mode;
13794
13795 if (! (*insn_data[icode].operand[1].predicate) (op0, mode1))
13796 op0 = copy_to_mode_reg (mode1, op0);
13797 if (! (*insn_data[icode].operand[2].predicate) (op1, mode2))
13798 {
13799
13800 error ("mask must be an immediate");
13801 return const0_rtx;
13802 }
13803 if (target == 0
13804 || GET_MODE (target) != tmode
13805 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
13806 target = gen_reg_rtx (tmode);
13807 pat = GEN_FCN (icode) (target, op0, op1);
13808 if (! pat)
13809 return 0;
13810 emit_insn (pat);
13811 return target;
13812
13813 case IX86_BUILTIN_PSLLDQI128:
13814 case IX86_BUILTIN_PSRLDQI128:
13815 icode = ( fcode == IX86_BUILTIN_PSLLDQI128 ? CODE_FOR_sse2_ashlti3
13816 : CODE_FOR_sse2_lshrti3);
13817 arg0 = TREE_VALUE (arglist);
13818 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
13819 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
13820 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
13821 tmode = insn_data[icode].operand[0].mode;
13822 mode1 = insn_data[icode].operand[1].mode;
13823 mode2 = insn_data[icode].operand[2].mode;
13824
13825 if (! (*insn_data[icode].operand[1].predicate) (op0, mode1))
13826 {
13827 op0 = copy_to_reg (op0);
13828 op0 = simplify_gen_subreg (mode1, op0, GET_MODE (op0), 0);
13829 }
13830 if (! (*insn_data[icode].operand[2].predicate) (op1, mode2))
13831 {
13832 error ("shift must be an immediate");
13833 return const0_rtx;
13834 }
13835 target = gen_reg_rtx (V2DImode);
13836 pat = GEN_FCN (icode) (simplify_gen_subreg (tmode, target, V2DImode, 0), op0, op1);
13837 if (! pat)
13838 return 0;
13839 emit_insn (pat);
13840 return target;
13841
13842 case IX86_BUILTIN_FEMMS:
13843 emit_insn (gen_femms ());
13844 return NULL_RTX;
13845
13846 case IX86_BUILTIN_PAVGUSB:
13847 return ix86_expand_binop_builtin (CODE_FOR_pavgusb, arglist, target);
13848
13849 case IX86_BUILTIN_PF2ID:
13850 return ix86_expand_unop_builtin (CODE_FOR_pf2id, arglist, target, 0);
13851
13852 case IX86_BUILTIN_PFACC:
13853 return ix86_expand_binop_builtin (CODE_FOR_pfacc, arglist, target);
13854
13855 case IX86_BUILTIN_PFADD:
13856 return ix86_expand_binop_builtin (CODE_FOR_addv2sf3, arglist, target);
13857
13858 case IX86_BUILTIN_PFCMPEQ:
13859 return ix86_expand_binop_builtin (CODE_FOR_eqv2sf3, arglist, target);
13860
13861 case IX86_BUILTIN_PFCMPGE:
13862 return ix86_expand_binop_builtin (CODE_FOR_gev2sf3, arglist, target);
13863
13864 case IX86_BUILTIN_PFCMPGT:
13865 return ix86_expand_binop_builtin (CODE_FOR_gtv2sf3, arglist, target);
13866
13867 case IX86_BUILTIN_PFMAX:
13868 return ix86_expand_binop_builtin (CODE_FOR_pfmaxv2sf3, arglist, target);
13869
13870 case IX86_BUILTIN_PFMIN:
13871 return ix86_expand_binop_builtin (CODE_FOR_pfminv2sf3, arglist, target);
13872
13873 case IX86_BUILTIN_PFMUL:
13874 return ix86_expand_binop_builtin (CODE_FOR_mulv2sf3, arglist, target);
13875
13876 case IX86_BUILTIN_PFRCP:
13877 return ix86_expand_unop_builtin (CODE_FOR_pfrcpv2sf2, arglist, target, 0);
13878
13879 case IX86_BUILTIN_PFRCPIT1:
13880 return ix86_expand_binop_builtin (CODE_FOR_pfrcpit1v2sf3, arglist, target);
13881
13882 case IX86_BUILTIN_PFRCPIT2:
13883 return ix86_expand_binop_builtin (CODE_FOR_pfrcpit2v2sf3, arglist, target);
13884
13885 case IX86_BUILTIN_PFRSQIT1:
13886 return ix86_expand_binop_builtin (CODE_FOR_pfrsqit1v2sf3, arglist, target);
13887
13888 case IX86_BUILTIN_PFRSQRT:
13889 return ix86_expand_unop_builtin (CODE_FOR_pfrsqrtv2sf2, arglist, target, 0);
13890
13891 case IX86_BUILTIN_PFSUB:
13892 return ix86_expand_binop_builtin (CODE_FOR_subv2sf3, arglist, target);
13893
13894 case IX86_BUILTIN_PFSUBR:
13895 return ix86_expand_binop_builtin (CODE_FOR_subrv2sf3, arglist, target);
13896
13897 case IX86_BUILTIN_PI2FD:
13898 return ix86_expand_unop_builtin (CODE_FOR_floatv2si2, arglist, target, 0);
13899
13900 case IX86_BUILTIN_PMULHRW:
13901 return ix86_expand_binop_builtin (CODE_FOR_pmulhrwv4hi3, arglist, target);
13902
13903 case IX86_BUILTIN_PF2IW:
13904 return ix86_expand_unop_builtin (CODE_FOR_pf2iw, arglist, target, 0);
13905
13906 case IX86_BUILTIN_PFNACC:
13907 return ix86_expand_binop_builtin (CODE_FOR_pfnacc, arglist, target);
13908
13909 case IX86_BUILTIN_PFPNACC:
13910 return ix86_expand_binop_builtin (CODE_FOR_pfpnacc, arglist, target);
13911
13912 case IX86_BUILTIN_PI2FW:
13913 return ix86_expand_unop_builtin (CODE_FOR_pi2fw, arglist, target, 0);
13914
13915 case IX86_BUILTIN_PSWAPDSI:
13916 return ix86_expand_unop_builtin (CODE_FOR_pswapdv2si2, arglist, target, 0);
13917
13918 case IX86_BUILTIN_PSWAPDSF:
13919 return ix86_expand_unop_builtin (CODE_FOR_pswapdv2sf2, arglist, target, 0);
13920
13921 case IX86_BUILTIN_SSE_ZERO:
13922 target = gen_reg_rtx (V4SFmode);
13923 emit_insn (gen_sse_clrv4sf (target));
13924 return target;
13925
13926 case IX86_BUILTIN_MMX_ZERO:
13927 target = gen_reg_rtx (DImode);
13928 emit_insn (gen_mmx_clrdi (target));
13929 return target;
13930
13931 case IX86_BUILTIN_CLRTI:
13932 target = gen_reg_rtx (V2DImode);
13933 emit_insn (gen_sse2_clrti (simplify_gen_subreg (TImode, target, V2DImode, 0)));
13934 return target;
13935
13936
13937 case IX86_BUILTIN_SQRTSD:
13938 return ix86_expand_unop1_builtin (CODE_FOR_vmsqrtv2df2, arglist, target);
13939 case IX86_BUILTIN_LOADAPD:
13940 return ix86_expand_unop_builtin (CODE_FOR_sse2_movapd, arglist, target, 1);
13941 case IX86_BUILTIN_LOADUPD:
13942 return ix86_expand_unop_builtin (CODE_FOR_sse2_movupd, arglist, target, 1);
13943
13944 case IX86_BUILTIN_STOREAPD:
13945 return ix86_expand_store_builtin (CODE_FOR_sse2_movapd, arglist);
13946 case IX86_BUILTIN_STOREUPD:
13947 return ix86_expand_store_builtin (CODE_FOR_sse2_movupd, arglist);
13948
13949 case IX86_BUILTIN_LOADSD:
13950 return ix86_expand_unop_builtin (CODE_FOR_sse2_loadsd, arglist, target, 1);
13951
13952 case IX86_BUILTIN_STORESD:
13953 return ix86_expand_store_builtin (CODE_FOR_sse2_storesd, arglist);
13954
13955 case IX86_BUILTIN_SETPD1:
13956 target = assign_386_stack_local (DFmode, 0);
13957 arg0 = TREE_VALUE (arglist);
13958 emit_move_insn (adjust_address (target, DFmode, 0),
13959 expand_expr (arg0, NULL_RTX, VOIDmode, 0));
13960 op0 = gen_reg_rtx (V2DFmode);
13961 emit_insn (gen_sse2_loadsd (op0, adjust_address (target, V2DFmode, 0)));
13962 emit_insn (gen_sse2_shufpd (op0, op0, op0, GEN_INT (0)));
13963 return op0;
13964
13965 case IX86_BUILTIN_SETPD:
13966 target = assign_386_stack_local (V2DFmode, 0);
13967 arg0 = TREE_VALUE (arglist);
13968 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
13969 emit_move_insn (adjust_address (target, DFmode, 0),
13970 expand_expr (arg0, NULL_RTX, VOIDmode, 0));
13971 emit_move_insn (adjust_address (target, DFmode, 8),
13972 expand_expr (arg1, NULL_RTX, VOIDmode, 0));
13973 op0 = gen_reg_rtx (V2DFmode);
13974 emit_insn (gen_sse2_movapd (op0, target));
13975 return op0;
13976
13977 case IX86_BUILTIN_LOADRPD:
13978 target = ix86_expand_unop_builtin (CODE_FOR_sse2_movapd, arglist,
13979 gen_reg_rtx (V2DFmode), 1);
13980 emit_insn (gen_sse2_shufpd (target, target, target, GEN_INT (1)));
13981 return target;
13982
13983 case IX86_BUILTIN_LOADPD1:
13984 target = ix86_expand_unop_builtin (CODE_FOR_sse2_loadsd, arglist,
13985 gen_reg_rtx (V2DFmode), 1);
13986 emit_insn (gen_sse2_shufpd (target, target, target, const0_rtx));
13987 return target;
13988
13989 case IX86_BUILTIN_STOREPD1:
13990 return ix86_expand_store_builtin (CODE_FOR_sse2_movapd, arglist);
13991 case IX86_BUILTIN_STORERPD:
13992 return ix86_expand_store_builtin (CODE_FOR_sse2_movapd, arglist);
13993
13994 case IX86_BUILTIN_CLRPD:
13995 target = gen_reg_rtx (V2DFmode);
13996 emit_insn (gen_sse_clrv2df (target));
13997 return target;
13998
13999 case IX86_BUILTIN_MFENCE:
14000 emit_insn (gen_sse2_mfence ());
14001 return 0;
14002 case IX86_BUILTIN_LFENCE:
14003 emit_insn (gen_sse2_lfence ());
14004 return 0;
14005
14006 case IX86_BUILTIN_CLFLUSH:
14007 arg0 = TREE_VALUE (arglist);
14008 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
14009 icode = CODE_FOR_sse2_clflush;
14010 if (! (*insn_data[icode].operand[0].predicate) (op0, Pmode))
14011 op0 = copy_to_mode_reg (Pmode, op0);
14012
14013 emit_insn (gen_sse2_clflush (op0));
14014 return 0;
14015
14016 case IX86_BUILTIN_MOVNTPD:
14017 return ix86_expand_store_builtin (CODE_FOR_sse2_movntv2df, arglist);
14018 case IX86_BUILTIN_MOVNTDQ:
14019 return ix86_expand_store_builtin (CODE_FOR_sse2_movntv2di, arglist);
14020 case IX86_BUILTIN_MOVNTI:
14021 return ix86_expand_store_builtin (CODE_FOR_sse2_movntsi, arglist);
14022
14023 case IX86_BUILTIN_LOADDQA:
14024 return ix86_expand_unop_builtin (CODE_FOR_sse2_movdqa, arglist, target, 1);
14025 case IX86_BUILTIN_LOADDQU:
14026 return ix86_expand_unop_builtin (CODE_FOR_sse2_movdqu, arglist, target, 1);
14027 case IX86_BUILTIN_LOADD:
14028 return ix86_expand_unop_builtin (CODE_FOR_sse2_loadd, arglist, target, 1);
14029
14030 case IX86_BUILTIN_STOREDQA:
14031 return ix86_expand_store_builtin (CODE_FOR_sse2_movdqa, arglist);
14032 case IX86_BUILTIN_STOREDQU:
14033 return ix86_expand_store_builtin (CODE_FOR_sse2_movdqu, arglist);
14034 case IX86_BUILTIN_STORED:
14035 return ix86_expand_store_builtin (CODE_FOR_sse2_stored, arglist);
14036
14037 case IX86_BUILTIN_MONITOR:
14038 arg0 = TREE_VALUE (arglist);
14039 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
14040 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
14041 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
14042 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
14043 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
14044 if (!REG_P (op0))
14045 op0 = copy_to_mode_reg (SImode, op0);
14046 if (!REG_P (op1))
14047 op1 = copy_to_mode_reg (SImode, op1);
14048 if (!REG_P (op2))
14049 op2 = copy_to_mode_reg (SImode, op2);
14050 emit_insn (gen_monitor (op0, op1, op2));
14051 return 0;
14052
14053 case IX86_BUILTIN_MWAIT:
14054 arg0 = TREE_VALUE (arglist);
14055 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
14056 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
14057 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
14058 if (!REG_P (op0))
14059 op0 = copy_to_mode_reg (SImode, op0);
14060 if (!REG_P (op1))
14061 op1 = copy_to_mode_reg (SImode, op1);
14062 emit_insn (gen_mwait (op0, op1));
14063 return 0;
14064
14065 case IX86_BUILTIN_LOADDDUP:
14066 return ix86_expand_unop_builtin (CODE_FOR_loadddup, arglist, target, 1);
14067
14068 case IX86_BUILTIN_LDDQU:
14069 return ix86_expand_unop_builtin (CODE_FOR_lddqu, arglist, target,
14070 1);
14071
14072 default:
14073 break;
14074 }
14075
14076 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
14077 if (d->code == fcode)
14078 {
14079
14080 if (d->icode == CODE_FOR_maskcmpv4sf3
14081 || d->icode == CODE_FOR_vmmaskcmpv4sf3
14082 || d->icode == CODE_FOR_maskncmpv4sf3
14083 || d->icode == CODE_FOR_vmmaskncmpv4sf3
14084 || d->icode == CODE_FOR_maskcmpv2df3
14085 || d->icode == CODE_FOR_vmmaskcmpv2df3
14086 || d->icode == CODE_FOR_maskncmpv2df3
14087 || d->icode == CODE_FOR_vmmaskncmpv2df3)
14088 return ix86_expand_sse_compare (d, arglist, target);
14089
14090 return ix86_expand_binop_builtin (d->icode, arglist, target);
14091 }
14092
14093 for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
14094 if (d->code == fcode)
14095 return ix86_expand_unop_builtin (d->icode, arglist, target, 0);
14096
14097 for (i = 0, d = bdesc_comi; i < ARRAY_SIZE (bdesc_comi); i++, d++)
14098 if (d->code == fcode)
14099 return ix86_expand_sse_comi (d, arglist, target);
14100
14101
14102 return 0;
14103 }
14104
14105
14106
14107 rtx
14108 ix86_force_to_memory (mode, operand)
14109 enum machine_mode mode;
14110 rtx operand;
14111 {
14112 rtx result;
14113 if (!reload_completed)
14114 abort ();
14115 if (TARGET_64BIT && TARGET_RED_ZONE)
14116 {
14117 result = gen_rtx_MEM (mode,
14118 gen_rtx_PLUS (Pmode,
14119 stack_pointer_rtx,
14120 GEN_INT (-RED_ZONE_SIZE)));
14121 emit_move_insn (result, operand);
14122 }
14123 else if (TARGET_64BIT && !TARGET_RED_ZONE)
14124 {
14125 switch (mode)
14126 {
14127 case HImode:
14128 case SImode:
14129 operand = gen_lowpart (DImode, operand);
14130
14131 case DImode:
14132 emit_insn (
14133 gen_rtx_SET (VOIDmode,
14134 gen_rtx_MEM (DImode,
14135 gen_rtx_PRE_DEC (DImode,
14136 stack_pointer_rtx)),
14137 operand));
14138 break;
14139 default:
14140 abort ();
14141 }
14142 result = gen_rtx_MEM (mode, stack_pointer_rtx);
14143 }
14144 else
14145 {
14146 switch (mode)
14147 {
14148 case DImode:
14149 {
14150 rtx operands[2];
14151 split_di (&operand, 1, operands, operands + 1);
14152 emit_insn (
14153 gen_rtx_SET (VOIDmode,
14154 gen_rtx_MEM (SImode,
14155 gen_rtx_PRE_DEC (Pmode,
14156 stack_pointer_rtx)),
14157 operands[1]));
14158 emit_insn (
14159 gen_rtx_SET (VOIDmode,
14160 gen_rtx_MEM (SImode,
14161 gen_rtx_PRE_DEC (Pmode,
14162 stack_pointer_rtx)),
14163 operands[0]));
14164 }
14165 break;
14166 case HImode:
14167
14168 if (!TARGET_PARTIAL_REG_STALL)
14169 operand = gen_lowpart (SImode, operand);
14170
14171 case SImode:
14172 emit_insn (
14173 gen_rtx_SET (VOIDmode,
14174 gen_rtx_MEM (GET_MODE (operand),
14175 gen_rtx_PRE_DEC (SImode,
14176 stack_pointer_rtx)),
14177 operand));
14178 break;
14179 default:
14180 abort ();
14181 }
14182 result = gen_rtx_MEM (mode, stack_pointer_rtx);
14183 }
14184 return result;
14185 }
14186
14187
14188 void
14189 ix86_free_from_memory (mode)
14190 enum machine_mode mode;
14191 {
14192 if (!TARGET_64BIT || !TARGET_RED_ZONE)
14193 {
14194 int size;
14195
14196 if (mode == DImode || TARGET_64BIT)
14197 size = 8;
14198 else if (mode == HImode && TARGET_PARTIAL_REG_STALL)
14199 size = 2;
14200 else
14201 size = 4;
14202
14203
14204 emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
14205 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
14206 GEN_INT (size))));
14207 }
14208 }
14209
14210
14211
14212
14213
14214 enum reg_class
14215 ix86_preferred_reload_class (x, class)
14216 rtx x;
14217 enum reg_class class;
14218 {
14219 if (GET_CODE (x) == CONST_VECTOR && x != CONST0_RTX (GET_MODE (x)))
14220 return NO_REGS;
14221 if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode)
14222 {
14223
14224 if (SSE_CLASS_P (class))
14225 return NO_REGS;
14226
14227 if (MAYBE_FLOAT_CLASS_P (class) && standard_80387_constant_p (x))
14228 {
14229
14230 if (MAYBE_SSE_CLASS_P (class))
14231 return (reg_class_subset_p (class, GENERAL_REGS)
14232 ? GENERAL_REGS : FLOAT_REGS);
14233 else
14234 return class;
14235 }
14236
14237 if (reg_class_subset_p (class, GENERAL_REGS))
14238 return GENERAL_REGS;
14239
14240 if (MAYBE_FLOAT_CLASS_P (class) || MAYBE_SSE_CLASS_P (class))
14241 return NO_REGS;
14242 }
14243 if (MAYBE_MMX_CLASS_P (class) && CONSTANT_P (x))
14244 return NO_REGS;
14245 if (GET_MODE (x) == QImode && ! reg_class_subset_p (class, Q_REGS))
14246 return Q_REGS;
14247 return class;
14248 }
14249
14250
14251
14252
14253
14254
14255
14256
14257
14258
14259
14260 int
14261 ix86_secondary_memory_needed (class1, class2, mode, strict)
14262 enum reg_class class1, class2;
14263 enum machine_mode mode;
14264 int strict;
14265 {
14266 if (MAYBE_FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class1)
14267 || MAYBE_FLOAT_CLASS_P (class2) != FLOAT_CLASS_P (class2)
14268 || MAYBE_SSE_CLASS_P (class1) != SSE_CLASS_P (class1)
14269 || MAYBE_SSE_CLASS_P (class2) != SSE_CLASS_P (class2)
14270 || MAYBE_MMX_CLASS_P (class1) != MMX_CLASS_P (class1)
14271 || MAYBE_MMX_CLASS_P (class2) != MMX_CLASS_P (class2))
14272 {
14273 if (strict)
14274 abort ();
14275 else
14276 return 1;
14277 }
14278 return (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2)
14279 || (SSE_CLASS_P (class1) != SSE_CLASS_P (class2)
14280 && (mode) != SImode)
14281 || (MMX_CLASS_P (class1) != MMX_CLASS_P (class2)
14282 && (mode) != SImode));
14283 }
14284
14285
14286
14287
14288
14289
14290 int
14291 ix86_register_move_cost (mode, class1, class2)
14292 enum machine_mode mode;
14293 enum reg_class class1, class2;
14294 {
14295
14296
14297
14298
14299 if (ix86_secondary_memory_needed (class1, class2, mode, 0))
14300 {
14301 int cost = 1;
14302
14303 cost += MAX (MEMORY_MOVE_COST (mode, class1, 0),
14304 MEMORY_MOVE_COST (mode, class1, 1));
14305 cost += MAX (MEMORY_MOVE_COST (mode, class2, 0),
14306 MEMORY_MOVE_COST (mode, class2, 1));
14307
14308
14309
14310
14311 if (CLASS_MAX_NREGS (class1, mode) > CLASS_MAX_NREGS (class2, mode))
14312 cost += 20;
14313
14314
14315
14316 if ((MMX_CLASS_P (class1) && MAYBE_FLOAT_CLASS_P (class2))
14317 || (MMX_CLASS_P (class2) && MAYBE_FLOAT_CLASS_P (class1)))
14318 cost += 20;
14319
14320 return cost;
14321 }
14322
14323
14324 if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2)
14325 || SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
14326 return ix86_cost->mmxsse_to_integer;
14327 if (MAYBE_FLOAT_CLASS_P (class1))
14328 return ix86_cost->fp_move;
14329 if (MAYBE_SSE_CLASS_P (class1))
14330 return ix86_cost->sse_move;
14331 if (MAYBE_MMX_CLASS_P (class1))
14332 return ix86_cost->mmx_move;
14333 return 2;
14334 }
14335
14336
14337 int
14338 ix86_hard_regno_mode_ok (regno, mode)
14339 int regno;
14340 enum machine_mode mode;
14341 {
14342
14343 if (CC_REGNO_P (regno))
14344 return GET_MODE_CLASS (mode) == MODE_CC;
14345 if (GET_MODE_CLASS (mode) == MODE_CC
14346 || GET_MODE_CLASS (mode) == MODE_RANDOM
14347 || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
14348 return 0;
14349 if (FP_REGNO_P (regno))
14350 return VALID_FP_MODE_P (mode);
14351 if (SSE_REGNO_P (regno))
14352 return (TARGET_SSE ? VALID_SSE_REG_MODE (mode) : 0);
14353 if (MMX_REGNO_P (regno))
14354 return (TARGET_MMX
14355 ? VALID_MMX_REG_MODE (mode) || VALID_MMX_REG_MODE_3DNOW (mode) : 0);
14356
14357
14358 if (!VALID_INT_MODE_P (mode) && !VALID_FP_MODE_P (mode))
14359 return 0;
14360
14361
14362 if (regno < 4 || mode != QImode || TARGET_64BIT)
14363 return 1;
14364 return reload_in_progress || reload_completed || !TARGET_PARTIAL_REG_STALL;
14365 }
14366
14367
14368
14369
14370
14371
14372
14373
14374
14375
14376
14377
14378 int
14379 ix86_memory_move_cost (mode, class, in)
14380 enum machine_mode mode;
14381 enum reg_class class;
14382 int in;
14383 {
14384 if (FLOAT_CLASS_P (class))
14385 {
14386 int index;
14387 switch (mode)
14388 {
14389 case SFmode:
14390 index = 0;
14391 break;
14392 case DFmode:
14393 index = 1;
14394 break;
14395 case XFmode:
14396 case TFmode:
14397 index = 2;
14398 break;
14399 default:
14400 return 100;
14401 }
14402 return in ? ix86_cost->fp_load [index] : ix86_cost->fp_store [index];
14403 }
14404 if (SSE_CLASS_P (class))
14405 {
14406 int index;
14407 switch (GET_MODE_SIZE (mode))
14408 {
14409 case 4:
14410 index = 0;
14411 break;
14412 case 8:
14413 index = 1;
14414 break;
14415 case 16:
14416 index = 2;
14417 break;
14418 default:
14419 return 100;
14420 }
14421 return in ? ix86_cost->sse_load [index] : ix86_cost->sse_store [index];
14422 }
14423 if (MMX_CLASS_P (class))
14424 {
14425 int index;
14426 switch (GET_MODE_SIZE (mode))
14427 {
14428 case 4:
14429 index = 0;
14430 break;
14431 case 8:
14432 index = 1;
14433 break;
14434 default:
14435 return 100;
14436 }
14437 return in ? ix86_cost->mmx_load [index] : ix86_cost->mmx_store [index];
14438 }
14439 switch (GET_MODE_SIZE (mode))
14440 {
14441 case 1:
14442 if (in)
14443 return (Q_CLASS_P (class) ? ix86_cost->int_load[0]
14444 : ix86_cost->movzbl_load);
14445 else
14446 return (Q_CLASS_P (class) ? ix86_cost->int_store[0]
14447 : ix86_cost->int_store[0] + 4);
14448 break;
14449 case 2:
14450 return in ? ix86_cost->int_load[1] : ix86_cost->int_store[1];
14451 default:
14452
14453 if (mode == TFmode)
14454 mode = XFmode;
14455 return ((in ? ix86_cost->int_load[2] : ix86_cost->int_store[2])
14456 * ((int) GET_MODE_SIZE (mode)
14457 + UNITS_PER_WORD -1 ) / UNITS_PER_WORD);
14458 }
14459 }
14460
14461 #if defined (DO_GLOBAL_CTORS_BODY) && defined (HAS_INIT_SECTION)
14462 static void
14463 ix86_svr3_asm_out_constructor (symbol, priority)
14464 rtx symbol;
14465 int priority ATTRIBUTE_UNUSED;
14466 {
14467 init_section ();
14468 fputs ("\tpushl $", asm_out_file);
14469 assemble_name (asm_out_file, XSTR (symbol, 0));
14470 fputc ('\n', asm_out_file);
14471 }
14472 #endif
14473
14474 #if TARGET_MACHO
14475
14476 static int current_machopic_label_num;
14477
14478
14479
14480
14481 void
14482 machopic_output_stub (file, symb, stub)
14483 FILE *file;
14484 const char *symb, *stub;
14485 {
14486 unsigned int length;
14487 char *binder_name, *symbol_name, lazy_ptr_name[32];
14488 int label = ++current_machopic_label_num;
14489
14490
14491 symb = (*targetm.strip_name_encoding) (symb);
14492
14493 length = strlen (stub);
14494 binder_name = alloca (length + 32);
14495 GEN_BINDER_NAME_FOR_STUB (binder_name, stub, length);
14496
14497 length = strlen (symb);
14498 symbol_name = alloca (length + 32);
14499 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
14500
14501 sprintf (lazy_ptr_name, "L%d$lz", label);
14502
14503 if (MACHOPIC_PURE)
14504 machopic_picsymbol_stub_section ();
14505 else
14506 machopic_symbol_stub_section ();
14507
14508 fprintf (file, "%s:\n", stub);
14509 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
14510
14511 if (MACHOPIC_PURE)
14512 {
14513 fprintf (file, "\tcall LPC$%d\nLPC$%d:\tpopl %%eax\n", label, label);
14514 fprintf (file, "\tmovl %s-LPC$%d(%%eax),%%edx\n", lazy_ptr_name, label);
14515 fprintf (file, "\tjmp %%edx\n");
14516 }
14517 else
14518 fprintf (file, "\tjmp *%s\n", lazy_ptr_name);
14519
14520 fprintf (file, "%s:\n", binder_name);
14521
14522 if (MACHOPIC_PURE)
14523 {
14524 fprintf (file, "\tlea %s-LPC$%d(%%eax),%%eax\n", lazy_ptr_name, label);
14525 fprintf (file, "\tpushl %%eax\n");
14526 }
14527 else
14528 fprintf (file, "\t pushl $%s\n", lazy_ptr_name);
14529
14530 fprintf (file, "\tjmp dyld_stub_binding_helper\n");
14531
14532 machopic_lazy_symbol_ptr_section ();
14533 fprintf (file, "%s:\n", lazy_ptr_name);
14534 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
14535 fprintf (file, "\t.long %s\n", binder_name);
14536 }
14537 #endif
14538
14539
14540
14541 void
14542 x86_order_regs_for_local_alloc ()
14543 {
14544 int pos = 0;
14545 int i;
14546
14547
14548 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
14549 if (GENERAL_REGNO_P (i) && call_used_regs[i])
14550 reg_alloc_order [pos++] = i;
14551
14552
14553 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
14554 if (GENERAL_REGNO_P (i) && !call_used_regs[i])
14555 reg_alloc_order [pos++] = i;
14556
14557
14558
14559 if (!TARGET_SSE_MATH)
14560 for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
14561 reg_alloc_order [pos++] = i;
14562
14563
14564 for (i = FIRST_SSE_REG; i <= LAST_SSE_REG; i++)
14565 reg_alloc_order [pos++] = i;
14566 for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
14567 reg_alloc_order [pos++] = i;
14568
14569
14570 if (TARGET_SSE_MATH)
14571 for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
14572 reg_alloc_order [pos++] = i;
14573
14574 for (i = FIRST_MMX_REG; i <= LAST_MMX_REG; i++)
14575 reg_alloc_order [pos++] = i;
14576
14577
14578
14579 while (pos < FIRST_PSEUDO_REGISTER)
14580 reg_alloc_order [pos++] = 0;
14581 }
14582
14583
14584
14585
14586 static rtx
14587 x86_this_parameter (function)
14588 tree function;
14589 {
14590 tree type = TREE_TYPE (function);
14591
14592 if (TARGET_64BIT)
14593 {
14594 int n = aggregate_value_p (TREE_TYPE (type)) != 0;
14595 return gen_rtx_REG (DImode, x86_64_int_parameter_registers[n]);
14596 }
14597
14598 if (ix86_fntype_regparm (type) > 0)
14599 {
14600 tree parm;
14601
14602 parm = TYPE_ARG_TYPES (type);
14603
14604
14605 for (; parm; parm = TREE_CHAIN (parm))
14606 if (TREE_VALUE (parm) == void_type_node)
14607 break;
14608
14609 if (parm)
14610 return gen_rtx_REG (SImode, 0);
14611 }
14612
14613 if (aggregate_value_p (TREE_TYPE (type)))
14614 return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 8));
14615 else
14616 return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 4));
14617 }
14618
14619
14620
14621 static bool
14622 x86_can_output_mi_thunk (thunk, delta, vcall_offset, function)
14623 tree thunk ATTRIBUTE_UNUSED;
14624 HOST_WIDE_INT delta ATTRIBUTE_UNUSED;
14625 HOST_WIDE_INT vcall_offset;
14626 tree function;
14627 {
14628
14629 if (TARGET_64BIT)
14630 return true;
14631
14632
14633 if (ix86_fntype_regparm (TREE_TYPE (function)) < 3)
14634 return true;
14635
14636
14637 if (vcall_offset)
14638 return false;
14639
14640
14641 if (flag_pic && !(*targetm.binds_local_p) (function))
14642 return false;
14643
14644
14645 return true;
14646 }
14647
14648
14649
14650
14651
14652
14653
14654 static void
14655 x86_output_mi_thunk (file, thunk, delta, vcall_offset, function)
14656 FILE *file ATTRIBUTE_UNUSED;
14657 tree thunk ATTRIBUTE_UNUSED;
14658 HOST_WIDE_INT delta;
14659 HOST_WIDE_INT vcall_offset;
14660 tree function;
14661 {
14662 rtx xops[3];
14663 rtx this = x86_this_parameter (function);
14664 rtx this_reg, tmp;
14665
14666
14667
14668 if (REG_P (this))
14669 this_reg = this;
14670 else if (vcall_offset)
14671 {
14672
14673 xops[0] = this;
14674 xops[1] = this_reg = gen_rtx_REG (Pmode, 0);
14675 output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops);
14676 }
14677 else
14678 this_reg = NULL_RTX;
14679
14680
14681 if (delta)
14682 {
14683 xops[0] = GEN_INT (delta);
14684 xops[1] = this_reg ? this_reg : this;
14685 if (TARGET_64BIT)
14686 {
14687 if (!x86_64_general_operand (xops[0], DImode))
14688 {
14689 tmp = gen_rtx_REG (DImode, FIRST_REX_INT_REG + 2 );
14690 xops[1] = tmp;
14691 output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", xops);
14692 xops[0] = tmp;
14693 xops[1] = this;
14694 }
14695 output_asm_insn ("add{q}\t{%0, %1|%1, %0}", xops);
14696 }
14697 else
14698 output_asm_insn ("add{l}\t{%0, %1|%1, %0}", xops);
14699 }
14700
14701
14702 if (vcall_offset)
14703 {
14704 if (TARGET_64BIT)
14705 tmp = gen_rtx_REG (DImode, FIRST_REX_INT_REG + 2 );
14706 else
14707 tmp = gen_rtx_REG (SImode, 2 );
14708
14709 xops[0] = gen_rtx_MEM (Pmode, this_reg);
14710 xops[1] = tmp;
14711 if (TARGET_64BIT)
14712 output_asm_insn ("mov{q}\t{%0, %1|%1, %0}", xops);
14713 else
14714 output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops);
14715
14716
14717 xops[0] = gen_rtx_MEM (Pmode, plus_constant (tmp, vcall_offset));
14718 if (TARGET_64BIT && !memory_operand (xops[0], Pmode))
14719 {
14720 rtx tmp2 = gen_rtx_REG (DImode, FIRST_REX_INT_REG + 3 );
14721 xops[0] = GEN_INT (vcall_offset);
14722 xops[1] = tmp2;
14723 output_asm_insn ("mov{q}\t{%0, %1|%1, %0}", xops);
14724 xops[0] = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, tmp, tmp2));
14725 }
14726 xops[1] = this_reg;
14727 if (TARGET_64BIT)
14728 output_asm_insn ("add{q}\t{%0, %1|%1, %0}", xops);
14729 else
14730 output_asm_insn ("add{l}\t{%0, %1|%1, %0}", xops);
14731 }
14732
14733
14734 if (this_reg && this_reg != this)
14735 {
14736 xops[0] = this_reg;
14737 xops[1] = this;
14738 output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops);
14739 }
14740
14741 xops[0] = XEXP (DECL_RTL (function), 0);
14742 if (TARGET_64BIT)
14743 {
14744 if (!flag_pic || (*targetm.binds_local_p) (function))
14745 output_asm_insn ("jmp\t%P0", xops);
14746 else
14747 {
14748 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, xops[0]), UNSPEC_GOTPCREL);
14749 tmp = gen_rtx_CONST (Pmode, tmp);
14750 tmp = gen_rtx_MEM (QImode, tmp);
14751 xops[0] = tmp;
14752 output_asm_insn ("jmp\t%A0", xops);
14753 }
14754 }
14755 else
14756 {
14757 if (!flag_pic || (*targetm.binds_local_p) (function))
14758 output_asm_insn ("jmp\t%P0", xops);
14759 else
14760 {
14761 tmp = gen_rtx_REG (SImode, 2 );
14762 output_set_got (tmp);
14763
14764 xops[1] = tmp;
14765 output_asm_insn ("mov{l}\t{%0@GOT(%1), %1|%1, %0@GOT[%1]}", xops);
14766 output_asm_insn ("jmp\t{*}%1", xops);
14767 }
14768 }
14769 }
14770
14771 int
14772 x86_field_alignment (field, computed)
14773 tree field;
14774 int computed;
14775 {
14776 enum machine_mode mode;
14777 tree type = TREE_TYPE (field);
14778
14779 if (TARGET_64BIT || TARGET_ALIGN_DOUBLE)
14780 return computed;
14781 mode = TYPE_MODE (TREE_CODE (type) == ARRAY_TYPE
14782 ? get_inner_array_type (type) : type);
14783 if (mode == DFmode || mode == DCmode
14784 || GET_MODE_CLASS (mode) == MODE_INT
14785 || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
14786 return MIN (32, computed);
14787 return computed;
14788 }
14789
14790
14791
14792 void
14793 x86_function_profiler (file, labelno)
14794 FILE *file;
14795 int labelno ATTRIBUTE_UNUSED;
14796 {
14797 if (TARGET_64BIT)
14798 if (flag_pic)
14799 {
14800 #ifndef NO_PROFILE_COUNTERS
14801 fprintf (file, "\tleaq\t%sP%d@(%%rip),%%r11\n", LPREFIX, labelno);
14802 #endif
14803 fprintf (file, "\tcall\t*%s@GOTPCREL(%%rip)\n", MCOUNT_NAME);
14804 }
14805 else
14806 {
14807 #ifndef NO_PROFILE_COUNTERS
14808 fprintf (file, "\tmovq\t$%sP%d,%%r11\n", LPREFIX, labelno);
14809 #endif
14810 fprintf (file, "\tcall\t%s\n", MCOUNT_NAME);
14811 }
14812 else if (flag_pic)
14813 {
14814 #ifndef NO_PROFILE_COUNTERS
14815 fprintf (file, "\tleal\t%sP%d@GOTOFF(%%ebx),%%%s\n",
14816 LPREFIX, labelno, PROFILE_COUNT_REGISTER);
14817 #endif
14818 fprintf (file, "\tcall\t*%s@GOT(%%ebx)\n", MCOUNT_NAME);
14819 }
14820 else
14821 {
14822 #ifndef NO_PROFILE_COUNTERS
14823 fprintf (file, "\tmovl\t$%sP%d,%%%s\n", LPREFIX, labelno,
14824 PROFILE_COUNT_REGISTER);
14825 #endif
14826 fprintf (file, "\tcall\t%s\n", MCOUNT_NAME);
14827 }
14828 }
14829
14830
14831
14832
14833
14834
14835 void
14836 x86_machine_dependent_reorg (first)
14837 rtx first ATTRIBUTE_UNUSED;
14838 {
14839 edge e;
14840
14841 if (!TARGET_ATHLON || !optimize || optimize_size)
14842 return;
14843 for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
14844 {
14845 basic_block bb = e->src;
14846 rtx ret = bb->end;
14847 rtx prev;
14848 bool insert = false;
14849
14850 if (!returnjump_p (ret) || !maybe_hot_bb_p (bb))
14851 continue;
14852 prev = prev_nonnote_insn (ret);
14853 if (prev && GET_CODE (prev) == CODE_LABEL)
14854 {
14855 edge e;
14856 for (e = bb->pred; e; e = e->pred_next)
14857 if (EDGE_FREQUENCY (e) && e->src->index > 0
14858 && !(e->flags & EDGE_FALLTHRU))
14859 insert = 1;
14860 }
14861 if (!insert)
14862 {
14863 prev = prev_real_insn (ret);
14864 if (prev && GET_CODE (prev) == JUMP_INSN
14865 && any_condjump_p (prev))
14866 insert = 1;
14867 }
14868 if (insert)
14869 emit_insn_before (gen_nop (), ret);
14870 }
14871 }
14872
14873 #include "gt-i386.h"