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