When loading double constants using two lwc1 instructions ("Load Word in
Coprocessor 1"), the words are swapped on Little-Endian MIPS machines.
More precisely, when compiling the following function with
mipsel-linux-gnu-gcc -O3 -mfp32 -march=mips1
double add_0x100000000(double num) {
return num + 4294967296.0;
}
The produced assembly (seen with objdump) is:
00000000 <add_0x100000000>:
0: 3c1c0000 lui gp,0x0
4: 279c0000 addiu gp,gp,0
8: 0399e021 addu gp,gp,t9
c: 8f820000 lw v0,0(gp)
10: 00000000 nop
14: c4400000 lwc1 $f0,0(v0) ; load the first 32-bit word
18: 00000000 nop
1c: c4410004 lwc1 $f1,4(v0) ; load the second 32-bit word
20: 03e00008 jr ra
24: 46206000 add.d $f0,$f12,$f0 ; perform the addition
(the rodata section contains "00000000 0000f041" to encode the constant).
When opening the produced file with Ghidra 10.0, the assembly code is
fine but the decompiler outputs:
double add_0x100000000(double param_1)
{
return param_1 + 5.465589744795806e-315;
}
5.465589744795806e-315 comes from the decoding of "0000f041 00000000"
instead of "00000000 0000f041": the words were swapped.
Fix this by swapping f0 and f1, f2 and f3... when using a Little-Endian
MIPS machine with 32-bit floating-point registers.
- The EVA instructions have prime=0x1E, this should be 0x1F. These
instructions are used to access user mode virtual address from
kernel mode, so probably not used often.
- General cleanup in the bit pattern. There was mixed used of
decimal and hex values for the same token, converted >9 to hex
- Added OCTEON instructions: lbx, blux, ldx, lhx, lhux, lwx, and lwux
- Implemented the multiple accumulator found in DSP for:
madd, maddu, mfhi, mflo, msub, msubu, mthi, mtlo, mult, and multu
These changes convert '00' to ac in the bit pattern and attach to
the original lo/hi pair and now lo1/hi1, lo2/hi2, and lo3/hi3 pairs.
The value of ac can range from 0 to 3. When ac=0, this refers to
the original HI/LO register pair of the architecture.
- some minor whitespace cleanup