This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH]: Fix space register usage under hppa-unknown-linux-gnu
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 6 Feb 2003 16:57:10 -0500 (EST)
- Subject: [PATCH]: Fix space register usage under hppa-unknown-linux-gnu
The hppa-unknown-linux-gnu port uses a flat address model (i.e., the same
space register values are used in space registers 4-7). We have been
incorrectly treating the port the same as hpux which doesn't have a flat
address model.
This patch sets MASK_NO_SPACE_REGS in the target default causing
TARGET_NO_SPACE_REGS to be true. The code generation has also been
improved for a number of situations where we do external branches
and don't need to load the new space register for the branch
destination. This is fixing new code introduced for EH support
and during the call rewrite for 3.3.
Installed to 3.3 and trunk. Tested on hppa-unknown-linux-gnu,
hppa64-hp-hpux11.11 and hppa2.0-hp-hpux11.11, 3.3 and main.
I also did some additional tests on hppa-linux using "-mlong-calls"
and "-mlong-calls -fPIC" to completely test the new code.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6605)
2003-02-06 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* config.gcc (hppa*-*-linux*): Set MASK_NO_SPACE_REGS in
target_cpu_default.
* pa.c (attr_length_call): Add 8 to call length (long indirect PA 1.X)
if not MASK_NO_SPACE_REGS.
(output_call): Adjust return pointer, don't load new space register
into %sr0, and use %sr4 for call if TARGET_NO_SPACE_REGS is true.
(pa_asm_output_mi_thunk): Don't load new space register into %sr0 if
TARGET_NO_SPACE_REGS is true.
* pa.md (return_external_pic): Add TARGET_NO_SPACE_REGS to insn
conditions.
(epilogue): Always use return_internal if TARGET_NO_SPACE_REGS is true.
(interspace_jump): Add new pattern for when TARGET_NO_SPACE_REGS is
true. Use bve when TARGET_64BIT is true.
Index: config.gcc
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config.gcc,v
retrieving revision 1.280
diff -u -3 -p -r1.280 config.gcc
--- config.gcc 30 Jan 2003 14:22:50 -0000 1.280
+++ config.gcc 4 Feb 2003 16:07:07 -0000
@@ -780,7 +780,7 @@ hppa*64*-*-linux* | parisc*64*-*-linux*)
need_64bit_hwint=yes
;;
hppa*-*-linux* | parisc*-*-linux*)
- target_cpu_default="MASK_PA_11"
+ target_cpu_default="MASK_PA_11 | MASK_NO_SPACE_REGS"
tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h pa/pa-linux.h \
pa/pa32-regs.h pa/pa32-linux.h"
tmake_file="t-slibgcc-elf-ver t-linux pa/t-linux"
Index: config/pa/pa.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa.c,v
retrieving revision 1.197
diff -u -3 -p -r1.197 pa.c
--- config/pa/pa.c 2 Feb 2003 06:04:58 -0000 1.197
+++ config/pa/pa.c 4 Feb 2003 16:07:07 -0000
@@ -6532,10 +6532,13 @@ attr_length_call (insn, sibcall)
if (TARGET_PA_20)
return (length + 32);
+ if (!TARGET_NO_SPACE_REGS)
+ length += 8;
+
if (!sibcall)
length += 8;
- return (length + 40);
+ return (length + 32);
}
}
}
@@ -6730,7 +6733,10 @@ output_call (insn, call_dest, sibcall)
if (!sibcall && !TARGET_PA_20)
{
output_asm_insn ("{bl|b,l} .+8,%%r2", xoperands);
- output_asm_insn ("addi 16,%%r2,%%r2", xoperands);
+ if (TARGET_NO_SPACE_REGS)
+ output_asm_insn ("addi 8,%%r2,%%r2", xoperands);
+ else
+ output_asm_insn ("addi 16,%%r2,%%r2", xoperands);
}
}
@@ -6752,14 +6758,23 @@ output_call (insn, call_dest, sibcall)
}
else
{
- output_asm_insn ("ldsid (%%r1),%%r31\n\tmtsp %%r31,%%sr0",
- xoperands);
+ if (!TARGET_NO_SPACE_REGS)
+ output_asm_insn ("ldsid (%%r1),%%r31\n\tmtsp %%r31,%%sr0",
+ xoperands);
if (sibcall)
- output_asm_insn ("be 0(%%sr0,%%r1)", xoperands);
+ {
+ if (TARGET_NO_SPACE_REGS)
+ output_asm_insn ("be 0(%%sr4,%%r1)", xoperands);
+ else
+ output_asm_insn ("be 0(%%sr0,%%r1)", xoperands);
+ }
else
{
- output_asm_insn ("ble 0(%%sr0,%%r1)", xoperands);
+ if (TARGET_NO_SPACE_REGS)
+ output_asm_insn ("ble 0(%%sr4,%%r1)", xoperands);
+ else
+ output_asm_insn ("ble 0(%%sr0,%%r1)", xoperands);
if (indirect_call)
output_asm_insn ("stw %%r31,-24(%%sp)", xoperands);
@@ -7026,7 +7041,7 @@ pa_asm_output_mi_thunk (file, thunk_fnde
pa_output_function_prologue (file, 0);
if (VAL_14_BITS_P (delta))
{
- if (! TARGET_64BIT && ! TARGET_PORTABLE_RUNTIME && flag_pic)
+ if (!TARGET_64BIT && !TARGET_PORTABLE_RUNTIME && flag_pic)
{
fprintf (file, "\taddil LT'%s,%%r19\n", lab);
fprintf (file, "\tldw RT'%s(%%r1),%%r22\n", lab);
@@ -7035,8 +7050,14 @@ pa_asm_output_mi_thunk (file, thunk_fnde
fprintf (file, "\tdepi 0,31,2,%%r22\n");
fprintf (file, "\tldw 4(%%sr0,%%r22),%%r19\n");
fprintf (file, "\tldw 0(%%sr0,%%r22),%%r22\n");
- fprintf (file, "\tldsid (%%sr0,%%r22),%%r1\n\tmtsp %%r1,%%sr0\n");
- fprintf (file, "\tbe 0(%%sr0,%%r22)\n\tldo ");
+ if (TARGET_NO_SPACE_REGS)
+ fprintf (file, "\tbe 0(%%sr4,%%r22)\n\tldo ");
+ else
+ {
+ fprintf (file, "\tldsid (%%sr0,%%r22),%%r1\n");
+ fprintf (file, "\tmtsp %%r1,%%sr0\n");
+ fprintf (file, "\tbe 0(%%sr0,%%r22)\n\tldo ");
+ }
fprintf (file, HOST_WIDE_INT_PRINT_DEC, delta);
fprintf (file, "(%%r26),%%r26\n");
}
@@ -7049,7 +7070,7 @@ pa_asm_output_mi_thunk (file, thunk_fnde
}
else
{
- if (! TARGET_64BIT && ! TARGET_PORTABLE_RUNTIME && flag_pic)
+ if (!TARGET_64BIT && !TARGET_PORTABLE_RUNTIME && flag_pic)
{
fprintf (file, "\taddil L'");
fprintf (file, HOST_WIDE_INT_PRINT_DEC, delta);
@@ -7063,8 +7084,14 @@ pa_asm_output_mi_thunk (file, thunk_fnde
fprintf (file, "\tdepi 0,31,2,%%r22\n");
fprintf (file, "\tldw 4(%%sr0,%%r22),%%r19\n");
fprintf (file, "\tldw 0(%%sr0,%%r22),%%r22\n");
- fprintf (file, "\tldsid (%%sr0,%%r22),%%r1\n\tmtsp %%r1,%%sr0\n");
- fprintf (file, "\tbe,n 0(%%sr0,%%r22)\n");
+ if (TARGET_NO_SPACE_REGS)
+ fprintf (file, "\tbe 0(%%sr4,%%r22)");
+ else
+ {
+ fprintf (file, "\tldsid (%%sr0,%%r22),%%r1\n");
+ fprintf (file, "\tmtsp %%r1,%%sr0\n");
+ fprintf (file, "\tbe,n 0(%%sr0,%%r22)\n");
+ }
}
else
{
Index: config/pa/pa.md
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa.md,v
retrieving revision 1.119
diff -u -3 -p -r1.119 pa.md
--- config/pa/pa.md 2 Feb 2003 06:04:58 -0000 1.119
+++ config/pa/pa.md 4 Feb 2003 16:07:08 -0000
@@ -5629,7 +5629,7 @@
[(return)
(clobber (reg:SI 1))
(use (reg:SI 2))]
- "flag_pic && current_function_calls_eh_return"
+ "!TARGET_NO_SPACE_REGS && flag_pic && current_function_calls_eh_return"
"ldsid (%%sr0,%%r2),%%r1\;mtsp %%r1,%%sr0\;be%* 0(%%sr0,%%r2)"
[(set_attr "type" "branch")
(set_attr "length" "12")])
@@ -5665,8 +5665,10 @@
/* EH returns bypass the normal return stub. Thus, we must do an
interspace branch to return from functions that call eh_return.
- This is only a problem for returns from shared code. */
- if (flag_pic && current_function_calls_eh_return)
+ This is only a problem for returns from shared code on ports
+ using space registers. */
+ if (!TARGET_NO_SPACE_REGS
+ && flag_pic && current_function_calls_eh_return)
x = gen_return_external_pic ();
else
x = gen_return_internal ();
@@ -6997,7 +6999,8 @@
;;; EH does longjmp's from and within the data section. Thus,
;;; an interspace branch is required for the longjmp implementation.
-;;; Registers r1 and r2 are used as scratch registers for the jump.
+;;; Registers r1 and r2 are used as scratch registers for the jump
+;;; when necessary.
(define_expand "interspace_jump"
[(parallel
[(set (pc) (match_operand 0 "pmode_register_operand" "a"))
@@ -7011,6 +7014,22 @@
(define_insn ""
[(set (pc) (match_operand 0 "pmode_register_operand" "a"))
(clobber (reg:SI 2))]
+ "TARGET_PA_20 && !TARGET_64BIT"
+ "bve%* (%0)"
+ [(set_attr "type" "branch")
+ (set_attr "length" "4")])
+
+(define_insn ""
+ [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
+ (clobber (reg:SI 2))]
+ "TARGET_NO_SPACE_REGS && !TARGET_64BIT"
+ "be%* 0(%%sr4,%0)"
+ [(set_attr "type" "branch")
+ (set_attr "length" "4")])
+
+(define_insn ""
+ [(set (pc) (match_operand 0 "pmode_register_operand" "a"))
+ (clobber (reg:SI 2))]
"!TARGET_64BIT"
"ldsid (%%sr0,%0),%%r2\; mtsp %%r2,%%sr0\; be%* 0(%%sr0,%0)"
[(set_attr "type" "branch")
@@ -7020,9 +7039,9 @@
[(set (pc) (match_operand 0 "pmode_register_operand" "a"))
(clobber (reg:DI 2))]
"TARGET_64BIT"
- "ldsid (%%sr0,%0),%%r2\; mtsp %%r2,%%sr0\; be%* 0(%%sr0,%0)"
+ "bve%* (%0)"
[(set_attr "type" "branch")
- (set_attr "length" "12")])
+ (set_attr "length" "4")])
(define_expand "builtin_longjmp"
[(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]