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