Commit 0e517585 authored by ebotcazou's avatar ebotcazou
Browse files

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.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142295 138bc75d-0d04-0410-961f-82ee72b054a4
parent 1f6a423f
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"
{
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";
[(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"
{
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")
......
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
......
// 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;
}
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