Thanks, Gabe. For when you or someone else does get a chance to look at it, here are some details that may be useful to you.
Starting from the Add_d::execute() function in atomic_simple_cpu_exec.cc (when compiled for MIPS), which is the function that simulates the double-precision floating-point add instruction, the variables Fs and Ft are declared as type 'double'. Then both are assigned to xc->readFloatRegOperand() (which is defined in src/cpu/simple/base.hh). This function returns thread->readFloatReg(). This function is defined in src/cpu/simple_thread.cc and returns floatRegs.f[flatIndex]. floatRegs.f is an array of type TheISA::FloatReg. FloatReg is typedef'ed in arch/mips/registers.hh as a float. So the addition is supposed to operate on double-precision (64-bit) floating-point operands, but is actually only getting float (32-bit) floating-point operands. In MIPS, the floating-point registers are 32-bits wide, so double-precision floating point operations are supposed to use pairs of floating-point registers to hold each operand and the result. So M5 ought to read two 32-bit floating-point registers for each operand and concatenate the bits into 64-bit double variables before doing any double-precision floating-point arithmetic. M5 used to handle this correctly. In particular, on the old m5-stable branch, starting from Add_d::execute(), xc->readFloatRegOperand() was passed a width argument of 64. Then, when it called thread->readFloatReg(), it passed along this width argument. Then, this function would call regs.readFloatReg() and pass along the width argument. This function would call RegFile::readFloatReg(), which would call FloatRegFile::readReg(), again passing along the width argument. Finally, this function would read two floating-point registers (if the width argument was 64) and concatenate the bits into a single 64-bit double. One additional monkey wrench is this. Many of these functions return a FloatReg type, which used to be typedef'ed as double, but is now typedef'ed as float (and in a different header file). All of these changes seem to be have been introduced in changeset 781969fbeca9. I understand the good intention of trying to eliminate all these width arguments, but in the end, it seems to have broken a legitimate use for them (to distinguish between single and double-precision operations). I haven't checked too carefully, but this same problem may be affecting ARM as well (since I think it uses the same paired floating-point register scheme). Also, other double-precision things like checking for NaNs may be broken by this change. On Wed, Dec 9, 2009 at 3:39 PM, Gabriel Michael Black <[email protected]> wrote: > I looked briefly at that change earlier, and I do think it's likely > that I broke it. I don't know how much time I'll have to dig into it > in the near future, but I'll put it on my short(ish :-/) list. > > Gabe > > Quoting Matt <[email protected]>: > >> Gabe, >> >> It looks like it was your changes that broke this. Do you have any >> insight on this? >> Thanks. >> >> On Fri, Dec 4, 2009 at 3:31 PM, Matt <[email protected]> wrote: >>> I'm having problems getting double-precision floating-point to work in >>> m5 for the MIPS isa. >>> >>> The 32-bit MIPS isa has 32 32-bit floating-point registers. >>> Double-precision floating-point numbers are stored in pairs of >>> floating-point registers. At least that's how I understand it. >>> >>> Simple floating point math used to work in m5 until changeset >>> 781969fbeca9. After the change, it seams that m5 does not read two >>> 32-bit floating point registers to get a double-precision >>> floating-point operand, but only one 32-bit floating-point register >>> (when it's simulating an add_d instruction, for example). This >>> results in incorrect floating point arithmetic. >>> >>> I have the following C program (compiled for MIPS) that exercises >>> the problem: >>> >>> #include<stdio.h> >>> >>> int main (void) >>> { >>> double x, y, z; >>> >>> x = 5.0; >>> y = 0.1; >>> >>> z = x + y; >>> >>> printf ("z = %lf\n", z); >>> >>> return 0; >>> } >>> >>> It should print "z = 5.1", but it doesn't because the simulation of >>> the floating-point addition is wrong. >>> >>> Can anyone tell me why this change was made that seems to break the >>> simulation of double-precision floating-point arithmetic in m5? >>> >>> Thanks. >>> >>> -- >>> Cheers, >>> Matt >>> >> >> >> >> -- >> Cheers, >> Matt >> > > > _______________________________________________ > m5-dev mailing list > [email protected] > http://m5sim.org/mailman/listinfo/m5-dev > -- Cheers, Matt _______________________________________________ m5-dev mailing list [email protected] http://m5sim.org/mailman/listinfo/m5-dev
