re PR target/38287 (segfault at -O2 -fPIC -mcpu=v8)
PR target/38287 * config/sparc/sparc.md (divsi3 expander): Remove constraints. (divsi3_sp32): Add new alternative with 'K' for operand #2. (cmp_sdiv_cc_set): Factor common string. (udivsi3_sp32): Add new alternative with 'K' for operand #2. Add TARGET_V9 case. (cmp_udiv_cc_set): Factor common string. From-SVN: r142295
This commit is contained in:
parent
07c9463afe
commit
72b415c586
4 changed files with 131 additions and 42 deletions
|
@ -1,3 +1,13 @@
|
|||
2008-11-30 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
PR target/38287
|
||||
* config/sparc/sparc.md (divsi3 expander): Remove constraints.
|
||||
(divsi3_sp32): Add new alternative with 'K' for operand #2.
|
||||
(cmp_sdiv_cc_set): Factor common string.
|
||||
(udivsi3_sp32): Add new alternative with 'K' for operand #2.
|
||||
Add TARGET_V9 case.
|
||||
(cmp_udiv_cc_set): Factor common string.
|
||||
|
||||
2008-11-30 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
|
||||
|
||||
PR middle-end/38283
|
||||
|
|
|
@ -4895,14 +4895,11 @@
|
|||
[(set_attr "type" "multi")
|
||||
(set_attr "length" "2")])
|
||||
|
||||
;; The V8 architecture specifies that there must be 3 instructions between
|
||||
;; a Y register write and a use of it for correct results.
|
||||
|
||||
(define_expand "divsi3"
|
||||
[(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
|
||||
(div:SI (match_operand:SI 1 "register_operand" "r,r")
|
||||
(match_operand:SI 2 "input_operand" "rI,m")))
|
||||
(clobber (match_scratch:SI 3 "=&r,&r"))])]
|
||||
[(parallel [(set (match_operand:SI 0 "register_operand" "")
|
||||
(div:SI (match_operand:SI 1 "register_operand" "")
|
||||
(match_operand:SI 2 "input_operand" "")))
|
||||
(clobber (match_scratch:SI 3 ""))])]
|
||||
"TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
|
||||
{
|
||||
if (TARGET_ARCH64)
|
||||
|
@ -4915,24 +4912,40 @@
|
|||
}
|
||||
})
|
||||
|
||||
;; The V8 architecture specifies that there must be at least 3 instructions
|
||||
;; between a write to the Y register and a use of it for correct results.
|
||||
;; We try to fill one of them with a simple constant or a memory load.
|
||||
|
||||
(define_insn "divsi3_sp32"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,r")
|
||||
(div:SI (match_operand:SI 1 "register_operand" "r,r")
|
||||
(match_operand:SI 2 "input_operand" "rI,m")))
|
||||
(clobber (match_scratch:SI 3 "=&r,&r"))]
|
||||
"(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
|
||||
&& TARGET_ARCH32"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
|
||||
(div:SI (match_operand:SI 1 "register_operand" "r,r,r")
|
||||
(match_operand:SI 2 "input_operand" "rI,K,m")))
|
||||
(clobber (match_scratch:SI 3 "=&r,&r,&r"))]
|
||||
"(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
|
||||
{
|
||||
if (which_alternative == 0)
|
||||
if (TARGET_V9)
|
||||
return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
|
||||
else
|
||||
return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
|
||||
else
|
||||
if (TARGET_V9)
|
||||
return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
|
||||
else
|
||||
return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
|
||||
output_asm_insn ("sra\t%1, 31, %3", operands);
|
||||
output_asm_insn ("wr\t%3, 0, %%y", operands);
|
||||
|
||||
switch (which_alternative)
|
||||
{
|
||||
case 0:
|
||||
if (TARGET_V9)
|
||||
return "sdiv\t%1, %2, %0";
|
||||
else
|
||||
return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
|
||||
case 1:
|
||||
if (TARGET_V9)
|
||||
return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
|
||||
else
|
||||
return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
|
||||
case 2:
|
||||
if (TARGET_V9)
|
||||
return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
|
||||
else
|
||||
return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
[(set_attr "type" "multi")
|
||||
(set (attr "length")
|
||||
|
@ -4967,10 +4980,13 @@
|
|||
(clobber (match_scratch:SI 3 "=&r"))]
|
||||
"TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
|
||||
{
|
||||
output_asm_insn ("sra\t%1, 31, %3", operands);
|
||||
output_asm_insn ("wr\t%3, 0, %%y", operands);
|
||||
|
||||
if (TARGET_V9)
|
||||
return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
|
||||
return "sdivcc\t%1, %2, %0";
|
||||
else
|
||||
return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
|
||||
return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
|
||||
}
|
||||
[(set_attr "type" "multi")
|
||||
(set (attr "length")
|
||||
|
@ -4985,29 +5001,48 @@
|
|||
"TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
|
||||
"")
|
||||
|
||||
;; The V8 architecture specifies that there must be 3 instructions between
|
||||
;; a Y register write and a use of it for correct results.
|
||||
;; The V8 architecture specifies that there must be at least 3 instructions
|
||||
;; between a write to the Y register and a use of it for correct results.
|
||||
;; We try to fill one of them with a simple constant or a memory load.
|
||||
|
||||
(define_insn "udivsi3_sp32"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
|
||||
(udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
|
||||
(match_operand:SI 2 "input_operand" "rI,m,r")))]
|
||||
"(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
|
||||
&& TARGET_ARCH32"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
|
||||
(udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
|
||||
(match_operand:SI 2 "input_operand" "rI,K,m,r")))]
|
||||
"(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
|
||||
{
|
||||
output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
|
||||
output_asm_insn ("wr\t%%g0, 0, %%y", operands);
|
||||
|
||||
switch (which_alternative)
|
||||
{
|
||||
default:
|
||||
return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
|
||||
case 0:
|
||||
if (TARGET_V9)
|
||||
return "udiv\t%1, %2, %0";
|
||||
else
|
||||
return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
|
||||
case 1:
|
||||
return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
|
||||
if (TARGET_V9)
|
||||
return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
|
||||
else
|
||||
return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
|
||||
case 2:
|
||||
return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
|
||||
if (TARGET_V9)
|
||||
return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
|
||||
else
|
||||
return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
|
||||
case 3:
|
||||
if (TARGET_V9)
|
||||
return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
|
||||
else
|
||||
return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "length" "5")])
|
||||
(set (attr "length")
|
||||
(if_then_else (eq_attr "isa" "v9")
|
||||
(const_int 3) (const_int 5)))])
|
||||
|
||||
(define_insn "udivsi3_sp64"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
|
@ -5033,13 +5068,14 @@
|
|||
(const_int 0)))
|
||||
(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(udiv:SI (match_dup 1) (match_dup 2)))]
|
||||
"TARGET_V8
|
||||
|| TARGET_DEPRECATED_V8_INSNS"
|
||||
"TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
|
||||
{
|
||||
output_asm_insn ("wr\t%%g0, 0, %%y", operands);
|
||||
|
||||
if (TARGET_V9)
|
||||
return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
|
||||
return "udivcc\t%1, %2, %0";
|
||||
else
|
||||
return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
|
||||
return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
|
||||
}
|
||||
[(set_attr "type" "multi")
|
||||
(set (attr "length")
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2008-11-30 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* g++.dg/opt/reload3.C: New test.
|
||||
|
||||
2008-11-30 Paul Thomas <pault@gcc.gnu.org>
|
||||
|
||||
PR fortran/35824
|
||||
|
|
39
gcc/testsuite/g++.dg/opt/reload3.C
Normal file
39
gcc/testsuite/g++.dg/opt/reload3.C
Normal file
|
@ -0,0 +1,39 @@
|
|||
// PR target/38287
|
||||
// { dg-do run }
|
||||
// { dg-options "-O2 -mcpu=v8 -fPIC" { target { { sparc*-*-* } && { ilp32 && fpic } } } }
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
class QTime
|
||||
{
|
||||
public:
|
||||
explicit QTime(int ms = 0) : ds(ms) {}
|
||||
static QTime currentTime() { return QTime(); }
|
||||
QTime addMSecs(int ms) const;
|
||||
int msecs() const { return ds; }
|
||||
private:
|
||||
unsigned ds;
|
||||
};
|
||||
|
||||
static const unsigned MSECS_PER_DAY = 86400000;
|
||||
|
||||
QTime QTime::addMSecs(int ms) const
|
||||
{
|
||||
QTime t;
|
||||
if ( ms < 0 ) {
|
||||
// % not well-defined for -ve, but / is.
|
||||
int negdays = (MSECS_PER_DAY-ms) / MSECS_PER_DAY;
|
||||
t.ds = ((int)ds + ms + negdays*MSECS_PER_DAY)
|
||||
% MSECS_PER_DAY;
|
||||
} else {
|
||||
t.ds = ((int)ds + ms) % MSECS_PER_DAY;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
if (QTime(1).addMSecs(1).msecs() != 2)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue