aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDuraid Madina <duraid@octopus.com.au>2006-01-16 14:33:04 +0000
committerDuraid Madina <duraid@octopus.com.au>2006-01-16 14:33:04 +0000
commit76bb6ae211b1d4d656c182a0b9e8a6e8877ee8d0 (patch)
tree802c303c38479704c5d3b9a94fb4e6510ba3701a /lib
parent1b5db7aaec8bbe350b1af42ecfe97c73f0e07d0f (diff)
downloadexternal_llvm-76bb6ae211b1d4d656c182a0b9e8a6e8877ee8d0.zip
external_llvm-76bb6ae211b1d4d656c182a0b9e8a6e8877ee8d0.tar.gz
external_llvm-76bb6ae211b1d4d656c182a0b9e8a6e8877ee8d0.tar.bz2
fixing divides: FP should now be 100%, and integers are fine too
unless you try to div/mod 0 by anything, in which case you will get some cute number, and not 0, which is bad. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25358 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/IA64/IA64ISelDAGToDAG.cpp41
1 files changed, 24 insertions, 17 deletions
diff --git a/lib/Target/IA64/IA64ISelDAGToDAG.cpp b/lib/Target/IA64/IA64ISelDAGToDAG.cpp
index 929e8f5..fd58567 100644
--- a/lib/Target/IA64/IA64ISelDAGToDAG.cpp
+++ b/lib/Target/IA64/IA64ISelDAGToDAG.cpp
@@ -183,6 +183,10 @@ SDOperand IA64DAGToDAGISel::SelectDIV(SDOperand Op) {
SDOperand TmpF1, TmpF2, TmpF3, TmpF4, TmpF5, TmpF6, TmpF7, TmpF8;
SDOperand TmpF9, TmpF10,TmpF11,TmpF12,TmpF13,TmpF14,TmpF15;
SDOperand Result;
+
+ // we'll need copies of F0 and F1
+ SDOperand F0 = CurDAG->getRegister(IA64::F0, MVT::f64);
+ SDOperand F1 = CurDAG->getRegister(IA64::F1, MVT::f64);
// OK, emit some code:
@@ -200,12 +204,10 @@ SDOperand IA64DAGToDAGISel::SelectDIV(SDOperand Op) {
TmpF4 = CurDAG->getTargetNode(IA64::FCVTXF, MVT::f64, TmpF2);
Chain = TmpF4.getValue(1);
} else { // is unsigned
- if(isModulus) { /* unsigned integer divides do not need any fcvt.x*f* insns */
- TmpF3 = CurDAG->getTargetNode(IA64::FCVTXUFS1, MVT::f64, TmpF1);
- Chain = TmpF3.getValue(1);
- TmpF4 = CurDAG->getTargetNode(IA64::FCVTXUFS1, MVT::f64, TmpF2);
- Chain = TmpF4.getValue(1);
- }
+ TmpF3 = CurDAG->getTargetNode(IA64::FCVTXUFS1, MVT::f64, TmpF1);
+ Chain = TmpF3.getValue(1);
+ TmpF4 = CurDAG->getTargetNode(IA64::FCVTXUFS1, MVT::f64, TmpF2);
+ Chain = TmpF4.getValue(1);
}
} else { // this is an FP divide/remainder, so we 'leak' some temp
@@ -226,10 +228,6 @@ SDOperand IA64DAGToDAGISel::SelectDIV(SDOperand Op) {
TmpPR = TmpF5.getValue(1);
Chain = TmpF5.getValue(2);
- // we'll need copies of F0 and F1
- SDOperand F0 = CurDAG->getRegister(IA64::F0, MVT::f64);
- SDOperand F1 = CurDAG->getRegister(IA64::F1, MVT::f64);
-
SDOperand minusB;
if(isModulus) { // for remainders, it'll be handy to have
// copies of -input_b
@@ -276,7 +274,7 @@ SDOperand IA64DAGToDAGISel::SelectDIV(SDOperand Op) {
// we two-address hack it. See the comment "for this to work..." on
// page 48 of Intel application note #245415
Result = CurDAG->getTargetNode(IA64::TCFMADS0, MVT::f64, // d.p. s0 rndg!
- TmpY3, TmpR0, TmpQ0, TmpPR);
+ TmpF5, TmpY3, TmpR0, TmpQ0, TmpPR);
Chain = Result.getValue(1);
return Result; // XXX: early exit!
} else { // this is *not* an FP divide, so there's a bit left to do:
@@ -290,13 +288,22 @@ SDOperand IA64DAGToDAGISel::SelectDIV(SDOperand Op) {
TmpF4, TmpQ2, TmpF3, TmpPR);
Chain = TmpR2.getValue(1);
-// we want TmpQ3 to have the same target register as the frcpa, so
-// we two-address hack it. See the comment "for this to work..." on
-// page 48 of Intel application note #245415
- TmpQ3 = CurDAG->getTargetNode(IA64::TCFMAS1, MVT::f64,
- TmpR2, TmpR2, TmpY2, TmpQ2, TmpPR);
+// we want TmpQ3 to have the same target register as the frcpa? maybe we
+// should two-address hack it. See the comment "for this to work..." on page
+// 48 of Intel application note #245415
+ TmpQ3 = CurDAG->getTargetNode(IA64::CFMAS1, MVT::f64,
+ TmpR2, TmpY2, TmpQ2, TmpPR);
Chain = TmpQ3.getValue(1);
-
+
+ // FIXME: this is unfortunate :(
+ // the story is that the dest reg of the fnma above and the fma below it
+ // (and therefore the src of the fcvt.fx[u] below as well) cannot
+ // be the same register, or this code breaks if the first argument is
+ // zero. (e.g. without this hack, 0%8 yields -64, not 0.)
+/* XXX: these two lines do nothing */
+ SDOperand bogus = CurDAG->getTargetNode(IA64::IUSE, MVT::Other, TmpR2);
+ Chain = bogus.getValue(0);
+
if(isSigned)
TmpQ = CurDAG->getTargetNode(IA64::FCVTFXTRUNCS1, MVT::f64, TmpQ3);
else