[parisc-linux-cvs] Re: 64 bit compiler bug
amodra@one.net.au
amodra@one.net.au
Thu, 31 May 2001 00:31:09 +0930
Here's what I finally commited to fix the 64-bit millicode call bug
(first group in Changelog), and a few other small fixes/enhancements.
The diff below for pa.md is against the source as it was before I
started attempting to fix the millicode problem as it shows the
final change better that way.
gcc/ChangeLog.puffin
* config/pa/pa.c (emit_hpdiv_const): Return reg is r2 for 64-bit
millicode.
(insn_refs_are_delayed): Correct comment.
* config/pa/pa.h (INSN_REFERENCES_ARE_DELAYED): Likewise.
* config/pa/pa.md (mulsi3): If TARGET_64BIT, clobber r2
instead of r31. Make associated insn !TARGET_64BIT, and
provide an additional 64-bit insn that clobbers r2.
(divsi3): Likewise.
(udivsi3): Likewise.
(modsi3): Likewise.
(umodsi3): Likewise.
* config/pa/pa.c (hppa_init_pic_save): Revert back to saving pic
register after last_parm_insn.
(compute_frame_size): 64-bit frame marker is 16 bytes.
* config/pa/pa-linux.h (FUNCTION_OK_FOR_SIBCALL): Define as 1.
(CC1_SPEC): Define with -mno-space-regs as default.
Index: config/pa/pa-linux.h
===================================================================
RCS file: /home/cvs/parisc/gcc/gcc/config/pa/pa-linux.h,v
retrieving revision 1.21
diff -u -p -r1.21 pa-linux.h
--- pa-linux.h 2001/05/01 12:40:14 1.21
+++ pa-linux.h 2001/05/30 14:23:50
@@ -31,6 +31,9 @@ Boston, MA 02111-1307, USA. */
#undef CPLUSPLUS_CPP_SPEC
+#undef CC1_SPEC
+#define CC1_SPEC "%{pg:} %{p:} %{!mspace-regs:-mno-space-regs}"
+
#undef LIB_SPEC
#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
@@ -50,9 +53,8 @@ Boston, MA 02111-1307, USA. */
%{!dynamic-linker:-dynamic-linker /lib/ld.so.1}} \
%{static:-static}}"
-/* Sibcalls, stubs, and elf sections don't play well. */
#undef FUNCTION_OK_FOR_SIBCALL
-#define FUNCTION_OK_FOR_SIBCALL(x) 0
+#define FUNCTION_OK_FOR_SIBCALL(DECL) 1
/* glibc's profiling functions don't need gcc to allocate counters. */
#define NO_PROFILE_COUNTERS 1
Index: config/pa/pa.c
===================================================================
RCS file: /home/cvs/parisc/gcc/gcc/config/pa/pa.c,v
retrieving revision 1.21
diff -u -p -r1.21 pa.c
--- pa.c 2001/04/17 00:45:01 1.21
+++ pa.c 2001/05/30 14:24:31
@@ -2925,7 +2925,7 @@ compute_frame_size (size, fregs_live)
allocated for any function that makes calls or otherwise allocates
stack space. */
if (!current_function_is_leaf || fsize)
- fsize += 32;
+ fsize += TARGET_64BIT ? 16 : 32;
return (fsize + STACK_BOUNDARY - 1) & ~(STACK_BOUNDARY - 1);
}
@@ -3271,7 +3271,6 @@ hppa_expand_prologue ()
}
}
-
void
output_function_epilogue (file, size)
FILE *file;
@@ -3429,7 +3428,7 @@ hppa_expand_epilogue ()
void
hppa_init_pic_save ()
{
- rtx insn, picreg;
+ rtx insn, picreg, where;
picreg = gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM);
PIC_OFFSET_TABLE_SAVE_RTX = gen_reg_rtx (Pmode);
@@ -3437,11 +3436,14 @@ hppa_init_pic_save ()
insn = gen_rtx_SET (VOIDmode, PIC_OFFSET_TABLE_SAVE_RTX, picreg);
/* Emit the insn at the beginning of the function after the prologue. */
- if (tail_recursion_reentry)
- emit_insn_before (insn, tail_recursion_reentry);
- else
- /* We must have been called via PROFILE_HOOK. */
- emit_insn (insn);
+ where = last_parm_insn;
+ if (!where)
+ {
+ push_topmost_sequence ();
+ where = get_insns ();
+ pop_topmost_sequence ();
+ }
+ emit_insn_after (insn, where);
}
void
@@ -4535,6 +4537,8 @@ emit_hpdiv_const (operands, unsignedp)
&& INTVAL (operands[2]) < 16
&& magic_milli[INTVAL (operands[2])])
{
+ rtx ret = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
+
emit_move_insn (gen_rtx_REG (SImode, 26), operands[1]);
emit
(gen_rtx
@@ -4548,7 +4552,7 @@ emit_hpdiv_const (operands, unsignedp)
gen_rtx_CLOBBER (VOIDmode, operands[3]),
gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 26)),
gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 25)),
- gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 31)))));
+ gen_rtx_CLOBBER (VOIDmode, ret))));
emit_move_insn (operands[0], gen_rtx_REG (SImode, 29));
return 1;
}
@@ -6989,12 +6993,18 @@ pa_can_combine_p (new, anchor, floater,
Millicode calls always expect their arguments in the integer argument
registers, and always return their result in %r29 (ret1). They
- are expected to clobber their arguments, %r1, %r29, and %r31 and
- nothing else.
+ are expected to clobber their arguments, %r1, %r29, and the return
+ pointer which is %r31 on 32-bit and %r2 on 64-bit, and nothing else.
- By considering this effects delayed reorg reorg can put insns
- which set the argument registers into the delay slot of the millicode
- call -- thus they act more like traditional CALL_INSNs.
+ This function tells reorg that the references to arguments and
+ millicode calls do not appear to happen until after the millicode call.
+ This allows reorg to put insns which set the argument registers into the
+ delay slot of the millicode call -- thus they act more like traditional
+ CALL_INSNs.
+
+ Note we can not consider side effects of the insn to be delayed because
+ the branch and link insn will clobber the return pointer. If we happened
+ to use the return pointer in the delay slot of the call, then we lose.
get_attr_type will try to recognize the given insn, so make sure to
filter out things it will not accept -- SEQUENCE, USE and CLOBBER insns
Index: config/pa/pa.h
===================================================================
RCS file: /home/cvs/parisc/gcc/gcc/config/pa/pa.h,v
retrieving revision 1.13
diff -u -p -r1.13 pa.h
--- pa.h 2001/05/01 12:40:14 1.13
+++ pa.h 2001/05/30 14:24:53
@@ -1736,8 +1736,8 @@ while (0)
Millicode calls always expect their arguments in the integer argument
registers, and always return their result in %r29 (ret1). They
- are expected to clobber their arguments, %r1, %r29, and %r31 and
- nothing else.
+ are expected to clobber their arguments, %r1, %r29, and the return
+ pointer which is %r31 on 32-bit and %r2 on 64-bit, and nothing else.
This macro tells reorg that the references to arguments and
millicode calls do not appear to happen until after the millicode call.
Index: config/pa/pa.md
===================================================================
RCS file: /home/cvs/parisc/gcc/gcc/config/pa/pa.md,v
retrieving revision 1.7
diff -u -p -r1.7 pa.md
--- pa.md 2001/04/17 00:45:01 1.7
+++ pa.md 2001/05/30 14:33:32
@@ -3869,11 +3869,12 @@
(clobber (match_dup 3))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
- (clobber (reg:SI 31))])
+ (clobber (match_dup 4))])
(set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
""
"
{
+ operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
if (TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT)
{
rtx scratch = gen_reg_rtx (DImode);
@@ -3930,7 +3931,7 @@
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 31))]
- ""
+ "!TARGET_64BIT"
"* return output_mul_insn (0, insn);"
[(set_attr "type" "milli")
(set (attr "length")
@@ -3955,6 +3956,17 @@
;; Out of reach, can use ble
(const_int 12)))])
+(define_insn ""
+ [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
+ (clobber (match_operand:SI 0 "register_operand" "=a"))
+ (clobber (reg:SI 26))
+ (clobber (reg:SI 25))
+ (clobber (reg:SI 2))]
+ "TARGET_64BIT"
+ "* return output_mul_insn (0, insn);"
+ [(set_attr "type" "milli")
+ (set (attr "length") (const_int 4))])
+
(define_expand "muldi3"
[(set (match_operand:DI 0 "register_operand" "")
(mult:DI (match_operand:DI 1 "register_operand" "")
@@ -4012,15 +4024,22 @@
(clobber (match_dup 4))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
- (clobber (reg:SI 31))])
+ (clobber (match_dup 5))])
(set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
""
"
{
operands[3] = gen_reg_rtx (SImode);
- operands[4] = gen_reg_rtx (SImode);
if (TARGET_64BIT)
- operands[4] = gen_rtx_REG (SImode, 2);
+ {
+ operands[5] = gen_rtx_REG (SImode, 2);
+ operands[4] = operands[5];
+ }
+ else
+ {
+ operands[5] = gen_rtx_REG (SImode, 31);
+ operands[4] = gen_reg_rtx (SImode);
+ }
if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0))
DONE;
}")
@@ -4033,7 +4052,7 @@
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 31))]
- ""
+ "!TARGET_64BIT"
"*
return output_div_insn (operands, 0, insn);"
[(set_attr "type" "milli")
@@ -4059,6 +4078,20 @@
;; Out of reach, can use ble
(const_int 12)))])
+(define_insn ""
+ [(set (reg:SI 29)
+ (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
+ (clobber (match_operand:SI 1 "register_operand" "=a"))
+ (clobber (match_operand:SI 2 "register_operand" "=&r"))
+ (clobber (reg:SI 26))
+ (clobber (reg:SI 25))
+ (clobber (reg:SI 2))]
+ "TARGET_64BIT"
+ "*
+ return output_div_insn (operands, 0, insn);"
+ [(set_attr "type" "milli")
+ (set (attr "length") (const_int 4))])
+
(define_expand "udivsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
(set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
@@ -4067,15 +4100,22 @@
(clobber (match_dup 4))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
- (clobber (reg:SI 31))])
+ (clobber (match_dup 5))])
(set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
""
"
{
operands[3] = gen_reg_rtx (SImode);
- operands[4] = gen_reg_rtx (SImode);
if (TARGET_64BIT)
- operands[4] = gen_rtx_REG (SImode, 2);
+ {
+ operands[5] = gen_rtx_REG (SImode, 2);
+ operands[4] = operands[5];
+ }
+ else
+ {
+ operands[5] = gen_rtx_REG (SImode, 31);
+ operands[4] = gen_reg_rtx (SImode);
+ }
if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1))
DONE;
}")
@@ -4088,7 +4128,7 @@
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 31))]
- ""
+ "!TARGET_64BIT"
"*
return output_div_insn (operands, 1, insn);"
[(set_attr "type" "milli")
@@ -4114,6 +4154,20 @@
;; Out of reach, can use ble
(const_int 12)))])
+(define_insn ""
+ [(set (reg:SI 29)
+ (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
+ (clobber (match_operand:SI 1 "register_operand" "=a"))
+ (clobber (match_operand:SI 2 "register_operand" "=&r"))
+ (clobber (reg:SI 26))
+ (clobber (reg:SI 25))
+ (clobber (reg:SI 2))]
+ "TARGET_64BIT"
+ "*
+ return output_div_insn (operands, 1, insn);"
+ [(set_attr "type" "milli")
+ (set (attr "length") (const_int 4))])
+
(define_expand "modsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
(set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
@@ -4122,14 +4176,21 @@
(clobber (match_dup 4))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
- (clobber (reg:SI 31))])
+ (clobber (match_dup 5))])
(set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
""
"
{
- operands[4] = gen_reg_rtx (SImode);
if (TARGET_64BIT)
- operands[4] = gen_rtx_REG (SImode, 2);
+ {
+ operands[5] = gen_rtx_REG (SImode, 2);
+ operands[4] = operands[5];
+ }
+ else
+ {
+ operands[5] = gen_rtx_REG (SImode, 31);
+ operands[4] = gen_reg_rtx (SImode);
+ }
operands[3] = gen_reg_rtx (SImode);
}")
@@ -4140,7 +4201,7 @@
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 31))]
- ""
+ "!TARGET_64BIT"
"*
return output_mod_insn (0, insn);"
[(set_attr "type" "milli")
@@ -4166,6 +4227,19 @@
;; Out of reach, can use ble
(const_int 12)))])
+(define_insn ""
+ [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
+ (clobber (match_operand:SI 0 "register_operand" "=a"))
+ (clobber (match_operand:SI 1 "register_operand" "=&r"))
+ (clobber (reg:SI 26))
+ (clobber (reg:SI 25))
+ (clobber (reg:SI 2))]
+ "TARGET_64BIT"
+ "*
+ return output_mod_insn (0, insn);"
+ [(set_attr "type" "milli")
+ (set (attr "length") (const_int 4))])
+
(define_expand "umodsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
(set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
@@ -4174,14 +4248,21 @@
(clobber (match_dup 4))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
- (clobber (reg:SI 31))])
+ (clobber (match_dup 5))])
(set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
""
"
{
- operands[4] = gen_reg_rtx (SImode);
if (TARGET_64BIT)
- operands[4] = gen_rtx_REG (SImode, 2);
+ {
+ operands[5] = gen_rtx_REG (SImode, 2);
+ operands[4] = operands[5];
+ }
+ else
+ {
+ operands[5] = gen_rtx_REG (SImode, 31);
+ operands[4] = gen_reg_rtx (SImode);
+ }
operands[3] = gen_reg_rtx (SImode);
}")
@@ -4192,7 +4273,7 @@
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 31))]
- ""
+ "!TARGET_64BIT"
"*
return output_mod_insn (1, insn);"
[(set_attr "type" "milli")
@@ -4217,6 +4298,19 @@
;; Out of reach, can use ble
(const_int 12)))])
+
+(define_insn ""
+ [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
+ (clobber (match_operand:SI 0 "register_operand" "=a"))
+ (clobber (match_operand:SI 1 "register_operand" "=&r"))
+ (clobber (reg:SI 26))
+ (clobber (reg:SI 25))
+ (clobber (reg:SI 2))]
+ "TARGET_64BIT"
+ "*
+ return output_mod_insn (1, insn);"
+ [(set_attr "type" "milli")
+ (set (attr "length") (const_int 4))])
;;- and instructions
;; We define DImode `and` so with DImode `not` we can get