1 #include "Jitter_CodeGen_x86.h"
2 
3 using namespace Jitter;
4 
5 template <typename FPUOP>
Emit_Fpu_Avx_MemMem(const STATEMENT & statement)6 void CCodeGen_x86::Emit_Fpu_Avx_MemMem(const STATEMENT& statement)
7 {
8 	auto dst = statement.dst->GetSymbol().get();
9 	auto src1 = statement.src1->GetSymbol().get();
10 
11 	((m_assembler).*(FPUOP::OpEdAvx()))(CX86Assembler::xMM0, CX86Assembler::xMM0, MakeMemoryFpSingleSymbolAddress(src1));
12 	m_assembler.VmovssEd(MakeMemoryFpSingleSymbolAddress(dst), CX86Assembler::xMM0);
13 }
14 
15 template <typename FPUOP>
Emit_Fpu_Avx_MemMemMem(const STATEMENT & statement)16 void CCodeGen_x86::Emit_Fpu_Avx_MemMemMem(const STATEMENT& statement)
17 {
18 	auto dst = statement.dst->GetSymbol().get();
19 	auto src1 = statement.src1->GetSymbol().get();
20 	auto src2 = statement.src2->GetSymbol().get();
21 
22 	auto dstRegister = CX86Assembler::xMM0;
23 	auto src1Register = CX86Assembler::xMM1;
24 
25 	m_assembler.VmovssEd(src1Register, MakeMemoryFpSingleSymbolAddress(src1));
26 	((m_assembler).*(FPUOP::OpEdAvx()))(dstRegister, src1Register, MakeMemoryFpSingleSymbolAddress(src2));
27 	m_assembler.VmovssEd(MakeMemoryFpSingleSymbolAddress(dst), dstRegister);
28 }
29 
Emit_Fp_Avx_Cmp_VarMemMem(const STATEMENT & statement)30 void CCodeGen_x86::Emit_Fp_Avx_Cmp_VarMemMem(const STATEMENT& statement)
31 {
32 	auto dst = statement.dst->GetSymbol().get();
33 	auto src1 = statement.src1->GetSymbol().get();
34 	auto src2 = statement.src2->GetSymbol().get();
35 
36 	auto dstReg = PrepareSymbolRegisterDef(dst, CX86Assembler::rAX);
37 	auto cmpReg = CX86Assembler::xMM0;
38 	auto resReg = CX86Assembler::xMM1;
39 
40 	auto conditionCode = GetSseConditionCode(statement.jmpCondition);
41 	m_assembler.VmovssEd(cmpReg, MakeMemoryFpSingleSymbolAddress(src1));
42 	m_assembler.VcmpssEd(resReg, cmpReg, MakeMemoryFpSingleSymbolAddress(src2), conditionCode);
43 	m_assembler.VmovdVo(CX86Assembler::MakeRegisterAddress(dstReg), resReg);
44 
45 	CommitSymbolRegister(dst, dstReg);
46 }
47 
Emit_Fp_Avx_Rsqrt_MemMem(const STATEMENT & statement)48 void CCodeGen_x86::Emit_Fp_Avx_Rsqrt_MemMem(const STATEMENT& statement)
49 {
50 	auto dst = statement.dst->GetSymbol().get();
51 	auto src1 = statement.src1->GetSymbol().get();
52 
53 	auto tmpIntRegister = CX86Assembler::rAX;
54 	auto resultRegister = CX86Assembler::xMM0;
55 	auto sqrtRegister = CX86Assembler::xMM1;
56 
57 	m_assembler.VsqrtssEd(sqrtRegister, CX86Assembler::xMM0, MakeMemoryFpSingleSymbolAddress(src1));
58 	m_assembler.MovId(tmpIntRegister, 0x3F800000);
59 	m_assembler.VmovdVo(resultRegister, CX86Assembler::MakeRegisterAddress(tmpIntRegister));
60 	m_assembler.VdivssEd(resultRegister, resultRegister, CX86Assembler::MakeXmmRegisterAddress(sqrtRegister));
61 	m_assembler.VmovssEd(MakeMemoryFpSingleSymbolAddress(dst), resultRegister);
62 }
63 
Emit_Fp_Avx_Rcpl_MemMem(const STATEMENT & statement)64 void CCodeGen_x86::Emit_Fp_Avx_Rcpl_MemMem(const STATEMENT& statement)
65 {
66 	auto dst = statement.dst->GetSymbol().get();
67 	auto src1 = statement.src1->GetSymbol().get();
68 
69 	auto tmpIntRegister = CX86Assembler::rAX;
70 	auto resultRegister = CX86Assembler::xMM0;
71 
72 	m_assembler.MovId(tmpIntRegister, 0x3F800000);
73 	m_assembler.VmovdVo(resultRegister, CX86Assembler::MakeRegisterAddress(tmpIntRegister));
74 	m_assembler.VdivssEd(resultRegister, resultRegister, MakeMemoryFpSingleSymbolAddress(src1));
75 	m_assembler.VmovssEd(MakeMemoryFpSingleSymbolAddress(dst), resultRegister);
76 }
77 
Emit_Fp_Avx_Mov_RelSRelI32(const STATEMENT & statement)78 void CCodeGen_x86::Emit_Fp_Avx_Mov_RelSRelI32(const STATEMENT& statement)
79 {
80 	auto dst = statement.dst->GetSymbol().get();
81 	auto src1 = statement.src1->GetSymbol().get();
82 
83 	assert(dst->m_type  == SYM_FP_REL_SINGLE);
84 	assert(src1->m_type == SYM_FP_REL_INT32);
85 
86 	m_assembler.Vcvtsi2ssEd(CX86Assembler::xMM0, CX86Assembler::MakeIndRegOffAddress(CX86Assembler::rBP, src1->m_valueLow));
87 	m_assembler.VmovssEd(CX86Assembler::MakeIndRegOffAddress(CX86Assembler::rBP, dst->m_valueLow), CX86Assembler::xMM0);
88 }
89 
Emit_Fp_Avx_ToIntTrunc_RelRel(const STATEMENT & statement)90 void CCodeGen_x86::Emit_Fp_Avx_ToIntTrunc_RelRel(const STATEMENT& statement)
91 {
92 	auto dst = statement.dst->GetSymbol().get();
93 	auto src1 = statement.src1->GetSymbol().get();
94 
95 	assert(dst->m_type  == SYM_FP_REL_SINGLE);
96 	assert(src1->m_type == SYM_FP_REL_SINGLE);
97 
98 	m_assembler.Vcvttss2siEd(CX86Assembler::rAX, CX86Assembler::MakeIndRegOffAddress(CX86Assembler::rBP, src1->m_valueLow));
99 	m_assembler.MovGd(CX86Assembler::MakeIndRegOffAddress(CX86Assembler::rBP, dst->m_valueLow), CX86Assembler::rAX);
100 }
101 
102 CCodeGen_x86::CONSTMATCHER CCodeGen_x86::g_fpuAvxConstMatchers[] =
103 {
104 	{ OP_FP_ADD, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_NIL, &CCodeGen_x86::Emit_Fpu_Avx_MemMemMem<FPUOP_ADD> },
105 	{ OP_FP_SUB, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_NIL, &CCodeGen_x86::Emit_Fpu_Avx_MemMemMem<FPUOP_SUB> },
106 	{ OP_FP_MUL, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_NIL, &CCodeGen_x86::Emit_Fpu_Avx_MemMemMem<FPUOP_MUL> },
107 	{ OP_FP_DIV, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_NIL, &CCodeGen_x86::Emit_Fpu_Avx_MemMemMem<FPUOP_DIV> },
108 	{ OP_FP_MAX, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_NIL, &CCodeGen_x86::Emit_Fpu_Avx_MemMemMem<FPUOP_MAX> },
109 	{ OP_FP_MIN, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_NIL, &CCodeGen_x86::Emit_Fpu_Avx_MemMemMem<FPUOP_MIN> },
110 
111 	{ OP_FP_CMP, MATCH_VARIABLE, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_NIL, &CCodeGen_x86::Emit_Fp_Avx_Cmp_VarMemMem },
112 
113 	{ OP_FP_SQRT,  MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_NIL, MATCH_NIL, &CCodeGen_x86::Emit_Fpu_Avx_MemMem<FPUOP_SQRT> },
114 	{ OP_FP_RSQRT, MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_NIL, MATCH_NIL, &CCodeGen_x86::Emit_Fp_Avx_Rsqrt_MemMem        },
115 	{ OP_FP_RCPL,  MATCH_MEMORY_FP_SINGLE, MATCH_MEMORY_FP_SINGLE, MATCH_NIL, MATCH_NIL, &CCodeGen_x86::Emit_Fp_Avx_Rcpl_MemMem         },
116 
117 	{ OP_MOV,            MATCH_RELATIVE_FP_SINGLE, MATCH_RELATIVE_FP_INT32,  MATCH_NIL, MATCH_NIL, &CCodeGen_x86::Emit_Fp_Avx_Mov_RelSRelI32    },
118 	{ OP_FP_TOINT_TRUNC, MATCH_RELATIVE_FP_SINGLE, MATCH_RELATIVE_FP_SINGLE, MATCH_NIL, MATCH_NIL, &CCodeGen_x86::Emit_Fp_Avx_ToIntTrunc_RelRel },
119 
120 	{ OP_MOV, MATCH_NIL, MATCH_NIL, MATCH_NIL, MATCH_NIL, nullptr },
121 };
122