1 #ifndef _JITTER_CODEGEN_X86_DIV_H_
2 #define _JITTER_CODEGEN_X86_DIV_H_
3 
4 template <bool isSigned>
Emit_DivTmp64RegReg(const STATEMENT & statement)5 void CCodeGen_x86::Emit_DivTmp64RegReg(const STATEMENT& statement)
6 {
7 	auto dst = statement.dst->GetSymbol().get();
8 	auto src1 = statement.src1->GetSymbol().get();
9 	auto src2 = statement.src2->GetSymbol().get();
10 
11 	assert(src1->m_type == SYM_REGISTER);
12 	assert(src2->m_type == SYM_REGISTER);
13 
14 	m_assembler.MovEd(CX86Assembler::rAX, CX86Assembler::MakeRegisterAddress(m_registers[src1->m_valueLow]));
15 	if(isSigned)
16 	{
17 		m_assembler.Cdq();
18 		m_assembler.IdivEd(CX86Assembler::MakeRegisterAddress(m_registers[src2->m_valueLow]));
19 	}
20 	else
21 	{
22 		m_assembler.XorEd(CX86Assembler::rDX, CX86Assembler::MakeRegisterAddress(CX86Assembler::rDX));
23 		m_assembler.DivEd(CX86Assembler::MakeRegisterAddress(m_registers[src2->m_valueLow]));
24 	}
25 	m_assembler.MovGd(MakeTemporary64SymbolLoAddress(dst), CX86Assembler::rAX);
26 	m_assembler.MovGd(MakeTemporary64SymbolHiAddress(dst), CX86Assembler::rDX);
27 }
28 
29 template <bool isSigned>
Emit_DivTmp64RegMem(const STATEMENT & statement)30 void CCodeGen_x86::Emit_DivTmp64RegMem(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 	assert(src1->m_type == SYM_REGISTER);
37 
38 	m_assembler.MovEd(CX86Assembler::rAX, CX86Assembler::MakeRegisterAddress(m_registers[src1->m_valueLow]));
39 	if(isSigned)
40 	{
41 		m_assembler.Cdq();
42 		m_assembler.IdivEd(MakeMemorySymbolAddress(src2));
43 	}
44 	else
45 	{
46 		m_assembler.XorEd(CX86Assembler::rDX, CX86Assembler::MakeRegisterAddress(CX86Assembler::rDX));
47 		m_assembler.DivEd(MakeMemorySymbolAddress(src2));
48 	}
49 	m_assembler.MovGd(MakeTemporary64SymbolLoAddress(dst), CX86Assembler::rAX);
50 	m_assembler.MovGd(MakeTemporary64SymbolHiAddress(dst), CX86Assembler::rDX);
51 }
52 
53 template <bool isSigned>
Emit_DivTmp64RegCst(const STATEMENT & statement)54 void CCodeGen_x86::Emit_DivTmp64RegCst(const STATEMENT& statement)
55 {
56 	auto dst = statement.dst->GetSymbol().get();
57 	auto src1 = statement.src1->GetSymbol().get();
58 	auto src2 = statement.src2->GetSymbol().get();
59 
60 	assert(src1->m_type == SYM_REGISTER);
61 	assert(src2->m_type == SYM_CONSTANT);
62 
63 	m_assembler.MovEd(CX86Assembler::rAX, CX86Assembler::MakeRegisterAddress(m_registers[src1->m_valueLow]));
64 	m_assembler.MovId(CX86Assembler::rCX, src2->m_valueLow);
65 	if(isSigned)
66 	{
67 		m_assembler.Cdq();
68 		m_assembler.IdivEd(CX86Assembler::MakeRegisterAddress(CX86Assembler::rCX));
69 	}
70 	else
71 	{
72 		m_assembler.XorEd(CX86Assembler::rDX, CX86Assembler::MakeRegisterAddress(CX86Assembler::rDX));
73 		m_assembler.DivEd(CX86Assembler::MakeRegisterAddress(CX86Assembler::rCX));
74 	}
75 	m_assembler.MovGd(MakeTemporary64SymbolLoAddress(dst), CX86Assembler::rAX);
76 	m_assembler.MovGd(MakeTemporary64SymbolHiAddress(dst), CX86Assembler::rDX);
77 }
78 
79 template <bool isSigned>
Emit_DivTmp64MemReg(const STATEMENT & statement)80 void CCodeGen_x86::Emit_DivTmp64MemReg(const STATEMENT& statement)
81 {
82 	auto dst = statement.dst->GetSymbol().get();
83 	auto src1 = statement.src1->GetSymbol().get();
84 	auto src2 = statement.src2->GetSymbol().get();
85 
86 	assert(src2->m_type == SYM_REGISTER);
87 
88 	m_assembler.MovEd(CX86Assembler::rAX, MakeMemorySymbolAddress(src1));
89 	if(isSigned)
90 	{
91 		m_assembler.Cdq();
92 		m_assembler.IdivEd(CX86Assembler::MakeRegisterAddress(m_registers[src2->m_valueLow]));
93 	}
94 	else
95 	{
96 		m_assembler.XorEd(CX86Assembler::rDX, CX86Assembler::MakeRegisterAddress(CX86Assembler::rDX));
97 		m_assembler.DivEd(CX86Assembler::MakeRegisterAddress(m_registers[src2->m_valueLow]));
98 	}
99 	m_assembler.MovGd(MakeTemporary64SymbolLoAddress(dst), CX86Assembler::rAX);
100 	m_assembler.MovGd(MakeTemporary64SymbolHiAddress(dst), CX86Assembler::rDX);
101 }
102 
103 template <bool isSigned>
Emit_DivTmp64MemMem(const STATEMENT & statement)104 void CCodeGen_x86::Emit_DivTmp64MemMem(const STATEMENT& statement)
105 {
106 	auto dst = statement.dst->GetSymbol().get();
107 	auto src1 = statement.src1->GetSymbol().get();
108 	auto src2 = statement.src2->GetSymbol().get();
109 
110 	m_assembler.MovEd(CX86Assembler::rAX, MakeMemorySymbolAddress(src1));
111 	if(isSigned)
112 	{
113 		m_assembler.Cdq();
114 		m_assembler.IdivEd(MakeMemorySymbolAddress(src2));
115 	}
116 	else
117 	{
118 		m_assembler.XorEd(CX86Assembler::rDX, CX86Assembler::MakeRegisterAddress(CX86Assembler::rDX));
119 		m_assembler.DivEd(MakeMemorySymbolAddress(src2));
120 	}
121 	m_assembler.MovGd(MakeTemporary64SymbolLoAddress(dst), CX86Assembler::rAX);
122 	m_assembler.MovGd(MakeTemporary64SymbolHiAddress(dst), CX86Assembler::rDX);
123 }
124 
125 template <bool isSigned>
Emit_DivTmp64MemCst(const STATEMENT & statement)126 void CCodeGen_x86::Emit_DivTmp64MemCst(const STATEMENT& statement)
127 {
128 	auto dst = statement.dst->GetSymbol().get();
129 	auto src1 = statement.src1->GetSymbol().get();
130 	auto src2 = statement.src2->GetSymbol().get();
131 
132 	assert(src2->m_type == SYM_CONSTANT);
133 
134 	m_assembler.MovEd(CX86Assembler::rAX, MakeMemorySymbolAddress(src1));
135 	m_assembler.MovId(CX86Assembler::rCX, src2->m_valueLow);
136 	if(isSigned)
137 	{
138 		m_assembler.Cdq();
139 		m_assembler.IdivEd(CX86Assembler::MakeRegisterAddress(CX86Assembler::rCX));
140 	}
141 	else
142 	{
143 		m_assembler.XorEd(CX86Assembler::rDX, CX86Assembler::MakeRegisterAddress(CX86Assembler::rDX));
144 		m_assembler.DivEd(CX86Assembler::MakeRegisterAddress(CX86Assembler::rCX));
145 	}
146 	m_assembler.MovGd(MakeTemporary64SymbolLoAddress(dst), CX86Assembler::rAX);
147 	m_assembler.MovGd(MakeTemporary64SymbolHiAddress(dst), CX86Assembler::rDX);
148 }
149 
150 template <bool isSigned>
Emit_DivTmp64CstReg(const STATEMENT & statement)151 void CCodeGen_x86::Emit_DivTmp64CstReg(const STATEMENT& statement)
152 {
153 	auto dst = statement.dst->GetSymbol().get();
154 	auto src1 = statement.src1->GetSymbol().get();
155 	auto src2 = statement.src2->GetSymbol().get();
156 
157 	assert(src1->m_type == SYM_CONSTANT);
158 	assert(src2->m_type == SYM_REGISTER);
159 
160 	m_assembler.MovId(CX86Assembler::rAX, src1->m_valueLow);
161 	if(isSigned)
162 	{
163 		m_assembler.Cdq();
164 		m_assembler.IdivEd(CX86Assembler::MakeRegisterAddress(m_registers[src2->m_valueLow]));
165 	}
166 	else
167 	{
168 		m_assembler.XorEd(CX86Assembler::rDX, CX86Assembler::MakeRegisterAddress(CX86Assembler::rDX));
169 		m_assembler.DivEd(CX86Assembler::MakeRegisterAddress(m_registers[src2->m_valueLow]));
170 	}
171 	m_assembler.MovGd(MakeTemporary64SymbolLoAddress(dst), CX86Assembler::rAX);
172 	m_assembler.MovGd(MakeTemporary64SymbolHiAddress(dst), CX86Assembler::rDX);
173 }
174 
175 template <bool isSigned>
Emit_DivTmp64CstMem(const STATEMENT & statement)176 void CCodeGen_x86::Emit_DivTmp64CstMem(const STATEMENT& statement)
177 {
178 	auto dst = statement.dst->GetSymbol().get();
179 	auto src1 = statement.src1->GetSymbol().get();
180 	auto src2 = statement.src2->GetSymbol().get();
181 
182 	assert(src1->m_type == SYM_CONSTANT);
183 
184 	m_assembler.MovId(CX86Assembler::rAX, src1->m_valueLow);
185 	if(isSigned)
186 	{
187 		m_assembler.Cdq();
188 		m_assembler.IdivEd(MakeMemorySymbolAddress(src2));
189 	}
190 	else
191 	{
192 		m_assembler.XorEd(CX86Assembler::rDX, CX86Assembler::MakeRegisterAddress(CX86Assembler::rDX));
193 		m_assembler.DivEd(MakeMemorySymbolAddress(src2));
194 	}
195 	m_assembler.MovGd(MakeTemporary64SymbolLoAddress(dst), CX86Assembler::rAX);
196 	m_assembler.MovGd(MakeTemporary64SymbolHiAddress(dst), CX86Assembler::rDX);
197 }
198 
199 #endif
200