Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 27 additions & 34 deletions Archs/MIPS/CMipsInstruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "Core/Common.h"
#include "Core/FileManager.h"
#include "Core/Misc.h"
#include "Util/Util.h"

CMipsInstruction::CMipsInstruction(MipsOpcodeData& opcode, MipsImmediateData& immediate, MipsRegisterData& registers)
{
Expand Down Expand Up @@ -47,39 +48,23 @@ int getImmediateBits(MipsImmediateType type)
}
}

// http://code.google.com/p/jpcsp/source/browse/trunk/src/jpcsp/Allegrex/VfpuState.java?spec=svn3676&r=3383#1196
int CMipsInstruction::floatToHalfFloat(int i)
bool CMipsInstruction::immediateToHalfFloat(int &out)
{
int s = ((i >> 16) & 0x00008000); // sign
int e = ((i >> 23) & 0x000000ff) - (127 - 15); // exponent
int f = ((i >> 0) & 0x007fffff); // fraction

// need to handle NaNs and Inf?
if (e <= 0) {
if (e < -10) {
if (s != 0) {
// handle -0.0
return 0x8000;
}
return 0;
}
f = (f | 0x00800000) >> (1 - e);
return s | (f >> 13);
} else if (e == 0xff - (127 - 15)) {
if (f == 0) {
// Inf
return s | 0x7c00;
}
// NAN
return s | 0x7fff;
ExpressionValue value = immediateData.primary.expression.evaluate();
if (value.isFloat())
{
out = toHalfFloat(value.floatValue);
return true;
}

if (e > 30) {
// Overflow
return s | 0x7c00;
else if (value.isInt())
{
out = toHalfFloat((double) value.intValue);
return true;
}
else
{
return false;
}

return s | (e << 10) | (f >> 13);
}

bool CMipsInstruction::Validate(const ValidateState &state)
Expand All @@ -101,7 +86,18 @@ bool CMipsInstruction::Validate(const ValidateState &state)
{
if (immediateData.primary.expression.isLoaded())
{
if (!immediateData.primary.expression.evaluateInteger(immediateData.primary.value))
bool isValidExpression;

if (immediateData.primary.type == MipsImmediateType::ImmediateHalfFloat)
{
isValidExpression = immediateToHalfFloat(immediateData.primary.value);
}
else
{
isValidExpression = immediateData.primary.expression.evaluateInteger(immediateData.primary.value);
}

if (!isValidExpression)
{
Logger::queueError(Logger::Error, "Invalid immediate expression");
return false;
Expand All @@ -110,9 +106,6 @@ bool CMipsInstruction::Validate(const ValidateState &state)
immediateData.primary.originalValue = immediateData.primary.value;
}

if (immediateData.primary.type == MipsImmediateType::ImmediateHalfFloat)
immediateData.primary.value = floatToHalfFloat(immediateData.primary.originalValue);

if (opcodeData.opcode.flags & MO_IMMALIGNED) // immediate must be aligned
{
if (immediateData.primary.value % 4)
Expand Down
2 changes: 1 addition & 1 deletion Archs/MIPS/CMipsInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ class CMipsInstruction: public CAssemblerCommand
private:
void encodeNormal() const;
void encodeVfpu() const;
int floatToHalfFloat(int i);
bool immediateToHalfFloat(int &out);

bool IgnoreLoadDelay;
int64_t RamPos;
Expand Down
30 changes: 15 additions & 15 deletions Archs/MIPS/MipsOpcodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ const tMipsOpcode MipsOpcodes[] = {
// hi |-------|-------|-------|-------|-------|-------|-------|-------|
{ "vadd.S", "vd,vs,vt", MIPS_VFPU0(0x00), MA_PSP, MO_VFPU },
{ "vsub.S", "vd,vs,vt", MIPS_VFPU0(0x01), MA_PSP, MO_VFPU },
{ "vsbn.S", "vd,vs,vt", MIPS_VFPU0(0x02), MA_PSP, MO_VFPU },
{ "vsbn.s", "vd,vs,vt", MIPS_VFPU0(0x02), MA_PSP, MO_VFPU|MO_VFPU_SINGLE },
{ "vdiv.S", "vd,vs,vt", MIPS_VFPU0(0x07), MA_PSP, MO_VFPU },

// 31-------26-----23----------------------------------------------0
Expand All @@ -614,7 +614,7 @@ const tMipsOpcode MipsOpcodes[] = {
// |-------|-------|-------|-------|-------|-------|-------|-------|
{ "vmul.S", "vd,vs,vt", MIPS_VFPU1(0), MA_PSP, MO_VFPU },
{ "vdot.S", "vd,vs,vt", MIPS_VFPU1(1), MA_PSP, MO_VFPU },
{ "vscl.S", "vd,vs,vt", MIPS_VFPU1(2), MA_PSP, MO_VFPU },
{ "vscl.S", "vd,vs,vSt", MIPS_VFPU1(2), MA_PSP, MO_VFPU },
{ "vhdp.S", "vd,vs,vt", MIPS_VFPU1(4), MA_PSP, MO_VFPU },
{ "vdet.S", "vd,vs,vt", MIPS_VFPU1(5), MA_PSP, MO_VFPU },
{ "vcrs.S", "vd,vs,vt", MIPS_VFPU1(6), MA_PSP, MO_VFPU },
Expand Down Expand Up @@ -738,18 +738,18 @@ const tMipsOpcode MipsOpcodes[] = {
{ "vrndf1.S", "vd", MIPS_VFPU4_12(0x02), MA_PSP, MO_VFPU },
{ "vrndf2.S", "vd", MIPS_VFPU4_12(0x03), MA_PSP, MO_VFPU },
// TODO: vsBZ?
{ "vf2h.S", "vd,vs", MIPS_VFPU4_12(0x12), MA_PSP, MO_VFPU },
{ "vh2f.S", "vd,vs", MIPS_VFPU4_12(0x13), MA_PSP, MO_VFPU },
{ "vf2h.S", "vHd,vs", MIPS_VFPU4_12(0x12), MA_PSP, MO_VFPU },
{ "vh2f.S", "vDd,vs", MIPS_VFPU4_12(0x13), MA_PSP, MO_VFPU },
// TODO: vsBZ?
{ "vlgb.S", "vd,vs", MIPS_VFPU4_12(0x17), MA_PSP, MO_VFPU },
{ "vuc2i.S", "vd,vs", MIPS_VFPU4_12(0x18), MA_PSP, MO_VFPU },
{ "vc2i.S", "vd,vs", MIPS_VFPU4_12(0x19), MA_PSP, MO_VFPU },
{ "vus2i.S", "vd,vs", MIPS_VFPU4_12(0x1a), MA_PSP, MO_VFPU },
{ "vs2i.S", "vd,vs", MIPS_VFPU4_12(0x1b), MA_PSP, MO_VFPU },
{ "vi2uc.S", "vd,vs", MIPS_VFPU4_12(0x1c), MA_PSP, MO_VFPU },
{ "vi2c.S", "vd,vs", MIPS_VFPU4_12(0x1d), MA_PSP, MO_VFPU },
{ "vi2us.S", "vd,vs", MIPS_VFPU4_12(0x1e), MA_PSP, MO_VFPU },
{ "vi2s.S", "vd,vs", MIPS_VFPU4_12(0x1f), MA_PSP, MO_VFPU },
{ "vuc2ifs.S", "vQd,vs", MIPS_VFPU4_12(0x18), MA_PSP, MO_VFPU },
{ "vc2i.S", "vQd,vs", MIPS_VFPU4_12(0x19), MA_PSP, MO_VFPU },
{ "vus2i.S", "vDd,vs", MIPS_VFPU4_12(0x1a), MA_PSP, MO_VFPU },
{ "vs2i.S", "vDd,vs", MIPS_VFPU4_12(0x1b), MA_PSP, MO_VFPU },
{ "vi2uc.S", "vFd,vs", MIPS_VFPU4_12(0x1c), MA_PSP, MO_VFPU },
{ "vi2c.S", "vFd,vs", MIPS_VFPU4_12(0x1d), MA_PSP, MO_VFPU },
{ "vi2us.S", "vHd,vs", MIPS_VFPU4_12(0x1e), MA_PSP, MO_VFPU },
{ "vi2s.S", "vHd,vs", MIPS_VFPU4_12(0x1f), MA_PSP, MO_VFPU },

// 31--------------21------16--------------------------------------0
// |= VF4-1.3 | rt | |
Expand All @@ -775,9 +775,9 @@ const tMipsOpcode MipsOpcodes[] = {
{ "vmtv.S", "vs,i7", MIPS_VFPU4_13(0x11)|0x00, MA_PSP, MO_VFPU },
{ "vmfvc.S", "vs,i7", MIPS_VFPU4_13(0x10)|0x80, MA_PSP, MO_VFPU },
{ "vmtvc.S", "vs,i7", MIPS_VFPU4_13(0x11)|0x80, MA_PSP, MO_VFPU },
{ "vt4444.S", "vd,vs", MIPS_VFPU4_13(0x19), MA_PSP, MO_VFPU },
{ "vt5551.S", "vd,vs", MIPS_VFPU4_13(0x1a), MA_PSP, MO_VFPU },
{ "vt5650.S", "vd,vs", MIPS_VFPU4_13(0x1b), MA_PSP, MO_VFPU },
{ "vt4444.S", "vHd,vs", MIPS_VFPU4_13(0x19), MA_PSP, MO_VFPU },
{ "vt5551.S", "vHd,vs", MIPS_VFPU4_13(0x1a), MA_PSP, MO_VFPU },
{ "vt5650.S", "vHd,vs", MIPS_VFPU4_13(0x1b), MA_PSP, MO_VFPU },

// 31-------26-----23----------------------------------------------0
// |= VFPU5| f | |
Expand Down
Loading