1 #include "Jitter_CodeGen_x86.h"
2 
3 using namespace Jitter;
4 
MakeRelativeFpSingleSymbolAddress(CSymbol * symbol)5 CX86Assembler::CAddress CCodeGen_x86::MakeRelativeFpSingleSymbolAddress(CSymbol* symbol)
6 {
7 	assert(symbol->m_type == SYM_FP_REL_SINGLE);
8 	assert((symbol->m_valueLow & 0x3) == 0);
9 	return CX86Assembler::MakeIndRegOffAddress(CX86Assembler::rBP, symbol->m_valueLow);
10 }
11 
MakeTemporaryFpSingleSymbolAddress(CSymbol * symbol)12 CX86Assembler::CAddress CCodeGen_x86::MakeTemporaryFpSingleSymbolAddress(CSymbol* symbol)
13 {
14 	assert(symbol->m_type == SYM_FP_TMP_SINGLE);
15 	assert(((symbol->m_stackLocation + m_stackLevel) & 0x3) == 0);
16 	return CX86Assembler::MakeIndRegOffAddress(CX86Assembler::rSP, symbol->m_stackLocation + m_stackLevel);
17 }
18 
MakeMemoryFpSingleSymbolAddress(CSymbol * symbol)19 CX86Assembler::CAddress CCodeGen_x86::MakeMemoryFpSingleSymbolAddress(CSymbol* symbol)
20 {
21 	switch(symbol->m_type)
22 	{
23 	case SYM_FP_REL_SINGLE:
24 		return MakeRelativeFpSingleSymbolAddress(symbol);
25 		break;
26 	case SYM_FP_TMP_SINGLE:
27 		return MakeTemporaryFpSingleSymbolAddress(symbol);
28 		break;
29 	default:
30 		throw std::exception();
31 		break;
32 	}
33 }
34 
GetSseConditionCode(Jitter::CONDITION condition)35 CX86Assembler::SSE_CMP_TYPE CCodeGen_x86::GetSseConditionCode(Jitter::CONDITION condition)
36 {
37 	CX86Assembler::SSE_CMP_TYPE conditionCode = CX86Assembler::SSE_CMP_EQ;
38 	switch(condition)
39 	{
40 	case CONDITION_EQ:
41 		conditionCode = CX86Assembler::SSE_CMP_EQ;
42 		break;
43 	case CONDITION_BL:
44 		conditionCode = CX86Assembler::SSE_CMP_LT;
45 		break;
46 	case CONDITION_BE:
47 		conditionCode = CX86Assembler::SSE_CMP_LE;
48 		break;
49 	case CONDITION_AB:
50 		conditionCode = CX86Assembler::SSE_CMP_NLE;
51 		break;
52 	default:
53 		assert(0);
54 		break;
55 	}
56 	return conditionCode;
57 }
58 
Emit_Fp_Abs_MemMem(const STATEMENT & statement)59 void CCodeGen_x86::Emit_Fp_Abs_MemMem(const STATEMENT& statement)
60 {
61 	CSymbol* dst = statement.dst->GetSymbol().get();
62 	CSymbol* src1 = statement.src1->GetSymbol().get();
63 
64 	m_assembler.MovEd(CX86Assembler::rAX, MakeMemoryFpSingleSymbolAddress(src1));
65 	m_assembler.AndId(CX86Assembler::MakeRegisterAddress(CX86Assembler::rAX), 0x7FFFFFFF);
66 	m_assembler.MovGd(MakeMemoryFpSingleSymbolAddress(dst), CX86Assembler::rAX);
67 }
68 
Emit_Fp_Neg_MemMem(const STATEMENT & statement)69 void CCodeGen_x86::Emit_Fp_Neg_MemMem(const STATEMENT& statement)
70 {
71 	CSymbol* dst = statement.dst->GetSymbol().get();
72 	CSymbol* src1 = statement.src1->GetSymbol().get();
73 
74 	m_assembler.MovEd(CX86Assembler::rAX, MakeMemoryFpSingleSymbolAddress(src1));
75 	m_assembler.XorId(CX86Assembler::MakeRegisterAddress(CX86Assembler::rAX), 0x80000000);
76 	m_assembler.MovGd(MakeMemoryFpSingleSymbolAddress(dst), CX86Assembler::rAX);
77 }
78 
Emit_Fp_LdCst_MemCst(const STATEMENT & statement)79 void CCodeGen_x86::Emit_Fp_LdCst_MemCst(const STATEMENT& statement)
80 {
81 	CSymbol* dst = statement.dst->GetSymbol().get();
82 	CSymbol* src1 = statement.src1->GetSymbol().get();
83 
84 	assert(src1->m_type == SYM_CONSTANT);
85 
86 	CX86Assembler::REGISTER tmpRegister = CX86Assembler::rAX;
87 
88 	m_assembler.MovId(tmpRegister, src1->m_valueLow);
89 	m_assembler.MovGd(MakeMemoryFpSingleSymbolAddress(dst), tmpRegister);
90 }
91 
92 CCodeGen_x86::CONSTMATCHER CCodeGen_x86::g_fpuConstMatchers[] =
93 {
94 	{ OP_FP_ABS, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_NIL, MATCH_NIL, &CCodeGen_x86::Emit_Fp_Abs_MemMem },
95 	{ OP_FP_NEG, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_NIL, MATCH_NIL, &CCodeGen_x86::Emit_Fp_Neg_MemMem },
96 
97 	{ OP_FP_LDCST, MATCH_MEMORY_FP_SINGLE, MATCH_CONSTANT, MATCH_NIL, MATCH_NIL, &CCodeGen_x86::Emit_Fp_LdCst_MemCst },
98 
99 	{ OP_MOV, MATCH_NIL, MATCH_NIL, MATCH_NIL, MATCH_NIL, nullptr },
100 };
101