示例#1
0
        // Normalize and optionally round floating point operand

        private static void fnorm(ref UFP a, ulong rnd)
        {
            a = new UFP();
            var normmask = new ulong[]
            {
                0x6000000000000000,
                0x7800000000000000,
                0x7F80000000000000,
                0x7FFF800000000000,
                0x7FFFFFFF80000000,
                0x7FFFFFFFFFFFFFFF
            };
            var normtab = new[] { 1, 2, 4, 8, 16, 32, 63 };

            if ((a.Fhi & FpUcry).NZ())
            {
                // carry set?
                //printf("%%PDP-10 FP: carry bit set at normalization, PC = %o\n", pager_PC);
                a.Flo = (a.Flo >> 1) | ((a.Fhi & 1) << 63); // try to recover
                a.Fhi = a.Fhi >> 1;                         // but root cause
                a.Exp = a.Exp + 1;                          // should be fixed!
            }
            if ((a.Fhi | a.Flo) == 0)
            {
                // if fraction = 0
                a.Sign = a.Exp = 0; // result is 0
                return;
            }
            while ((a.Fhi & FpUnorm) == 0)
            {
                // normalized?
                int i;
                for (i = 0; i < 6; i++)
                {
                    if ((a.Fhi & normmask[i]).NZ())
                    {
                        break;
                    }
                }
                a.Fhi = (a.Fhi << normtab[i]) | (a.Flo >> (64 - normtab[i]));
                a.Flo = a.Flo << normtab[i];
                a.Exp = a.Exp - normtab[i];
            }
            if (rnd.NZ())
            {
                // rounding?
                a.Fhi = a.Fhi + rnd; // add round const
                if ((a.Fhi & FpUcry).NZ())
                {
                    // if carry out,
                    a.Fhi = a.Fhi >> 1; // renormalize
                    a.Exp = a.Exp + 1;
                }
            }
            return;
        }
示例#2
0
        // Pack floating point result

        private ulong fpack(UFP r, out ulong lo, bool setlo, bool fdvneg)
        {
            var val = new ulong[2];

            if (r.Exp < 0)
            {
                setf(_fAov | _fFov | _fFxu | _fT1);
            }
            else if ((ulong)r.Exp > _fpMExp)
            {
                setf(_fAov | _fFov | _fT1);
            }
            val[0] = (((((ulong)r.Exp) & _fpMExp) << FpVExp) |
                      ((r.Fhi & FpUfhi) >> FpVUfhi)) & B36.DMASK;
            if (setlo)
            {
                val[1] = ((r.Fhi & FpUflo) >> FpVUflo) & B36.MMASK;
            }
            else
            {
                val[1] = 0;
            }
            if (r.Sign.NZ()) // negate?
            {
                if (fdvneg)
                {
                    // fdvr special?
                    val[1] = ~val[1] & B36.MMASK; // 1's comp
                    val[0] = ~val[0] & B36.DMASK;
                }
                else
                {
                    dmovn(val);
                }
            }
            lo = 0;
            if (setlo)
            {
                lo = val[1];
            }
            return(val[0]);
        }
示例#3
0
        // Unpack floating point operand

        private static void funpack(ulong h, ulong l, out UFP r, bool sgn)
        {
            r = new UFP {
                Sign = getFpsign(h), Exp = getFpexp(h)
            };

            var fphi = getFphi(h);
            var fplo = getFplo(l);

            r.Fhi = (fphi << FpVUfhi) | (fplo << FpVUflo);
            r.Flo = 0;

            if (r.Sign.NZ())
            {
                r.Exp = r.Exp ^ (int)_fpMExp; // 1s comp exp
                if (sgn)                      // signed frac?
                {
                    if (r.Fhi.NZ())
                    {
                        r.Fhi = r.Fhi | FpUcry; // extend sign
                    }
                    else
                    {
                        r.Exp = r.Exp + 1;
                        r.Fhi = FpUcry | FpUnorm;
                    }
                }
                else // abs frac
                if (r.Fhi.NZ())
                {
                    r.Fhi = uneg(r.Fhi) & FpUfrac;
                }
                else
                {
                    r.Exp = r.Exp + 1;
                    r.Fhi = FpUnorm;
                }
            }
            return;
        }
示例#4
0
 private static void duneg(ref UFP x)
 {
     //#define DUNEG(x)        x.flo = UNEG (x.flo); x.fhi = ~x.fhi + (x.flo == 0)
     x.Flo = uneg(x.Flo);
     x.Fhi = ~x.Fhi + (x.Flo == 0).B();
 }