Commit f17f9332 by Jakub Jelinek Committed by Jakub Jelinek

re PR c++/5964 (g++ generates code that results in "word displacement will not…

re PR c++/5964 (g++ generates code that results in "word displacement will not fit in 16 bits" on sparcv9)

	PR c++/5964
	* config/sparc/sparc.md (empty_delay_slot, branch_type): New
	attributes.
	(length): Compute variable length for branches/calls/jumps here.
	(branch, inverted_branch, normal_fp_branch, inverted_fp_branch,
	normal_fpe_branch, inverted_fpe_branch): Remove length attribute,
	define branch_type attribute.
	(divsi3_sp32): Maximum length is 6 not 7.
	(call_address_struct_value_sp32, call_symbolic_struct_value_sp32,
	call_address_untyped_struct_value_sp32,
	call_symbolic_untyped_struct_value_sp32): Set length to 3 not 2.
	* config/sparc/sparc.c (empty_delay_slot): New function.
	* config/sparc/sparc.h (ADJUST_INSN_LENGTH): Remove.
	* config/sparc/sparc-protos.h (empty_delay_slot): Add prototype.

	* g++.dg/opt/longbranch1.C: New test.

From-SVN: r51557
parent 13992aca
2002-03-29 Jakub Jelinek <jakub@redhat.com>
PR c++/5964
* config/sparc/sparc.md (empty_delay_slot, branch_type): New
attributes.
(length): Compute variable length for branches/calls/jumps here.
(branch, inverted_branch, normal_fp_branch, inverted_fp_branch,
normal_fpe_branch, inverted_fpe_branch): Remove length attribute,
define branch_type attribute.
(divsi3_sp32): Maximum length is 6 not 7.
(call_address_struct_value_sp32, call_symbolic_struct_value_sp32,
call_address_untyped_struct_value_sp32,
call_symbolic_untyped_struct_value_sp32): Set length to 3 not 2.
* config/sparc/sparc.c (empty_delay_slot): New function.
* config/sparc/sparc.h (ADJUST_INSN_LENGTH): Remove.
* config/sparc/sparc-protos.h (empty_delay_slot): Add prototype.
2002-03-29 Jakub Jelinek <jakub@redhat.com>
* combine.c (set_nonzero_bits_and_sign_copies): Don't call
nonzero_bits if not needed.
(nonzero_bits) [XOR]: Likewise.
......
......@@ -99,6 +99,7 @@ extern int arith_4096_operand PARAMS ((rtx, enum machine_mode));
extern int zero_operand PARAMS ((rtx, enum machine_mode));
extern int fp_zero_operand PARAMS ((rtx, enum machine_mode));
extern int reg_or_0_operand PARAMS ((rtx, enum machine_mode));
extern int empty_delay_slot PARAMS ((rtx));
extern int eligible_for_epilogue_delay PARAMS ((rtx, int));
extern int eligible_for_return_delay PARAMS ((rtx));
extern int eligible_for_sibcall_delay PARAMS ((rtx));
......
......@@ -2459,6 +2459,26 @@ leaf_return_peephole_ok ()
return (actual_fsize == 0);
}
/* Return nonzero if a branch/jump/call instruction will be emitting
nop into its delay slot. */
int
empty_delay_slot (insn)
rtx insn;
{
rtx seq;
/* If no previous instruction (should not happen), return true. */
if (PREV_INSN (insn) == NULL)
return 1;
seq = NEXT_INSN (PREV_INSN (insn));
if (GET_CODE (PATTERN (seq)) == SEQUENCE)
return 0;
return 1;
}
/* Return nonzero if TRIAL can go into the function epilogue's
delay slot. SLOT is the slot we are trying to fill. */
......
......@@ -2655,14 +2655,6 @@ do { \
case FIX: \
return 19;
/* Conditional branches with empty delay slots have a length of two. */
#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
do { \
if (GET_CODE (INSN) == CALL_INSN \
|| (GET_CODE (INSN) == JUMP_INSN && ! simplejump_p (insn))) \
LENGTH += 1; \
} while (0)
/* Control the assembler format that we output. */
/* Output at beginning of assembler file. */
......
......@@ -87,8 +87,75 @@
"ialu,compare,shift,load,sload,store,uncond_branch,branch,call,sibcall,call_no_delay_slot,return,imul,idiv,fpload,fpstore,fp,fpmove,fpcmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrts,fpsqrtd,cmove,multi,misc"
(const_string "ialu"))
;; true if branch/call has empty delay slot and will emit a nop in it
(define_attr "empty_delay_slot" "false,true"
(symbol_ref "empty_delay_slot (insn)"))
(define_attr "branch_type" "none,icc,fcc,reg" (const_string "none"))
;; Length (in # of insns).
(define_attr "length" "" (const_int 1))
(define_attr "length" ""
(cond [(eq_attr "type" "uncond_branch,call,sibcall")
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 2)
(const_int 1))
(eq_attr "branch_type" "icc")
(if_then_else (match_operand 0 "noov_compare64_op" "")
(if_then_else (lt (pc) (match_dup 1))
(if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 2)
(const_int 1))
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 4)
(const_int 3)))
(if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 2)
(const_int 1))
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 4)
(const_int 3))))
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 2)
(const_int 1)))
(eq_attr "branch_type" "fcc")
(if_then_else (match_operand 0 "fcc0_reg_operand" "")
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 2)
(const_int 1))
(if_then_else (lt (pc) (match_dup 2))
(if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 2)
(const_int 1))
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 4)
(const_int 3)))
(if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 2)
(const_int 1))
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 4)
(const_int 3)))))
(eq_attr "branch_type" "reg")
(if_then_else (lt (pc) (match_dup 2))
(if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 2)
(const_int 1))
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 4)
(const_int 3)))
(if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 2)
(const_int 1))
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 4)
(const_int 3))))
] (const_int 1)))
;; FP precision.
(define_attr "fptype" "single,double" (const_string "single"))
......@@ -1898,18 +1965,7 @@
! final_sequence, insn);
}"
[(set_attr "type" "branch")
(set (attr "length")
(if_then_else (match_operand 0 "noov_compare64_op" "")
(if_then_else (lt (pc) (match_dup 1))
(if_then_else (lt (minus (match_dup 1) (pc))
(const_int 260000))
(const_int 1)
(const_int 3))
(if_then_else (lt (minus (pc) (match_dup 1))
(const_int 260000))
(const_int 1)
(const_int 3)))
(const_int 1)))])
(set_attr "branch_type" "icc")])
;; XXX fpcmp nop braindamage
(define_insn "*inverted_branch"
......@@ -1926,18 +1982,7 @@
! final_sequence, insn);
}"
[(set_attr "type" "branch")
(set (attr "length")
(if_then_else (match_operand 0 "noov_compare64_op" "")
(if_then_else (lt (pc) (match_dup 1))
(if_then_else (lt (minus (match_dup 1) (pc))
(const_int 260000))
(const_int 1)
(const_int 3))
(if_then_else (lt (minus (pc) (match_dup 1))
(const_int 260000))
(const_int 1)
(const_int 3)))
(const_int 1)))])
(set_attr "branch_type" "icc")])
;; XXX fpcmp nop braindamage
(define_insn "*normal_fp_branch"
......@@ -1955,18 +2000,7 @@
! final_sequence, insn);
}"
[(set_attr "type" "branch")
(set (attr "length")
(if_then_else (match_operand 0 "fcc0_reg_operand" "")
(const_int 1)
(if_then_else (lt (pc) (match_dup 2))
(if_then_else (lt (minus (match_dup 2) (pc))
(const_int 260000))
(const_int 1)
(const_int 3))
(if_then_else (lt (minus (pc) (match_dup 2))
(const_int 260000))
(const_int 1)
(const_int 3)))))])
(set_attr "branch_type" "fcc")])
;; XXX fpcmp nop braindamage
(define_insn "*inverted_fp_branch"
......@@ -1984,18 +2018,7 @@
! final_sequence, insn);
}"
[(set_attr "type" "branch")
(set (attr "length")
(if_then_else (match_operand 0 "fcc0_reg_operand" "")
(const_int 1)
(if_then_else (lt (pc) (match_dup 2))
(if_then_else (lt (minus (match_dup 2) (pc))
(const_int 260000))
(const_int 1)
(const_int 3))
(if_then_else (lt (minus (pc) (match_dup 2))
(const_int 260000))
(const_int 1)
(const_int 3)))))])
(set_attr "branch_type" "fcc")])
;; XXX fpcmp nop braindamage
(define_insn "*normal_fpe_branch"
......@@ -2013,18 +2036,7 @@
! final_sequence, insn);
}"
[(set_attr "type" "branch")
(set (attr "length")
(if_then_else (match_operand 0 "fcc0_reg_operand" "")
(const_int 1)
(if_then_else (lt (pc) (match_dup 2))
(if_then_else (lt (minus (match_dup 2) (pc))
(const_int 260000))
(const_int 1)
(const_int 3))
(if_then_else (lt (minus (pc) (match_dup 2))
(const_int 260000))
(const_int 1)
(const_int 3)))))])
(set_attr "branch_type" "fcc")])
;; XXX fpcmp nop braindamage
(define_insn "*inverted_fpe_branch"
......@@ -2042,18 +2054,7 @@
! final_sequence, insn);
}"
[(set_attr "type" "branch")
(set (attr "length")
(if_then_else (match_operand 0 "fcc0_reg_operand" "")
(const_int 1)
(if_then_else (lt (pc) (match_dup 2))
(if_then_else (lt (minus (match_dup 2) (pc))
(const_int 260000))
(const_int 1)
(const_int 3))
(if_then_else (lt (minus (pc) (match_dup 2))
(const_int 260000))
(const_int 1)
(const_int 3)))))])
(set_attr "branch_type" "fcc")])
;; Sparc V9-specific jump insns. None of these are guaranteed to be
;; in the architecture.
......@@ -2076,16 +2077,7 @@
! final_sequence, insn);
}"
[(set_attr "type" "branch")
(set (attr "length")
(if_then_else (lt (pc) (match_dup 2))
(if_then_else (lt (minus (match_dup 2) (pc))
(const_int 32000))
(const_int 1)
(const_int 3))
(if_then_else (lt (minus (pc) (match_dup 2))
(const_int 32000))
(const_int 1)
(const_int 3))))])
(set_attr "branch_type" "reg")])
;; XXX
(define_insn "*inverted_int_branch_sp64"
......@@ -2103,16 +2095,7 @@
! final_sequence, insn);
}"
[(set_attr "type" "branch")
(set (attr "length")
(if_then_else (lt (pc) (match_dup 2))
(if_then_else (lt (minus (match_dup 2) (pc))
(const_int 32000))
(const_int 1)
(const_int 3))
(if_then_else (lt (minus (pc) (match_dup 2))
(const_int 32000))
(const_int 1)
(const_int 3))))])
(set_attr "branch_type" "reg")])
;; Load program counter insns.
......@@ -6473,7 +6456,7 @@
[(set_attr "type" "multi")
(set (attr "length")
(if_then_else (eq_attr "isa" "v9")
(const_int 4) (const_int 7)))])
(const_int 4) (const_int 6)))])
(define_insn "divsi3_sp64"
[(set (match_operand:SI 0 "register_operand" "=r")
......@@ -8499,7 +8482,7 @@
"! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
"call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
[(set_attr "type" "call_no_delay_slot")
(set_attr "length" "2")])
(set_attr "length" "3")])
;; This is a call that wants a structure value.
;; There is no such critter for v9 (??? we may need one anyway).
......@@ -8512,7 +8495,7 @@
"! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
"call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
[(set_attr "type" "call_no_delay_slot")
(set_attr "length" "2")])
(set_attr "length" "3")])
;; This is a call that may want a structure value. This is used for
;; untyped_calls.
......@@ -8525,7 +8508,7 @@
"! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
"call\\t%a0, %1\\n\\tnop\\n\\tnop"
[(set_attr "type" "call_no_delay_slot")
(set_attr "length" "2")])
(set_attr "length" "3")])
;; This is a call that wants a structure value.
(define_insn "*call_symbolic_untyped_struct_value_sp32"
......@@ -8537,7 +8520,7 @@
"! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
"call\\t%a0, %1\\n\\tnop\\n\\tnop"
[(set_attr "type" "call_no_delay_slot")
(set_attr "length" "2")])
(set_attr "length" "3")])
(define_expand "call_value"
;; Note that this expression is not used for generating RTL.
......
......@@ -2,6 +2,8 @@
* g++.dg/opt/static1.C: New test.
* g++.dg/opt/longbranch1.C: New test.
2002-03-28 Hans-Peter Nilsson <hp@bitrange.com>
* gcc.dg/weak-1.c: Fix typo in scan-assembler pattern.
......
// PR c++/5964
// This testcase failed to link on sparc -m64 -O0, because instruction
// lengths were incorrectly computed
// { dg-do link }
// { dg-options "-O0" }
#define makecode for (int i = 1; i < 1000; ++i) i *= 3
#define muchcode \
makecode; makecode; makecode; makecode; makecode; makecode; \
makecode; makecode; makecode; makecode; makecode; makecode; \
makecode; makecode; makecode; makecode; makecode; makecode; \
makecode; makecode; makecode; makecode; makecode; makecode
#define verymuchcode \
muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \
muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \
muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \
muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \
muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \
muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \
muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \
muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \
muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \
muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \
muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \
muchcode; muchcode; muchcode; muchcode; muchcode; muchcode; \
muchcode; muchcode; muchcode; muchcode; muchcode; muchcode
int
main (int argc, char **argv)
{
loop:
verymuchcode;
delete[] argv;
goto loop;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment