diff options
Diffstat (limited to 'llvm/lib/Target/IA64/IA64ISelPattern.cpp')
| -rw-r--r-- | llvm/lib/Target/IA64/IA64ISelPattern.cpp | 14 | 
1 files changed, 13 insertions, 1 deletions
| diff --git a/llvm/lib/Target/IA64/IA64ISelPattern.cpp b/llvm/lib/Target/IA64/IA64ISelPattern.cpp index 599f2891e13..261a502d287 100644 --- a/llvm/lib/Target/IA64/IA64ISelPattern.cpp +++ b/llvm/lib/Target/IA64/IA64ISelPattern.cpp @@ -1087,9 +1087,19 @@ pC = pA OR pB        .addReg(TmpF8).addReg(TmpF10).addReg(TmpF10).addReg(TmpPR);      BuildMI(BB, IA64::CFNMAS1, 4,TmpF13)        .addReg(TmpF4).addReg(TmpF11).addReg(TmpF3).addReg(TmpPR); + +       // FIXME: this is unfortunate :( +       // the story is that the dest reg of the fnma above and the fma below +       // (and therefore possibly the src of the fcvt.fx[u] 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.)      BuildMI(BB, IA64::CFMAS1,  4,TmpF14)        .addReg(TmpF13).addReg(TmpF12).addReg(TmpF11).addReg(TmpPR); +    if(isModulus) { // XXX: fragile! fixes _only_ mod, *breaks* div! ! +      BuildMI(BB, IA64::IUSE, 1).addReg(TmpF13); // hack :( +    } +      if(!isFP) {        // round to an integer        if(isSigned) @@ -1113,14 +1123,16 @@ pC = pA OR pB        BuildMI(BB, IA64::CFMOV, 2, Result)  	.addReg(bogoResult).addReg(TmpF15).addReg(TmpPR);        } -      else +      else {  	BuildMI(BB, IA64::GETFSIG, 1, Result).addReg(TmpF15); +      }      } else { // this is a modulus        if(!isFP) {  	// answer = q * (-b) + a  	unsigned ModulusResult = MakeReg(MVT::f64);  	unsigned TmpF = MakeReg(MVT::f64);  	unsigned TmpI = MakeReg(MVT::i64); +	  	BuildMI(BB, IA64::SUB, 2, TmpI).addReg(IA64::r0).addReg(Tmp2);  	BuildMI(BB, IA64::SETFSIG, 1, TmpF).addReg(TmpI);  	BuildMI(BB, IA64::XMAL, 3, ModulusResult) | 

