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