the value of TREE_SYMBOL_REFERENCED.
* pa-ghpux9.h (LINK_SPEC): Pass "-z" to the linker to enable
trap on null pointer dereference for programs built on hpux9.
* pa-hpux9.h, pa1-ghpux9.h, pa1-hpux9.h: Likewise.
* pa.c (output_function_prologue): No longer need to keep
track of the total number code bytes when TARGET_GAS &&
not TARGET_PORTABLE_RUNTIME.
* pa.h (DBX_OUTPUT_MAIN_SOURCE_FILE_END): Use .NSUBSPA when
not TARGET_PORTABLE_RUNTIME.
(ASM_OUTPUT_FUNCTION_PREFIX): Define. Prefix functions with
.NSUBSPA when TARGET_GAS and not TARGET_PORTABLE_RUNTIME.
* pa.md (symbolic high patterns): Use 'H' to print the symbolic
address so that the constant part gets rounded.
* pa.c (print_operand): Handle 'H' operand for high part of a
symbolic address with a rounded constant.
(output_global_address): New argument "rounded_constant". All
callers changed appropriately.
* x-pa-hpux (FIXPROTO_DEFINES): Add -D_HPUX_SOURCE.
* pa.h (CPP_SPEC): Only pass -D_HPUX_SOURCE and -D_HIUX_SOURCE if
-ansi is not present.
(CPP_PREDEFINES): Remove -D_HPUX_SOURCE and/or -D_HIUX_SOURCE.
* pa-ghiux.h (CPP_PREDEFINES): Likewise.
* pa-gux7.h (CPP_PREDEFINES): Likewise.
* pa-hiux.h (CPP_PREDEFINES): Likewise.
* pa-hpux.h (CPP_PREDEFINES): Likewise.
* pa-hpux7.h (CPP_PREDEFINES): Likewise.
* pa1-ghiux.h (CPP_PREDEFINES): Likewise.
* pa1-hiux.h (CPP_PREDEFINES): Likewise.
* pa-hpux.h (LINK_SPEC): If -mlinker-opt, then pass -O to the
linker.
* pa-ghpux.h, pa-hpux9.h, pa-ghpux9.h: Likewise.
* pa1-ghpux9.h, pa1-hpux9.h: Likewise.
* pa.h (LINK_SPEC): Likewise.
(TARGET_SWITCHES): Add -mlinker-opt.
* pa.md (all peepholes): Disable if TARGET_SOFT_FLOAT.
* pa.c (pa_reorg): If TARGET_GAS, then emit insns to mark
the beginning and end of the branch table.
* pa.md (begin_brtab): New insn. Just a marker so GCC knows
where to put the .begin_brtab pseudo-op.
(end_brtab): Similarly.
* pa.h (EXTRA_SECTIONS): Add in_ctors and in_dtors if
CTORS_SECTION_FUNCTION is defined. Else define dummy
versions of CTORS_SECTION_FUNCTION and DTORS_SECTION_FUNCTION.
(EXTRA_SECTION_FUNCTIONS): Add CTORS_SECTION_FUNCTION and
DTORS_SECTION_FUNCTION.
* pa.md: Add peepholes to improve spill code generated
by reload when we run out of FP registers.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@10612
138bc75d-0d04-0410-961f-
82ee72b054a4
/* Predefines are the one noteworthy difference between HPUX and HIUX. */
#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dhppa -DPWB -Dunix -D_HIUX_SOURCE -D__H3050R -D__H3050RX -Asystem(unix) -Asystem(hiux) -Acpu(hppa) -Amachine(hppa)"
+#define CPP_PREDEFINES "-Dhppa -DPWB -Dunix -D__H3050R -D__H3050RX -Asystem(unix) -Asystem(hiux) -Acpu(hppa) -Amachine(hppa)"
#define LIB_SPEC "%{!shared:%{!p:%{!pg:-lc}}%{p: -L/lib/libp/ -lc}%{pg: -L/lib/libp/ -lc}}"
#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -D_HPUX_SOURCE -Asystem(unix) -Asystem(hpux) -Acpu(hppa) -Amachine(hppa)"
+#define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -Asystem(unix) -Asystem(hpux) -Acpu(hppa) -Amachine(hppa)"
#undef LINK_SPEC
#define LINK_SPEC \
- "%{!shared:-u main} %{static:-a archive} %{g*:-a archive} %{shared:-b}"
+ "%{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{g*:-a archive} %{shared:-b}"
/* hpux8 and later have C++ compatible include files, so do not
pretend they are `extern "C"'. */
#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p: -L/lib/libp/ -lc}%{pg: -L/lib/libp/ -lc}"
#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -D_HPUX_SOURCE -Asystem(unix) -Asystem(hpux) -Acpu(hppa) -Amachine(hppa)"
+#define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -Asystem(unix) -Asystem(hpux) -Acpu(hppa) -Amachine(hppa)"
#include "pa/pa-hpux.h"
-/* We can debug dynamically linked executables on hpux9. */
+/* We can debug dynamically linked executables on hpux9; we also want
+ dereferecing of a NULL pointer to cause a SEGV. */
#undef LINK_SPEC
#define LINK_SPEC \
- "%{!shared:-u main} %{static:-a archive} %{shared:-b}"
+ "-z %{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{shared:-b}"
ASM_GENERATE_INTERNAL_LABEL (hp_profile_label_name, "LP",
hp_profile_labelno);
- if (insn_addresses)
+ /* If we're using GAS and not using the portable runtime model, then
+ we don't need to accumulate the total number of code bytes. */
+ if (TARGET_GAS && ! TARGET_PORTABLE_RUNTIME)
+ total_code_bytes = 0;
+ else if (insn_addresses)
{
unsigned int old_total = total_code_bytes;
total_code_bytes += insn_addresses[INSN_UID (get_last_insn())];
- total_code_bytes += FUNCTION_BOUNDARY /BITS_PER_UNIT;
+ total_code_bytes += FUNCTION_BOUNDARY / BITS_PER_UNIT;
/* Be prepared to handle overflows. */
total_code_bytes = old_total > total_code_bytes ? -1 : total_code_bytes;
}
return;
case 'G':
- output_global_address (file, x);
+ output_global_address (file, x, 0);
+ return;
+ case 'H':
+ output_global_address (file, x, 1);
return;
case 0: /* Don't do anything special */
break;
/* output a SYMBOL_REF or a CONST expression involving a SYMBOL_REF. */
void
-output_global_address (file, x)
+output_global_address (file, x, round_constant)
FILE *file;
rtx x;
+ int round_constant;
{
/* Imagine (high (const (plus ...))). */
offset = INTVAL (XEXP (XEXP (x, 0),1));
else abort ();
+ /* How bogus. The compiler is apparently responsible for
+ rounding the constant if it uses an LR field selector.
+
+ The linker and/or assembler seem a better place since
+ they have to do this kind of thing already.
+
+ If we fail to do this, HP's optimizing linker may eliminate
+ an addil, but not update the ldw/stw/ldo instruction that
+ uses the result of the addil. */
+ if (round_constant)
+ offset = ((offset + 0x1000) & ~0x1fff);
+
if (GET_CODE (XEXP (x, 0)) == PLUS)
{
if (offset < 0)
if (!read_only_operand (base) && !flag_pic)
fprintf (file, "-$global$");
- fprintf (file, "%s", sep);
- if (offset) fprintf (file,"%d", offset);
+ if (offset)
+ fprintf (file,"%s%d", sep, offset);
}
else
output_addr_const (file, x);
|| GET_CODE (PATTERN (insn)) != ADDR_VEC)
continue;
+ /* If needed, emit marker for the beginning of the branch table. */
+ if (TARGET_GAS)
+ emit_insn_before (gen_begin_brtab (), insn);
+
pattern = PATTERN (insn);
location = PREV_INSN (insn);
length = XVECLEN (pattern, 0);
+
for (i = 0; i < length; i++)
{
/* Emit the jump itself. */
emit_label_after (tmp, location);
location = NEXT_INSN (location);
}
+
+ /* If needed, emit marker for the end of the branch table. */
+ if (TARGET_GAS)
+ emit_insn_before (gen_end_brtab (), location);
/* Delete the ADDR_VEC. */
delete_insn (insn);
}
}
+ else if (TARGET_GAS)
+ {
+ /* Sill need an end_brtab insn. */
+ insns = get_insns ();
+ for (insn = insns; insn; insn = NEXT_INSN (insn))
+ {
+ /* Find an ADDR_VEC insn. */
+ if (GET_CODE (insn) != JUMP_INSN
+ || GET_CODE (PATTERN (insn)) != ADDR_VEC)
+ continue;
+
+ /* Now generate markers for the beginning and end of the
+ branc table. */
+ emit_insn_before (gen_begin_brtab (), insn);
+ emit_insn_after (gen_end_brtab (), insn);
+ }
+ }
}
{"no-gas", -128}, \
{"soft-float", 256}, \
{"no-soft-float", -256}, \
+ {"linker-opt", 0}, \
{ "", TARGET_DEFAULT}}
#ifndef TARGET_DEFAULT
/* gdb needs a null N_SO at the end of each file for scattered loading. */
#undef DBX_OUTPUT_MAIN_SOURCE_FILE_END
-#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \
+#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \
+ if (!TARGET_PORTABLE_RUNTIME) \
+ fputs ("\t.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n", FILE); \
+ else \
+ fprintf (FILE, "%s\n", TEXT_SECTION_ASM_OP); \
fprintf (FILE, \
- "%s\n\t.stabs \"%s\",%d,0,0,L$text_end\nL$text_end:\n",\
- TEXT_SECTION_ASM_OP, "" , N_SO)
+ "\t.stabs \"\",%d,0,0,L$text_end0000\nL$text_end0000:\n", N_SO)
#if (TARGET_DEFAULT & 1) == 0
#define CPP_SPEC "%{msnake:-D__hp9000s700 -D_PA_RISC1_1}\
- %{mpa-risc-1-1:-D__hp9000s700 -D_PA_RISC1_1}"
+ %{mpa-risc-1-1:-D__hp9000s700 -D_PA_RISC1_1}\
+ %{!ansi: -D_HPUX_SOURCE -D_HIUX_SOURCE}"
#else
-#define CPP_SPEC "%{!mpa-risc-1-0:%{!mnosnake:%{!msoft-float:-D__hp9000s700 -D_PA_RISC1_1}}}"
+#define CPP_SPEC "%{!mpa-risc-1-0:%{!mnosnake:%{!msoft-float:-D__hp9000s700 -D_PA_RISC1_1}}} %{!ansi: -D_HPUX_SOURCE -D_HIUX_SOURCE}"
#endif
/* Defines for a K&R CC */
#define CC1_SPEC "%{pg:} %{p:}"
-#define LINK_SPEC "%{!shared:-u main} %{shared:-b}"
+#define LINK_SPEC "%{mlinker-opt:-O} %{!shared:-u main} %{shared:-b}"
/* We don't want -lg. */
#ifndef LIB_SPEC
/* Names to predefine in the preprocessor for this target machine. */
-#define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -Dunix -D_HPUX_SOURCE -Dhp9000 -Dhp800 -Dspectrum -DREVARGV -Asystem(unix) -Asystem(bsd) -Acpu(hppa) -Amachine(hppa)"
+#define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -Dunix -Dhp9000 -Dhp800 -Dspectrum -DREVARGV -Asystem(unix) -Asystem(bsd) -Acpu(hppa) -Amachine(hppa)"
/* HPUX has a program 'chatr' to list the dependencies of dynamically
linked executables and shared libraries. */
fprintf (FILE, ",ARGW%d=FR", (ARG1));} while (0)
#endif
+#define ASM_OUTPUT_FUNCTION_PREFIX(FILE, NAME) \
+ if (!TARGET_PORTABLE_RUNTIME && TARGET_GAS && in_section == in_text) \
+ fputs ("\t.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n", FILE);
+
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
do { tree fntype = TREE_TYPE (TREE_TYPE (DECL)); \
tree tree_type = TREE_TYPE (DECL); \
/* Define the .bss section for ASM_OUTPUT_LOCAL to use. */
+#ifndef CTORS_SECTION_FUNCTION
#define EXTRA_SECTIONS in_bss, in_readonly_data
+#define CTORS_SECTION_FUNCTION
+#define DTORS_SECTION_FUNCTION
+#else
+#define EXTRA_SECTIONS in_bss, in_readonly_data, in_ctors, in_dtors
+#endif
/* FIXME: HPUX ld generates incorrect GOT entries for "T" fixups
which reference data within the $TEXT$ space (for example constant
fprintf (asm_out_file, "%s\n", READONLY_DATA_ASM_OP); \
in_section = in_readonly_data; \
} \
-}
+} \
+CTORS_SECTION_FUNCTION \
+DTORS_SECTION_FUNCTION
/* How to refer to registers in assembler output.
fputc ('\n', FILE); } while (0)
/* This is how to output a command to make the user-level label named NAME
- defined for reference from other files. */
+ defined for reference from other files.
+
+ We call assemble_name, which in turn sets TREE_SYMBOL_REFERENCED. This
+ macro will restore the original value of TREE_SYMBOL_REFERENCED to avoid
+ placing useless function definitions in the output file. */
#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
- do { fputs ("\t.IMPORT ", FILE); \
+ do { int save_referenced; \
+ save_referenced = TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL)); \
+ fputs ("\t.IMPORT ", FILE); \
assemble_name (FILE, NAME); \
if (FUNCTION_NAME_P (NAME)) \
fputs (",CODE\n", FILE); \
else \
fputs (",DATA\n", FILE); \
+ TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL)) = save_referenced; \
} while (0)
/* The bogus HP assembler requires ALL external references to be
abort (); \
else if (flag_pic == 2) \
fputs ("RT'", FILE); \
- output_global_address (FILE, XEXP (addr, 1)); \
+ output_global_address (FILE, XEXP (addr, 1), 0); \
fputs ("(", FILE); \
output_operand (XEXP (addr, 0), 0); \
fputs (")", FILE); \
extern char *output_block_move ();
extern char *output_cbranch ();
extern char *output_bb ();
+extern char *output_bvb ();
extern char *output_dbra ();
extern char *output_movb ();
extern char *output_return ();
extern char *output_call ();
+extern char *output_millicode_call ();
extern char *output_mul_insn ();
extern char *output_div_insn ();
extern char *output_mod_insn ();
&& ! function_label_operand (operands[1])
&& ! read_only_operand (operands[1])
&& ! flag_pic"
- "addil LR'%G1,%%r27"
+ "addil LR'%H1,%%r27"
[(set_attr "type" "binary")
(set_attr "length" "4")])
"*
{
if (symbolic_operand (operands[1], Pmode))
- return \"ldil LR'%G1,%0\";
+ return \"ldil LR'%H1,%0\";
else
return \"ldil L'%G1,%0\";
}"
[(set_attr "type" "move")
(set_attr "length" "4")])
+;; These are just placeholders so we know where branch tables
+;; begin and end.
+(define_insn "begin_brtab"
+ [(const_int 1)]
+ "TARGET_GAS"
+ ".begin_brtab"
+ [(set_attr "type" "move")
+ (set_attr "length" "0")])
+
+(define_insn "end_brtab"
+ [(const_int 2)]
+ "TARGET_GAS"
+ ".end_brtab"
+ [(set_attr "type" "move")
+ (set_attr "length" "0")])
+
;;; Hope this is only within a function...
(define_insn "indirect_jump"
[(set (pc) (match_operand:SI 0 "register_operand" "r"))]
(set (match_operand 3 "register_operand" "+f")
(plus (match_operand 4 "register_operand" "f")
(match_operand 5 "register_operand" "f")))]
- "TARGET_SNAKE && fmpyaddoperands (operands)"
+ "! TARGET_SOFT_FLOAT && TARGET_SNAKE && fmpyaddoperands (operands)"
"*
{
if (GET_MODE (operands[0]) == DFmode)
(set (match_operand 0 "register_operand" "=f")
(mult (match_operand 1 "register_operand" "f")
(match_operand 2 "register_operand" "f")))]
- "TARGET_SNAKE && fmpyaddoperands (operands)"
+ "! TARGET_SOFT_FLOAT && TARGET_SNAKE && fmpyaddoperands (operands)"
"*
{
if (GET_MODE (operands[0]) == DFmode)
(set (match_operand 3 "register_operand" "+f")
(minus (match_operand 4 "register_operand" "f")
(match_operand 5 "register_operand" "f")))]
- "TARGET_SNAKE && fmpysuboperands (operands)"
+ "! TARGET_SOFT_FLOAT && TARGET_SNAKE && fmpysuboperands (operands)"
"*
{
if (GET_MODE (operands[0]) == DFmode)
(set (match_operand 0 "register_operand" "=f")
(mult (match_operand 1 "register_operand" "f")
(match_operand 2 "register_operand" "f")))]
- "TARGET_SNAKE && fmpysuboperands (operands)"
+ "! TARGET_SOFT_FLOAT && TARGET_SNAKE && fmpysuboperands (operands)"
"*
{
if (GET_MODE (operands[0]) == DFmode)
return \"fmpysub,sgl %1,%2,%0,%5,%3\";
}")
+;; Clean up turds left by reload.
+(define_peephole
+ [(set (match_operand 0 "reg_or_nonsymb_mem_operand" "")
+ (match_operand 1 "register_operand" "f"))
+ (set (match_operand 2 "register_operand" "f")
+ (match_dup 0))]
+ "! TARGET_SOFT_FLOAT
+ && GET_CODE (operands[0]) == MEM
+ && ! MEM_VOLATILE_P (operands[0])
+ && GET_MODE (operands[0]) == GET_MODE (operands[1])
+ && GET_MODE (operands[0]) == GET_MODE (operands[2])
+ && GET_MODE (operands[0]) == DFmode
+ && REGNO_REG_CLASS (REGNO (operands[1]))
+ == REGNO_REG_CLASS (REGNO (operands[2]))"
+ "*
+{
+ enum machine_mode mode = GET_MODE (operands[0]);
+ rtx xoperands[2];
+
+ if (FP_REG_P (operands[1]))
+ output_asm_insn (output_fp_move_double (operands), operands);
+ else
+ output_asm_insn (output_move_double (operands), operands);
+
+ if (rtx_equal_p (operands[1], operands[2]))
+ return \"\";
+
+ xoperands[0] = operands[2];
+ xoperands[1] = operands[1];
+
+ if (FP_REG_P (xoperands[1]))
+ output_asm_insn (output_fp_move_double (xoperands), xoperands);
+ else
+ output_asm_insn (output_move_double (xoperands), xoperands);
+
+ return \"\";
+}")
+
;; Flush the I and D cache line found at the address in operand 0.
;; This is used by the trampoline code for nested functions.
;; So long as the trampoline itself is less than 32 bytes this
ALLOCA=alloca.o
+
+# So putenv and other functions get seen by fixproto.
+FIXPROTO_DEFINES = -D_HPUX_SOURCE