2006-06-15 04:19:30 +00:00
|
|
|
#include <assert.h>
|
|
|
|
#include "CodeGen_FPU.h"
|
2007-12-14 01:41:48 +00:00
|
|
|
#include "CodeGen_StackPatterns.h"
|
2006-06-15 04:19:30 +00:00
|
|
|
#include "PtrMacro.h"
|
|
|
|
|
|
|
|
using namespace CodeGen;
|
2008-02-17 23:51:25 +00:00
|
|
|
using namespace std;
|
2006-06-15 04:19:30 +00:00
|
|
|
|
|
|
|
CCacheBlock* CFPU::m_pBlock = NULL;
|
|
|
|
|
2008-01-21 04:09:08 +00:00
|
|
|
bool CCodeGen::RegisterFpSingleHasNextUse(XMMREGISTER registerId)
|
|
|
|
{
|
|
|
|
unsigned int nCount = m_Shadow.GetCount();
|
|
|
|
|
|
|
|
for(unsigned int i = 0; i < nCount; i += 2)
|
|
|
|
{
|
|
|
|
if(m_Shadow.GetAt(i) == FP_SINGLE_REGISTER)
|
|
|
|
{
|
|
|
|
if(m_Shadow.GetAt(i + 1) == registerId) return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
void CFPU::Begin(CCacheBlock* pBlock)
|
|
|
|
{
|
|
|
|
m_pBlock = pBlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFPU::End()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFPU::PushSingle(void* pAddr)
|
|
|
|
{
|
|
|
|
//fld dword ptr[pAddr]
|
|
|
|
m_pBlock->StreamWrite(2, 0xD9, 0x05);
|
|
|
|
m_pBlock->StreamWriteWord((uint32)((uint8*)pAddr - (uint8*)0));
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFPU::PushSingleImm(float nValue)
|
|
|
|
{
|
|
|
|
if(nValue == 0.0)
|
|
|
|
{
|
|
|
|
//fldz
|
|
|
|
m_pBlock->StreamWrite(2, 0xD9, 0xEE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//push nValue
|
|
|
|
m_pBlock->StreamWrite(1, 0x68);
|
|
|
|
m_pBlock->StreamWriteWord(*(uint32*)&nValue);
|
|
|
|
|
|
|
|
//fld dword ptr [esp]
|
|
|
|
m_pBlock->StreamWrite(3, 0xD9, 0x04, 0x24);
|
|
|
|
|
|
|
|
//add esp, 4
|
|
|
|
m_pBlock->StreamWrite(3, 0x83, 0xC4, 0x04);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-11 07:05:37 +00:00
|
|
|
//void CFPU::PushWord(void* pAddr)
|
|
|
|
//{
|
|
|
|
// //fild dword ptr[pAddr]
|
|
|
|
// m_pBlock->StreamWrite(2, 0xDB, 0x00 | (0x00 << 3) | 0x05);
|
|
|
|
// m_pBlock->StreamWriteWord((uint32)((uint8*)pAddr - (uint8*)0));
|
|
|
|
//}
|
2006-06-15 04:19:30 +00:00
|
|
|
|
|
|
|
void CFPU::PullSingle(void* pAddr)
|
|
|
|
{
|
|
|
|
//fstp dword ptr[pAddr]
|
|
|
|
m_pBlock->StreamWrite(2, 0xD9, 0x00 | (0x03 << 3) | 0x05);
|
|
|
|
m_pBlock->StreamWriteWord((uint32)((uint8*)pAddr - (uint8*)0));
|
|
|
|
}
|
|
|
|
|
2007-12-11 07:05:37 +00:00
|
|
|
//void CFPU::PullWord(void* pAddr)
|
|
|
|
//{
|
|
|
|
// //fistp dword ptr[pAddr]
|
|
|
|
// m_pBlock->StreamWrite(2, 0xDB, 0x00 | (0x03 << 3) | 0x05);
|
|
|
|
// m_pBlock->StreamWriteWord((uint32)((uint8*)pAddr - (uint8*)0));
|
|
|
|
//}
|
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
|
|
|
|
void CFPU::PushRoundingMode()
|
|
|
|
{
|
|
|
|
//sub esp, 4
|
|
|
|
m_pBlock->StreamWrite(3, 0x83, 0xEC, 0x04);
|
|
|
|
|
|
|
|
//fwait
|
|
|
|
m_pBlock->StreamWrite(1, 0x9B);
|
|
|
|
|
|
|
|
//fnstcw word ptr [esp]
|
|
|
|
m_pBlock->StreamWrite(3, 0xD9, 0x3C, 0x24);
|
|
|
|
}
|
|
|
|
|
2007-12-11 07:05:37 +00:00
|
|
|
|
2006-06-15 04:19:30 +00:00
|
|
|
void CFPU::PullRoundingMode()
|
|
|
|
{
|
|
|
|
//fldcw word ptr [esp]
|
|
|
|
m_pBlock->StreamWrite(3, 0xD9, 0x2C, 0x24);
|
|
|
|
|
|
|
|
//add esp, 4
|
|
|
|
m_pBlock->StreamWrite(3, 0x83, 0xC4, 0x04);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFPU::SetRoundingMode(ROUNDMODE nMode)
|
|
|
|
{
|
|
|
|
//sub esp, 4
|
|
|
|
m_pBlock->StreamWrite(3, 0x83, 0xEC, 0x04);
|
|
|
|
|
|
|
|
//fwait
|
|
|
|
m_pBlock->StreamWrite(1, 0x9B);
|
|
|
|
|
|
|
|
//fnstcw word ptr [esp]
|
|
|
|
m_pBlock->StreamWrite(3, 0xD9, 0x3C, 0x24);
|
|
|
|
|
|
|
|
//pop eax
|
|
|
|
m_pBlock->StreamWrite(1, 0x58);
|
|
|
|
|
|
|
|
//and eax, 0xFFFFF3FF
|
|
|
|
m_pBlock->StreamWrite(1, 0x25);
|
|
|
|
m_pBlock->StreamWriteWord(0xFFFFF3FF);
|
|
|
|
|
|
|
|
//or eax, nMode << 10
|
|
|
|
m_pBlock->StreamWrite(1, 0x0D);
|
|
|
|
m_pBlock->StreamWriteWord(nMode << 10);
|
|
|
|
|
|
|
|
//push eax
|
|
|
|
m_pBlock->StreamWrite(1, 0x50);
|
|
|
|
|
|
|
|
//fldcw word ptr [esp]
|
|
|
|
m_pBlock->StreamWrite(3, 0xD9, 0x2C, 0x24);
|
|
|
|
|
|
|
|
//add esp, 4
|
|
|
|
m_pBlock->StreamWrite(3, 0x83, 0xC4, 0x04);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFPU::Add()
|
|
|
|
{
|
|
|
|
//faddp
|
|
|
|
m_pBlock->StreamWrite(2, 0xDE, 0xC1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFPU::Abs()
|
|
|
|
{
|
|
|
|
//fabs
|
|
|
|
m_pBlock->StreamWrite(2, 0xD9, 0xE1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFPU::Dup()
|
|
|
|
{
|
|
|
|
//fld st
|
|
|
|
m_pBlock->StreamWrite(2, 0xD9, 0xC0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFPU::Sub()
|
|
|
|
{
|
|
|
|
//fsubp
|
|
|
|
m_pBlock->StreamWrite(2, 0xDE, 0xE9);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFPU::Mul()
|
|
|
|
{
|
|
|
|
//fmulp
|
|
|
|
m_pBlock->StreamWrite(2, 0xDE, 0xC9);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFPU::Div()
|
|
|
|
{
|
|
|
|
//fdivp
|
|
|
|
m_pBlock->StreamWrite(2, 0xDE, 0xF9);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFPU::Neg()
|
|
|
|
{
|
|
|
|
//fchs
|
|
|
|
m_pBlock->StreamWrite(2, 0xD9, 0xE0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFPU::Rcpl()
|
|
|
|
{
|
|
|
|
//fld1
|
|
|
|
m_pBlock->StreamWrite(2, 0xD9, 0xE8);
|
|
|
|
|
|
|
|
//fdivrp
|
|
|
|
m_pBlock->StreamWrite(2, 0xDE, 0xF1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFPU::Sqrt()
|
|
|
|
{
|
|
|
|
//fsqrt
|
|
|
|
m_pBlock->StreamWrite(2, 0xD9, 0xFA);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFPU::Cmp(CCodeGen::CONDITION nCondition)
|
|
|
|
{
|
|
|
|
unsigned int nRegister;
|
|
|
|
|
|
|
|
//fcomip
|
|
|
|
m_pBlock->StreamWrite(2, 0xDF, 0xF1);
|
|
|
|
|
|
|
|
//fstp
|
|
|
|
m_pBlock->StreamWrite(2, 0xDD, 0xD8);
|
|
|
|
|
|
|
|
nRegister = CCodeGen::AllocateRegister(CCodeGen::REGISTER_HASLOW);
|
|
|
|
|
|
|
|
switch(nCondition)
|
|
|
|
{
|
|
|
|
case CCodeGen::CONDITION_EQ:
|
|
|
|
//sete reg[l]
|
|
|
|
m_pBlock->StreamWrite(3, 0x0F, 0x94, 0xC0 | (CCodeGen::m_nRegisterLookup[nRegister]));
|
|
|
|
break;
|
|
|
|
case CCodeGen::CONDITION_BL:
|
|
|
|
//setb reg[l]
|
|
|
|
m_pBlock->StreamWrite(3, 0x0F, 0x92, 0xC0 | (CCodeGen::m_nRegisterLookup[nRegister]));
|
|
|
|
break;
|
|
|
|
case CCodeGen::CONDITION_BE:
|
|
|
|
//setbe reg[l]
|
|
|
|
m_pBlock->StreamWrite(3, 0x0F, 0x96, 0xC0 | (CCodeGen::m_nRegisterLookup[nRegister]));
|
|
|
|
break;
|
|
|
|
case CCodeGen::CONDITION_AB:
|
|
|
|
//seta reg[l]
|
|
|
|
m_pBlock->StreamWrite(3, 0x0F, 0x97, 0xC0 | (CCodeGen::m_nRegisterLookup[nRegister]));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
//movzx reg, reg[l]
|
|
|
|
m_pBlock->StreamWrite(3, 0x0F, 0xB6, 0xC0 | (CCodeGen::m_nRegisterLookup[nRegister] << 3) | (CCodeGen::m_nRegisterLookup[nRegister]));
|
|
|
|
|
|
|
|
CCodeGen::PushReg(nRegister);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFPU::Round()
|
|
|
|
{
|
|
|
|
//frndint
|
|
|
|
m_pBlock->StreamWrite(2, 0xD9, 0xFC);
|
|
|
|
}
|
2007-12-11 07:05:37 +00:00
|
|
|
|
|
|
|
//New stuff
|
|
|
|
|
2007-12-14 01:41:48 +00:00
|
|
|
void CCodeGen::FP_PushSingleReg(XMMREGISTER registerId)
|
2007-12-11 07:05:37 +00:00
|
|
|
{
|
2007-12-14 01:41:48 +00:00
|
|
|
m_Shadow.Push(registerId);
|
|
|
|
m_Shadow.Push(FP_SINGLE_REGISTER);
|
2007-12-11 07:05:37 +00:00
|
|
|
}
|
|
|
|
|
2007-12-14 01:41:48 +00:00
|
|
|
void CCodeGen::FP_PushSingle(size_t offset)
|
2007-12-11 07:05:37 +00:00
|
|
|
{
|
2007-12-14 01:41:48 +00:00
|
|
|
m_Shadow.Push(static_cast<uint32>(offset));
|
|
|
|
m_Shadow.Push(FP_SINGLE_RELATIVE);
|
2007-12-11 07:05:37 +00:00
|
|
|
}
|
|
|
|
|
2007-12-14 01:41:48 +00:00
|
|
|
void CCodeGen::FP_LoadSingleRelativeInRegister(XMMREGISTER destination, uint32 source)
|
2007-12-11 07:05:37 +00:00
|
|
|
{
|
2007-12-14 01:41:48 +00:00
|
|
|
m_Assembler.MovssEd(destination,
|
|
|
|
CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, source));
|
2007-12-11 07:05:37 +00:00
|
|
|
}
|
|
|
|
|
2007-12-14 01:41:48 +00:00
|
|
|
void CCodeGen::FP_PushWord(size_t offset)
|
2007-12-11 07:05:37 +00:00
|
|
|
{
|
2007-12-14 01:41:48 +00:00
|
|
|
XMMREGISTER resultRegister = AllocateXmmRegister();
|
|
|
|
m_Assembler.Cvtsi2ssEd(resultRegister,
|
|
|
|
CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, static_cast<uint32>(offset)));
|
|
|
|
FP_PushSingleReg(resultRegister);
|
2007-12-11 07:05:37 +00:00
|
|
|
}
|
|
|
|
|
2007-12-14 01:41:48 +00:00
|
|
|
void CCodeGen::FP_PullSingle(size_t offset)
|
2007-12-11 07:05:37 +00:00
|
|
|
{
|
2007-12-14 01:41:48 +00:00
|
|
|
if(FitsPattern<SingleFpSingleRegister>())
|
|
|
|
{
|
|
|
|
XMMREGISTER valueRegister = static_cast<XMMREGISTER>(GetPattern<SingleFpSingleRegister>());
|
|
|
|
m_Assembler.MovssEd(CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, static_cast<uint32>(offset)),
|
|
|
|
valueRegister);
|
|
|
|
FreeXmmRegister(valueRegister);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
assert(0);
|
|
|
|
}
|
2007-12-11 07:05:37 +00:00
|
|
|
}
|
|
|
|
|
2007-12-14 01:41:48 +00:00
|
|
|
void CCodeGen::FP_PullWordTruncate(size_t offset)
|
2007-12-11 07:05:37 +00:00
|
|
|
{
|
2007-12-14 01:41:48 +00:00
|
|
|
if(FitsPattern<SingleFpSingleRelative>())
|
|
|
|
{
|
|
|
|
SingleFpSingleRelative::PatternValue op = GetPattern<SingleFpSingleRelative>();
|
|
|
|
unsigned int valueRegister = AllocateRegister();
|
|
|
|
m_Assembler.Cvttss2siEd(m_nRegisterLookupEx[valueRegister],
|
|
|
|
CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, op));
|
|
|
|
m_Assembler.MovGd(CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, static_cast<uint32>(offset)),
|
|
|
|
m_nRegisterLookupEx[valueRegister]);
|
|
|
|
FreeRegister(valueRegister);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
assert(0);
|
|
|
|
}
|
2007-12-11 07:05:37 +00:00
|
|
|
}
|
|
|
|
|
2008-03-03 00:38:28 +00:00
|
|
|
void CCodeGen::FP_GenericTwoOperand(const MdTwoOperandFunction& instruction)
|
|
|
|
{
|
|
|
|
if(FitsPattern<DualFpSingleRelative>())
|
|
|
|
{
|
|
|
|
DualFpSingleRelative::PatternValue ops = GetPattern<DualFpSingleRelative>();
|
|
|
|
XMMREGISTER resultRegister = AllocateXmmRegister();
|
|
|
|
FP_LoadSingleRelativeInRegister(resultRegister, ops.first);
|
|
|
|
instruction(resultRegister,
|
|
|
|
CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, ops.second));
|
|
|
|
FP_PushSingleReg(resultRegister);
|
|
|
|
}
|
|
|
|
else if(FitsPattern<FpSingleRelativeRegister>())
|
|
|
|
{
|
|
|
|
FpSingleRelativeRegister::PatternValue ops = GetPattern<FpSingleRelativeRegister>();
|
|
|
|
XMMREGISTER resultRegister = AllocateXmmRegister();
|
|
|
|
{
|
|
|
|
XMMREGISTER sourceRegister = static_cast<XMMREGISTER>(ops.second);
|
|
|
|
FP_LoadSingleRelativeInRegister(resultRegister, ops.first);
|
|
|
|
instruction(resultRegister,
|
|
|
|
CX86Assembler::MakeXmmRegisterAddress(sourceRegister));
|
|
|
|
if(!RegisterFpSingleHasNextUse(sourceRegister))
|
|
|
|
{
|
|
|
|
FreeXmmRegister(sourceRegister);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
FP_PushSingleReg(resultRegister);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw exception();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-14 01:41:48 +00:00
|
|
|
void CCodeGen::FP_Add()
|
2007-12-11 07:05:37 +00:00
|
|
|
{
|
2007-12-14 01:41:48 +00:00
|
|
|
if(FitsPattern<DualFpSingleRelative>())
|
|
|
|
{
|
|
|
|
DualFpSingleRelative::PatternValue ops = GetPattern<DualFpSingleRelative>();
|
|
|
|
XMMREGISTER resultRegister = AllocateXmmRegister();
|
|
|
|
FP_LoadSingleRelativeInRegister(resultRegister, ops.first);
|
|
|
|
m_Assembler.AddssEd(resultRegister,
|
|
|
|
CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, ops.second));
|
|
|
|
FP_PushSingleReg(resultRegister);
|
|
|
|
}
|
2008-01-21 04:09:08 +00:00
|
|
|
else if(FitsPattern<CommutativeFpSingleRegisterRelative>())
|
|
|
|
{
|
|
|
|
CommutativeFpSingleRegisterRelative::PatternValue ops = GetPattern<CommutativeFpSingleRegisterRelative>();
|
|
|
|
XMMREGISTER destinationRegister = static_cast<XMMREGISTER>(ops.first);
|
|
|
|
XMMREGISTER resultRegister = RegisterFpSingleHasNextUse(destinationRegister) ? AllocateXmmRegister() : destinationRegister;
|
|
|
|
m_Assembler.AddssEd(resultRegister,
|
|
|
|
CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, ops.second));
|
|
|
|
FP_PushSingleReg(resultRegister);
|
|
|
|
}
|
2007-12-14 01:41:48 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
assert(0);
|
|
|
|
}
|
2007-12-11 07:05:37 +00:00
|
|
|
}
|
|
|
|
|
2008-03-06 03:14:33 +00:00
|
|
|
void CCodeGen::FP_Abs()
|
|
|
|
{
|
|
|
|
if(FitsPattern<SingleFpSingleRelative>())
|
|
|
|
{
|
|
|
|
SingleFpSingleRelative::PatternValue op = GetPattern<SingleFpSingleRelative>();
|
|
|
|
XMMREGISTER resultRegister = AllocateXmmRegister();
|
|
|
|
unsigned int tempRegister = AllocateRegister();
|
|
|
|
m_Assembler.MovId(m_nRegisterLookupEx[tempRegister], 0x7FFFFFFF);
|
|
|
|
m_Assembler.AndEd(m_nRegisterLookupEx[tempRegister],
|
|
|
|
CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, op));
|
|
|
|
m_Assembler.MovdVo(resultRegister,
|
|
|
|
CX86Assembler::MakeRegisterAddress(m_nRegisterLookupEx[tempRegister]));
|
|
|
|
FreeRegister(tempRegister);
|
|
|
|
FP_PushSingleReg(resultRegister);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw runtime_error("Not implemented.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-14 01:41:48 +00:00
|
|
|
void CCodeGen::FP_Sub()
|
2007-12-11 07:05:37 +00:00
|
|
|
{
|
2008-03-03 00:38:28 +00:00
|
|
|
FP_GenericTwoOperand(bind(&CX86Assembler::SubssEd, m_Assembler, _1, _2));
|
2007-12-11 07:05:37 +00:00
|
|
|
}
|
|
|
|
|
2007-12-14 01:41:48 +00:00
|
|
|
void CCodeGen::FP_Mul()
|
2007-12-11 07:05:37 +00:00
|
|
|
{
|
2008-03-03 00:38:28 +00:00
|
|
|
FP_GenericTwoOperand(bind(&CX86Assembler::MulssEd, m_Assembler, _1, _2));
|
2007-12-11 07:05:37 +00:00
|
|
|
}
|
|
|
|
|
2007-12-14 01:41:48 +00:00
|
|
|
void CCodeGen::FP_Div()
|
2007-12-11 07:05:37 +00:00
|
|
|
{
|
2007-12-14 01:41:48 +00:00
|
|
|
if(FitsPattern<DualFpSingleRelative>())
|
|
|
|
{
|
|
|
|
DualFpSingleRelative::PatternValue ops = GetPattern<DualFpSingleRelative>();
|
|
|
|
XMMREGISTER resultRegister = AllocateXmmRegister();
|
|
|
|
FP_LoadSingleRelativeInRegister(resultRegister, ops.first);
|
|
|
|
m_Assembler.DivssEd(resultRegister,
|
|
|
|
CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, ops.second));
|
|
|
|
FP_PushSingleReg(resultRegister);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-03-03 00:38:28 +00:00
|
|
|
throw runtime_error("Not implemented.");
|
2007-12-14 01:41:48 +00:00
|
|
|
}
|
2007-12-11 07:05:37 +00:00
|
|
|
}
|
2007-12-29 17:22:26 +00:00
|
|
|
|
|
|
|
void CCodeGen::FP_Cmp(CCodeGen::CONDITION condition)
|
|
|
|
{
|
|
|
|
if(FitsPattern<DualFpSingleRelative>())
|
|
|
|
{
|
|
|
|
DualFpSingleRelative::PatternValue ops = GetPattern<DualFpSingleRelative>();
|
|
|
|
CX86Assembler::SSE_CMP_TYPE conditionCode;
|
|
|
|
switch(condition)
|
|
|
|
{
|
|
|
|
case CONDITION_EQ:
|
|
|
|
conditionCode = CX86Assembler::SSE_CMP_EQ;
|
|
|
|
break;
|
2008-01-03 07:42:54 +00:00
|
|
|
case CONDITION_BL:
|
|
|
|
conditionCode = CX86Assembler::SSE_CMP_LT;
|
|
|
|
break;
|
2008-01-15 20:27:44 +00:00
|
|
|
case CONDITION_BE:
|
|
|
|
conditionCode = CX86Assembler::SSE_CMP_LE;
|
|
|
|
break;
|
2007-12-29 17:22:26 +00:00
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
XMMREGISTER tempResultRegister = AllocateXmmRegister();
|
|
|
|
unsigned int resultRegister = AllocateRegister();
|
2008-01-15 20:27:44 +00:00
|
|
|
FP_LoadSingleRelativeInRegister(tempResultRegister, ops.second);
|
2007-12-29 17:22:26 +00:00
|
|
|
m_Assembler.CmpssEd(tempResultRegister,
|
2008-01-15 20:27:44 +00:00
|
|
|
CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, ops.first),
|
2007-12-29 17:22:26 +00:00
|
|
|
conditionCode);
|
|
|
|
//Can't move directly to register using MOVSS, so we use CVTTSS2SI
|
|
|
|
//0x00000000 -- CVT -> zero
|
|
|
|
//0xFFFFFFFF -- CVT -> not zero
|
|
|
|
m_Assembler.Cvttss2siEd(m_nRegisterLookupEx[resultRegister],
|
|
|
|
CX86Assembler::MakeXmmRegisterAddress(tempResultRegister));
|
|
|
|
FreeXmmRegister(tempResultRegister);
|
|
|
|
PushReg(resultRegister);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-03-03 00:38:28 +00:00
|
|
|
throw runtime_error("Not implemented.");
|
2007-12-29 17:22:26 +00:00
|
|
|
}
|
|
|
|
}
|
2008-01-07 04:05:17 +00:00
|
|
|
|
|
|
|
void CCodeGen::FP_Neg()
|
|
|
|
{
|
|
|
|
if(FitsPattern<SingleFpSingleRelative>())
|
|
|
|
{
|
|
|
|
SingleFpSingleRelative::PatternValue op = GetPattern<SingleFpSingleRelative>();
|
|
|
|
XMMREGISTER resultRegister = AllocateXmmRegister();
|
|
|
|
m_Assembler.PxorVo(resultRegister,
|
|
|
|
CX86Assembler::MakeXmmRegisterAddress(resultRegister));
|
|
|
|
m_Assembler.SubssEd(resultRegister,
|
|
|
|
CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, op));
|
|
|
|
FP_PushSingleReg(resultRegister);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-03-03 00:38:28 +00:00
|
|
|
throw runtime_error("Not implemented.");
|
2008-01-07 04:05:17 +00:00
|
|
|
}
|
|
|
|
}
|
2008-02-17 23:51:25 +00:00
|
|
|
|
|
|
|
void CCodeGen::FP_Sqrt()
|
|
|
|
{
|
|
|
|
if(FitsPattern<SingleFpSingleRelative>())
|
|
|
|
{
|
|
|
|
SingleFpSingleRelative::PatternValue op = GetPattern<SingleFpSingleRelative>();
|
|
|
|
XMMREGISTER resultRegister = AllocateXmmRegister();
|
|
|
|
m_Assembler.SqrtssEd(resultRegister,
|
|
|
|
CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, op));
|
|
|
|
FP_PushSingleReg(resultRegister);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw runtime_error("Not implemented.");
|
|
|
|
}
|
|
|
|
}
|
2008-03-03 00:38:28 +00:00
|
|
|
|
|
|
|
void CCodeGen::FP_Rsqrt()
|
|
|
|
{
|
|
|
|
if(FitsPattern<SingleFpSingleRelative>())
|
|
|
|
{
|
|
|
|
SingleFpSingleRelative::PatternValue op = GetPattern<SingleFpSingleRelative>();
|
|
|
|
XMMREGISTER resultRegister = AllocateXmmRegister();
|
|
|
|
m_Assembler.RsqrtssEd(resultRegister,
|
|
|
|
CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, op));
|
|
|
|
FP_PushSingleReg(resultRegister);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw runtime_error("Not implemented.");
|
|
|
|
}
|
|
|
|
}
|