Project Home
Project Home
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
BroadcastCommunity.qnx.com will be offline from May 31 6:00pm until June 2 12:00AM for upcoming system upgrades. For more information please go to https://community.qnx.com/sf/discussion/do/listPosts/projects.bazaar/discussion.bazaar.topc28418
Forum Topic - mips fpu context: (5 Items)
   
mips fpu context  
Hello,

Could someone confirm how are FPU registers laid out in MIPS 
context?

The logic that used to be coded in gdb assumes something 
that doesn't work. With the logic I am going to describe it 
works, but I am not sure if it is of generic value, or it 
just happens to work with the two targets I was testing with.

In the context, we reserve 32 8-byte values to store FPU 
register values. Mips has 16 8-byte regs or 32 4-byte float 
registers. When used as double, then even+next odd comprise 
singe double value.

The logic that used to be in gdb calculated offset as

regno * 8

and on big endian systems, it would add 4.

However, that doesn't work. What works is this:


(regno & ~1) * 8    (i.e. calculate offset of closest 
previous even regno)

then:
On big endian:
	for even regno, add 4.
On little endian:
	for odd regno, add 4.


This effectively means that every odd-indexed 8-byte value 
in our context is unused which seems strange.


Is this new logic correct, or are there other gotchas?


Thanks,

Aleksandar
Re: mips fpu context  
Here's the code that stores the context (t2 is pointing at a
MIPS_FPU_REGS structure).


	cfc1	t1,$31
	sdc1	 $f0, 0*8(t2)
	sdc1	 $f1, 1*8(t2)
	sdc1	 $f2, 2*8(t2)
	sdc1	 $f3, 3*8(t2)
	sdc1	 $f4, 4*8(t2)
	sdc1	 $f5, 5*8(t2)
	sdc1	 $f6, 6*8(t2)
	sdc1	 $f7, 7*8(t2)
	sdc1	 $f8, 8*8(t2)
	sdc1	 $f9, 9*8(t2)
	sdc1	$f10,10*8(t2)
	sdc1	$f11,11*8(t2)
	sdc1	$f12,12*8(t2)
	sdc1	$f13,13*8(t2)
	sdc1	$f14,14*8(t2)
	sdc1	$f15,15*8(t2)
	sdc1	$f16,16*8(t2)
	sdc1	$f17,17*8(t2)
	sdc1	$f18,18*8(t2)
	sdc1	$f19,19*8(t2)
	sdc1	$f20,20*8(t2)
	sdc1	$f21,21*8(t2)
	sdc1	$f22,22*8(t2)
	sdc1	$f23,23*8(t2)
	sdc1	$f24,24*8(t2)
	sdc1	$f25,25*8(t2)
	sdc1	$f26,26*8(t2)
	sdc1	$f27,27*8(t2)
	sdc1	$f28,28*8(t2)
	sdc1	$f29,29*8(t2)
	sdc1	$f30,30*8(t2)
	sdc1	$f31,31*8(t2)
	sw		t1,REG_FPCR31(t2)


On Thu, Apr 01, 2010 at 02:45:38PM -0400, Aleksandar Ristovski wrote:
> Hello,
> 
> Could someone confirm how are FPU registers laid out in MIPS 
> context?
> 
> The logic that used to be coded in gdb assumes something 
> that doesn't work. With the logic I am going to describe it 
> works, but I am not sure if it is of generic value, or it 
> just happens to work with the two targets I was testing with.
> 
> In the context, we reserve 32 8-byte values to store FPU 
> register values. Mips has 16 8-byte regs or 32 4-byte float 
> registers. When used as double, then even+next odd comprise 
> singe double value.
> 
> The logic that used to be in gdb calculated offset as
> 
> regno * 8
> 
> and on big endian systems, it would add 4.
> 
> However, that doesn't work. What works is this:
> 
> 
> (regno & ~1) * 8    (i.e. calculate offset of closest 
> previous even regno)
> 
> then:
> On big endian:
> 	for even regno, add 4.
> On little endian:
> 	for odd regno, add 4.
> 
> 
> This effectively means that every odd-indexed 8-byte value 
> in our context is unused which seems strange.
> 
> 
> Is this new logic correct, or are there other gotchas?
> 
> 
> Thanks,
> 
> Aleksandar
> 
> 
> 
> 
> _______________________________________________
> 
> OSTech
> http://community.qnx.com/sf/go/post51070
> 

-- 
Brian Stecher (bstecher@qnx.com)        QNX Software Systems
phone: +1 (613) 591-0931 (voice)        175 Terence Matthews Cr.
       +1 (613) 591-3579 (fax)          Kanata, Ontario, Canada K2M 1W8
Re: mips fpu context  
sdc1 is 64-bit store which matches what I am observing (full 
double value is stored at even-indexed locations).

The book mentions 32-bit and 64-bit cpus. The code snippet 
(using sdc1 on odd-numbered fp registers) suggests the code 
is for 64-bit cpus.

Shouldn't we have two different snippets, one for 32 bit 
which would use swc1 instructions to store 4 bytes of each 
fp register, and another version which would use sdc1 as it 
does now?

Or, how can I detect which flavour is in question: 32-bit or 
64-bit FP registers?



Thanks,

Aleksandar


On 02/04/2010 9:32, Brian Stecher wrote:
> Here's the code that stores the context (t2 is pointing at a
> MIPS_FPU_REGS structure).
>
>
> 	cfc1	t1,$31
> 	sdc1	 $f0, 0*8(t2)
> 	sdc1	 $f1, 1*8(t2)
> 	sdc1	 $f2, 2*8(t2)
> 	sdc1	 $f3, 3*8(t2)
> 	sdc1	 $f4, 4*8(t2)
> 	sdc1	 $f5, 5*8(t2)
> 	sdc1	 $f6, 6*8(t2)
> 	sdc1	 $f7, 7*8(t2)
> 	sdc1	 $f8, 8*8(t2)
> 	sdc1	 $f9, 9*8(t2)
> 	sdc1	$f10,10*8(t2)
> 	sdc1	$f11,11*8(t2)
> 	sdc1	$f12,12*8(t2)
> 	sdc1	$f13,13*8(t2)
> 	sdc1	$f14,14*8(t2)
> 	sdc1	$f15,15*8(t2)
> 	sdc1	$f16,16*8(t2)
> 	sdc1	$f17,17*8(t2)
> 	sdc1	$f18,18*8(t2)
> 	sdc1	$f19,19*8(t2)
> 	sdc1	$f20,20*8(t2)
> 	sdc1	$f21,21*8(t2)
> 	sdc1	$f22,22*8(t2)
> 	sdc1	$f23,23*8(t2)
> 	sdc1	$f24,24*8(t2)
> 	sdc1	$f25,25*8(t2)
> 	sdc1	$f26,26*8(t2)
> 	sdc1	$f27,27*8(t2)
> 	sdc1	$f28,28*8(t2)
> 	sdc1	$f29,29*8(t2)
> 	sdc1	$f30,30*8(t2)
> 	sdc1	$f31,31*8(t2)
> 	sw		t1,REG_FPCR31(t2)
>
>
> On Thu, Apr 01, 2010 at 02:45:38PM -0400, Aleksandar Ristovski wrote:
>> Hello,
>>
>> Could someone confirm how are FPU registers laid out in MIPS
>> context?
>>
>> The logic that used to be coded in gdb assumes something
>> that doesn't work. With the logic I am going to describe it
>> works, but I am not sure if it is of generic value, or it
>> just happens to work with the two targets I was testing with.
>>
>> In the context, we reserve 32 8-byte values to store FPU
>> register values. Mips has 16 8-byte regs or 32 4-byte float
>> registers. When used as double, then even+next odd comprise
>> singe double value.
>>
>> The logic that used to be in gdb calculated offset as
>>
>> regno * 8
>>
>> and on big endian systems, it would add 4.
>>
>> However, that doesn't work. What works is this:
>>
>>
>> (regno&  ~1) * 8    (i.e. calculate offset of closest
>> previous even regno)
>>
>> then:
>> On big endian:
>> 	for even regno, add 4.
>> On little endian:
>> 	for odd regno, add 4.
>>
>>
>> This effectively means that every odd-indexed 8-byte value
>> in our context is unused which seems strange.
>>
>>
>> Is this new logic correct, or are there other gotchas?
>>
>>
>> Thanks,
>>
>> Aleksandar
>>
>>
>>
>>
>> _______________________________________________
>>
>> OSTech
>> http://community.qnx.com/sf/go/post51070
>>
>

Re: mips fpu context  
Any comments?

Is there anywhere an overview of particular MIPS cpu-s that we support
and what kind of fpu-s they have?

Thanks,

Aleksandar

Re: mips fpu context  
Ok, to conclude this:

it is treated the way it is because of the emulator.

I tried with implementing saving/restoring FP registers using swc1 or sdc1 depending on the FR bit in CP0 status 
register and it seems to work (I don't have a 64-bit FPU target), but then there is a mismatch between representation on
 a target with real FPU vs target without FPU.

So, while it seems that on 32-bit FPUs we are executing 16 superfluous instructions per store/load of FP context, they 
don't seem to hurt either.

With changed GDB's idea of how are FPRs stored, things work consistently, regardless of FPU presence.

Drawback is that GDB will only interpret FP registers as 32 single precision registers (paired to represent 16 double 
precision registers) and can not really represent real 64-bit FPU.