comparison gcc/config/pa/pa.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* Subroutines for insn-output.c for HPPA. 1 /* Subroutines for insn-output.c for HPPA.
2 Copyright (C) 1992-2018 Free Software Foundation, Inc. 2 Copyright (C) 1992-2020 Free Software Foundation, Inc.
3 Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.c 3 Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.c
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify 7 GCC is free software; you can redistribute it and/or modify
105 static int pa_can_combine_p (rtx_insn *, rtx_insn *, rtx_insn *, int, rtx, 105 static int pa_can_combine_p (rtx_insn *, rtx_insn *, rtx_insn *, int, rtx,
106 rtx, rtx); 106 rtx, rtx);
107 static bool forward_branch_p (rtx_insn *); 107 static bool forward_branch_p (rtx_insn *);
108 static void compute_zdepwi_operands (unsigned HOST_WIDE_INT, unsigned *); 108 static void compute_zdepwi_operands (unsigned HOST_WIDE_INT, unsigned *);
109 static void compute_zdepdi_operands (unsigned HOST_WIDE_INT, unsigned *); 109 static void compute_zdepdi_operands (unsigned HOST_WIDE_INT, unsigned *);
110 static int compute_movmem_length (rtx_insn *); 110 static int compute_cpymem_length (rtx_insn *);
111 static int compute_clrmem_length (rtx_insn *); 111 static int compute_clrmem_length (rtx_insn *);
112 static bool pa_assemble_integer (rtx, unsigned int, int); 112 static bool pa_assemble_integer (rtx, unsigned int, int);
113 static void remove_useless_addtr_insns (int); 113 static void remove_useless_addtr_insns (int);
114 static void store_reg (int, HOST_WIDE_INT, int); 114 static void store_reg (int, HOST_WIDE_INT, int);
115 static void store_reg_modify (int, int, HOST_WIDE_INT); 115 static void store_reg_modify (int, int, HOST_WIDE_INT);
116 static void load_reg (int, HOST_WIDE_INT, int); 116 static void load_reg (int, HOST_WIDE_INT, int);
117 static void set_reg_plus_d (int, int, HOST_WIDE_INT, int); 117 static void set_reg_plus_d (int, int, HOST_WIDE_INT, int);
118 static rtx pa_function_value (const_tree, const_tree, bool); 118 static rtx pa_function_value (const_tree, const_tree, bool);
119 static rtx pa_libcall_value (machine_mode, const_rtx); 119 static rtx pa_libcall_value (machine_mode, const_rtx);
120 static bool pa_function_value_regno_p (const unsigned int); 120 static bool pa_function_value_regno_p (const unsigned int);
121 static void pa_output_function_prologue (FILE *); 121 static void pa_output_function_prologue (FILE *) ATTRIBUTE_UNUSED;
122 static void pa_linux_output_function_prologue (FILE *) ATTRIBUTE_UNUSED;
122 static void update_total_code_bytes (unsigned int); 123 static void update_total_code_bytes (unsigned int);
123 static void pa_output_function_epilogue (FILE *); 124 static void pa_output_function_epilogue (FILE *);
124 static int pa_adjust_cost (rtx_insn *, int, rtx_insn *, int, unsigned int); 125 static int pa_adjust_cost (rtx_insn *, int, rtx_insn *, int, unsigned int);
125 static int pa_issue_rate (void); 126 static int pa_issue_rate (void);
126 static int pa_reloc_rw_mask (void); 127 static int pa_reloc_rw_mask (void);
161 static void output_deferred_plabels (void); 162 static void output_deferred_plabels (void);
162 static void output_deferred_profile_counters (void) ATTRIBUTE_UNUSED; 163 static void output_deferred_profile_counters (void) ATTRIBUTE_UNUSED;
163 static void pa_file_end (void); 164 static void pa_file_end (void);
164 static void pa_init_libfuncs (void); 165 static void pa_init_libfuncs (void);
165 static rtx pa_struct_value_rtx (tree, int); 166 static rtx pa_struct_value_rtx (tree, int);
166 static bool pa_pass_by_reference (cumulative_args_t, machine_mode, 167 static bool pa_pass_by_reference (cumulative_args_t,
167 const_tree, bool); 168 const function_arg_info &);
168 static int pa_arg_partial_bytes (cumulative_args_t, machine_mode, 169 static int pa_arg_partial_bytes (cumulative_args_t, const function_arg_info &);
169 tree, bool); 170 static void pa_function_arg_advance (cumulative_args_t,
170 static void pa_function_arg_advance (cumulative_args_t, machine_mode, 171 const function_arg_info &);
171 const_tree, bool); 172 static rtx pa_function_arg (cumulative_args_t, const function_arg_info &);
172 static rtx pa_function_arg (cumulative_args_t, machine_mode,
173 const_tree, bool);
174 static pad_direction pa_function_arg_padding (machine_mode, const_tree); 173 static pad_direction pa_function_arg_padding (machine_mode, const_tree);
175 static unsigned int pa_function_arg_boundary (machine_mode, const_tree); 174 static unsigned int pa_function_arg_boundary (machine_mode, const_tree);
176 static struct machine_function * pa_init_machine_status (void); 175 static struct machine_function * pa_init_machine_status (void);
177 static reg_class_t pa_secondary_reload (bool, rtx, reg_class_t, 176 static reg_class_t pa_secondary_reload (bool, rtx, reg_class_t,
178 machine_mode, 177 machine_mode,
196 static section *pa_function_section (tree, enum node_frequency, bool, bool); 195 static section *pa_function_section (tree, enum node_frequency, bool, bool);
197 static bool pa_cannot_force_const_mem (machine_mode, rtx); 196 static bool pa_cannot_force_const_mem (machine_mode, rtx);
198 static bool pa_legitimate_constant_p (machine_mode, rtx); 197 static bool pa_legitimate_constant_p (machine_mode, rtx);
199 static unsigned int pa_section_type_flags (tree, const char *, int); 198 static unsigned int pa_section_type_flags (tree, const char *, int);
200 static bool pa_legitimate_address_p (machine_mode, rtx, bool); 199 static bool pa_legitimate_address_p (machine_mode, rtx, bool);
201 static bool pa_callee_copies (cumulative_args_t, machine_mode, 200 static bool pa_callee_copies (cumulative_args_t, const function_arg_info &);
202 const_tree, bool);
203 static unsigned int pa_hard_regno_nregs (unsigned int, machine_mode); 201 static unsigned int pa_hard_regno_nregs (unsigned int, machine_mode);
204 static bool pa_hard_regno_mode_ok (unsigned int, machine_mode); 202 static bool pa_hard_regno_mode_ok (unsigned int, machine_mode);
205 static bool pa_modes_tieable_p (machine_mode, machine_mode); 203 static bool pa_modes_tieable_p (machine_mode, machine_mode);
206 static bool pa_can_change_mode_class (machine_mode, machine_mode, reg_class_t); 204 static bool pa_can_change_mode_class (machine_mode, machine_mode, reg_class_t);
207 static HOST_WIDE_INT pa_starting_frame_offset (void); 205 static HOST_WIDE_INT pa_starting_frame_offset (void);
206 static section* pa_elf_select_rtx_section(machine_mode, rtx, unsigned HOST_WIDE_INT) ATTRIBUTE_UNUSED;
208 207
209 /* The following extra sections are only used for SOM. */ 208 /* The following extra sections are only used for SOM. */
210 static GTY(()) section *som_readonly_data_section; 209 static GTY(()) section *som_readonly_data_section;
211 static GTY(()) section *som_one_only_readonly_data_section; 210 static GTY(()) section *som_one_only_readonly_data_section;
212 static GTY(()) section *som_one_only_data_section; 211 static GTY(()) section *som_one_only_data_section;
260 #undef TARGET_ASM_UNALIGNED_DI_OP 259 #undef TARGET_ASM_UNALIGNED_DI_OP
261 #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP 260 #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
262 #undef TARGET_ASM_INTEGER 261 #undef TARGET_ASM_INTEGER
263 #define TARGET_ASM_INTEGER pa_assemble_integer 262 #define TARGET_ASM_INTEGER pa_assemble_integer
264 263
265 #undef TARGET_ASM_FUNCTION_PROLOGUE
266 #define TARGET_ASM_FUNCTION_PROLOGUE pa_output_function_prologue
267 #undef TARGET_ASM_FUNCTION_EPILOGUE 264 #undef TARGET_ASM_FUNCTION_EPILOGUE
268 #define TARGET_ASM_FUNCTION_EPILOGUE pa_output_function_epilogue 265 #define TARGET_ASM_FUNCTION_EPILOGUE pa_output_function_epilogue
269 266
270 #undef TARGET_FUNCTION_VALUE 267 #undef TARGET_FUNCTION_VALUE
271 #define TARGET_FUNCTION_VALUE pa_function_value 268 #define TARGET_FUNCTION_VALUE pa_function_value
451 while (1) 448 while (1)
452 { 449 {
453 dash = strchr (str, '-'); 450 dash = strchr (str, '-');
454 if (!dash) 451 if (!dash)
455 { 452 {
456 warning (0, "value of -mfixed-range must have form REG1-REG2"); 453 warning (0, "value of %<-mfixed-range%> must have form REG1-REG2");
457 return; 454 return;
458 } 455 }
459 *dash = '\0'; 456 *dash = '\0';
460 457
461 comma = strchr (dash + 1, ','); 458 comma = strchr (dash + 1, ',');
537 warning (0, "PIC code generation is not compatible with fast indirect calls"); 534 warning (0, "PIC code generation is not compatible with fast indirect calls");
538 } 535 }
539 536
540 if (! TARGET_GAS && write_symbols != NO_DEBUG) 537 if (! TARGET_GAS && write_symbols != NO_DEBUG)
541 { 538 {
542 warning (0, "-g is only supported when using GAS on this processor,"); 539 warning (0, "%<-g%> is only supported when using GAS on this processor");
543 warning (0, "-g option disabled"); 540 warning (0, "%<-g%> option disabled");
544 write_symbols = NO_DEBUG; 541 write_symbols = NO_DEBUG;
545 } 542 }
546 543
547 /* We only support the "big PIC" model now. And we always generate PIC 544 /* We only support the "big PIC" model now. And we always generate PIC
548 code when in 64bit mode. */ 545 code when in 64bit mode. */
552 /* Disable -freorder-blocks-and-partition as we don't support hot and 549 /* Disable -freorder-blocks-and-partition as we don't support hot and
553 cold partitioning. */ 550 cold partitioning. */
554 if (flag_reorder_blocks_and_partition) 551 if (flag_reorder_blocks_and_partition)
555 { 552 {
556 inform (input_location, 553 inform (input_location,
557 "-freorder-blocks-and-partition does not work " 554 "%<-freorder-blocks-and-partition%> does not work "
558 "on this architecture"); 555 "on this architecture");
559 flag_reorder_blocks_and_partition = 0; 556 flag_reorder_blocks_and_partition = 0;
560 flag_reorder_blocks = 1; 557 flag_reorder_blocks = 1;
561 } 558 }
562 559
563 /* We can't guarantee that .dword is available for 32-bit targets. */ 560 /* We can't guarantee that .dword is available for 32-bit targets. */
652 pa_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, 649 pa_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
653 machine_mode mode ATTRIBUTE_UNUSED, 650 machine_mode mode ATTRIBUTE_UNUSED,
654 int ignore ATTRIBUTE_UNUSED) 651 int ignore ATTRIBUTE_UNUSED)
655 { 652 {
656 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 653 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
657 unsigned int fcode = DECL_FUNCTION_CODE (fndecl); 654 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
658 655
659 switch (fcode) 656 switch (fcode)
660 { 657 {
661 case PA_BUILTIN_FABSQ: 658 case PA_BUILTIN_FABSQ:
662 case PA_BUILTIN_COPYSIGNQ: 659 case PA_BUILTIN_COPYSIGNQ:
1133 newoffset = (offset & ~ mask); 1130 newoffset = (offset & ~ mask);
1134 1131
1135 /* If the newoffset will not fit in 14 bits (ldo), then 1132 /* If the newoffset will not fit in 14 bits (ldo), then
1136 handling this would take 4 or 5 instructions (2 to load 1133 handling this would take 4 or 5 instructions (2 to load
1137 the SYMBOL_REF + 1 or 2 to load the newoffset + 1 to 1134 the SYMBOL_REF + 1 or 2 to load the newoffset + 1 to
1138 add the new offset and the SYMBOL_REF.) Combine can 1135 add the new offset and the SYMBOL_REF.) Combine cannot
1139 not handle 4->2 or 5->2 combinations, so do not create 1136 handle 4->2 or 5->2 combinations, so do not create
1140 them. */ 1137 them. */
1141 if (! VAL_14_BITS_P (newoffset) 1138 if (! VAL_14_BITS_P (newoffset)
1142 && GET_CODE (XEXP (x, 0)) == SYMBOL_REF) 1139 && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
1143 { 1140 {
1144 rtx const_part = plus_constant (Pmode, XEXP (x, 0), newoffset); 1141 rtx const_part = plus_constant (Pmode, XEXP (x, 0), newoffset);
2984 2981
2985 Basic structure is the same as emit_block_move, except that we 2982 Basic structure is the same as emit_block_move, except that we
2986 count insns rather than emit them. */ 2983 count insns rather than emit them. */
2987 2984
2988 static int 2985 static int
2989 compute_movmem_length (rtx_insn *insn) 2986 compute_cpymem_length (rtx_insn *insn)
2990 { 2987 {
2991 rtx pat = PATTERN (insn); 2988 rtx pat = PATTERN (insn);
2992 unsigned int align = INTVAL (XEXP (XVECEXP (pat, 0, 7), 0)); 2989 unsigned int align = INTVAL (XEXP (XVECEXP (pat, 0, 7), 0));
2993 unsigned long n_bytes = INTVAL (XEXP (XVECEXP (pat, 0, 6), 0)); 2990 unsigned long n_bytes = INTVAL (XEXP (XVECEXP (pat, 0, 6), 0));
2994 unsigned int n_insns = 0; 2991 unsigned int n_insns = 0;
3840 /* Finally, round to the preferred stack boundary. */ 3837 /* Finally, round to the preferred stack boundary. */
3841 return ((size + PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1) 3838 return ((size + PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1)
3842 & ~(PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1)); 3839 & ~(PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1));
3843 } 3840 }
3844 3841
3845 /* On HP-PA, move-double insns between fpu and cpu need an 8-byte block 3842 /* Output function label, and associated .PROC and .CALLINFO statements. */
3846 of memory. If any fpu reg is used in the function, we allocate 3843
3847 such a block here, at the bottom of the frame, just in case it's needed. 3844 void
3848 3845 pa_output_function_label (FILE *file)
3849 If this function is a leaf procedure, then we may choose not
3850 to do a "save" insn. The decision about whether or not
3851 to do this is made in regclass.c. */
3852
3853 static void
3854 pa_output_function_prologue (FILE *file)
3855 { 3846 {
3856 /* The function's label and associated .PROC must never be 3847 /* The function's label and associated .PROC must never be
3857 separated and must be output *after* any profiling declarations 3848 separated and must be output *after* any profiling declarations
3858 to avoid changing spaces/subspaces within a procedure. */ 3849 to avoid changing spaces/subspaces within a procedure. */
3859 ASM_OUTPUT_LABEL (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); 3850 ASM_OUTPUT_LABEL (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
3895 3886
3896 if (fr_saved) 3887 if (fr_saved)
3897 fprintf (file, ",ENTRY_FR=%d", fr_saved + 11); 3888 fprintf (file, ",ENTRY_FR=%d", fr_saved + 11);
3898 3889
3899 fputs ("\n\t.ENTRY\n", file); 3890 fputs ("\n\t.ENTRY\n", file);
3900 3891 }
3892
3893 /* Output function prologue. */
3894
3895 static void
3896 pa_output_function_prologue (FILE *file)
3897 {
3898 pa_output_function_label (file);
3899 remove_useless_addtr_insns (0);
3900 }
3901
3902 /* The label is output by ASM_DECLARE_FUNCTION_NAME on linux. */
3903
3904 static void
3905 pa_linux_output_function_prologue (FILE *file ATTRIBUTE_UNUSED)
3906 {
3901 remove_useless_addtr_insns (0); 3907 remove_useless_addtr_insns (0);
3902 } 3908 }
3903 3909
3904 void 3910 void
3905 pa_expand_prologue (void) 3911 pa_expand_prologue (void)
4011 and allocating the stack frame at the same time. If so, just 4017 and allocating the stack frame at the same time. If so, just
4012 make a note of it and defer allocating the frame until saving 4018 make a note of it and defer allocating the frame until saving
4013 the callee registers. */ 4019 the callee registers. */
4014 if (VAL_14_BITS_P (actual_fsize) && local_fsize == 0) 4020 if (VAL_14_BITS_P (actual_fsize) && local_fsize == 0)
4015 merge_sp_adjust_with_store = 1; 4021 merge_sp_adjust_with_store = 1;
4016 /* Can not optimize. Adjust the stack frame by actual_fsize 4022 /* Cannot optimize. Adjust the stack frame by actual_fsize
4017 bytes. */ 4023 bytes. */
4018 else 4024 else
4019 set_reg_plus_d (STACK_POINTER_REGNUM, STACK_POINTER_REGNUM, 4025 set_reg_plus_d (STACK_POINTER_REGNUM, STACK_POINTER_REGNUM,
4020 actual_fsize, 1); 4026 actual_fsize, 1);
4021 } 4027 }
4046 offset += UNITS_PER_WORD; 4052 offset += UNITS_PER_WORD;
4047 } 4053 }
4048 } 4054 }
4049 4055
4050 for (i = 18; i >= 4; i--) 4056 for (i = 18; i >= 4; i--)
4051 if (df_regs_ever_live_p (i) && ! call_used_regs[i]) 4057 if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i))
4052 { 4058 {
4053 store_reg (i, offset, HARD_FRAME_POINTER_REGNUM); 4059 store_reg (i, offset, HARD_FRAME_POINTER_REGNUM);
4054 offset += UNITS_PER_WORD; 4060 offset += UNITS_PER_WORD;
4055 gr_saved++; 4061 gr_saved++;
4056 } 4062 }
4086 offset += UNITS_PER_WORD; 4092 offset += UNITS_PER_WORD;
4087 } 4093 }
4088 } 4094 }
4089 4095
4090 for (i = 18; i >= 3; i--) 4096 for (i = 18; i >= 3; i--)
4091 if (df_regs_ever_live_p (i) && ! call_used_regs[i]) 4097 if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i))
4092 { 4098 {
4093 /* If merge_sp_adjust_with_store is nonzero, then we can 4099 /* If merge_sp_adjust_with_store is nonzero, then we can
4094 optimize the first GR save. */ 4100 optimize the first GR save. */
4095 if (merge_sp_adjust_with_store) 4101 if (merge_sp_adjust_with_store)
4096 { 4102 {
4387 offset += UNITS_PER_WORD; 4393 offset += UNITS_PER_WORD;
4388 } 4394 }
4389 } 4395 }
4390 4396
4391 for (i = 18; i >= 4; i--) 4397 for (i = 18; i >= 4; i--)
4392 if (df_regs_ever_live_p (i) && ! call_used_regs[i]) 4398 if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i))
4393 { 4399 {
4394 load_reg (i, offset, HARD_FRAME_POINTER_REGNUM); 4400 load_reg (i, offset, HARD_FRAME_POINTER_REGNUM);
4395 offset += UNITS_PER_WORD; 4401 offset += UNITS_PER_WORD;
4396 } 4402 }
4397 } 4403 }
4424 } 4430 }
4425 } 4431 }
4426 4432
4427 for (i = 18; i >= 3; i--) 4433 for (i = 18; i >= 3; i--)
4428 { 4434 {
4429 if (df_regs_ever_live_p (i) && ! call_used_regs[i]) 4435 if (df_regs_ever_live_p (i) && !call_used_or_fixed_reg_p (i))
4430 { 4436 {
4431 /* Only for the first load. 4437 /* Only for the first load.
4432 merge_sp_adjust_with_load holds the register load 4438 merge_sp_adjust_with_load holds the register load
4433 with which we will merge the sp adjustment. */ 4439 with which we will merge the sp adjustment. */
4434 if (merge_sp_adjust_with_load == 0 4440 if (merge_sp_adjust_with_load == 0
4567 } 4573 }
4568 4574
4569 void 4575 void
4570 hppa_profile_hook (int label_no) 4576 hppa_profile_hook (int label_no)
4571 { 4577 {
4572 /* We use SImode for the address of the function in both 32 and
4573 64-bit code to avoid having to provide DImode versions of the
4574 lcla2 and load_offset_label_address insn patterns. */
4575 rtx reg = gen_reg_rtx (SImode);
4576 rtx_code_label *label_rtx = gen_label_rtx (); 4578 rtx_code_label *label_rtx = gen_label_rtx ();
4577 int reg_parm_stack_space = REG_PARM_STACK_SPACE (NULL_TREE); 4579 int reg_parm_stack_space = REG_PARM_STACK_SPACE (NULL_TREE);
4578 rtx arg_bytes, begin_label_rtx, mcount, sym; 4580 rtx arg_bytes, begin_label_rtx, mcount, sym;
4579 rtx_insn *call_insn; 4581 rtx_insn *call_insn;
4580 char begin_label_name[16]; 4582 char begin_label_name[16];
4602 emit_move_insn (gen_rtx_REG (word_mode, 26), gen_rtx_REG (word_mode, 2)); 4604 emit_move_insn (gen_rtx_REG (word_mode, 26), gen_rtx_REG (word_mode, 2));
4603 4605
4604 if (!use_mcount_pcrel_call) 4606 if (!use_mcount_pcrel_call)
4605 { 4607 {
4606 /* The address of the function is loaded into %r25 with an instruction- 4608 /* The address of the function is loaded into %r25 with an instruction-
4607 relative sequence that avoids the use of relocations. The sequence 4609 relative sequence that avoids the use of relocations. We use SImode
4608 is split so that the load_offset_label_address instruction can 4610 for the address of the function in both 32 and 64-bit code to avoid
4609 occupy the delay slot of the call to _mcount. */ 4611 having to provide DImode versions of the lcla2 pattern. */
4610 if (TARGET_PA_20) 4612 if (TARGET_PA_20)
4611 emit_insn (gen_lcla2 (reg, label_rtx)); 4613 emit_insn (gen_lcla2 (gen_rtx_REG (SImode, 25), label_rtx));
4612 else 4614 else
4613 emit_insn (gen_lcla1 (reg, label_rtx)); 4615 emit_insn (gen_lcla1 (gen_rtx_REG (SImode, 25), label_rtx));
4614
4615 emit_insn (gen_load_offset_label_address (gen_rtx_REG (SImode, 25),
4616 reg,
4617 begin_label_rtx,
4618 label_rtx));
4619 } 4616 }
4620 4617
4621 if (!NO_DEFERRED_PROFILE_COUNTERS) 4618 if (!NO_DEFERRED_PROFILE_COUNTERS)
4622 { 4619 {
4623 rtx count_label_rtx, addr, r24; 4620 rtx count_label_rtx, addr, r24;
5059 && GET_CODE (XVECEXP (pat, 0, 0)) == SET 5056 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
5060 && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 0)) == MEM 5057 && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 0)) == MEM
5061 && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 1)) == MEM 5058 && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 1)) == MEM
5062 && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 0)) == BLKmode 5059 && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 0)) == BLKmode
5063 && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 1)) == BLKmode) 5060 && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 1)) == BLKmode)
5064 length += compute_movmem_length (insn) - 4; 5061 length += compute_cpymem_length (insn) - 4;
5065 /* Block clear pattern. */ 5062 /* Block clear pattern. */
5066 else if (NONJUMP_INSN_P (insn) 5063 else if (NONJUMP_INSN_P (insn)
5067 && GET_CODE (pat) == PARALLEL 5064 && GET_CODE (pat) == PARALLEL
5068 && GET_CODE (XVECEXP (pat, 0, 0)) == SET 5065 && GET_CODE (XVECEXP (pat, 0, 0)) == SET
5069 && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 0)) == MEM 5066 && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 0)) == MEM
6222 support these types, so hopefully there shouldn't be any compatibility 6219 support these types, so hopefully there shouldn't be any compatibility
6223 issues. This may have to be revisited when HP releases a C99 compiler 6220 issues. This may have to be revisited when HP releases a C99 compiler
6224 or updates the ABI. */ 6221 or updates the ABI. */
6225 6222
6226 static bool 6223 static bool
6227 pa_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, 6224 pa_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
6228 machine_mode mode, const_tree type, 6225 {
6229 bool named ATTRIBUTE_UNUSED) 6226 HOST_WIDE_INT size = arg.type_size_in_bytes ();
6230 {
6231 HOST_WIDE_INT size;
6232
6233 if (type)
6234 size = int_size_in_bytes (type);
6235 else
6236 size = GET_MODE_SIZE (mode);
6237
6238 if (TARGET_64BIT) 6227 if (TARGET_64BIT)
6239 return size <= 0; 6228 return size <= 0;
6240 else 6229 else
6241 return size <= 0 || size > 8; 6230 return size <= 0 || size > 8;
6242 } 6231 }
6376 tree valist_type; 6365 tree valist_type;
6377 tree t, u; 6366 tree t, u;
6378 unsigned int size, ofs; 6367 unsigned int size, ofs;
6379 bool indirect; 6368 bool indirect;
6380 6369
6381 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, 0); 6370 indirect = pass_va_arg_by_reference (type);
6382 if (indirect) 6371 if (indirect)
6383 { 6372 {
6384 type = ptr; 6373 type = ptr;
6385 ptr = build_pointer_type (type); 6374 ptr = build_pointer_type (type);
6386 } 6375 }
7855 || distance < MAX_PCREL17F_OFFSET)) 7844 || distance < MAX_PCREL17F_OFFSET))
7856 length += 8; 7845 length += 8;
7857 7846
7858 /* 64-bit plabel sequence. */ 7847 /* 64-bit plabel sequence. */
7859 else if (TARGET_64BIT && !local_call) 7848 else if (TARGET_64BIT && !local_call)
7860 length += sibcall ? 28 : 24; 7849 length += 24;
7861 7850
7862 /* non-pic long absolute branch sequence. */ 7851 /* non-pic long absolute branch sequence. */
7863 else if ((TARGET_LONG_ABS_CALL || local_call) && !flag_pic) 7852 else if ((TARGET_LONG_ABS_CALL || local_call) && !flag_pic)
7864 length += 12; 7853 length += 12;
7865 7854
7927 long pc-relative sequence described in the 64-bit runtime 7916 long pc-relative sequence described in the 64-bit runtime
7928 architecture. So, we use a slightly longer indirect call. */ 7917 architecture. So, we use a slightly longer indirect call. */
7929 xoperands[0] = pa_get_deferred_plabel (call_dest); 7918 xoperands[0] = pa_get_deferred_plabel (call_dest);
7930 xoperands[1] = gen_label_rtx (); 7919 xoperands[1] = gen_label_rtx ();
7931 7920
7932 /* If this isn't a sibcall, we put the load of %r27 into the 7921 /* Put the load of %r27 into the delay slot. We don't need to
7933 delay slot. We can't do this in a sibcall as we don't 7922 do anything when generating fast indirect calls. */
7934 have a second call-clobbered scratch register available. 7923 if (seq_length != 0)
7935 We don't need to do anything when generating fast indirect
7936 calls. */
7937 if (seq_length != 0 && !sibcall)
7938 { 7924 {
7939 final_scan_insn (NEXT_INSN (insn), asm_out_file, 7925 final_scan_insn (NEXT_INSN (insn), asm_out_file,
7940 optimize, 0, NULL); 7926 optimize, 0, NULL);
7941 7927
7942 /* Now delete the delay insn. */ 7928 /* Now delete the delay insn. */
7943 SET_INSN_DELETED (NEXT_INSN (insn)); 7929 SET_INSN_DELETED (NEXT_INSN (insn));
7944 seq_length = 0;
7945 } 7930 }
7946 7931
7947 output_asm_insn ("addil LT'%0,%%r27", xoperands); 7932 output_asm_insn ("addil LT'%0,%%r27", xoperands);
7948 output_asm_insn ("ldd RT'%0(%%r1),%%r1", xoperands); 7933 output_asm_insn ("ldd RT'%0(%%r1),%%r1", xoperands);
7949 output_asm_insn ("ldd 0(%%r1),%%r1", xoperands); 7934 output_asm_insn ("ldd 0(%%r1),%%r1", xoperands);
7950 7935 output_asm_insn ("ldd 16(%%r1),%%r2", xoperands);
7951 if (sibcall) 7936 output_asm_insn ("bve,l (%%r2),%%r2", xoperands);
7952 { 7937 output_asm_insn ("ldd 24(%%r1),%%r27", xoperands);
7953 output_asm_insn ("ldd 24(%%r1),%%r27", xoperands); 7938 seq_length = 1;
7954 output_asm_insn ("ldd 16(%%r1),%%r1", xoperands);
7955 output_asm_insn ("bve (%%r1)", xoperands);
7956 }
7957 else
7958 {
7959 output_asm_insn ("ldd 16(%%r1),%%r2", xoperands);
7960 output_asm_insn ("bve,l (%%r2),%%r2", xoperands);
7961 output_asm_insn ("ldd 24(%%r1),%%r27", xoperands);
7962 seq_length = 1;
7963 }
7964 } 7939 }
7965 else 7940 else
7966 { 7941 {
7967 int indirect_call = 0; 7942 int indirect_call = 0;
7968 7943
8051 8026
8052 if (flag_pic) 8027 if (flag_pic)
8053 { 8028 {
8054 output_asm_insn ("addil LT'%0,%%r19", xoperands); 8029 output_asm_insn ("addil LT'%0,%%r19", xoperands);
8055 output_asm_insn ("ldw RT'%0(%%r1),%%r1", xoperands); 8030 output_asm_insn ("ldw RT'%0(%%r1),%%r1", xoperands);
8056 output_asm_insn ("ldw 0(%%r1),%%r1", xoperands); 8031 output_asm_insn ("ldw 0(%%r1),%%r22", xoperands);
8057 } 8032 }
8058 else 8033 else
8059 { 8034 {
8060 output_asm_insn ("addil LR'%0-$global$,%%r27", 8035 output_asm_insn ("addil LR'%0-$global$,%%r27",
8061 xoperands); 8036 xoperands);
8062 output_asm_insn ("ldw RR'%0-$global$(%%r1),%%r1", 8037 output_asm_insn ("ldw RR'%0-$global$(%%r1),%%r22",
8063 xoperands); 8038 xoperands);
8064 } 8039 }
8065 8040
8066 output_asm_insn ("bb,>=,n %%r1,30,.+16", xoperands); 8041 output_asm_insn ("bb,>=,n %%r22,30,.+16", xoperands);
8067 output_asm_insn ("depi 0,31,2,%%r1", xoperands); 8042 output_asm_insn ("depi 0,31,2,%%r22", xoperands);
8068 output_asm_insn ("ldw 4(%%sr0,%%r1),%%r19", xoperands); 8043 /* Should this be an ordered load to ensure the target
8069 output_asm_insn ("ldw 0(%%sr0,%%r1),%%r1", xoperands); 8044 address is loaded before the global pointer? */
8045 output_asm_insn ("ldw 0(%%r22),%%r1", xoperands);
8046 output_asm_insn ("ldw 4(%%r22),%%r19", xoperands);
8070 8047
8071 if (!sibcall && !TARGET_PA_20) 8048 if (!sibcall && !TARGET_PA_20)
8072 { 8049 {
8073 output_asm_insn ("{bl|b,l} .+8,%%r2", xoperands); 8050 output_asm_insn ("{bl|b,l} .+8,%%r2", xoperands);
8074 if (TARGET_NO_SPACE_REGS || (local_call && !flag_pic)) 8051 if (TARGET_NO_SPACE_REGS || (local_call && !flag_pic))
8157 return 8; 8134 return 8;
8158 8135
8159 if (TARGET_PORTABLE_RUNTIME) 8136 if (TARGET_PORTABLE_RUNTIME)
8160 return 16; 8137 return 16;
8161 8138
8162 /* Inline version of $$dyncall. */
8163 if ((TARGET_NO_SPACE_REGS || TARGET_PA_20) && !optimize_size)
8164 return 20;
8165
8166 if (!TARGET_LONG_CALLS 8139 if (!TARGET_LONG_CALLS
8167 && ((TARGET_PA_20 && !TARGET_SOM && distance < 7600000) 8140 && ((TARGET_PA_20 && !TARGET_SOM && distance < 7600000)
8168 || distance < MAX_PCREL17F_OFFSET)) 8141 || distance < MAX_PCREL17F_OFFSET))
8169 return 8; 8142 return 8;
8170 8143
8171 /* Out of reach, can use ble. */ 8144 /* Out of reach, can use ble. */
8172 if (!flag_pic) 8145 if (!flag_pic)
8173 return 12; 8146 return 12;
8174 8147
8175 /* Inline version of $$dyncall. */ 8148 /* Inline versions of $$dyncall. */
8176 if (TARGET_NO_SPACE_REGS || TARGET_PA_20)
8177 return 20;
8178
8179 if (!optimize_size) 8149 if (!optimize_size)
8180 return 36; 8150 {
8151 if (TARGET_NO_SPACE_REGS)
8152 return 28;
8153
8154 if (TARGET_PA_20)
8155 return 32;
8156 }
8181 8157
8182 /* Long PIC pc-relative call. */ 8158 /* Long PIC pc-relative call. */
8183 return 20; 8159 return 20;
8184 } 8160 }
8185 8161
8211 { 8187 {
8212 output_asm_insn ("ldil L'$$dyncall,%%r31\n\t" 8188 output_asm_insn ("ldil L'$$dyncall,%%r31\n\t"
8213 "ldo R'$$dyncall(%%r31),%%r31", xoperands); 8189 "ldo R'$$dyncall(%%r31),%%r31", xoperands);
8214 pa_output_arg_descriptor (insn); 8190 pa_output_arg_descriptor (insn);
8215 return "blr %%r0,%%r2\n\tbv,n %%r0(%%r31)"; 8191 return "blr %%r0,%%r2\n\tbv,n %%r0(%%r31)";
8216 }
8217
8218 /* Maybe emit a fast inline version of $$dyncall. */
8219 if ((TARGET_NO_SPACE_REGS || TARGET_PA_20) && !optimize_size)
8220 {
8221 output_asm_insn ("bb,>=,n %%r22,30,.+12\n\t"
8222 "ldw 2(%%r22),%%r19\n\t"
8223 "ldw -2(%%r22),%%r22", xoperands);
8224 pa_output_arg_descriptor (insn);
8225 if (TARGET_NO_SPACE_REGS)
8226 {
8227 if (TARGET_PA_20)
8228 return "bve,l,n (%%r22),%%r2\n\tnop";
8229 return "ble 0(%%sr4,%%r22)\n\tcopy %%r31,%%r2";
8230 }
8231 return "bve,l (%%r22),%%r2\n\tstw %%r2,-24(%%sp)";
8232 } 8192 }
8233 8193
8234 /* Now the normal case -- we can reach $$dyncall directly or 8194 /* Now the normal case -- we can reach $$dyncall directly or
8235 we're sure that we can get there via a long-branch stub. 8195 we're sure that we can get there via a long-branch stub.
8236 8196
8257 output_asm_insn ("ldil L'$$dyncall,%%r2", xoperands); 8217 output_asm_insn ("ldil L'$$dyncall,%%r2", xoperands);
8258 pa_output_arg_descriptor (insn); 8218 pa_output_arg_descriptor (insn);
8259 return "ble R'$$dyncall(%%sr4,%%r2)\n\tcopy %%r31,%%r2"; 8219 return "ble R'$$dyncall(%%sr4,%%r2)\n\tcopy %%r31,%%r2";
8260 } 8220 }
8261 8221
8262 /* Maybe emit a fast inline version of $$dyncall. The long PIC 8222 /* The long PIC pc-relative call sequence is five instructions. So,
8263 pc-relative call sequence is five instructions. The inline PA 2.0 8223 let's use an inline version of $$dyncall when the calling sequence
8264 version of $$dyncall is also five instructions. The PA 1.X versions 8224 has a roughly similar number of instructions and we are not optimizing
8265 are longer but still an overall win. */ 8225 for size. We need two instructions to load the return pointer plus
8266 if (TARGET_NO_SPACE_REGS || TARGET_PA_20 || !optimize_size) 8226 the $$dyncall implementation. */
8267 { 8227 if (!optimize_size)
8268 output_asm_insn ("bb,>=,n %%r22,30,.+12\n\t" 8228 {
8269 "ldw 2(%%r22),%%r19\n\t"
8270 "ldw -2(%%r22),%%r22", xoperands);
8271 if (TARGET_NO_SPACE_REGS) 8229 if (TARGET_NO_SPACE_REGS)
8272 { 8230 {
8273 pa_output_arg_descriptor (insn); 8231 pa_output_arg_descriptor (insn);
8274 if (TARGET_PA_20) 8232 output_asm_insn ("bl .+8,%%r2\n\t"
8275 return "bve,l,n (%%r22),%%r2\n\tnop"; 8233 "ldo 20(%%r2),%%r2\n\t"
8276 return "ble 0(%%sr4,%%r22)\n\tcopy %%r31,%%r2"; 8234 "extru,<> %%r22,30,1,%%r0\n\t"
8235 "bv,n %%r0(%%r22)\n\t"
8236 "ldw -2(%%r22),%%r21\n\t"
8237 "bv %%r0(%%r21)\n\t"
8238 "ldw 2(%%r22),%%r19", xoperands);
8239 return "";
8277 } 8240 }
8278 if (TARGET_PA_20) 8241 if (TARGET_PA_20)
8279 { 8242 {
8280 pa_output_arg_descriptor (insn); 8243 pa_output_arg_descriptor (insn);
8281 return "bve,l (%%r22),%%r2\n\tstw %%r2,-24(%%sp)"; 8244 output_asm_insn ("bl .+8,%%r2\n\t"
8282 } 8245 "ldo 24(%%r2),%%r2\n\t"
8283 output_asm_insn ("bl .+8,%%r2\n\t" 8246 "stw %%r2,-24(%%sp)\n\t"
8284 "ldo 16(%%r2),%%r2\n\t" 8247 "extru,<> %r22,30,1,%%r0\n\t"
8285 "ldsid (%%r22),%%r1\n\t" 8248 "bve,n (%%r22)\n\t"
8286 "mtsp %%r1,%%sr0", xoperands); 8249 "ldw -2(%%r22),%%r21\n\t"
8287 pa_output_arg_descriptor (insn); 8250 "bve (%%r21)\n\t"
8288 return "be 0(%%sr0,%%r22)\n\tstw %%r2,-24(%%sp)"; 8251 "ldw 2(%%r22),%%r19", xoperands);
8289 } 8252 return "";
8290 8253 }
8254 }
8255
8291 /* We need a long PIC call to $$dyncall. */ 8256 /* We need a long PIC call to $$dyncall. */
8292 xoperands[0] = gen_rtx_SYMBOL_REF (Pmode, "$$dyncall"); 8257 xoperands[0] = gen_rtx_SYMBOL_REF (Pmode, "$$dyncall");
8293 xoperands[1] = gen_rtx_REG (Pmode, 2); 8258 xoperands[1] = gen_rtx_REG (Pmode, 2);
8294 xoperands[2] = gen_rtx_REG (Pmode, 1); 8259 xoperands[2] = gen_rtx_REG (Pmode, 1);
8295 pa_output_pic_pcrel_sequence (xoperands); 8260 pa_output_pic_pcrel_sequence (xoperands);
8367 static void 8332 static void
8368 pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta, 8333 pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta,
8369 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED, 8334 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
8370 tree function) 8335 tree function)
8371 { 8336 {
8337 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
8372 static unsigned int current_thunk_number; 8338 static unsigned int current_thunk_number;
8373 int val_14 = VAL_14_BITS_P (delta); 8339 int val_14 = VAL_14_BITS_P (delta);
8374 unsigned int old_last_address = last_address, nbytes = 0; 8340 unsigned int old_last_address = last_address, nbytes = 0;
8375 char label[17]; 8341 char label[17];
8376 rtx xoperands[4]; 8342 rtx xoperands[4];
8377 8343
8378 xoperands[0] = XEXP (DECL_RTL (function), 0); 8344 xoperands[0] = XEXP (DECL_RTL (function), 0);
8379 xoperands[1] = XEXP (DECL_RTL (thunk_fndecl), 0); 8345 xoperands[1] = XEXP (DECL_RTL (thunk_fndecl), 0);
8380 xoperands[2] = GEN_INT (delta); 8346 xoperands[2] = GEN_INT (delta);
8381 8347
8348 assemble_start_function (thunk_fndecl, fnname);
8382 final_start_function (emit_barrier (), file, 1); 8349 final_start_function (emit_barrier (), file, 1);
8383 8350
8384 /* Output the thunk. We know that the function is in the same 8351 /* Output the thunk. We know that the function is in the same
8385 translation unit (i.e., the same space) as the thunk, and that 8352 translation unit (i.e., the same space) as the thunk, and that
8386 thunks are output after their method. Thus, we don't need an 8353 thunks are output after their method. Thus, we don't need an
8594 & ~(FUNCTION_BOUNDARY / BITS_PER_UNIT - 1)); 8561 & ~(FUNCTION_BOUNDARY / BITS_PER_UNIT - 1));
8595 last_address += nbytes; 8562 last_address += nbytes;
8596 if (old_last_address > last_address) 8563 if (old_last_address > last_address)
8597 last_address = UINT_MAX; 8564 last_address = UINT_MAX;
8598 update_total_code_bytes (nbytes); 8565 update_total_code_bytes (nbytes);
8566 assemble_end_function (thunk_fndecl, fnname);
8599 } 8567 }
8600 8568
8601 /* Only direct calls to static functions are allowed to be sibling (tail) 8569 /* Only direct calls to static functions are allowed to be sibling (tail)
8602 call optimized. 8570 call optimized.
8603 8571
9443 return true; 9411 return true;
9444 9412
9445 return false; 9413 return false;
9446 } 9414 }
9447 9415
9448 /* Update the data in CUM to advance over an argument 9416 /* Update the data in CUM to advance over argument ARG. */
9449 of mode MODE and data type TYPE.
9450 (TYPE is null for libcalls where that information may not be available.) */
9451 9417
9452 static void 9418 static void
9453 pa_function_arg_advance (cumulative_args_t cum_v, machine_mode mode, 9419 pa_function_arg_advance (cumulative_args_t cum_v,
9454 const_tree type, bool named ATTRIBUTE_UNUSED) 9420 const function_arg_info &arg)
9455 { 9421 {
9456 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 9422 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
9457 int arg_size = pa_function_arg_size (mode, type); 9423 int arg_size = pa_function_arg_size (arg.mode, arg.type);
9458 9424
9459 cum->nargs_prototype--; 9425 cum->nargs_prototype--;
9460 cum->words += (arg_size 9426 cum->words += (arg_size
9461 + ((cum->words & 01) 9427 + ((cum->words & 01)
9462 && type != NULL_TREE 9428 && arg.type != NULL_TREE
9463 && arg_size > 1)); 9429 && arg_size > 1));
9464 } 9430 }
9465 9431
9466 /* Return the location of a parameter that is passed in a register or NULL 9432 /* Return the location of a parameter that is passed in a register or NULL
9467 if the parameter has any component that is passed in memory. 9433 if the parameter has any component that is passed in memory.
9470 further testing. 9436 further testing.
9471 9437
9472 ??? We might want to restructure this so that it looks more like other 9438 ??? We might want to restructure this so that it looks more like other
9473 ports. */ 9439 ports. */
9474 static rtx 9440 static rtx
9475 pa_function_arg (cumulative_args_t cum_v, machine_mode mode, 9441 pa_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
9476 const_tree type, bool named ATTRIBUTE_UNUSED)
9477 { 9442 {
9478 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 9443 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
9444 tree type = arg.type;
9445 machine_mode mode = arg.mode;
9479 int max_arg_words = (TARGET_64BIT ? 8 : 4); 9446 int max_arg_words = (TARGET_64BIT ? 8 : 4);
9480 int alignment = 0; 9447 int alignment = 0;
9481 int arg_size; 9448 int arg_size;
9482 int fpr_reg_base; 9449 int fpr_reg_base;
9483 int gpr_reg_base; 9450 int gpr_reg_base;
9484 rtx retval; 9451 rtx retval;
9485 9452
9486 if (mode == VOIDmode) 9453 if (arg.end_marker_p ())
9487 return NULL_RTX; 9454 return NULL_RTX;
9488 9455
9489 arg_size = pa_function_arg_size (mode, type); 9456 arg_size = pa_function_arg_size (mode, type);
9490 9457
9491 /* If this arg would be passed partially or totally on the stack, then 9458 /* If this arg would be passed partially or totally on the stack, then
9681 9648
9682 /* If this arg would be passed totally in registers or totally on the stack, 9649 /* If this arg would be passed totally in registers or totally on the stack,
9683 then this routine should return zero. */ 9650 then this routine should return zero. */
9684 9651
9685 static int 9652 static int
9686 pa_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode, 9653 pa_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
9687 tree type, bool named ATTRIBUTE_UNUSED)
9688 { 9654 {
9689 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 9655 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
9690 unsigned int max_arg_words = 8; 9656 unsigned int max_arg_words = 8;
9691 unsigned int offset = 0; 9657 unsigned int offset = 0;
9692 9658
9693 if (!TARGET_64BIT) 9659 if (!TARGET_64BIT)
9694 return 0; 9660 return 0;
9695 9661
9696 if (pa_function_arg_size (mode, type) > 1 && (cum->words & 1)) 9662 if (pa_function_arg_size (arg.mode, arg.type) > 1 && (cum->words & 1))
9697 offset = 1; 9663 offset = 1;
9698 9664
9699 if (cum->words + offset + pa_function_arg_size (mode, type) <= max_arg_words) 9665 if (cum->words + offset + pa_function_arg_size (arg.mode, arg.type)
9666 <= max_arg_words)
9700 /* Arg fits fully into registers. */ 9667 /* Arg fits fully into registers. */
9701 return 0; 9668 return 0;
9702 else if (cum->words + offset >= max_arg_words) 9669 else if (cum->words + offset >= max_arg_words)
9703 /* Arg fully on the stack. */ 9670 /* Arg fully on the stack. */
9704 return 0; 9671 return 0;
9801 if (flag_tm) 9768 if (flag_tm)
9802 som_tm_clone_table_section 9769 som_tm_clone_table_section
9803 = get_unnamed_section (0, output_section_asm_op, 9770 = get_unnamed_section (0, output_section_asm_op,
9804 "\t.SPACE $PRIVATE$\n\t.SUBSPA $TM_CLONE_TABLE$"); 9771 "\t.SPACE $PRIVATE$\n\t.SUBSPA $TM_CLONE_TABLE$");
9805 9772
9806 /* FIXME: HPUX ld generates incorrect GOT entries for "T" fixups 9773 /* HPUX ld generates incorrect GOT entries for "T" fixups which
9807 which reference data within the $TEXT$ space (for example constant 9774 reference data within the $TEXT$ space (for example constant
9808 strings in the $LIT$ subspace). 9775 strings in the $LIT$ subspace).
9809 9776
9810 The assemblers (GAS and HP as) both have problems with handling 9777 The assemblers (GAS and HP as) both have problems with handling
9811 the difference of two symbols which is the other correct way to 9778 the difference of two symbols. This is the other correct way to
9812 reference constant data during PIC code generation. 9779 reference constant data during PIC code generation.
9813 9780
9814 So, there's no way to reference constant data which is in the 9781 Thus, we can't put constant data needing relocation in the $TEXT$
9815 $TEXT$ space during PIC generation. Instead place all constant 9782 space during PIC generation.
9816 data into the $PRIVATE$ subspace (this reduces sharing, but it 9783
9817 works correctly). */ 9784 Previously, we placed all constant data into the $DATA$ subspace
9818 readonly_data_section = flag_pic ? data_section : som_readonly_data_section; 9785 when generating PIC code. This reduces sharing, but it works
9786 correctly. Now we rely on pa_reloc_rw_mask() for section selection.
9787 This puts constant data not needing relocation into the $TEXT$ space. */
9788 readonly_data_section = som_readonly_data_section;
9819 9789
9820 /* We must not have a reference to an external symbol defined in a 9790 /* We must not have a reference to an external symbol defined in a
9821 shared library in a readonly section, else the SOM linker will 9791 shared library in a readonly section, else the SOM linker will
9822 complain. 9792 complain.
9823 9793
9833 return som_tm_clone_table_section; 9803 return som_tm_clone_table_section;
9834 } 9804 }
9835 9805
9836 /* On hpux10, the linker will give an error if we have a reference 9806 /* On hpux10, the linker will give an error if we have a reference
9837 in the read-only data section to a symbol defined in a shared 9807 in the read-only data section to a symbol defined in a shared
9838 library. Therefore, expressions that might require a reloc can 9808 library. Therefore, expressions that might require a reloc
9839 not be placed in the read-only data section. */ 9809 cannot be placed in the read-only data section. */
9840 9810
9841 static section * 9811 static section *
9842 pa_select_section (tree exp, int reloc, 9812 pa_select_section (tree exp, int reloc,
9843 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) 9813 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
9844 { 9814 {
9846 && TREE_READONLY (exp) 9816 && TREE_READONLY (exp)
9847 && !TREE_THIS_VOLATILE (exp) 9817 && !TREE_THIS_VOLATILE (exp)
9848 && DECL_INITIAL (exp) 9818 && DECL_INITIAL (exp)
9849 && (DECL_INITIAL (exp) == error_mark_node 9819 && (DECL_INITIAL (exp) == error_mark_node
9850 || TREE_CONSTANT (DECL_INITIAL (exp))) 9820 || TREE_CONSTANT (DECL_INITIAL (exp)))
9851 && !reloc) 9821 && !(reloc & pa_reloc_rw_mask ()))
9852 { 9822 {
9853 if (TARGET_SOM 9823 if (TARGET_SOM
9854 && DECL_ONE_ONLY (exp) 9824 && DECL_ONE_ONLY (exp)
9855 && !DECL_WEAK (exp)) 9825 && !DECL_WEAK (exp))
9856 return som_one_only_readonly_data_section; 9826 return som_one_only_readonly_data_section;
9857 else 9827 else
9858 return readonly_data_section; 9828 return readonly_data_section;
9859 } 9829 }
9860 else if (CONSTANT_CLASS_P (exp) && !reloc) 9830 else if (CONSTANT_CLASS_P (exp)
9831 && !(reloc & pa_reloc_rw_mask ()))
9861 return readonly_data_section; 9832 return readonly_data_section;
9862 else if (TARGET_SOM 9833 else if (TARGET_SOM
9863 && TREE_CODE (exp) == VAR_DECL 9834 && TREE_CODE (exp) == VAR_DECL
9864 && DECL_ONE_ONLY (exp) 9835 && DECL_ONE_ONLY (exp)
9865 && !DECL_WEAK (exp)) 9836 && !DECL_WEAK (exp))
9866 return som_one_only_data_section; 9837 return som_one_only_data_section;
9867 else 9838 else
9868 return data_section; 9839 return data_section;
9869 } 9840 }
9870 9841
9842 /* Implement pa_elf_select_rtx_section. If X is a function label operand
9843 and the function is in a COMDAT group, place the plabel reference in the
9844 .data.rel.ro.local section. The linker ignores references to symbols in
9845 discarded sections from this section. */
9846
9847 static section *
9848 pa_elf_select_rtx_section (machine_mode mode, rtx x,
9849 unsigned HOST_WIDE_INT align)
9850 {
9851 if (function_label_operand (x, VOIDmode))
9852 {
9853 tree decl = SYMBOL_REF_DECL (x);
9854
9855 if (!decl || (DECL_P (decl) && DECL_COMDAT_GROUP (decl)))
9856 return get_named_section (NULL, ".data.rel.ro.local", 1);
9857 }
9858
9859 return default_elf_select_rtx_section (mode, x, align);
9860 }
9861
9871 /* Implement pa_reloc_rw_mask. */ 9862 /* Implement pa_reloc_rw_mask. */
9872 9863
9873 static int 9864 static int
9874 pa_reloc_rw_mask (void) 9865 pa_reloc_rw_mask (void)
9875 { 9866 {
9876 /* We force (const (plus (symbol) (const_int))) to memory when the 9867 if (flag_pic || (TARGET_SOM && !TARGET_HPUX_11))
9877 const_int doesn't fit in a 14-bit integer. The SOM linker can't 9868 return 3;
9878 handle this construct in read-only memory and we want to avoid 9869
9879 this for ELF. So, we always force an RTX needing relocation to 9870 /* HP linker does not support global relocs in readonly memory. */
9880 the data section. */ 9871 return TARGET_SOM ? 2 : 0;
9881 return 3;
9882 } 9872 }
9883 9873
9884 static void 9874 static void
9885 pa_globalize_label (FILE *stream, const char *name) 9875 pa_globalize_label (FILE *stream, const char *name)
9886 { 9876 {
10006 return false; 9996 return false;
10007 9997
10008 /* There is no way to load QImode or HImode values directly from memory 9998 /* There is no way to load QImode or HImode values directly from memory
10009 to a FP register. SImode loads to the FP registers are not zero 9999 to a FP register. SImode loads to the FP registers are not zero
10010 extended. On the 64-bit target, this conflicts with the definition 10000 extended. On the 64-bit target, this conflicts with the definition
10011 of LOAD_EXTEND_OP. Thus, we can't allow changing between modes with 10001 of LOAD_EXTEND_OP. Thus, we reject all mode changes in the FP registers
10012 different sizes in the floating-point registers. */ 10002 except for DImode to SImode on the 64-bit target. It is handled by
10003 register renaming in pa_print_operand. */
10013 if (MAYBE_FP_REG_CLASS_P (rclass)) 10004 if (MAYBE_FP_REG_CLASS_P (rclass))
10014 return false; 10005 return TARGET_64BIT && from == DImode && to == SImode;
10015 10006
10016 /* TARGET_HARD_REGNO_MODE_OK places modes with sizes larger than a word 10007 /* TARGET_HARD_REGNO_MODE_OK places modes with sizes larger than a word
10017 in specific sets of registers. Thus, we cannot allow changing 10008 in specific sets of registers. Thus, we cannot allow changing
10018 to a larger mode when it's larger than a word. */ 10009 to a larger mode when it's larger than a word. */
10019 if (GET_MODE_SIZE (to) > UNITS_PER_WORD 10010 if (GET_MODE_SIZE (to) > UNITS_PER_WORD
10043 } 10034 }
10044 10035
10045 10036
10046 /* Length in units of the trampoline instruction code. */ 10037 /* Length in units of the trampoline instruction code. */
10047 10038
10048 #define TRAMPOLINE_CODE_SIZE (TARGET_64BIT ? 24 : (TARGET_PA_20 ? 32 : 40)) 10039 #define TRAMPOLINE_CODE_SIZE (TARGET_64BIT ? 24 : (TARGET_PA_20 ? 36 : 48))
10049 10040
10050 10041
10051 /* Output assembler code for a block containing the constant parts 10042 /* Output assembler code for a block containing the constant parts
10052 of a trampoline, leaving space for the variable parts.\ 10043 of a trampoline, leaving space for the variable parts.\
10053 10044
10064 static void 10055 static void
10065 pa_asm_trampoline_template (FILE *f) 10056 pa_asm_trampoline_template (FILE *f)
10066 { 10057 {
10067 if (!TARGET_64BIT) 10058 if (!TARGET_64BIT)
10068 { 10059 {
10069 fputs ("\tldw 36(%r22),%r21\n", f);
10070 fputs ("\tbb,>=,n %r21,30,.+16\n", f);
10071 if (ASSEMBLER_DIALECT == 0)
10072 fputs ("\tdepi 0,31,2,%r21\n", f);
10073 else
10074 fputs ("\tdepwi 0,31,2,%r21\n", f);
10075 fputs ("\tldw 4(%r21),%r19\n", f);
10076 fputs ("\tldw 0(%r21),%r21\n", f);
10077 if (TARGET_PA_20) 10060 if (TARGET_PA_20)
10078 { 10061 {
10079 fputs ("\tbve (%r21)\n", f); 10062 fputs ("\tmfia %r20\n", f);
10080 fputs ("\tldw 40(%r22),%r29\n", f); 10063 fputs ("\tldw 48(%r20),%r22\n", f);
10064 fputs ("\tcopy %r22,%r21\n", f);
10065 fputs ("\tbb,>=,n %r22,30,.+16\n", f);
10066 fputs ("\tdepwi 0,31,2,%r22\n", f);
10067 fputs ("\tldw 0(%r22),%r21\n", f);
10068 fputs ("\tldw 4(%r22),%r19\n", f);
10069 fputs ("\tbve (%r21)\n", f);
10070 fputs ("\tldw 52(%r1),%r29\n", f);
10081 fputs ("\t.word 0\n", f); 10071 fputs ("\t.word 0\n", f);
10082 fputs ("\t.word 0\n", f); 10072 fputs ("\t.word 0\n", f);
10073 fputs ("\t.word 0\n", f);
10083 } 10074 }
10084 else 10075 else
10085 { 10076 {
10077 if (ASSEMBLER_DIALECT == 0)
10078 {
10079 fputs ("\tbl .+8,%r20\n", f);
10080 fputs ("\tdepi 0,31,2,%r20\n", f);
10081 }
10082 else
10083 {
10084 fputs ("\tb,l .+8,%r20\n", f);
10085 fputs ("\tdepwi 0,31,2,%r20\n", f);
10086 }
10087 fputs ("\tldw 40(%r20),%r22\n", f);
10088 fputs ("\tcopy %r22,%r21\n", f);
10089 fputs ("\tbb,>=,n %r22,30,.+16\n", f);
10090 if (ASSEMBLER_DIALECT == 0)
10091 fputs ("\tdepi 0,31,2,%r22\n", f);
10092 else
10093 fputs ("\tdepwi 0,31,2,%r22\n", f);
10094 fputs ("\tldw 0(%r22),%r21\n", f);
10095 fputs ("\tldw 4(%r22),%r19\n", f);
10086 fputs ("\tldsid (%r21),%r1\n", f); 10096 fputs ("\tldsid (%r21),%r1\n", f);
10087 fputs ("\tmtsp %r1,%sr0\n", f); 10097 fputs ("\tmtsp %r1,%sr0\n", f);
10088 fputs ("\tbe 0(%sr0,%r21)\n", f); 10098 fputs ("\tbe 0(%sr0,%r21)\n", f);
10089 fputs ("\tldw 40(%r22),%r29\n", f); 10099 fputs ("\tldw 44(%r20),%r29\n", f);
10090 } 10100 }
10091 fputs ("\t.word 0\n", f); 10101 fputs ("\t.word 0\n", f);
10092 fputs ("\t.word 0\n", f); 10102 fputs ("\t.word 0\n", f);
10093 fputs ("\t.word 0\n", f); 10103 fputs ("\t.word 0\n", f);
10094 fputs ("\t.word 0\n", f); 10104 fputs ("\t.word 0\n", f);
10098 fputs ("\t.dword 0\n", f); 10108 fputs ("\t.dword 0\n", f);
10099 fputs ("\t.dword 0\n", f); 10109 fputs ("\t.dword 0\n", f);
10100 fputs ("\t.dword 0\n", f); 10110 fputs ("\t.dword 0\n", f);
10101 fputs ("\t.dword 0\n", f); 10111 fputs ("\t.dword 0\n", f);
10102 fputs ("\tmfia %r31\n", f); 10112 fputs ("\tmfia %r31\n", f);
10103 fputs ("\tldd 24(%r31),%r1\n", f); 10113 fputs ("\tldd 24(%r31),%r27\n", f);
10104 fputs ("\tldd 24(%r1),%r27\n", f); 10114 fputs ("\tldd 32(%r31),%r31\n", f);
10105 fputs ("\tldd 16(%r1),%r1\n", f); 10115 fputs ("\tldd 16(%r27),%r1\n", f);
10106 fputs ("\tbve (%r1)\n", f); 10116 fputs ("\tbve (%r1)\n", f);
10107 fputs ("\tldd 32(%r31),%r31\n", f); 10117 fputs ("\tldd 24(%r27),%r27\n", f);
10108 fputs ("\t.dword 0 ; fptr\n", f); 10118 fputs ("\t.dword 0 ; fptr\n", f);
10109 fputs ("\t.dword 0 ; static link\n", f); 10119 fputs ("\t.dword 0 ; static link\n", f);
10110 } 10120 }
10111 } 10121 }
10112 10122
10113 /* Emit RTL insns to initialize the variable parts of a trampoline. 10123 /* Emit RTL insns to initialize the variable parts of a trampoline.
10114 FNADDR is an RTX for the address of the function's pure code. 10124 FNADDR is an RTX for the address of the function's pure code.
10115 CXT is an RTX for the static chain value for the function. 10125 CXT is an RTX for the static chain value for the function.
10116 10126
10117 Move the function address to the trampoline template at offset 36. 10127 Move the function address to the trampoline template at offset 48.
10118 Move the static chain value to trampoline template at offset 40. 10128 Move the static chain value to trampoline template at offset 52.
10119 Move the trampoline address to trampoline template at offset 44. 10129 Move the trampoline address to trampoline template at offset 56.
10120 Move r19 to trampoline template at offset 48. The latter two 10130 Move r19 to trampoline template at offset 60. The latter two
10121 words create a plabel for the indirect call to the trampoline. 10131 words create a plabel for the indirect call to the trampoline.
10122 10132
10123 A similar sequence is used for the 64-bit port but the plabel is 10133 A similar sequence is used for the 64-bit port but the plabel is
10124 at the beginning of the trampoline. 10134 at the beginning of the trampoline.
10125 10135
10141 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL); 10151 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
10142 r_tramp = force_reg (Pmode, XEXP (m_tramp, 0)); 10152 r_tramp = force_reg (Pmode, XEXP (m_tramp, 0));
10143 10153
10144 if (!TARGET_64BIT) 10154 if (!TARGET_64BIT)
10145 { 10155 {
10146 tmp = adjust_address (m_tramp, Pmode, 36); 10156 tmp = adjust_address (m_tramp, Pmode, 48);
10147 emit_move_insn (tmp, fnaddr); 10157 emit_move_insn (tmp, fnaddr);
10148 tmp = adjust_address (m_tramp, Pmode, 40); 10158 tmp = adjust_address (m_tramp, Pmode, 52);
10149 emit_move_insn (tmp, chain_value); 10159 emit_move_insn (tmp, chain_value);
10150 10160
10151 /* Create a fat pointer for the trampoline. */ 10161 /* Create a fat pointer for the trampoline. */
10152 tmp = adjust_address (m_tramp, Pmode, 44); 10162 tmp = adjust_address (m_tramp, Pmode, 56);
10153 emit_move_insn (tmp, r_tramp); 10163 emit_move_insn (tmp, r_tramp);
10154 tmp = adjust_address (m_tramp, Pmode, 48); 10164 tmp = adjust_address (m_tramp, Pmode, 60);
10155 emit_move_insn (tmp, gen_rtx_REG (Pmode, 19)); 10165 emit_move_insn (tmp, gen_rtx_REG (Pmode, 19));
10156 10166
10157 /* fdc and fic only use registers for the address to flush, 10167 /* fdc and fic only use registers for the address to flush,
10158 they do not accept integer displacements. We align the 10168 they do not accept integer displacements. We align the
10159 start and end addresses to the beginning of their respective 10169 start and end addresses to the beginning of their respective
10201 gen_reg_rtx (Pmode), 10211 gen_reg_rtx (Pmode),
10202 gen_reg_rtx (Pmode))); 10212 gen_reg_rtx (Pmode)));
10203 } 10213 }
10204 10214
10205 #ifdef HAVE_ENABLE_EXECUTE_STACK 10215 #ifdef HAVE_ENABLE_EXECUTE_STACK
10206  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"), 10216 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
10207 LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode); 10217 LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode);
10208 #endif 10218 #endif
10209 } 10219 }
10210 10220
10211 /* Perform any machine-specific adjustment in the address of the trampoline. 10221 /* Perform any machine-specific adjustment in the address of the trampoline.
10212 ADDR contains the address that was passed to pa_trampoline_init. 10222 ADDR contains the address that was passed to pa_trampoline_init.
10213 Adjust the trampoline address to point to the plabel at offset 44. */ 10223 Adjust the trampoline address to point to the plabel at offset 56. */
10214 10224
10215 static rtx 10225 static rtx
10216 pa_trampoline_adjust_address (rtx addr) 10226 pa_trampoline_adjust_address (rtx addr)
10217 { 10227 {
10218 if (!TARGET_64BIT) 10228 if (!TARGET_64BIT)
10219 addr = memory_address (Pmode, plus_constant (Pmode, addr, 46)); 10229 addr = memory_address (Pmode, plus_constant (Pmode, addr, 58));
10220 return addr; 10230 return addr;
10221 } 10231 }
10222 10232
10223 static rtx 10233 static rtx
10224 pa_delegitimize_address (rtx orig_x) 10234 pa_delegitimize_address (rtx orig_x)
10767 can override this behavior for better compatibility with openmp at the 10777 can override this behavior for better compatibility with openmp at the
10768 risk of library incompatibilities. Arguments are always passed by value 10778 risk of library incompatibilities. Arguments are always passed by value
10769 in the 64-bit HP runtime. */ 10779 in the 64-bit HP runtime. */
10770 10780
10771 static bool 10781 static bool
10772 pa_callee_copies (cumulative_args_t cum ATTRIBUTE_UNUSED, 10782 pa_callee_copies (cumulative_args_t, const function_arg_info &)
10773 machine_mode mode ATTRIBUTE_UNUSED,
10774 const_tree type ATTRIBUTE_UNUSED,
10775 bool named ATTRIBUTE_UNUSED)
10776 { 10783 {
10777 return !TARGET_CALLER_COPIES; 10784 return !TARGET_CALLER_COPIES;
10778 } 10785 }
10779 10786
10780 /* Implement TARGET_HARD_REGNO_NREGS. */ 10787 /* Implement TARGET_HARD_REGNO_NREGS. */