Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | # ========== Copyright Header Begin ========================================== |
2 | # | |
3 | # OpenSPARC T2 Processor File: SS_InstrFormat.py | |
4 | # Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
5 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
6 | # | |
7 | # The above named program is free software; you can redistribute it and/or | |
8 | # modify it under the terms of the GNU General Public | |
9 | # License version 2 as published by the Free Software Foundation. | |
10 | # | |
11 | # The above named program is distributed in the hope that it will be | |
12 | # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | # General Public License for more details. | |
15 | # | |
16 | # You should have received a copy of the GNU General Public | |
17 | # License along with this work; if not, write to the Free Software | |
18 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
19 | # | |
20 | # ========== Copyright Header End ============================================ | |
21 | ||
22 | from SS_Instr import * | |
23 | ||
24 | ss_vis1 = {} | |
25 | ss_vis2 = {} | |
26 | ss_vis3 = {} | |
27 | ||
28 | #============================================================================ | |
29 | # SS_opf_fff | |
30 | #============================================================================ | |
31 | ||
32 | class SS_opf_fff(SS_InstrAsm): | |
33 | def __init__(self,name): | |
34 | SS_InstrAsm.__init__(self,name) | |
35 | ||
36 | def run_exe_s(self,file): | |
37 | self.s_code(file,'run_exe_') | |
38 | self.ld_sim(file,'%g5') | |
39 | self.ld_rs1(file,'%g1') | |
40 | self.ld_rs2(file,'%g2') | |
41 | self.ld_rd(file,'%g3') | |
42 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
43 | self.branch(file,'ne','%xcc','fpop_disabled_trap') | |
44 | self.nop(file) | |
45 | self.ld_frf(file,'%g1','%f0') | |
46 | self.ld_frf(file,'%g2','%f4') | |
47 | self.opr(file,self.name,'%f0','%f4','%f8') | |
48 | self.branch(file,'a,a','%xcc','opf_fprs_f') | |
49 | ||
50 | def run_exe_c(self,file): | |
51 | file.write('#if defined(ARCH_X64)\n') | |
52 | self.c_code_beg(file,'run_exe_') | |
53 | file.write(' if (s->sim_state.fp_disabled())\n') | |
54 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
55 | file.write(' uint32_t rs1 = s->get_frf(i->rs1);\n') | |
56 | file.write(' uint32_t rs2 = s->get_frf(i->rs2);\n') | |
57 | file.write(' uint32_t r32;\n') | |
58 | file.write(' uint64_t v64;\n') | |
59 | if (self.name in ['fpadd16s','fpsub16s']): | |
60 | file.write(' r32 = 0;\n') | |
61 | file.write(' for (int n = 0; n < 2; n++) {\n') | |
62 | if (self.name == 'fpadd16s'): | |
63 | file.write(' v64 = (rs1 & 0xffff) + (rs2 & 0xffff);\n') | |
64 | else: | |
65 | file.write(' v64 = (rs1 & 0xffff) - (rs2 & 0xffff);\n') | |
66 | file.write(' r32 |= ((v64 & 0xffff) << (n << 4));\n') | |
67 | file.write(' rs1 >>= 16;\n') | |
68 | file.write(' rs2 >>= 16;\n') | |
69 | file.write(' }\n') | |
70 | elif (self.name in ['fpadd32s','fpsub32s']): | |
71 | if (self.name == 'fpadd32s'): | |
72 | file.write(' v64 = rs1 + rs2;\n') | |
73 | else: | |
74 | file.write(' v64 = rs1 - rs2;\n') | |
75 | file.write(' r32 = v64;\n') | |
76 | elif (self.name == 'fors'): | |
77 | file.write(' r32 = rs1 | rs2;\n') | |
78 | elif (self.name == 'fnors'): | |
79 | file.write(' r32 = ~(rs1 | rs2);\n') | |
80 | elif (self.name == 'fands'): | |
81 | file.write(' r32 = rs1 & rs2;\n') | |
82 | elif (self.name == 'fnands'): | |
83 | file.write(' r32 = ~(rs1 & rs2);\n') | |
84 | elif (self.name == 'fxors'): | |
85 | file.write(' r32 = rs1 ^ rs2;\n') | |
86 | elif (self.name == 'fxnors'): | |
87 | file.write(' r32 = ~(rs1 ^ rs2);\n') | |
88 | elif (self.name == 'fornot1s'): | |
89 | file.write(' r32 = (~rs1) | rs2;\n') | |
90 | elif (self.name == 'fornot2s'): | |
91 | file.write(' r32 = rs1 | (~rs2);\n') | |
92 | elif (self.name == 'fandnot1s'): | |
93 | file.write(' r32 = (~rs1) & rs2;\n') | |
94 | elif (self.name == 'fandnot2s'): | |
95 | file.write(' r32 = rs1 & (~rs2);\n') | |
96 | file.write(' s->get_frf(i->rd) = r32;\n') | |
97 | file.write(' s->set_fprs(i->rd);\n') | |
98 | file.write(' s->npc = npc+4;\n') | |
99 | file.write(' return npc;\n') | |
100 | self.c_code_end(file) | |
101 | file.write('#else\n') | |
102 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
103 | file.write('#endif\n') | |
104 | ||
105 | def run_dec_c(self,file): | |
106 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
107 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
108 | self.ill_ibe(file) | |
109 | self.dec_fff(file,'','idx_exe_'+self.name) | |
110 | self.c_code_end(file) | |
111 | ||
112 | def gen_exe_tbl(self,file,mode): | |
113 | if mode == 'trc': | |
114 | file.write(' trc_exe_fff, /* '+self.name+' */\n') | |
115 | elif mode == 'v8_run': | |
116 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
117 | else: | |
118 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
119 | ||
120 | ss_vis1[0x051] = SS_opf_fff('fpadd16s') | |
121 | ss_vis1[0x053] = SS_opf_fff('fpadd32s') | |
122 | ss_vis1[0x055] = SS_opf_fff('fpsub16s') | |
123 | ss_vis1[0x057] = SS_opf_fff('fpsub32s') | |
124 | ss_vis1[0x07d] = SS_opf_fff('fors') | |
125 | ss_vis1[0x063] = SS_opf_fff('fnors') | |
126 | ss_vis1[0x071] = SS_opf_fff('fands') | |
127 | ss_vis1[0x06f] = SS_opf_fff('fnands') | |
128 | ss_vis1[0x06d] = SS_opf_fff('fxors') | |
129 | ss_vis1[0x073] = SS_opf_fff('fxnors') | |
130 | ss_vis1[0x07b] = SS_opf_fff('fornot1s') | |
131 | ss_vis1[0x077] = SS_opf_fff('fornot2s') | |
132 | ss_vis1[0x069] = SS_opf_fff('fandnot1s') | |
133 | ss_vis1[0x065] = SS_opf_fff('fandnot2s') | |
134 | ||
135 | #============================================================================ | |
136 | # SS_opf_ddd | |
137 | #============================================================================ | |
138 | ||
139 | class SS_opf_ddd(SS_InstrAsm): | |
140 | def __init__(self,name): | |
141 | SS_InstrAsm.__init__(self,name) | |
142 | ||
143 | def run_exe_s(self,file): | |
144 | self.s_code(file,'run_exe_') | |
145 | self.ld_sim(file,'%g5') | |
146 | self.ld_rs1(file,'%g1') | |
147 | self.ld_rs2(file,'%g2') | |
148 | self.ld_rd(file,'%g3') | |
149 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
150 | self.branch(file,'ne','%xcc','fpop_disabled_trap') | |
151 | self.nop(file) | |
152 | self.ld_drf(file,'%g1','%f0') | |
153 | self.ld_drf(file,'%g2','%f4') | |
154 | self.opr(file,self.name,'%f0','%f4','%f8') | |
155 | self.branch(file,'a,a','%xcc','opf_fprs_d') | |
156 | ||
157 | def run_exe_c(self,file): | |
158 | file.write('#if defined(ARCH_X64)\n') | |
159 | self.c_code_beg(file,'run_exe_') | |
160 | file.write(' if (s->sim_state.fp_disabled())\n') | |
161 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
162 | file.write(' uint64_t rs1 = s->get_drf(i->rs1);\n') | |
163 | file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n') | |
164 | file.write(' uint64_t r64,v64;\n') | |
165 | if (self.name in ['fmul8sux16','fmul8ulx16']): | |
166 | file.write(' int32_t s32_0, s32_1;\n') | |
167 | file.write(' uint32_t r32;\n') | |
168 | file.write(' r64 = 0;\n') | |
169 | if (self.name == 'fmul8sux16'): | |
170 | file.write(' rs1 >>= 8;\n') | |
171 | file.write(' for (int n = 0; n < 4; n++) {\n') | |
172 | file.write(' s32_0 = (int32_t)rs1;\n') | |
173 | if (self.name == 'fmul8ulx16'): | |
174 | file.write(' s32_0 &= 0xff;\n') | |
175 | else: | |
176 | file.write(' s32_0 = (s32_0 << 24) >> 24;\n') | |
177 | file.write(' s32_1 = (int32_t)rs2;\n') | |
178 | file.write(' s32_1 = (s32_1 << 16) >> 16;\n') | |
179 | file.write(' r32 = s32_0 * s32_1;\n') | |
180 | if (self.name == 'fmul8sux16'): | |
181 | file.write(' if ((r32 & 0x80) != 0)\n') | |
182 | file.write(' r32 += (0x80 << 1);\n') | |
183 | file.write(' r32 >>= 8;\n') | |
184 | else: | |
185 | file.write(' if ((r32 & 0x8000) != 0)\n') | |
186 | file.write(' r32 += (0x8000 << 1);\n') | |
187 | file.write(' r32 >>= 16;\n') | |
188 | file.write(' r64 |= (((uint64_t)(r32 & 0xffff)) << (n << 4));\n') | |
189 | file.write(' rs1 >>= 16;\n') | |
190 | file.write(' rs2 >>= 16;\n') | |
191 | file.write(' }\n') | |
192 | elif (self.name in ['fpadd16','fpsub16']): | |
193 | file.write(' r64 = 0;\n') | |
194 | file.write(' for (int n = 0; n < 4; n++) {\n') | |
195 | if (self.name == 'fpadd16'): | |
196 | file.write(' v64 = (rs1 & 0xffff) + (rs2 & 0xffff);\n') | |
197 | else: | |
198 | file.write(' v64 = (rs1 & 0xffff) - (rs2 & 0xffff);\n') | |
199 | file.write(' r64 |= ((v64 & 0xffff) << (n << 4));\n') | |
200 | file.write(' rs1 >>= 16;\n') | |
201 | file.write(' rs2 >>= 16;\n') | |
202 | file.write(' }\n') | |
203 | elif (self.name in ['fpadd32','fpsub32']): | |
204 | file.write(' r64 = 0;\n') | |
205 | file.write(' for (int n = 0; n < 2; n++) {\n') | |
206 | if (self.name == 'fpadd32'): | |
207 | file.write(' v64 = (rs1 & 0xffffffff) + (rs2 & 0xffffffff);\n') | |
208 | else: | |
209 | file.write(' v64 = (rs1 & 0xffffffff) - (rs2 & 0xffffffff);\n') | |
210 | file.write(' r64 |= ((v64 & 0xffffffff) << (n << 5));\n') | |
211 | file.write(' rs1 >>= 32;\n') | |
212 | file.write(' rs2 >>= 32;\n') | |
213 | file.write(' }\n') | |
214 | elif (self.name == 'for'): | |
215 | file.write(' r64 = rs1 | rs2;\n') | |
216 | elif (self.name == 'fnor'): | |
217 | file.write(' r64 = ~(rs1 | rs2);\n') | |
218 | elif (self.name == 'fand'): | |
219 | file.write(' r64 = rs1 & rs2;\n') | |
220 | elif (self.name == 'fnand'): | |
221 | file.write(' r64 = ~(rs1 & rs2);\n') | |
222 | elif (self.name == 'fxor'): | |
223 | file.write(' r64 = rs1 ^ rs2;\n') | |
224 | elif (self.name == 'fxnor'): | |
225 | file.write(' r64 = ~(rs1 ^ rs2);\n') | |
226 | elif (self.name == 'fornot1'): | |
227 | file.write(' r64 = (~rs1) | rs2;\n') | |
228 | elif (self.name == 'fornot2'): | |
229 | file.write(' r64 = rs1 | (~rs2);\n') | |
230 | elif (self.name == 'fandnot1'): | |
231 | file.write(' r64 = (~rs1) & rs2;\n') | |
232 | elif (self.name == 'fandnot2'): | |
233 | file.write(' r64 = rs1 & (~rs2);\n') | |
234 | file.write(' s->get_drf(i->rd) = r64;\n') | |
235 | file.write(' s->set_fprs(i->rd);\n') | |
236 | file.write(' s->npc = npc+4;\n') | |
237 | file.write(' return npc;\n') | |
238 | self.c_code_end(file) | |
239 | file.write('#else\n') | |
240 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
241 | file.write('#endif\n') | |
242 | ||
243 | def run_dec_c(self,file): | |
244 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
245 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
246 | self.ill_ibe(file) | |
247 | self.dec_ddd(file,'','idx_exe_'+self.name) | |
248 | self.c_code_end(file) | |
249 | ||
250 | def gen_exe_tbl(self,file,mode): | |
251 | if mode == 'trc': | |
252 | file.write(' trc_exe_ddd, /* '+self.name+' */\n') | |
253 | elif mode == 'v8_run': | |
254 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
255 | else: | |
256 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
257 | ||
258 | ss_vis1[0x036] = SS_opf_ddd('fmul8sux16') | |
259 | ss_vis1[0x037] = SS_opf_ddd('fmul8ulx16') | |
260 | ss_vis1[0x050] = SS_opf_ddd('fpadd16') | |
261 | ss_vis1[0x052] = SS_opf_ddd('fpadd32') | |
262 | ss_vis1[0x054] = SS_opf_ddd('fpsub16') | |
263 | ss_vis1[0x056] = SS_opf_ddd('fpsub32') | |
264 | ss_vis1[0x07c] = SS_opf_ddd('for') | |
265 | ss_vis1[0x062] = SS_opf_ddd('fnor') | |
266 | ss_vis1[0x070] = SS_opf_ddd('fand') | |
267 | ss_vis1[0x06e] = SS_opf_ddd('fnand') | |
268 | ss_vis1[0x06c] = SS_opf_ddd('fxor') | |
269 | ss_vis1[0x072] = SS_opf_ddd('fxnor') | |
270 | ss_vis1[0x07a] = SS_opf_ddd('fornot1') | |
271 | ss_vis1[0x076] = SS_opf_ddd('fornot2') | |
272 | ss_vis1[0x068] = SS_opf_ddd('fandnot1') | |
273 | ss_vis1[0x064] = SS_opf_ddd('fandnot2') | |
274 | ||
275 | #============================================================================ | |
276 | # SS_opf_ddd3 | |
277 | #============================================================================ | |
278 | ||
279 | class SS_opf_ddd3(SS_InstrAsm): | |
280 | def __init__(self,name): | |
281 | SS_InstrAsm.__init__(self,name) | |
282 | ||
283 | def run_exe_s(self,file): | |
284 | self.s_code(file,'run_exe_') | |
285 | self.ld_sim(file,'%g5') | |
286 | self.ld_rs1(file,'%g1') | |
287 | self.ld_rs2(file,'%g2') | |
288 | self.ld_rd(file,'%g3') | |
289 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
290 | self.branch(file,'ne','%xcc','fpop_disabled_trap') | |
291 | self.nop(file) | |
292 | self.ld_drf(file,'%g1','%f0') | |
293 | self.ld_drf(file,'%g2','%f4') | |
294 | self.ld_drf(file,'%g3','%f8') | |
295 | self.opr(file,self.name,'%f0','%f4','%f8') | |
296 | self.branch(file,'a,a','%xcc','opf_fprs_d') | |
297 | ||
298 | def run_exe_c(self,file): | |
299 | file.write('#if defined(ARCH_X64)\n') | |
300 | self.c_code_beg(file,'run_exe_') | |
301 | file.write(' if (s->sim_state.fp_disabled())\n') | |
302 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
303 | file.write(' uint64_t rs1 = s->get_drf(i->rs1);\n') | |
304 | file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n') | |
305 | file.write(' uint64_t rd = s->get_drf(i->rd);\n') | |
306 | file.write(' uint64_t sum = 0;\n') | |
307 | file.write(' uint64_t v64;\n') | |
308 | file.write(' for (int n = 0; n < 8; n++) {\n') | |
309 | file.write(' v64 = (rs1 & 0xff) - (rs2 & 0xff);\n') | |
310 | file.write(' if (v64 >> 63)\n') | |
311 | file.write(' v64 = -v64;\n') | |
312 | file.write(' sum += v64;\n') | |
313 | file.write(' rs1 >>= 8;\n') | |
314 | file.write(' rs2 >>= 8;\n') | |
315 | file.write(' }\n') | |
316 | file.write(' s->get_drf(i->rd) = rd + sum;\n') | |
317 | file.write(' s->set_fprs(i->rd);\n') | |
318 | file.write(' s->npc = npc+4;\n') | |
319 | file.write(' return npc;\n') | |
320 | self.c_code_end(file) | |
321 | file.write('#else\n') | |
322 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
323 | file.write('#endif\n') | |
324 | ||
325 | def run_dec_c(self,file): | |
326 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
327 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
328 | self.ill_ibe(file) | |
329 | self.dec_ddd(file,'','idx_exe_'+self.name) | |
330 | self.c_code_end(file) | |
331 | ||
332 | def gen_exe_tbl(self,file,mode): | |
333 | if mode == 'v8_run': | |
334 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
335 | else: | |
336 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
337 | ||
338 | ss_vis1[0x03e] = SS_opf_ddd3('pdist') | |
339 | ||
340 | #============================================================================ | |
341 | # SS_opf_dfd | |
342 | #============================================================================ | |
343 | ||
344 | class SS_opf_dfd(SS_InstrAsm): | |
345 | def __init__(self,name): | |
346 | SS_InstrAsm.__init__(self,name) | |
347 | ||
348 | def run_exe_s(self,file): | |
349 | self.s_code(file,'run_exe_') | |
350 | self.ld_sim(file,'%g5') | |
351 | self.ld_rs1(file,'%g1') | |
352 | self.ld_rs2(file,'%g2') | |
353 | self.ld_rd(file,'%g3') | |
354 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
355 | self.branch(file,'ne','%xcc','fpop_disabled_trap') | |
356 | self.nop(file) | |
357 | self.ld_frf(file,'%g1','%f0') | |
358 | self.ld_drf(file,'%g2','%f4') | |
359 | self.opr(file,self.name,'%f0','%f4','%f8') | |
360 | self.branch(file,'a,a','%xcc','opf_fprs_d') | |
361 | ||
362 | def run_exe_c(self,file): | |
363 | file.write('#if defined(ARCH_X64)\n') | |
364 | self.c_code_beg(file,'run_exe_') | |
365 | file.write(' if (s->sim_state.fp_disabled())\n') | |
366 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
367 | file.write(' uint32_t rs1 = s->get_frf(i->rs1);\n') | |
368 | file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n') | |
369 | file.write(' uint64_t rd = 0;\n') | |
370 | file.write(' for (int n = 0; n < 4; n++) {\n') | |
371 | file.write(' uint32_t v32 = rs1 & 0xff;\n') | |
372 | file.write(' int32_t s32_0 = (int32_t)rs2;\n') | |
373 | file.write(' s32_0 = (s32_0 << 16) >> 16;\n') | |
374 | file.write(' uint32_t r32 = s32_0 * v32;\n') | |
375 | file.write(' if ((r32 & 0x80) != 0)\n') | |
376 | file.write(' r32 += 0x100;\n') | |
377 | file.write(' r32 >>= 8;\n') | |
378 | file.write(' rd |= (((uint64_t)(r32 & 0xffff)) << (n << 4));\n') | |
379 | file.write(' rs1 >>= 8;\n') | |
380 | file.write(' rs2 >>= 16;\n') | |
381 | file.write(' }\n') | |
382 | file.write(' s->get_drf(i->rd) = rd;\n') | |
383 | file.write(' s->set_fprs(i->rd);\n') | |
384 | file.write(' s->npc = npc+4;\n') | |
385 | file.write(' return npc;\n') | |
386 | self.c_code_end(file) | |
387 | file.write('#else\n') | |
388 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
389 | file.write('#endif\n') | |
390 | ||
391 | def run_dec_c(self,file): | |
392 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
393 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
394 | self.ill_ibe(file) | |
395 | self.dec_dfd(file,'','idx_exe_'+self.name) | |
396 | self.c_code_end(file) | |
397 | ||
398 | def gen_exe_tbl(self,file,mode): | |
399 | if mode == 'trc': | |
400 | file.write(' trc_exe_dfd, /* '+self.name+' */\n') | |
401 | elif mode == 'v8_run': | |
402 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
403 | else: | |
404 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
405 | ||
406 | ss_vis1[0x031] = SS_opf_dfd('fmul8x16') | |
407 | ||
408 | #============================================================================ | |
409 | # SS_opf_dff | |
410 | #============================================================================ | |
411 | ||
412 | class SS_opf_dff(SS_InstrAsm): | |
413 | def __init__(self,name): | |
414 | SS_InstrAsm.__init__(self,name) | |
415 | ||
416 | def run_exe_s(self,file): | |
417 | self.s_code(file,'run_exe_') | |
418 | self.ld_sim(file,'%g5') | |
419 | self.ld_rs1(file,'%g1') | |
420 | self.ld_rs2(file,'%g2') | |
421 | self.ld_rd(file,'%g3') | |
422 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
423 | self.branch(file,'ne','%xcc','fpop_disabled_trap') | |
424 | self.nop(file) | |
425 | self.ld_frf(file,'%g1','%f0') | |
426 | self.ld_frf(file,'%g2','%f4') | |
427 | self.opr(file,self.name,'%f0','%f4','%f8') | |
428 | self.branch(file,'a,a','%xcc','opf_fprs_d') | |
429 | ||
430 | def run_exe_c(self,file): | |
431 | file.write('#if defined(ARCH_X64)\n') | |
432 | self.c_code_beg(file,'run_exe_') | |
433 | file.write(' if (s->sim_state.fp_disabled())\n') | |
434 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
435 | file.write(' uint32_t rs1 = s->get_frf(i->rs1);\n') | |
436 | file.write(' uint32_t rs2 = s->get_frf(i->rs2);\n') | |
437 | if (self.name in ['fmul8x16au','fmul8x16al']): | |
438 | if (self.name == 'fmul8x16au'): | |
439 | file.write(' int32_t s32_0 = (rs2 >> 16);\n') | |
440 | else: | |
441 | file.write(' int32_t s32_0 = rs2;\n') | |
442 | file.write(' uint64_t rd = 0;\n') | |
443 | file.write(' for (int n = 0; n < 4; n++) {\n') | |
444 | file.write(' uint32_t v32 = rs1 & 0xff;\n') | |
445 | file.write(' s32_0 = (s32_0 << 16) >> 16;\n') | |
446 | file.write(' uint32_t r32 = s32_0 * v32;\n') | |
447 | file.write(' if ((r32 & 0x80) != 0)\n') | |
448 | file.write(' r32 += 0x100;\n') | |
449 | file.write(' r32 >>= 8;\n') | |
450 | file.write(' rd |= (((uint64_t)(r32 & 0xffff)) << (n << 4));\n') | |
451 | file.write(' rs1 >>= 8;\n') | |
452 | file.write(' rs2 >>= 16;\n') | |
453 | file.write(' }\n') | |
454 | elif (self.name in ['fmuld8sux16','fmuld8ulx16']): | |
455 | file.write(' uint64_t rd = 0;\n') | |
456 | if (self.name == 'fmuld8sux16'): | |
457 | file.write(' rs1 >>= 8;\n') | |
458 | file.write(' for (int n = 0; n < 2; n++) {\n') | |
459 | file.write(' int32_t s32_0 = rs1;\n') | |
460 | if (self.name == 'fmuld8ulx16'): | |
461 | file.write(' s32_0 &= 0xff;\n') | |
462 | else: | |
463 | file.write(' s32_0 = (s32_0 << 24) >> 24;\n') | |
464 | file.write(' int32_t s32_1 = rs2;\n') | |
465 | file.write(' s32_1 = (s32_1 << 16) >> 16;\n') | |
466 | file.write(' uint32_t r32 = s32_0 * s32_1;\n') | |
467 | if (self.name == 'fmuld8sux16'): | |
468 | file.write(' rd |= (((uint64_t)(r32 & 0xffffff)) << ((n << 5) + 8));\n') | |
469 | else: | |
470 | file.write(' rd |= (((uint64_t)r32) << (n << 5));\n') | |
471 | file.write(' rs1 >>= 16;\n') | |
472 | file.write(' rs2 >>= 16;\n') | |
473 | file.write(' }\n') | |
474 | elif (self.name == 'fpmerge'): | |
475 | file.write(' uint64_t rd = 0;\n') | |
476 | file.write(' uint64_t d0 = rs1;\n') | |
477 | file.write(' uint64_t d1 = rs2;\n') | |
478 | file.write(' for (int n = 0; n < 4; n++) {\n') | |
479 | file.write(' rd |= ((d0 & 0xff) << ((n << 4) + 8));\n') | |
480 | file.write(' rd |= ((d1 & 0xff) << (n << 4));\n') | |
481 | file.write(' d0 >>= 8;\n') | |
482 | file.write(' d1 >>= 8;\n') | |
483 | file.write(' }\n') | |
484 | file.write(' s->get_drf(i->rd) = rd;\n') | |
485 | file.write(' s->set_fprs(i->rd);\n') | |
486 | file.write(' s->npc = npc+4;\n') | |
487 | file.write(' return npc;\n') | |
488 | self.c_code_end(file) | |
489 | file.write('#else\n') | |
490 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
491 | file.write('#endif\n') | |
492 | ||
493 | def run_dec_c(self,file): | |
494 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
495 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
496 | self.ill_ibe(file) | |
497 | self.dec_dff(file,'','idx_exe_'+self.name) | |
498 | self.c_code_end(file) | |
499 | ||
500 | def gen_exe_tbl(self,file,mode): | |
501 | if mode == 'trc': | |
502 | file.write(' trc_exe_dff, /* '+self.name+' */\n') | |
503 | elif mode == 'v8_run': | |
504 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
505 | else: | |
506 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
507 | ||
508 | ||
509 | ss_vis1[0x033] = SS_opf_dff('fmul8x16au') | |
510 | ss_vis1[0x035] = SS_opf_dff('fmul8x16al') | |
511 | ss_vis1[0x038] = SS_opf_dff('fmuld8sux16') | |
512 | ss_vis1[0x039] = SS_opf_dff('fmuld8ulx16') | |
513 | ss_vis1[0x04b] = SS_opf_dff('fpmerge') | |
514 | ||
515 | #============================================================================ | |
516 | # SS_opf_d0d | |
517 | #============================================================================ | |
518 | ||
519 | class SS_opf_d0d(SS_InstrAsm): | |
520 | def __init__(self,name): | |
521 | SS_InstrAsm.__init__(self,name) | |
522 | ||
523 | def run_exe_s(self,file): | |
524 | self.s_code(file,'run_exe_') | |
525 | self.ld_sim(file,'%g5') | |
526 | self.ld_rs2(file,'%g2') | |
527 | self.ld_rd(file,'%g3') | |
528 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
529 | self.branch(file,'ne','%xcc','fpop_disabled_trap') | |
530 | self.nop(file) | |
531 | self.ld_drf(file,'%g2','%f4') | |
532 | self.op2(file,self.name,'%f4','%f8') | |
533 | self.branch(file,'a,a','%xcc','opf_fprs_d') | |
534 | ||
535 | def run_exe_c(self,file): | |
536 | file.write('#if defined(ARCH_X64)\n') | |
537 | self.c_code_beg(file,'run_exe_') | |
538 | file.write(' if (s->sim_state.fp_disabled())\n') | |
539 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
540 | file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n') | |
541 | if (self.name == 'fsrc2'): | |
542 | file.write(' s->get_drf(i->rd) = rs2;\n') | |
543 | elif (self.name == 'fnot2'): | |
544 | file.write(' s->get_drf(i->rd) = ~rs2;\n') | |
545 | file.write(' s->set_fprs(i->rd);\n') | |
546 | file.write(' s->npc = npc+4;\n') | |
547 | file.write(' return npc;\n') | |
548 | self.c_code_end(file) | |
549 | file.write('#else\n') | |
550 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
551 | file.write('#endif\n') | |
552 | ||
553 | def run_dec_c(self,file): | |
554 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
555 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
556 | file.write(' if (o.is_zero_18_14())\n') | |
557 | file.write(' {\n') | |
558 | self.ill_ibe(file) | |
559 | self.dec_d0d(file,' ','idx_exe_'+self.name) | |
560 | file.write(' }\n') | |
561 | file.write(' else\n') | |
562 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
563 | self.c_code_end(file) | |
564 | ||
565 | def gen_exe_tbl(self,file,mode): | |
566 | if mode == 'trc': | |
567 | file.write(' trc_exe_d0d, /* '+self.name+' */\n') | |
568 | elif mode == 'v8_run': | |
569 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
570 | else: | |
571 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
572 | ||
573 | ||
574 | ss_vis1[0x078] = SS_opf_d0d('fsrc2') | |
575 | ss_vis1[0x066] = SS_opf_d0d('fnot2') | |
576 | ||
577 | #============================================================================ | |
578 | # SS_opf_dd0 | |
579 | #============================================================================ | |
580 | ||
581 | class SS_opf_dd0(SS_InstrAsm): | |
582 | def __init__(self,name): | |
583 | SS_InstrAsm.__init__(self,name) | |
584 | ||
585 | def run_exe_s(self,file): | |
586 | self.s_code(file,'run_exe_') | |
587 | self.ld_sim(file,'%g5') | |
588 | self.ld_rs1(file,'%g1') | |
589 | self.ld_rd(file,'%g3') | |
590 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
591 | self.branch(file,'ne','%xcc','fpop_disabled_trap') | |
592 | self.nop(file) | |
593 | self.ld_drf(file,'%g1','%f0') | |
594 | self.op2(file,self.name,'%f0','%f8') | |
595 | self.branch(file,'a,a','%xcc','opf_fprs_d') | |
596 | ||
597 | def run_exe_c(self,file): | |
598 | file.write('#if defined(ARCH_X64)\n') | |
599 | self.c_code_beg(file,'run_exe_') | |
600 | file.write(' if (s->sim_state.fp_disabled())\n') | |
601 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
602 | file.write(' uint64_t rs1 = s->get_drf(i->rs1);\n') | |
603 | if (self.name == 'fsrc1'): | |
604 | file.write(' s->get_drf(i->rd) = rs1;\n') | |
605 | elif (self.name == 'fnot1'): | |
606 | file.write(' s->get_drf(i->rd) = ~rs1;\n') | |
607 | file.write(' s->set_fprs(i->rd);\n') | |
608 | file.write(' s->npc = npc+4;\n') | |
609 | file.write(' return npc;\n') | |
610 | self.c_code_end(file) | |
611 | file.write('#else\n') | |
612 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
613 | file.write('#endif\n') | |
614 | ||
615 | def run_dec_c(self,file): | |
616 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
617 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
618 | file.write(' if (o.is_zero_4_0())\n') | |
619 | file.write(' {\n') | |
620 | self.ill_ibe(file) | |
621 | self.dec_dd0(file,' ','idx_exe_'+self.name) | |
622 | file.write(' }\n') | |
623 | file.write(' else\n') | |
624 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
625 | self.c_code_end(file) | |
626 | ||
627 | def gen_exe_tbl(self,file,mode): | |
628 | if mode == 'trc': | |
629 | file.write(' trc_exe_dd0, /* '+self.name+' */\n') | |
630 | elif mode == 'v8_run': | |
631 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
632 | else: | |
633 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
634 | ||
635 | ss_vis1[0x074] = SS_opf_dd0('fsrc1') | |
636 | ss_vis1[0x06a] = SS_opf_dd0('fnot1') | |
637 | ||
638 | #============================================================================ | |
639 | # SS_opf_f0f | |
640 | #============================================================================ | |
641 | ||
642 | class SS_opf_f0f(SS_InstrAsm): | |
643 | def __init__(self,name): | |
644 | SS_InstrAsm.__init__(self,name) | |
645 | ||
646 | def run_exe_s(self,file): | |
647 | self.s_code(file,'run_exe_') | |
648 | self.ld_sim(file,'%g5') | |
649 | self.ld_rs2(file,'%g2') | |
650 | self.ld_rd(file,'%g3') | |
651 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
652 | self.branch(file,'ne','%xcc','fpop_disabled_trap') | |
653 | self.nop(file) | |
654 | self.ld_frf(file,'%g2','%f4') | |
655 | self.op2(file,self.name,'%f4','%f8') | |
656 | self.branch(file,'a,a','%xcc','opf_fprs_f') | |
657 | ||
658 | def run_exe_c(self,file): | |
659 | file.write('#if defined(ARCH_X64)\n') | |
660 | self.c_code_beg(file,'run_exe_') | |
661 | file.write(' if (s->sim_state.fp_disabled())\n') | |
662 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
663 | file.write(' uint32_t rs2 = s->get_frf(i->rs2);\n') | |
664 | if (self.name == 'fsrc2s'): | |
665 | file.write(' s->get_frf(i->rd) = rs2;\n') | |
666 | elif (self.name == 'fnot2s'): | |
667 | file.write(' s->get_frf(i->rd) = ~rs2;\n') | |
668 | file.write(' s->set_fprs(i->rd);\n') | |
669 | file.write(' s->npc = npc+4;\n') | |
670 | file.write(' return npc;\n') | |
671 | self.c_code_end(file) | |
672 | file.write('#else\n') | |
673 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
674 | file.write('#endif\n') | |
675 | ||
676 | def run_dec_c(self,file): | |
677 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
678 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
679 | file.write(' if (o.is_zero_18_14())\n') | |
680 | file.write(' {\n') | |
681 | self.ill_ibe(file) | |
682 | self.dec_f0f(file,' ','idx_exe_'+self.name) | |
683 | file.write(' }\n') | |
684 | file.write(' else\n') | |
685 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
686 | self.c_code_end(file) | |
687 | ||
688 | def gen_exe_tbl(self,file,mode): | |
689 | if mode == 'trc': | |
690 | file.write(' trc_exe_f0f, /* '+self.name+' */\n') | |
691 | elif mode == 'v8_run': | |
692 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
693 | else: | |
694 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
695 | ||
696 | ss_vis1[0x079] = SS_opf_f0f('fsrc2s') | |
697 | ss_vis1[0x067] = SS_opf_f0f('fnot2s') | |
698 | ||
699 | #============================================================================ | |
700 | # SS_opf_ff0 | |
701 | #============================================================================ | |
702 | ||
703 | class SS_opf_ff0(SS_InstrAsm): | |
704 | def __init__(self,name): | |
705 | SS_InstrAsm.__init__(self,name) | |
706 | ||
707 | def run_exe_s(self,file): | |
708 | self.s_code(file,'run_exe_') | |
709 | self.ld_sim(file,'%g5') | |
710 | self.ld_rs1(file,'%g1') | |
711 | self.ld_rd(file,'%g3') | |
712 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
713 | self.branch(file,'ne','%xcc','fpop_disabled_trap') | |
714 | self.nop(file) | |
715 | self.ld_frf(file,'%g1','%f0') | |
716 | self.op2(file,self.name,'%f0','%f8') | |
717 | self.branch(file,'a,a','%xcc','opf_fprs_f') | |
718 | ||
719 | def run_exe_c(self,file): | |
720 | file.write('#if defined(ARCH_X64)\n') | |
721 | self.c_code_beg(file,'run_exe_') | |
722 | file.write(' if (s->sim_state.fp_disabled())\n') | |
723 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
724 | file.write(' uint32_t rs1 = s->get_frf(i->rs1);\n') | |
725 | if (self.name == 'fsrc1s'): | |
726 | file.write(' s->get_frf(i->rd) = rs1;\n') | |
727 | elif (self.name == 'fnot1s'): | |
728 | file.write(' s->get_frf(i->rd) = ~rs1;\n') | |
729 | file.write(' s->set_fprs(i->rd);\n') | |
730 | file.write(' s->npc = npc+4;\n') | |
731 | file.write(' return npc;\n') | |
732 | self.c_code_end(file) | |
733 | file.write('#else\n') | |
734 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
735 | file.write('#endif\n') | |
736 | ||
737 | def run_dec_c(self,file): | |
738 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
739 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
740 | file.write(' if (o.is_zero_4_0())\n') | |
741 | file.write(' {\n') | |
742 | self.ill_ibe(file) | |
743 | self.dec_ff0(file,' ','idx_exe_'+self.name) | |
744 | file.write(' }\n') | |
745 | file.write(' else\n') | |
746 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
747 | self.c_code_end(file) | |
748 | ||
749 | def gen_exe_tbl(self,file,mode): | |
750 | if mode == 'trc': | |
751 | file.write(' trc_exe_ff0, /* '+self.name+' */\n') | |
752 | elif mode == 'v8_run': | |
753 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
754 | else: | |
755 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
756 | ||
757 | ss_vis1[0x075] = SS_opf_ff0('fsrc1s') | |
758 | ss_vis1[0x06b] = SS_opf_ff0('fnot1s') | |
759 | ||
760 | ||
761 | #============================================================================ | |
762 | # SS_opf_d0f | |
763 | #============================================================================ | |
764 | ||
765 | class SS_opf_d0f(SS_InstrAsm): | |
766 | def __init__(self,name): | |
767 | SS_InstrAsm.__init__(self,name) | |
768 | ||
769 | def run_exe_s(self,file): | |
770 | self.s_code(file,'run_exe_') | |
771 | self.ld_sim(file,'%g5') | |
772 | self.ld_rs2(file,'%g2') | |
773 | self.ld_rd(file,'%g3') | |
774 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
775 | self.branch(file,'ne','%xcc','fpop_disabled_trap') | |
776 | self.nop(file) | |
777 | self.ld_frf(file,'%g2','%f4') | |
778 | self.op2(file,self.name,'%f4','%f8') | |
779 | self.branch(file,'a,a','%xcc','opf_fprs_d') | |
780 | ||
781 | def run_exe_c(self,file): | |
782 | file.write('#if defined(ARCH_X64)\n') | |
783 | self.c_code_beg(file,'run_exe_') | |
784 | file.write(' if (s->sim_state.fp_disabled())\n') | |
785 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
786 | file.write(' uint32_t rs2 = s->get_frf(i->rs2);\n') | |
787 | file.write(' uint64_t rd = 0;\n') | |
788 | file.write(' for (int n = 0; n < 4; n++) {\n') | |
789 | file.write(' uint64_t v64 = (rs2 & 0xff) << 4;\n') | |
790 | file.write(' rd |= (v64 << (n << 4));\n') | |
791 | file.write(' rs2 >>= 8;\n') | |
792 | file.write(' }\n') | |
793 | file.write(' s->get_drf(i->rd) = rd;\n') | |
794 | file.write(' s->set_fprs(i->rd);\n') | |
795 | file.write(' s->npc = npc+4;\n') | |
796 | file.write(' return npc;\n') | |
797 | self.c_code_end(file) | |
798 | file.write('#else\n') | |
799 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
800 | file.write('#endif\n') | |
801 | ||
802 | def run_dec_c(self,file): | |
803 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
804 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
805 | file.write(' if (o.is_zero_18_14())\n') | |
806 | file.write(' {\n') | |
807 | self.ill_ibe(file) | |
808 | self.dec_d0f(file,' ','idx_exe_'+self.name) | |
809 | file.write(' }\n') | |
810 | file.write(' else\n') | |
811 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
812 | self.c_code_end(file) | |
813 | ||
814 | def gen_exe_tbl(self,file,mode): | |
815 | if mode == 'trc': | |
816 | file.write(' trc_exe_d0f, /* '+self.name+' */\n') | |
817 | elif mode == 'v8_run': | |
818 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
819 | else: | |
820 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
821 | ||
822 | ss_vis1[0x04d] = SS_opf_d0f('fexpand') | |
823 | ||
824 | #============================================================================ | |
825 | # SS_opf_d00 | |
826 | #============================================================================ | |
827 | ||
828 | class SS_opf_d00(SS_InstrAsm): | |
829 | def __init__(self,name): | |
830 | SS_InstrAsm.__init__(self,name) | |
831 | ||
832 | def run_exe_s(self,file): | |
833 | self.s_code(file,'run_exe_') | |
834 | self.ld_sim(file,'%g5') | |
835 | self.ld_rd(file,'%g3') | |
836 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
837 | self.branch(file,'ne','%xcc','fpop_disabled_trap') | |
838 | self.nop(file) | |
839 | self.op1(file,self.name,'%f8') | |
840 | self.branch(file,'a,a','%xcc','opf_fprs_d') | |
841 | ||
842 | def run_exe_c(self,file): | |
843 | file.write('#if defined(ARCH_X64)\n') | |
844 | self.c_code_beg(file,'run_exe_') | |
845 | file.write(' if (s->sim_state.fp_disabled())\n') | |
846 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
847 | if (self.name == 'fzero'): | |
848 | file.write(' s->get_drf(i->rd) = 0;\n') | |
849 | elif (self.name == 'fone'): | |
850 | file.write(' s->get_drf(i->rd) = ~(uint64_t)0;\n') | |
851 | file.write(' s->set_fprs(i->rd);\n') | |
852 | file.write(' s->npc = npc+4;\n') | |
853 | file.write(' return npc;\n') | |
854 | self.c_code_end(file) | |
855 | file.write('#else\n') | |
856 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
857 | file.write('#endif\n') | |
858 | ||
859 | def run_dec_c(self,file): | |
860 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
861 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
862 | file.write(' if (o.is_zero_4_0() && o.is_zero_18_14())\n') | |
863 | file.write(' {\n') | |
864 | self.ill_ibe(file) | |
865 | self.dec_d00(file,' ','idx_exe_'+self.name) | |
866 | file.write(' }\n') | |
867 | file.write(' else\n') | |
868 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
869 | self.c_code_end(file) | |
870 | ||
871 | def gen_exe_tbl(self,file,mode): | |
872 | if mode == 'trc': | |
873 | file.write(' trc_exe_d00, /* '+self.name+' */\n') | |
874 | elif mode == 'v8_run': | |
875 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
876 | else: | |
877 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
878 | ||
879 | ss_vis1[0x060] = SS_opf_d00('fzero') | |
880 | ss_vis1[0x07e] = SS_opf_d00('fone') | |
881 | ||
882 | #============================================================================ | |
883 | # SS_opf_f00 | |
884 | #============================================================================ | |
885 | ||
886 | class SS_opf_f00(SS_InstrAsm): | |
887 | def __init__(self,name): | |
888 | SS_InstrAsm.__init__(self,name) | |
889 | ||
890 | def run_exe_s(self,file): | |
891 | self.s_code(file,'run_exe_') | |
892 | self.ld_sim(file,'%g5') | |
893 | self.ld_rd(file,'%g3') | |
894 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
895 | self.branch(file,'ne','%xcc','fpop_disabled_trap') | |
896 | self.nop(file) | |
897 | self.op1(file,self.name,'%f8') | |
898 | self.branch(file,'a,a','%xcc','opf_fprs_f') | |
899 | ||
900 | def run_exe_c(self,file): | |
901 | file.write('#if defined(ARCH_X64)\n') | |
902 | self.c_code_beg(file,'run_exe_') | |
903 | file.write(' if (s->sim_state.fp_disabled())\n') | |
904 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
905 | if (self.name == 'fzeros'): | |
906 | file.write(' s->get_frf(i->rd) = 0;\n') | |
907 | elif (self.name == 'fones'): | |
908 | file.write(' s->get_frf(i->rd) = ~(uint32_t)0;\n') | |
909 | file.write(' s->set_fprs(i->rd);\n') | |
910 | file.write(' s->npc = npc+4;\n') | |
911 | file.write(' return npc;\n') | |
912 | self.c_code_end(file) | |
913 | file.write('#else\n') | |
914 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
915 | file.write('#endif\n') | |
916 | ||
917 | def run_dec_c(self,file): | |
918 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
919 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
920 | file.write(' if (o.is_zero_4_0() && o.is_zero_18_14())\n') | |
921 | file.write(' {\n') | |
922 | self.ill_ibe(file) | |
923 | self.dec_f00(file,' ','idx_exe_'+self.name) | |
924 | file.write(' }\n') | |
925 | file.write(' else\n') | |
926 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
927 | self.c_code_end(file) | |
928 | ||
929 | def gen_exe_tbl(self,file,mode): | |
930 | if mode == 'trc': | |
931 | file.write(' trc_exe_f00, /* '+self.name+' */\n') | |
932 | elif mode == 'v8_run': | |
933 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
934 | else: | |
935 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
936 | ||
937 | ss_vis1[0x061] = SS_opf_f00('fzeros') | |
938 | ss_vis1[0x07f] = SS_opf_f00('fones') | |
939 | ||
940 | #============================================================================ | |
941 | # SS_opf_rdd | |
942 | #============================================================================ | |
943 | ||
944 | class SS_opf_rdd(SS_InstrAsm): | |
945 | def __init__(self,name): | |
946 | SS_InstrAsm.__init__(self,name) | |
947 | ||
948 | def run_exe_s(self,file): | |
949 | self.s_code(file,'run_exe_') | |
950 | self.ld_sim(file,'%g5') | |
951 | self.ld_rs1(file,'%g1') | |
952 | self.ld_rs2(file,'%g2') | |
953 | self.ld_rd(file,'%g3') | |
954 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
955 | self.branch(file,'ne','%xcc','fpop_disabled_trap') | |
956 | self.nop(file) | |
957 | self.ld_drf(file,'%g1','%f0') | |
958 | self.mov(file,self.NPC,self.PC) | |
959 | self.ld_drf(file,'%g2','%f4') | |
960 | self.add(file,self.NPC,4,self.NPC) | |
961 | self.opr(file,self.name,'%f0','%f4','%g4') | |
962 | self.branch(file,'rnz,a','%g3','1f') # irf[rd] = val when rd != 0 | |
963 | self.st_irf(file,'%g3','%g4') | |
964 | file.write('1:\n') | |
965 | self.retl_st_npc(file,self.NPC) | |
966 | ||
967 | def run_exe_c(self,file): | |
968 | file.write('#if defined(ARCH_X64)\n') | |
969 | self.c_code_beg(file,'run_exe_') | |
970 | file.write(' if (s->sim_state.fp_disabled())\n') | |
971 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
972 | file.write(' if (SS_Strand::reg_off2idx(i->rd) != 0) {\n') | |
973 | file.write(' uint64_t rs1 = s->get_drf(i->rs1);\n') | |
974 | file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n') | |
975 | file.write(' uint64_t r64;\n') | |
976 | file.write(' int32_t s32_0, s32_1;\n') | |
977 | if (self.name in ['fcmple16','fcmpne16','fcmpgt16','fcmpeq16']): | |
978 | file.write(' uint32_t v32;\n') | |
979 | file.write(' r64 = 0;\n') | |
980 | file.write(' for (int n = 0; n < 4; n++) {\n') | |
981 | file.write(' s32_0 = (int32_t)rs1;\n') | |
982 | file.write(' s32_0 = (s32_0 << 16) >> 16;\n') | |
983 | file.write(' s32_1 = (int32_t)rs2;\n') | |
984 | file.write(' s32_1 = (s32_1 << 16) >> 16;\n') | |
985 | if (self.name == 'fcmple16'): | |
986 | file.write(' v32 = (s32_0 <= s32_1) ? 1 : 0;\n') | |
987 | elif (self.name == 'fcmpne16'): | |
988 | file.write(' v32 = (s32_0 != s32_1) ? 1 : 0;\n') | |
989 | elif (self.name == 'fcmpgt16'): | |
990 | file.write(' v32 = (s32_0 > s32_1) ? 1 : 0;\n') | |
991 | elif (self.name == 'fcmpeq16'): | |
992 | file.write(' v32 = (s32_0 == s32_1) ? 1 : 0;\n') | |
993 | file.write(' r64 |= (((uint64_t)v32) << n);\n') | |
994 | file.write(' rs1 >>= 16;\n') | |
995 | file.write(' rs2 >>= 16;\n') | |
996 | file.write(' }\n') | |
997 | elif (self.name in ['fcmple32','fcmpne32','fcmpgt32','fcmpeq32']): | |
998 | file.write(' uint64_t v64;\n') | |
999 | file.write(' r64 = 0;\n') | |
1000 | file.write(' for (int n = 0; n < 2; n++) {\n') | |
1001 | file.write(' s32_0 = (int32_t)rs1;\n') | |
1002 | file.write(' s32_1 = (int32_t)rs2;\n') | |
1003 | if (self.name == 'fcmple32'): | |
1004 | file.write(' v64 = (s32_0 <= s32_1) ? 1 : 0;\n') | |
1005 | elif (self.name == 'fcmpne32'): | |
1006 | file.write(' v64 = (s32_0 != s32_1) ? 1 : 0;\n') | |
1007 | elif (self.name == 'fcmpgt32'): | |
1008 | file.write(' v64 = (s32_0 > s32_1) ? 1 : 0;\n') | |
1009 | elif (self.name == 'fcmpeq32'): | |
1010 | file.write(' v64 = (s32_0 == s32_1) ? 1 : 0;\n') | |
1011 | file.write(' r64 |= (v64 << n);\n') | |
1012 | file.write(' rs1 >>= 32;\n') | |
1013 | file.write(' rs2 >>= 32;\n') | |
1014 | file.write(' }\n') | |
1015 | file.write(' s->get_irf(i->rd) = r64;\n') | |
1016 | file.write(' }\n') | |
1017 | file.write(' s->npc = npc+4;\n') | |
1018 | file.write(' return npc;\n') | |
1019 | self.c_code_end(file) | |
1020 | file.write('#else\n') | |
1021 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
1022 | file.write('#endif\n') | |
1023 | ||
1024 | def run_dec_c(self,file): | |
1025 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
1026 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1027 | self.ill_ibe(file) | |
1028 | self.dec_rdd(file,'','idx_exe_'+self.name) | |
1029 | self.c_code_end(file) | |
1030 | ||
1031 | def gen_exe_tbl(self,file,mode): | |
1032 | if mode == 'trc': | |
1033 | file.write(' trc_exe_rdd, /* '+self.name+' */\n') | |
1034 | elif mode == 'v8_run': | |
1035 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
1036 | else: | |
1037 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
1038 | ||
1039 | ss_vis1[0x020] = SS_opf_rdd('fcmple16') | |
1040 | ss_vis1[0x022] = SS_opf_rdd('fcmpne16') | |
1041 | ss_vis1[0x024] = SS_opf_rdd('fcmple32') | |
1042 | ss_vis1[0x026] = SS_opf_rdd('fcmpne32') | |
1043 | ss_vis1[0x028] = SS_opf_rdd('fcmpgt16') | |
1044 | ss_vis1[0x02a] = SS_opf_rdd('fcmpeq16') | |
1045 | ss_vis1[0x02c] = SS_opf_rdd('fcmpgt32') | |
1046 | ss_vis1[0x02e] = SS_opf_rdd('fcmpeq32') | |
1047 | ||
1048 | ||
1049 | #============================================================================ | |
1050 | # SS_opf_rrr_nofdis | |
1051 | #============================================================================ | |
1052 | ||
1053 | class SS_opf_rrr_nofdis(SS_InstrAsm): | |
1054 | def __init__(self,name): | |
1055 | SS_InstrAsm.__init__(self,name) | |
1056 | ||
1057 | def run_exe_s(self,file): | |
1058 | self.s_code(file,'run_exe_') | |
1059 | self.ld_rs1(file,'%g1') | |
1060 | self.ld_rs2(file,'%g2') | |
1061 | self.ld_rd(file,'%g3') | |
1062 | self.ld_irf(file,'%g1','%g1') | |
1063 | self.mov(file,self.NPC,self.PC) | |
1064 | self.ld_irf(file,'%g2','%g2') | |
1065 | self.add(file,self.NPC,4,self.NPC) | |
1066 | self.opr(file,self.name,'%g1','%g2','%g4') | |
1067 | self.branch(file,'rnz,a','%g3','1f') # irf[rd] = val when rd != 0 | |
1068 | self.st_irf(file,'%g3','%g4') | |
1069 | file.write('1:\n') | |
1070 | self.retl_st_npc(file,self.NPC) | |
1071 | ||
1072 | def run_exe_c(self,file): | |
1073 | file.write('#if defined(ARCH_X64)\n') | |
1074 | self.c_code_beg(file,'run_exe_') | |
1075 | file.write(' if (SS_Strand::reg_off2idx(i->rd) != 0) {\n') | |
1076 | file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n') | |
1077 | file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n') | |
1078 | file.write(' uint64_t r64 = 0;\n') | |
1079 | file.write(' r64 |= (((rs1 >> 11) & 0x3) << 0);\n') | |
1080 | file.write(' r64 |= (((rs1 >> 33) & 0x3) << 2);\n') | |
1081 | file.write(' r64 |= (((rs1 >> 55) & 0x1) << 4);\n') | |
1082 | file.write(' r64 |= (((rs1 >> 13) & 0xf) << 5);\n') | |
1083 | file.write(' r64 |= (((rs1 >> 35) & 0xf) << 9);\n') | |
1084 | file.write(' r64 |= (((rs1 >> 56) & 0xf) << 13);\n') | |
1085 | file.write(' uint32_t n;\n') | |
1086 | file.write(' uint64_t v64;\n') | |
1087 | file.write(' switch (rs2 & 0x7) {\n') | |
1088 | file.write(' case 0: n = 0; v64 = 0; break;\n') | |
1089 | file.write(' case 1: n = 1; v64 = 0x1; break;\n') | |
1090 | file.write(' case 2: n = 2; v64 = 0x3; break;\n') | |
1091 | file.write(' case 3: n = 3; v64 = 0x7; break;\n') | |
1092 | file.write(' case 4: n = 4; v64 = 0xf; break;\n') | |
1093 | file.write(' default: n = 5; v64 = 0x1f; break;\n') | |
1094 | file.write(' }\n') | |
1095 | file.write(' r64 |= (((rs1 >> 17) & v64) << 17);\n') | |
1096 | file.write(' r64 |= (((rs1 >> 39) & v64) << (17 + n));\n') | |
1097 | file.write(' r64 |= (((rs1 >> 60) & 0xf) << (17 + (n << 1)));\n') | |
1098 | if (self.name == 'array16'): | |
1099 | file.write(' r64 <<= 1;\n') | |
1100 | elif (self.name == 'array32'): | |
1101 | file.write(' r64 <<= 2;\n') | |
1102 | file.write(' s->get_irf(i->rd) = r64;\n') | |
1103 | file.write(' }\n') | |
1104 | file.write(' s->npc = npc+4;\n') | |
1105 | file.write(' return npc;\n') | |
1106 | self.c_code_end(file) | |
1107 | file.write('#else\n') | |
1108 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
1109 | file.write('#endif\n') | |
1110 | ||
1111 | def run_dec_c(self,file): | |
1112 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
1113 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1114 | self.ill_ibe(file) | |
1115 | self.dec_rrr(file,'','idx_exe_'+self.name) | |
1116 | self.c_code_end(file) | |
1117 | ||
1118 | def gen_exe_tbl(self,file,mode): | |
1119 | if mode == 'trc': | |
1120 | file.write(' trc_exe_rrr, /* '+self.name+' */\n') | |
1121 | elif mode == 'v8_run': | |
1122 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
1123 | else: | |
1124 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
1125 | ||
1126 | ss_vis1[0x010] = SS_opf_rrr_nofdis('array8') | |
1127 | ss_vis1[0x012] = SS_opf_rrr_nofdis('array16') | |
1128 | ss_vis1[0x014] = SS_opf_rrr_nofdis('array32') | |
1129 | ||
1130 | #============================================================================ | |
1131 | # SS_edge | |
1132 | #============================================================================ | |
1133 | ||
1134 | class SS_edge(SS_InstrCpp): | |
1135 | def __init__(self,name): | |
1136 | SS_InstrCpp.__init__(self,name) | |
1137 | self.out = ['rd', 'g0'] | |
1138 | ||
1139 | def run_exe_c(self,file): | |
1140 | for out in self.out: | |
1141 | self.c_code_beg_name(file,'run_exe_'+self.name+'_'+out) | |
1142 | if (out == 'rd'): | |
1143 | file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n') | |
1144 | file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n') | |
1145 | if (self.name[:5] == 'edge8'): | |
1146 | file.write(' uint32_t result32 = 0xff;\n') | |
1147 | file.write(' uint32_t value32 = rs1 & 0x7;\n') | |
1148 | elif (self.name[:6] == 'edge16'): | |
1149 | file.write(' uint32_t result32 = 0xf;\n') | |
1150 | file.write(' uint32_t value32 = (rs1 >> 1) & 0x3;\n') | |
1151 | elif (self.name[:6] == 'edge32'): | |
1152 | file.write(' uint32_t result32 = 0x3;\n') | |
1153 | file.write(' uint32_t value32 = (rs1 >> 2) & 0x1;\n') | |
1154 | if (self.name[-1] == 'l' or self.name[-2] == 'l'): | |
1155 | file.write(' uint32_t s0 = (result32 << value32) & result32;\n') | |
1156 | else: | |
1157 | file.write(' uint32_t s0 = result32 >> value32;\n') | |
1158 | if (self.name[:5] == 'edge8'): | |
1159 | file.write(' value32 = 7 - (rs2 & 0x7);\n') | |
1160 | elif (self.name[:6] == 'edge16'): | |
1161 | file.write(' value32 = 3 - ((rs2 >> 1) & 0x3);\n') | |
1162 | elif (self.name[:6] == 'edge32'): | |
1163 | file.write(' value32 = 1 - ((rs2 >> 2) & 0x1);\n') | |
1164 | if (self.name[-1] == 'l' or self.name[-2] == 'l'): | |
1165 | file.write(' uint32_t s1 = result32 >> value32;\n') | |
1166 | else: | |
1167 | file.write(' uint32_t s1 = (result32 << value32) & result32;\n') | |
1168 | file.write(' if (s->pstate.am()) {\n') | |
1169 | file.write(' if (((rs1 & s->mask_pstate_am) >> 3) == ((rs2 & s->mask_pstate_am) >> 3))\n') | |
1170 | file.write(' s0 &= s1;\n') | |
1171 | file.write(' }\n') | |
1172 | file.write(' else {\n') | |
1173 | file.write(' if ((rs1 >> 3) == (rs2 >> 3))\n') | |
1174 | file.write(' s0 &= s1;\n') | |
1175 | file.write(' }\n') | |
1176 | file.write(' s->get_irf(i->rd) = s0;\n') | |
1177 | if (self.name[-1] != 'n'): | |
1178 | if (out == 'g0'): | |
1179 | file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n') | |
1180 | file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n') | |
1181 | file.write(' uint64_t rd = rs1 - rs2;\n') | |
1182 | file.write(' uint64_t v = (rs1 & ~rs2 & ~rd) | (~rs1 & rs2 & rd);\n') | |
1183 | file.write(' uint64_t c = (~rs1 & rs2) | (rd & (~rs1 | rs2));\n') | |
1184 | file.write(' uint32_t xcc = ((v >> 63) & 0x1) << 1;\n') | |
1185 | file.write(' uint32_t icc = ((v >> 31) & 0x1) << 1;\n') | |
1186 | file.write(' icc |= ((c >> 31) & 0x1);\n') | |
1187 | file.write(' xcc |= ((c >> 63) & 0x1);\n') | |
1188 | file.write(' icc |= ((rd >> 31) & 0x1) << 3;\n') | |
1189 | file.write(' xcc |= ((rd >> 63) & 0x1) << 3;\n') | |
1190 | file.write(' if (rd == 0)\n') | |
1191 | file.write(' xcc |= 0x4;\n') | |
1192 | file.write(' if ((rd & 0xffffffff) == 0)\n') | |
1193 | file.write(' icc |= 0x4;\n') | |
1194 | file.write(' s->ccr.set((xcc << 4) | icc);\n') | |
1195 | file.write(' s->pc = s->npc();\n') | |
1196 | file.write(' s->npc = s->npc() + 4;\n') | |
1197 | file.write(' return s->pc();\n') | |
1198 | self.c_code_end(file) | |
1199 | ||
1200 | def run_dec_c(self,file): | |
1201 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
1202 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1203 | self.ill_ibe(file) | |
1204 | file.write(' if (o.get_rd_irf())\n') | |
1205 | self.dec_rrr(file,' ','idx_exe_'+self.name+'_rd') | |
1206 | file.write(' else\n') | |
1207 | self.dec_0rr(file,' ','idx_exe_'+self.name+'_g0') | |
1208 | self.c_code_end(file) | |
1209 | ||
1210 | def gen_exe_tbl(self,file,mode): | |
1211 | if mode == 'v8_run': | |
1212 | mode = 'run' | |
1213 | for out in self.out: | |
1214 | if mode == 'trc': | |
1215 | file.write(' trc_exe_rrr, /* '+self.name+'_'+out+' */\n') | |
1216 | else: | |
1217 | file.write(' '+mode+'_exe_'+self.name+'_'+out+',\n') | |
1218 | ||
1219 | ss_vis1[0x000] = SS_edge('edge8') | |
1220 | ss_vis1[0x002] = SS_edge('edge8l') | |
1221 | ss_vis1[0x004] = SS_edge('edge16') | |
1222 | ss_vis1[0x006] = SS_edge('edge16l') | |
1223 | ss_vis1[0x008] = SS_edge('edge32') | |
1224 | ss_vis1[0x00a] = SS_edge('edge32l') | |
1225 | ||
1226 | ss_vis2[0x001] = SS_edge('edge8n') | |
1227 | ss_vis2[0x003] = SS_edge('edge8ln') | |
1228 | ss_vis2[0x005] = SS_edge('edge16n') | |
1229 | ss_vis2[0x007] = SS_edge('edge16ln') | |
1230 | ss_vis2[0x009] = SS_edge('edge32n') | |
1231 | ss_vis2[0x00b] = SS_edge('edge32ln') | |
1232 | ||
1233 | #============================================================================ | |
1234 | # SS_opf_ddd_gsr | |
1235 | #============================================================================ | |
1236 | ||
1237 | class SS_opf_ddd_gsr(SS_InstrAsm): | |
1238 | def __init__(self,name): | |
1239 | SS_InstrAsm.__init__(self,name) | |
1240 | ||
1241 | def run_exe_s(self,file): | |
1242 | self.s_code(file,'run_exe_') | |
1243 | self.ld_sim(file,'%g5') | |
1244 | self.ld_rs1(file,'%g1') | |
1245 | self.ld_rs2(file,'%g2') | |
1246 | self.ld_gsr(file,'%g4') | |
1247 | self.ld_rd(file,'%g3') | |
1248 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
1249 | self.branch(file,'ne,a','%xcc','fpop_disabled_trap') | |
1250 | self.rd_gsr(file,'%g5') | |
1251 | self.wr_gsr(file,'%g4') | |
1252 | self.ld_drf(file,'%g1','%f0') | |
1253 | self.ld_drf(file,'%g2','%f4') | |
1254 | self.opr(file,self.name,'%f0','%f4','%f8') | |
1255 | self.branch(file,'a,a','%xcc','opf_fprs_gsr_d') | |
1256 | ||
1257 | def run_exe_c(self,file): | |
1258 | file.write('#if defined(ARCH_X64)\n') | |
1259 | self.c_code_beg(file,'run_exe_') | |
1260 | file.write(' if (s->sim_state.fp_disabled())\n') | |
1261 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
1262 | file.write(' uint64_t rs1 = s->get_drf(i->rs1);\n') | |
1263 | file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n') | |
1264 | file.write(' uint64_t rd = 0;\n') | |
1265 | file.write(' uint64_t v64;\n') | |
1266 | file.write(' uint32_t v32;\n') | |
1267 | if (self.name == 'fpack32'): | |
1268 | file.write(' v32 = s->gsr.scale();\n') | |
1269 | file.write(' for (int n = 0; n < 2; n++) {\n') | |
1270 | file.write(' if ((rs2 & 0x80000000) != 0)\n') | |
1271 | file.write(' v64 = 0;\n') | |
1272 | file.write(' else {\n') | |
1273 | file.write(' v64 = ((rs2 & 0xffffffff) << v32) >> 23;\n') | |
1274 | file.write(' if ((v64 & 0xffffffffffffff00llu) != 0)\n') | |
1275 | file.write(' v64 = 255;\n') | |
1276 | file.write(' }\n') | |
1277 | file.write(' rd |= ((v64 & 0xff) << (n << 5));\n') | |
1278 | file.write(' rd |= ((rs1 & 0xffffff) << ((n << 5) + 8));\n') | |
1279 | file.write(' rs1 >>= 32;\n') | |
1280 | file.write(' rs2 >>= 32;\n') | |
1281 | file.write(' }\n') | |
1282 | elif (self.name == 'bshuffle'): | |
1283 | file.write(' v64 = s->gsr.mask();\n') | |
1284 | file.write(' for (int n = 0; n < 8; n++) {\n') | |
1285 | file.write(' uint_t index = (v64 >> (n << 2)) & 0xf;\n') | |
1286 | file.write(' switch (index) {\n') | |
1287 | file.write(' case 0: v32 = rs1 >> 56; break;\n') | |
1288 | file.write(' case 1: v32 = rs1 >> 48; break;\n') | |
1289 | file.write(' case 2: v32 = rs1 >> 40; break;\n') | |
1290 | file.write(' case 3: v32 = rs1 >> 32; break;\n') | |
1291 | file.write(' case 4: v32 = rs1 >> 24; break;\n') | |
1292 | file.write(' case 5: v32 = rs1 >> 16; break;\n') | |
1293 | file.write(' case 6: v32 = rs1 >> 8; break;\n') | |
1294 | file.write(' case 7: v32 = rs1 ; break;\n') | |
1295 | file.write(' case 8: v32 = rs2 >> 56; break;\n') | |
1296 | file.write(' case 9: v32 = rs2 >> 48; break;\n') | |
1297 | file.write(' case 10: v32 = rs2 >> 40; break;\n') | |
1298 | file.write(' case 11: v32 = rs2 >> 32; break;\n') | |
1299 | file.write(' case 12: v32 = rs2 >> 24; break;\n') | |
1300 | file.write(' case 13: v32 = rs2 >> 16; break;\n') | |
1301 | file.write(' case 14: v32 = rs2 >> 8; break;\n') | |
1302 | file.write(' case 15: v32 = rs2 ; break;\n') | |
1303 | file.write(' }\n') | |
1304 | file.write(' rd |= (((uint64_t)(v32 & 0xff)) << (n << 3));\n') | |
1305 | file.write(' }\n') | |
1306 | elif (self.name == 'faligndata'): | |
1307 | file.write(' v64 = s->gsr.align();\n') | |
1308 | file.write(' if (v64 != 0)\n') | |
1309 | file.write(' rd = (rs1 << (v64 << 3)) | (rs2 >> ((8 - v64) << 3));\n') | |
1310 | file.write(' else\n') | |
1311 | file.write(' rd = rs1;\n') | |
1312 | file.write(' s->get_drf(i->rd) = rd;\n') | |
1313 | file.write(' s->set_fprs(i->rd);\n') | |
1314 | file.write(' s->npc = npc+4;\n') | |
1315 | file.write(' return npc;\n') | |
1316 | self.c_code_end(file) | |
1317 | file.write('#else\n') | |
1318 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
1319 | file.write('#endif\n') | |
1320 | ||
1321 | def run_dec_c(self,file): | |
1322 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
1323 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1324 | self.ill_ibe(file) | |
1325 | self.dec_ddd(file,'','idx_exe_'+self.name) | |
1326 | self.c_code_end(file) | |
1327 | ||
1328 | def gen_exe_tbl(self,file,mode): | |
1329 | if mode == 'trc': | |
1330 | file.write(' trc_exe_ddd, /* '+self.name+' */\n') | |
1331 | elif mode == 'v8_run': | |
1332 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
1333 | else: | |
1334 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
1335 | ||
1336 | ss_vis1[0x03a] = SS_opf_ddd_gsr('fpack32') | |
1337 | ss_vis2[0x04c] = SS_opf_ddd_gsr('bshuffle') | |
1338 | ss_vis1[0x048] = SS_opf_ddd_gsr('faligndata') | |
1339 | ||
1340 | #============================================================================ | |
1341 | # SS_opf_f0d_gsr | |
1342 | #============================================================================ | |
1343 | ||
1344 | class SS_opf_f0d_gsr(SS_InstrAsm): | |
1345 | def __init__(self,name): | |
1346 | SS_InstrAsm.__init__(self,name) | |
1347 | ||
1348 | def run_exe_s(self,file): | |
1349 | self.s_code(file,'run_exe_') | |
1350 | self.ld_sim(file,'%g5') | |
1351 | self.ld_rs2(file,'%g2') | |
1352 | self.ld_gsr(file,'%g4') | |
1353 | self.ld_rd(file,'%g3') | |
1354 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
1355 | self.branch(file,'ne,a','%xcc','fpop_disabled_trap') | |
1356 | self.nop(file) | |
1357 | self.rd_gsr(file,'%g5') | |
1358 | self.wr_gsr(file,'%g4') | |
1359 | self.ld_drf(file,'%g2','%f4') | |
1360 | self.op2(file,self.name,'%f4','%f8') | |
1361 | self.branch(file,'a,a','%xcc','opf_fprs_gsr_f') | |
1362 | ||
1363 | def run_exe_c(self,file): | |
1364 | file.write('#if defined(ARCH_X64)\n') | |
1365 | self.c_code_beg(file,'run_exe_') | |
1366 | file.write(' if (s->sim_state.fp_disabled())\n') | |
1367 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
1368 | file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n') | |
1369 | file.write(' uint32_t rd = 0;\n') | |
1370 | if (self.name == 'fpack16'): | |
1371 | file.write(' uint64_t v64 = s->gsr.scale() & 0xf;\n') | |
1372 | file.write(' uint64_t r64;\n') | |
1373 | file.write(' for (int n = 0; n < 4; n++) {\n') | |
1374 | file.write(' if ((rs2 & 0x8000) != 0)\n') | |
1375 | file.write(' r64 = 0;\n') | |
1376 | file.write(' else {\n') | |
1377 | file.write(' r64 = ((rs2 & 0xffff) << v64) >> 7;\n') | |
1378 | file.write(' if ((r64 & 0xffffffffffffff00llu) != 0)\n') | |
1379 | file.write(' r64 = 255;\n') | |
1380 | file.write(' }\n') | |
1381 | file.write(' rd |= ((r64 & 0xff) << (n << 3));\n') | |
1382 | file.write(' rs2 >>= 16;\n') | |
1383 | file.write(' }\n') | |
1384 | elif (self.name == 'fpackfix'): | |
1385 | file.write(' uint64_t v64 = s->gsr.scale() & 0x1f;\n') | |
1386 | file.write(' int64_t s64;\n') | |
1387 | file.write(' for (int n = 0; n < 2; n++) {\n') | |
1388 | file.write(' if ((rs2 & 0x80000000) == 0)\n') | |
1389 | file.write(' s64 = rs2 & 0xffffffff;\n') | |
1390 | file.write(' else\n') | |
1391 | file.write(' s64 = rs2 | 0xffffffff00000000llu;\n') | |
1392 | file.write(' s64 = (s64 << v64) >> 16;\n') | |
1393 | file.write(' if (s64 < -32768)\n') | |
1394 | file.write(' s64 = -32768;\n') | |
1395 | file.write(' else if (s64 > 32767)\n') | |
1396 | file.write(' s64 = 32767;\n') | |
1397 | file.write(' rd |= ((s64 & 0xffff) << (n << 4));\n') | |
1398 | file.write(' rs2 >>= 32;\n') | |
1399 | file.write(' }\n') | |
1400 | file.write(' s->get_frf(i->rd) = rd;\n') | |
1401 | file.write(' s->set_fprs(i->rd);\n') | |
1402 | file.write(' s->npc = npc+4;\n') | |
1403 | file.write(' return npc;\n') | |
1404 | self.c_code_end(file) | |
1405 | file.write('#else\n') | |
1406 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
1407 | file.write('#endif\n') | |
1408 | ||
1409 | def run_dec_c(self,file): | |
1410 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
1411 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1412 | file.write(' if (o.is_zero_18_14())\n') | |
1413 | file.write(' {\n') | |
1414 | self.ill_ibe(file) | |
1415 | self.dec_f0d(file,' ','idx_exe_'+self.name) | |
1416 | file.write(' }\n') | |
1417 | file.write(' else\n') | |
1418 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1419 | self.c_code_end(file) | |
1420 | ||
1421 | def gen_exe_tbl(self,file,mode): | |
1422 | if mode == 'trc': | |
1423 | file.write(' trc_exe_f0d, /* '+self.name+' */\n') | |
1424 | elif mode == 'v8_run': | |
1425 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
1426 | else: | |
1427 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
1428 | ||
1429 | ss_vis1[0x03b] = SS_opf_f0d_gsr('fpack16') | |
1430 | ss_vis1[0x03d] = SS_opf_f0d_gsr('fpackfix') | |
1431 | ||
1432 | #============================================================================ | |
1433 | # SS_opf_rrr_gsr | |
1434 | #============================================================================ | |
1435 | ||
1436 | class SS_opf_rrr_gsr(SS_InstrAsm): | |
1437 | def __init__(self,name): | |
1438 | SS_InstrAsm.__init__(self,name) | |
1439 | ||
1440 | def run_exe_s(self,file): | |
1441 | self.s_code(file,'run_exe_') | |
1442 | self.ld_sim(file,'%g5') | |
1443 | self.ld_rs1(file,'%g1') | |
1444 | self.ld_rs2(file,'%g2') | |
1445 | self.ld_gsr(file,'%g4') | |
1446 | self.ld_rd(file,'%g3') | |
1447 | self.andcc(file,'%g5','F_FP_DISABLED','%g0') | |
1448 | self.branch(file,'ne,a','%xcc','fpop_disabled_trap') | |
1449 | self.nop(file) | |
1450 | self.rd_gsr(file,'%g5') | |
1451 | self.wr_gsr(file,'%g4') | |
1452 | self.ld_irf(file,'%g1','%g1') | |
1453 | self.mov(file,self.NPC,self.PC) | |
1454 | self.ld_irf(file,'%g2','%g2') | |
1455 | self.add(file,self.NPC,4,self.NPC) | |
1456 | self.opr(file,self.name,'%g1','%g2','%g4') | |
1457 | self.rd_gsr(file,'%g1') | |
1458 | self.branch(file,'rnz,a','%g3','1f') | |
1459 | self.st_irf(file,'%g3','%g4') | |
1460 | file.write('1:\n') | |
1461 | self.st_gsr(file,'%g1') | |
1462 | self.st_npc(file,self.NPC) | |
1463 | self.retl(file) | |
1464 | self.wr_gsr(file,'%g5') | |
1465 | ||
1466 | def run_exe_c(self,file): | |
1467 | file.write('#if defined(ARCH_X64)\n') | |
1468 | self.c_code_beg(file,'run_exe_') | |
1469 | file.write(' if (s->sim_state.fp_disabled())\n') | |
1470 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
1471 | file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n') | |
1472 | file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n') | |
1473 | file.write(' uint64_t r64 = rs1 + rs2;\n') | |
1474 | if (self.name in ['alignaddr','alignaddrl']): | |
1475 | file.write(' if (SS_Strand::reg_off2idx(i->rd) != 0)\n') | |
1476 | file.write(' s->get_irf(i->rd) = r64 & 0xfffffffffffffff8llu;\n') | |
1477 | file.write(' r64 &= 0x7;\n') | |
1478 | if (self.name == 'alignaddrl'): | |
1479 | file.write(' r64 = (-r64) & 0x7;\n') | |
1480 | file.write(' s->gsr.align(r64);\n') | |
1481 | elif (self.name == 'bmask'): | |
1482 | file.write(' if (SS_Strand::reg_off2idx(i->rd) != 0)\n') | |
1483 | file.write(' s->get_irf(i->rd) = r64;\n') | |
1484 | file.write(' s->gsr.mask(r64 & 0xffffffff);\n') | |
1485 | file.write(' s->npc = npc+4;\n') | |
1486 | file.write(' return npc;\n') | |
1487 | self.c_code_end(file) | |
1488 | file.write('#else\n') | |
1489 | file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name)) | |
1490 | file.write('#endif\n') | |
1491 | ||
1492 | def run_dec_c(self,file): | |
1493 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
1494 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1495 | self.ill_ibe(file) | |
1496 | self.dec_rrr(file,'','idx_exe_'+self.name) | |
1497 | self.c_code_end(file) | |
1498 | ||
1499 | def gen_exe_tbl(self,file,mode): | |
1500 | if mode == 'trc': | |
1501 | file.write(' trc_exe_rrr, /* '+self.name+' */\n') | |
1502 | elif mode == 'v8_run': | |
1503 | file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n') | |
1504 | else: | |
1505 | file.write(' '+mode+'_exe_'+self.name+',\n') | |
1506 | ||
1507 | ss_vis1[0x018] = SS_opf_rrr_gsr('alignaddr') | |
1508 | ss_vis2[0x019] = SS_opf_rrr_gsr('bmask') | |
1509 | ss_vis1[0x01a] = SS_opf_rrr_gsr('alignaddrl') | |
1510 | ||
1511 | #============================================================================ | |
1512 | # SS_opf_003_gsr | |
1513 | #============================================================================ | |
1514 | ||
1515 | class SS_opf_003_gsr(SS_InstrAsm): | |
1516 | def __init__(self,name): | |
1517 | SS_InstrAsm.__init__(self,name) | |
1518 | ||
1519 | def run_exe_c(self,file): | |
1520 | self.c_code_beg_name(file,'run_exe_'+self.name) | |
1521 | file.write(' if (s->sim_state.fp_disabled())\n') | |
1522 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
1523 | file.write(' uint64_t mode = i->rs2;\n') | |
1524 | file.write(' s->gsr.im(mode >> 2);\n') | |
1525 | file.write(' s->gsr.irnd(mode);\n') | |
1526 | file.write(' s->npc = npc+4;\n') | |
1527 | file.write(' return npc;\n') | |
1528 | file.write('}\n') | |
1529 | ||
1530 | def run_dec_c(self,file): | |
1531 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
1532 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1533 | file.write(' if (o.is_zero_29_25() && o.is_zero_18_14() && o.is_zero_4_3())\n') | |
1534 | file.write(' {\n') | |
1535 | self.ill_ibe(file) | |
1536 | self.dec_003(file,' ','idx_exe_'+self.name) | |
1537 | file.write(' }\n') | |
1538 | file.write(' else\n') | |
1539 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1540 | self.c_code_end(file) | |
1541 | ||
1542 | def gen_exe_tbl(self,file,mode): | |
1543 | if mode == 'v8_run': | |
1544 | mode = 'run' | |
1545 | self.gen_exe_passthrough(file,mode) | |
1546 | ||
1547 | ss_vis2[0x081] = SS_opf_003_gsr('siam') | |
1548 | ||
1549 | #============================================================================ | |
1550 | # SS_vis3_rrr | |
1551 | #============================================================================ | |
1552 | ||
1553 | class SS_vis3_rrr(SS_InstrCpp): | |
1554 | def __init__(self,name): | |
1555 | SS_InstrCpp.__init__(self,name) | |
1556 | self.out = ['rd', 'g0'] | |
1557 | ||
1558 | def run_exe_c(self,file): | |
1559 | for out in self.out: | |
1560 | self.c_code_beg_name(file,'run_exe_'+self.name+'_'+out) | |
1561 | if self.name == 'addxccc': | |
1562 | file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n') | |
1563 | file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n') | |
1564 | file.write(' uint64_t rd = 0;\n') | |
1565 | file.write(' uint64_t cc = s->ccr.xcc() & 0x1;\n') | |
1566 | file.write(' rd = rs1 + rs2 + cc;\n') | |
1567 | file.write(' uint8_t ccr = 0;\n') | |
1568 | file.write(' /* xcc.n */\n') | |
1569 | file.write(' if (rd >> 63)\n') | |
1570 | file.write(' ccr = 0x80;\n') | |
1571 | file.write(' /* icc.n */\n') | |
1572 | file.write(' if ((rd << 32) >> 63)\n') | |
1573 | file.write(' ccr |= 0x08;\n') | |
1574 | file.write(' /* xcc.z */\n') | |
1575 | file.write(' if (rd == 0)\n') | |
1576 | file.write(' ccr |= 0x44;\n') | |
1577 | file.write(' /* icc.z */\n') | |
1578 | file.write(' if (((rd << 32) >> 32) == 0)\n') | |
1579 | file.write(' ccr |= 0x4;\n') | |
1580 | file.write(' uint64_t m = 0x80000000;\n') | |
1581 | file.write(' uint64_t x = rs1 & m;\n') | |
1582 | file.write(' /* icc.v */\n') | |
1583 | file.write(' if ((x == (rs2 & m)) && (x != (rd & m)))\n') | |
1584 | file.write(' ccr |= 0x02;\n') | |
1585 | file.write(' m = 0x8000000000000000;\n') | |
1586 | file.write(' x = rs1 & m;\n') | |
1587 | file.write(' /* xcc.v */\n') | |
1588 | file.write(' if ((x == (rs2 & m)) && (x != (rd & m)))\n') | |
1589 | file.write(' ccr |= 0x20;\n') | |
1590 | file.write(' x = (rs1 & 0xffffffff) + (rs2 & 0xffffffff) + cc;\n') | |
1591 | file.write(' uint64_t icc_c = x >> 32;\n') | |
1592 | file.write(' /* icc.c */\n') | |
1593 | file.write(' if (icc_c == 1)\n') | |
1594 | file.write(' ccr |= 0x1;\n') | |
1595 | file.write(' x = (rs1 >> 32) + (rs2 >> 32) + icc_c;\n') | |
1596 | file.write(' /* xcc.c */\n') | |
1597 | file.write(' if ((x >> 32) == 1)\n') | |
1598 | file.write(' ccr |= 0x10;\n') | |
1599 | file.write(' s->ccr.set(ccr);\n') | |
1600 | elif out == 'rd': | |
1601 | file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n') | |
1602 | file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n') | |
1603 | file.write(' uint64_t rd = 0;\n') | |
1604 | if self.name in ['xmulx', 'xmulxhi']: | |
1605 | file.write(' for (int n=0; n<64; n++) {\n') | |
1606 | file.write(' if (rs1 & 1)\n') | |
1607 | file.write(' rd ^= rs2;\n') | |
1608 | file.write(' rs1 = (rs1 >> 1) | (rd << 63);\n') | |
1609 | file.write(' rd >>= 1;\n') | |
1610 | file.write(' }\n') | |
1611 | if self.name == 'xmulx': | |
1612 | file.write(' rd = rs1;\n') | |
1613 | elif self.name == 'addxc': | |
1614 | file.write(' uint64_t cc = s->ccr.xcc() & 0x1;\n') | |
1615 | file.write(' rd = rs1 + rs2 + cc;\n') | |
1616 | elif self.name == 'umulxhi': | |
1617 | file.write(' /* based on ab * cd = (ac<<64) + ((ad+cb)<<32) + bd ... */\n') | |
1618 | file.write(' uint64_t a = rs1 >> 32;\n') | |
1619 | file.write(' uint64_t b = rs1 & ((~0ull) >> 32);\n') | |
1620 | file.write(' uint64_t c = rs2 >> 32;\n') | |
1621 | file.write(' uint64_t d = rs2 & ((~0ull) >> 32);\n') | |
1622 | file.write(' uint64_t bd = b * d;\n') | |
1623 | file.write(' uint64_t ad = a * d;\n') | |
1624 | file.write(' uint64_t cb = c * b;\n') | |
1625 | file.write(' uint64_t ac = a * c;\n') | |
1626 | file.write(' uint64_t tmp = (ad & ((~0ull) >> 32)) + (bd >> 32);\n') | |
1627 | file.write(' uint64_t carry = ((tmp >> 32) != 0) ? 1 : 0;\n') | |
1628 | file.write(' tmp = (ad >> 32) + carry;\n') | |
1629 | file.write(' carry = ((tmp >> 32) != 0) ? 1 : 0;\n') | |
1630 | file.write(' if (carry)\n') | |
1631 | file.write(' ac += ( ( (uint64_t) 1 ) << 32 );\n') | |
1632 | file.write(' ad += (bd >> 32);\n') | |
1633 | file.write(' tmp = (cb & ((~0ull) >> 32)) + (ad & ((~0ull) >> 32));\n') | |
1634 | file.write(' carry = ((tmp >> 32) != 0) ? 1 : 0;\n') | |
1635 | file.write(' tmp = (cb >> 32) + (ad >> 32) + carry;\n') | |
1636 | file.write(' carry = ((tmp >> 32) != 0) ? 1 : 0;\n') | |
1637 | file.write(' if (carry)\n') | |
1638 | file.write(' ac += ( ( (uint64_t) 1 ) << 32 );\n') | |
1639 | file.write(' rd = ac + ( ( cb + ad ) >> 32 );\n') | |
1640 | if out == 'rd': | |
1641 | file.write(' s->get_irf(i->rd) = rd;\n') | |
1642 | file.write(' s->npc = npc+4;\n') | |
1643 | file.write(' return npc;\n') | |
1644 | self.c_code_end(file) | |
1645 | ||
1646 | def run_dec_c(self,file): | |
1647 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
1648 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1649 | self.ill_ibe(file) | |
1650 | file.write(' if (o.get_rd_irf())\n') | |
1651 | self.dec_rrr(file,' ','idx_exe_'+self.name+'_rd') | |
1652 | file.write(' else\n') | |
1653 | self.dec_0rr(file,' ','idx_exe_'+self.name+'_g0') | |
1654 | self.c_code_end(file) | |
1655 | ||
1656 | def gen_exe_tbl(self,file,mode): | |
1657 | for out in self.out: | |
1658 | if mode == 'trc': | |
1659 | file.write(' trc_exe_rrr, /* '+self.name+'_'+out+' */\n') | |
1660 | else: | |
1661 | if mode == 'v8_run': | |
1662 | mode = 'run' | |
1663 | file.write(' '+mode+'_exe_'+self.name+'_'+out+',\n') | |
1664 | ||
1665 | ||
1666 | ss_vis3[0x011] = SS_vis3_rrr('addxc') | |
1667 | ss_vis3[0x013] = SS_vis3_rrr('addxccc') | |
1668 | ss_vis3[0x016] = SS_vis3_rrr('umulxhi') | |
1669 | ss_vis3[0x115] = SS_vis3_rrr('xmulx') | |
1670 | ss_vis3[0x116] = SS_vis3_rrr('xmulxhi') | |
1671 | ||
1672 | #============================================================================ | |
1673 | # SS_cmask | |
1674 | #============================================================================ | |
1675 | ||
1676 | class SS_cmask(SS_InstrCpp): | |
1677 | def __init__(self,name): | |
1678 | SS_InstrCpp.__init__(self,name) | |
1679 | ||
1680 | def run_exe_c(self,file): | |
1681 | self.c_code_beg_name(file,'run_exe_'+self.name) | |
1682 | file.write(' if (s->sim_state.fp_disabled())\n') | |
1683 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
1684 | file.write(' uint64_t mask;\n') | |
1685 | file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n') | |
1686 | if self.name == 'cmask8': | |
1687 | file.write(' mask = (rs2 & 0x1) ? 0x7 : 0xf;\n') | |
1688 | file.write(' mask |= (rs2 & 0x2) ? 0x60 : 0xe0;\n') | |
1689 | file.write(' mask |= (rs2 & 0x4) ? 0x500 : 0xd00;\n') | |
1690 | file.write(' mask |= (rs2 & 0x8) ? 0x4000 : 0xc000;\n') | |
1691 | file.write(' mask |= (rs2 & 0x10) ? 0x30000 : 0xb0000;\n') | |
1692 | file.write(' mask |= (rs2 & 0x20) ? 0x200000 : 0xa00000;\n') | |
1693 | file.write(' mask |= (rs2 & 0x40) ? 0x1000000 : 0x9000000;\n') | |
1694 | file.write(' mask |= (rs2 & 0x80) ? 0x00000000 : 0x80000000;\n') | |
1695 | elif self.name == 'cmask16': | |
1696 | file.write(' mask = (rs2 & 0x1) ? 0x67 : 0xef;\n') | |
1697 | file.write(' mask |= (rs2 & 0x2) ? 0x4500 : 0xcd00;\n') | |
1698 | file.write(' mask |= (rs2 & 0x4) ? 0x230000 : 0xab0000;\n') | |
1699 | file.write(' mask |= (rs2 & 0x8) ? 0x01000000 : 0x89000000;\n') | |
1700 | else: | |
1701 | file.write(' mask = (rs2 & 0x1) ? 0x4567 : 0xcdef;\n') | |
1702 | file.write(' mask |= (rs2 & 0x2) ? 0x01230000 : 0x89ab0000;\n') | |
1703 | file.write(' s->gsr.mask(mask);\n') | |
1704 | file.write(' s->npc = npc+4;\n') | |
1705 | file.write(' return npc;\n') | |
1706 | self.c_code_end(file) | |
1707 | ||
1708 | def run_dec_c(self,file): | |
1709 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
1710 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1711 | file.write(' if (o.is_zero_29_25() && o.is_zero_18_14())\n') | |
1712 | file.write(' {\n') | |
1713 | self.ill_ibe(file) | |
1714 | self.dec_00r(file,' ','idx_exe_'+self.name) | |
1715 | file.write(' }\n') | |
1716 | file.write(' else\n') | |
1717 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
1718 | self.c_code_end(file) | |
1719 | ||
1720 | def gen_exe_tbl(self,file,mode): | |
1721 | if mode == 'trc': | |
1722 | file.write(' trc_exe_00r, /* '+self.name+' */\n') | |
1723 | else: | |
1724 | if mode == 'v8_run': | |
1725 | mode = 'run' | |
1726 | file.write(' '+mode+'_exe_'+self.name+',\n') | |
1727 | ||
1728 | ss_vis3[0x01b] = SS_cmask('cmask8') | |
1729 | ss_vis3[0x01d] = SS_cmask('cmask16') | |
1730 | ss_vis3[0x01f] = SS_cmask('cmask32') | |
1731 | ||
1732 | #============================================================================ | |
1733 | # SS_vis3_ddd | |
1734 | #============================================================================ | |
1735 | ||
1736 | class SS_vis3_ddd(SS_InstrCpp): | |
1737 | def __init__(self,name): | |
1738 | SS_InstrCpp.__init__(self,name) | |
1739 | ||
1740 | def run_exe_c(self,file): | |
1741 | self.c_code_beg_name(file,'run_exe_'+self.name) | |
1742 | file.write(' if (s->sim_state.fp_disabled())\n') | |
1743 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
1744 | file.write(' uint64_t rs1 = s->get_drf(i->rs1);\n') | |
1745 | file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n') | |
1746 | file.write(' uint64_t rd = 0;\n') | |
1747 | ||
1748 | if self.name == 'fchksm16': | |
1749 | file.write(' uint64_t x;\n') | |
1750 | file.write(' for (int n=0; n<4; n++) {\n') | |
1751 | file.write(' x = (rs1 & 0xffff) + (rs2 & 0xffff);\n') | |
1752 | file.write(' x = x + (x >> 16);\n') | |
1753 | file.write(' rd |= ( (x & 0xffff) << (n << 4) );\n') | |
1754 | file.write(' rs1 >>= 16;\n') | |
1755 | file.write(' rs2 >>= 16;\n') | |
1756 | file.write(' }\n') | |
1757 | ||
1758 | elif self.name == 'fmean16': | |
1759 | file.write(' int x1,x2;\n') | |
1760 | file.write(' for (int n=0; n<4; n++) {\n') | |
1761 | file.write(' x1 = ( (int) (rs1 << 16) ) >> 16;\n') | |
1762 | file.write(' x2 = ( (int) (rs2 << 16) ) >> 16;\n') | |
1763 | file.write(' x1 = x1 + x2 + 1;\n') | |
1764 | file.write(' rd |= ( ( (uint64_t) ( (x1 >> 1) & 0xffff ) ) << (n << 4) );\n') | |
1765 | file.write(' rs1 >>= 16;\n') | |
1766 | file.write(' rs2 >>= 16;\n') | |
1767 | file.write(' }\n') | |
1768 | ||
1769 | elif self.name == 'fpadd64': | |
1770 | file.write(' rd = rs1 + rs2;\n') | |
1771 | ||
1772 | elif self.name == 'fpsub64': | |
1773 | file.write(' rd = rs1 - rs2;\n') | |
1774 | ||
1775 | elif self.name in ['fpadds16', 'fpsubs16', 'fpadds32', 'fpsubs32']: | |
1776 | file.write(' uint64_t x,x1,x2;\n') | |
1777 | if self.name in ['fpadds16', 'fpsubs16']: | |
1778 | file.write(' uint64_t sm = 0x8000;\n') | |
1779 | file.write(' uint64_t m = 0xffff;\n') | |
1780 | file.write(' for (int n=0; n<4; n++) {\n') | |
1781 | else: | |
1782 | file.write(' uint64_t sm = 0x80000000;\n') | |
1783 | file.write(' uint64_t m = 0xffffffff;\n') | |
1784 | file.write(' for (int n=0; n<2; n++) {\n') | |
1785 | file.write(' x1 = rs1 & m;\n') | |
1786 | file.write(' x2 = rs2 & m;\n') | |
1787 | if self.name in ['fpadds16', 'fpadds32']: | |
1788 | file.write(' x = (x1 + x2) & m;\n') | |
1789 | file.write(' if (((x1 & sm) == (x2 & sm)) && ((x & sm) != (x1 & sm)))\n') | |
1790 | else: | |
1791 | file.write(' x = (x1 - x2) & m;\n') | |
1792 | file.write(' if (((x1 & sm) != (x2 & sm)) && ((x & sm) != (x1 & sm)))\n') | |
1793 | file.write(' x = ( (x1 & sm) == 0 ) ? (sm - 1) : sm;\n') | |
1794 | if self.name in ['fpadds16', 'fpsubs16']: | |
1795 | file.write(' rd |= x << (n << 4);\n') | |
1796 | file.write(' rs1 >>= 16;\n') | |
1797 | file.write(' rs2 >>= 16;\n') | |
1798 | else: | |
1799 | file.write(' rd |= x << (n << 5);\n') | |
1800 | file.write(' rs1 >>= 32;\n') | |
1801 | file.write(' rs2 >>= 32;\n') | |
1802 | file.write(' }\n') | |
1803 | ||
1804 | elif self.name in ['fsll16', 'fsrl16', 'fslas16', 'fsra16']: | |
1805 | file.write(' uint64_t sv;\n') | |
1806 | file.write(' int x0,x1;\n') | |
1807 | file.write(' for (int n=0; n<4; n++) {\n') | |
1808 | file.write(' sv = rs2 & 0xf;\n') | |
1809 | if self.name == 'fsll16': | |
1810 | file.write(' x0 = (rs1 & 0xffff) << sv;\n') | |
1811 | elif self.name == 'fsrl16': | |
1812 | file.write(' x0 = (rs1 & 0xffff) >> sv;\n') | |
1813 | elif self.name == 'fslas16': | |
1814 | file.write(' x1 = (int) rs1;\n') | |
1815 | file.write(' x1 = (x1 << 16) >> 16;\n') | |
1816 | file.write(' x0 = x1 << sv;\n') | |
1817 | file.write(' x1 = x0 >> 15;\n') | |
1818 | file.write(' if ((x1 != 0) && (x1 != 0xffffffff)) {\n'); | |
1819 | file.write(' if ((x1 & 0x80000000) == 0)\n') | |
1820 | file.write(' x0 = 0x7fff;\n') | |
1821 | file.write(' else\n') | |
1822 | file.write(' x0 = 0x8000;\n') | |
1823 | file.write(' }\n') | |
1824 | elif self.name == 'fsra16': | |
1825 | file.write(' x1 = (int) rs1;\n') | |
1826 | file.write(' x1 = (x1 << 16) >> 16;\n') | |
1827 | file.write(' x0 = x1 >> sv;\n') | |
1828 | file.write(' rd |= (((uint64_t) (x0 & 0xffff)) << (n << 4));\n') | |
1829 | file.write(' rs1 >>= 16;\n') | |
1830 | file.write(' rs2 >>= 16;\n') | |
1831 | file.write(' }\n') | |
1832 | ||
1833 | elif self.name in ['fsll32', 'fsrl32', 'fslas32', 'fsra32']: | |
1834 | file.write(' uint64_t sv;\n') | |
1835 | file.write(' int64_t y0,y1;\n') | |
1836 | file.write(' int x0,x1;\n') | |
1837 | file.write(' for (int n=0; n<2; n++) {\n') | |
1838 | file.write(' sv = rs2 & 0x1f;\n') | |
1839 | if self.name == 'fsll32': | |
1840 | file.write(' x0 = (rs1 & 0xffffffff) << sv;\n') | |
1841 | elif self.name == 'fsrl32': | |
1842 | file.write(' x0 = (rs1 & 0xffffffff) >> sv;\n') | |
1843 | elif self.name == 'fslas32': | |
1844 | file.write(' y1 = rs1;\n') | |
1845 | file.write(' y1 = (y1 << 32) >> 32;\n') | |
1846 | file.write(' y0 = y1 << sv;\n') | |
1847 | file.write(' y1 = y0 >> 31;\n') | |
1848 | file.write(' if ((y1 != 0) && (y1 != 0xffffffffffffffff)) {\n'); | |
1849 | file.write(' if ((y1 & 0x8000000000000000) == 0)\n') | |
1850 | file.write(' x0 = 0x7fffffff;\n') | |
1851 | file.write(' else\n') | |
1852 | file.write(' x0 = 0x80000000;\n') | |
1853 | file.write(' }\n') | |
1854 | file.write(' else\n') | |
1855 | file.write(' x0 = y0;\n') | |
1856 | elif self.name == 'fsra32': | |
1857 | file.write(' x1 = (int) rs1;\n') | |
1858 | file.write(' x0 = x1 >> sv;\n') | |
1859 | file.write(' rd |= ((((uint64_t) x0) & 0xffffffff) << (n << 5));\n') | |
1860 | file.write(' rs1 >>= 32;\n') | |
1861 | file.write(' rs2 >>= 32;\n') | |
1862 | file.write(' }\n') | |
1863 | ||
1864 | file.write(' s->get_drf(i->rd) = rd;\n') | |
1865 | file.write(' s->set_fprs(i->rd);\n') | |
1866 | file.write(' s->npc = npc+4;\n') | |
1867 | file.write(' return npc;\n') | |
1868 | self.c_code_end(file) | |
1869 | ||
1870 | def run_dec_c(self,file): | |
1871 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
1872 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1873 | self.ill_ibe(file) | |
1874 | self.dec_ddd(file,' ','idx_exe_'+self.name) | |
1875 | self.c_code_end(file) | |
1876 | ||
1877 | def gen_exe_tbl(self,file,mode): | |
1878 | if mode == 'trc': | |
1879 | file.write(' trc_exe_ddd, /* '+self.name+' */\n') | |
1880 | else: | |
1881 | if mode == 'v8_run': | |
1882 | mode = 'run' | |
1883 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
1884 | ||
1885 | ||
1886 | ss_vis3[0x021] = SS_vis3_ddd('fsll16') | |
1887 | ss_vis3[0x023] = SS_vis3_ddd('fsrl16') | |
1888 | ss_vis3[0x025] = SS_vis3_ddd('fsll32') | |
1889 | ss_vis3[0x027] = SS_vis3_ddd('fsrl32') | |
1890 | ss_vis3[0x029] = SS_vis3_ddd('fslas16') | |
1891 | ss_vis3[0x02b] = SS_vis3_ddd('fsra16') | |
1892 | ss_vis3[0x02d] = SS_vis3_ddd('fslas32') | |
1893 | ss_vis3[0x02f] = SS_vis3_ddd('fsra32') | |
1894 | ss_vis3[0x040] = SS_vis3_ddd('fmean16') | |
1895 | ss_vis3[0x042] = SS_vis3_ddd('fpadd64') | |
1896 | ss_vis3[0x044] = SS_vis3_ddd('fchksm16') | |
1897 | ss_vis3[0x046] = SS_vis3_ddd('fpsub64') | |
1898 | ss_vis3[0x058] = SS_vis3_ddd('fpadds16') | |
1899 | ss_vis3[0x05a] = SS_vis3_ddd('fpadds32') | |
1900 | ss_vis3[0x05c] = SS_vis3_ddd('fpsubs16') | |
1901 | ss_vis3[0x05e] = SS_vis3_ddd('fpsubs32') | |
1902 | ||
1903 | #============================================================================ | |
1904 | # SS_vis3_fff | |
1905 | #============================================================================ | |
1906 | ||
1907 | class SS_vis3_fff(SS_InstrCpp): | |
1908 | def __init__(self,name): | |
1909 | SS_InstrCpp.__init__(self,name) | |
1910 | ||
1911 | def run_exe_c(self,file): | |
1912 | self.c_code_beg_name(file,'run_exe_'+self.name) | |
1913 | file.write(' if (s->sim_state.fp_disabled())\n') | |
1914 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
1915 | file.write(' uint32_t rs1 = s->get_frf(i->rs1);\n') | |
1916 | file.write(' uint32_t rs2 = s->get_frf(i->rs2);\n') | |
1917 | file.write(' uint32_t rd = 0;\n') | |
1918 | if self.name in ['fpadds16s', 'fpsubs16s', 'fpadds32s', 'fpsubs32s']: | |
1919 | file.write(' uint64_t x;\n') | |
1920 | if self.name in ['fpadds16s', 'fpsubs16s']: | |
1921 | file.write(' uint64_t x1,x2;\n') | |
1922 | file.write(' uint64_t sm = 0x8000;\n') | |
1923 | file.write(' uint64_t m = 0xffff;\n') | |
1924 | file.write(' for (int n=0; n<2; n++) {\n') | |
1925 | file.write(' x1 = rs1 & m;\n') | |
1926 | file.write(' x2 = rs2 & m;\n') | |
1927 | if self.name == 'fpadds16s': | |
1928 | file.write(' x = (x1 + x2) & m;\n') | |
1929 | file.write(' if (((x1 & sm) == (x2 & sm)) && ((x & sm) != (x1 & sm)))\n') | |
1930 | else: | |
1931 | file.write(' x = (x1 - x2) & m;\n') | |
1932 | file.write(' if (((x1 & sm) != (x2 & sm)) && ((x & sm) != (x1 & sm)))\n') | |
1933 | file.write(' x = ( (x1 & sm) == 0 ) ? (sm - 1) : sm;\n') | |
1934 | file.write(' rd |= x << (n << 4);\n') | |
1935 | file.write(' rs1 >>= 16;\n') | |
1936 | file.write(' rs2 >>= 16;\n') | |
1937 | file.write(' }\n') | |
1938 | else: | |
1939 | file.write(' uint64_t sm = 0x80000000;\n') | |
1940 | if self.name == 'fpadds32s': | |
1941 | file.write(' x = rs1 + rs2;\n') | |
1942 | file.write(' if (((rs1 & sm) == (rs2 & sm)) && ((x & sm) != (rs1 & sm)))\n') | |
1943 | else: | |
1944 | file.write(' x = rs1 - rs2;\n') | |
1945 | file.write(' if (((rs1 & sm) != (rs2 & sm)) && ((x & sm) != (rs1 & sm)))\n') | |
1946 | file.write(' x = ( (rs1 & sm) == 0 ) ? (sm - 1) : sm;\n') | |
1947 | file.write(' rd = x;\n') | |
1948 | file.write(' s->get_frf(i->rd) = rd;\n') | |
1949 | file.write(' s->set_fprs(i->rd);\n') | |
1950 | file.write(' s->npc = npc+4;\n') | |
1951 | file.write(' return npc;\n') | |
1952 | self.c_code_end(file) | |
1953 | ||
1954 | def run_dec_c(self,file): | |
1955 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
1956 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
1957 | self.ill_ibe(file) | |
1958 | self.dec_fff(file,' ','idx_exe_'+self.name) | |
1959 | self.c_code_end(file) | |
1960 | ||
1961 | def gen_exe_tbl(self,file,mode): | |
1962 | if mode == 'trc': | |
1963 | file.write(' trc_exe_fff, /* '+self.name+' */\n') | |
1964 | else: | |
1965 | if mode == 'v8_run': | |
1966 | mode = 'run' | |
1967 | file.write(' %s_exe_%s,\n' % (mode,self.name)) | |
1968 | ||
1969 | ||
1970 | ss_vis3[0x059] = SS_vis3_fff('fpadds16s') | |
1971 | ss_vis3[0x05b] = SS_vis3_fff('fpadds32s') | |
1972 | ss_vis3[0x05d] = SS_vis3_fff('fpsubs16s') | |
1973 | ss_vis3[0x05f] = SS_vis3_fff('fpsubs32s') | |
1974 | ||
1975 | #============================================================================ | |
1976 | # SS_vis3_rdd | |
1977 | #============================================================================ | |
1978 | ||
1979 | class SS_vis3_rdd(SS_InstrCpp): | |
1980 | def __init__(self,name): | |
1981 | SS_InstrCpp.__init__(self,name) | |
1982 | self.out = ['rd', 'g0'] | |
1983 | ||
1984 | def run_exe_c(self,file): | |
1985 | for out in self.out: | |
1986 | self.c_code_beg_name(file,'run_exe_'+self.name+'_'+out) | |
1987 | file.write(' if (s->sim_state.fp_disabled())\n') | |
1988 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
1989 | if out == 'rd': | |
1990 | file.write(' uint64_t rs1 = s->get_drf(i->rs1);\n') | |
1991 | file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n') | |
1992 | file.write(' uint64_t rd = 0;\n'); | |
1993 | ||
1994 | if self.name == 'pdistn': | |
1995 | file.write(' for (int n=0; n<8; n++) {\n') | |
1996 | file.write(' uint64_t v = (rs1 & 0xff) - (rs2 & 0xff);\n') | |
1997 | file.write(' if ((v & 0x8000000000000000) != 0)\n') | |
1998 | file.write(' v = -v;\n') | |
1999 | file.write(' rd += v;\n') | |
2000 | file.write(' rs1 >>= 8;\n') | |
2001 | file.write(' rs2 >>= 8;\n') | |
2002 | file.write(' }\n'); | |
2003 | ||
2004 | elif self.name in ['fucmple8', 'fucmpne8', 'fucmpgt8', 'fucmpeq8']: | |
2005 | file.write(' for (int n=0; n<8; n++) {\n') | |
2006 | file.write(' uint16_t s1 = (uint16_t) rs1 & 0xff;\n') | |
2007 | file.write(' uint16_t s2 = (uint16_t) rs2 & 0xff;\n') | |
2008 | if self.name == 'fucmple8': | |
2009 | file.write(' uint64_t v = (s1 <= s2) ? 1 : 0;\n') | |
2010 | elif self.name == 'fucmpne8': | |
2011 | file.write(' uint64_t v = (s1 != s2) ? 1 : 0;\n') | |
2012 | elif self.name == 'fucmpgt8': | |
2013 | file.write(' uint64_t v = (s1 > s2) ? 1 : 0;\n') | |
2014 | elif self.name == 'fucmpeq8': | |
2015 | file.write(' uint64_t v = (s1 == s2) ? 1 : 0;\n') | |
2016 | file.write(' rd |= (v << n);\n') | |
2017 | file.write(' rs1 >>= 8;\n') | |
2018 | file.write(' rs2 >>= 8;\n') | |
2019 | file.write(' }\n'); | |
2020 | ||
2021 | file.write(' s->get_irf(i->rd) = rd;\n') | |
2022 | ||
2023 | file.write(' s->npc = npc+4;\n') | |
2024 | file.write(' return npc;\n') | |
2025 | self.c_code_end(file) | |
2026 | ||
2027 | def run_dec_c(self,file): | |
2028 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
2029 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
2030 | self.ill_ibe(file) | |
2031 | file.write(' if (o.get_rd_irf())\n') | |
2032 | self.dec_rdd(file,' ','idx_exe_'+self.name+'_rd') | |
2033 | file.write(' else\n') | |
2034 | self.dec_0dd(file,' ','idx_exe_'+self.name+'_g0') | |
2035 | self.c_code_end(file) | |
2036 | ||
2037 | def gen_exe_tbl(self,file,mode): | |
2038 | for out in self.out: | |
2039 | if mode == 'trc': | |
2040 | file.write(' trc_exe_rdd, /* '+self.name+'_'+out+' */\n') | |
2041 | else: | |
2042 | if mode == 'v8_run': | |
2043 | mode = 'run' | |
2044 | file.write(' '+mode+'_exe_'+self.name+'_'+out+',\n') | |
2045 | ||
2046 | ||
2047 | ss_vis3[0x03f] = SS_vis3_rdd('pdistn') | |
2048 | ss_vis3[0x120] = SS_vis3_rdd('fucmple8') | |
2049 | ss_vis3[0x122] = SS_vis3_rdd('fucmpne8') | |
2050 | ss_vis3[0x128] = SS_vis3_rdd('fucmpgt8') | |
2051 | ss_vis3[0x12a] = SS_vis3_rdd('fucmpeq8') | |
2052 | ||
2053 | #============================================================================ | |
2054 | # SS_vis3_movitof | |
2055 | #============================================================================ | |
2056 | ||
2057 | class SS_vis3_movitof(SS_InstrCpp): | |
2058 | def __init__(self,name): | |
2059 | SS_InstrCpp.__init__(self,name) | |
2060 | ||
2061 | def run_exe_c(self,file): | |
2062 | self.c_code_beg_name(file,'run_exe_'+self.name) | |
2063 | file.write(' if (s->sim_state.fp_disabled())\n') | |
2064 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
2065 | ||
2066 | if self.name == 'movxtod': | |
2067 | file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n') | |
2068 | file.write(' s->get_drf(i->rd) = rs2;\n') | |
2069 | ||
2070 | elif self.name == 'movwtos': | |
2071 | file.write(' uint32_t rs2 = s->get_irf(i->rs2);\n') | |
2072 | file.write(' s->get_frf(i->rd) = rs2;\n') | |
2073 | ||
2074 | file.write(' s->set_fprs(i->rd);\n') | |
2075 | file.write(' s->npc = npc+4;\n') | |
2076 | file.write(' return npc;\n') | |
2077 | self.c_code_end(file) | |
2078 | ||
2079 | def run_dec_c(self,file): | |
2080 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
2081 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
2082 | file.write(' if (o.is_zero_18_14())\n') | |
2083 | file.write(' {\n') | |
2084 | self.ill_ibe(file) | |
2085 | if self.name == 'movxtod': | |
2086 | self.dec_d0r(file,' ','idx_exe_'+self.name) | |
2087 | else: | |
2088 | self.dec_f0r(file,' ','idx_exe_'+self.name) | |
2089 | file.write(' }\n') | |
2090 | file.write(' else\n') | |
2091 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
2092 | self.c_code_end(file) | |
2093 | ||
2094 | def gen_exe_tbl(self,file,mode): | |
2095 | if mode == 'trc': | |
2096 | if self.name == 'movxtod': | |
2097 | file.write(' trc_exe_d0r, /* '+self.name+' */\n') | |
2098 | else: | |
2099 | file.write(' trc_exe_f0r, /* '+self.name+' */\n') | |
2100 | else: | |
2101 | if mode == 'v8_run': | |
2102 | mode = 'run' | |
2103 | file.write(' '+mode+'_exe_'+self.name+',\n') | |
2104 | ||
2105 | ||
2106 | ||
2107 | ss_vis3[0x118] = SS_vis3_movitof('movxtod') | |
2108 | ss_vis3[0x119] = SS_vis3_movitof('movwtos') | |
2109 | ||
2110 | #============================================================================ | |
2111 | # SS_vis3_movftoi | |
2112 | #============================================================================ | |
2113 | ||
2114 | class SS_vis3_movftoi(SS_InstrCpp): | |
2115 | def __init__(self,name): | |
2116 | SS_InstrCpp.__init__(self,name) | |
2117 | self.out = ['rd', 'g0'] | |
2118 | ||
2119 | def run_exe_c(self,file): | |
2120 | for out in self.out: | |
2121 | self.c_code_beg_name(file,'run_exe_'+self.name+'_'+out) | |
2122 | file.write(' if (s->sim_state.fp_disabled())\n') | |
2123 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
2124 | if out == 'rd': | |
2125 | if self.name == 'movdtox': | |
2126 | file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n') | |
2127 | file.write(' s->get_irf(i->rd) = rs2;\n') | |
2128 | elif self.name == 'movstouw': | |
2129 | file.write(' uint32_t rs2 = s->get_frf(i->rs2);\n') | |
2130 | file.write(' s->get_irf(i->rd) = rs2;\n') | |
2131 | elif self.name == 'movstosw': | |
2132 | file.write(' uint32_t rs2 = s->get_frf(i->rs2);\n') | |
2133 | file.write(' s->get_irf(i->rd) = (int) rs2;\n') | |
2134 | file.write(' s->npc = npc+4;\n') | |
2135 | file.write(' return npc;\n') | |
2136 | self.c_code_end(file) | |
2137 | ||
2138 | def run_dec_c(self,file): | |
2139 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
2140 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
2141 | file.write(' if (o.is_zero_18_14())\n') | |
2142 | file.write(' {\n') | |
2143 | self.ill_ibe(file) | |
2144 | file.write(' if (o.get_rd_irf())\n') | |
2145 | if self.name == 'movdtox': | |
2146 | self.dec_r0d(file,' ','idx_exe_'+self.name+'_rd') | |
2147 | elif self.name in ['movstouw', 'movstosw']: | |
2148 | self.dec_r0f(file,' ','idx_exe_'+self.name+'_rd') | |
2149 | file.write(' else\n') | |
2150 | self.dec_00r(file,' ','idx_exe_'+self.name+'_g0') | |
2151 | file.write(' }\n') | |
2152 | file.write(' else\n') | |
2153 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
2154 | self.c_code_end(file) | |
2155 | ||
2156 | def gen_exe_tbl(self,file,mode): | |
2157 | for out in self.out: | |
2158 | if mode == 'trc': | |
2159 | if self.name == 'movdtox': | |
2160 | file.write(' trc_exe_r0d, /* '+self.name+'_'+out+' */\n') | |
2161 | else: | |
2162 | file.write(' trc_exe_r0f, /* '+self.name+'_'+out+' */\n') | |
2163 | else: | |
2164 | if mode == 'v8_run': | |
2165 | mode = 'run' | |
2166 | file.write(' '+mode+'_exe_'+self.name+'_'+out+',\n') | |
2167 | ||
2168 | ||
2169 | ss_vis3[0x110] = SS_vis3_movftoi('movdtox') | |
2170 | ss_vis3[0x111] = SS_vis3_movftoi('movstouw') | |
2171 | ss_vis3[0x113] = SS_vis3_movftoi('movstosw') | |
2172 | ||
2173 | #============================================================================ | |
2174 | # SS_vis3_flcmp | |
2175 | #============================================================================ | |
2176 | ||
2177 | class SS_vis3_flcmp(SS_InstrCpp): | |
2178 | def __init__(self,name): | |
2179 | SS_InstrCpp.__init__(self,name) | |
2180 | ||
2181 | def run_exe_c(self,file): | |
2182 | self.c_code_beg_name(file,'run_exe_'+self.name) | |
2183 | file.write(' if (s->sim_state.fp_disabled())\n') | |
2184 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
2185 | file.write(' '+setup.product+'_Strand* ss = ('+setup.product+'_Strand*)s;\n') | |
2186 | file.write(' ss->get_fsr();\n') | |
2187 | file.write(' int fccx;\n') | |
2188 | if self.name == 'flcmps': | |
2189 | file.write(' uint32_t rs1 = ss->get_frf(i->rs1);\n') | |
2190 | file.write(' uint32_t rs2 = ss->get_frf(i->rs2);\n') | |
2191 | file.write(' if ((((uint32_t) 0xff) << 24) < (rs2 << 1))\n') | |
2192 | file.write(' fccx = 3;\n') | |
2193 | file.write(' else if ((((uint32_t) 0xff) << 24) < (rs1 << 1))\n') | |
2194 | file.write(' fccx = 2;\n') | |
2195 | file.write(' else {\n') | |
2196 | file.write(' int aSign = rs1 >> 31;\n') | |
2197 | file.write(' int bSign = rs2 >> 31;\n') | |
2198 | file.write(' if (aSign != bSign)\n') | |
2199 | file.write(' fccx = aSign && ((uint32_t)((rs1|rs2)<<1) != 0);\n') | |
2200 | file.write(' else\n') | |
2201 | file.write(' fccx = (rs1 != rs2) && (aSign ^ (rs1 < rs2));\n') | |
2202 | file.write(' if (fccx == 0 && rs1 == 0x80000000 && rs2 == 0)\n') | |
2203 | file.write(' fccx = 1;\n') | |
2204 | file.write(' }\n') | |
2205 | elif self.name == 'flcmpd': | |
2206 | file.write(' uint64_t rs1 = ss->get_drf(i->rs1);\n') | |
2207 | file.write(' uint64_t rs2 = ss->get_drf(i->rs2);\n') | |
2208 | file.write(' if ((((uint64_t) 0x7ff) << 53) < (rs2 << 1))\n') | |
2209 | file.write(' fccx = 3;\n') | |
2210 | file.write(' else if ((((uint64_t) 0x7ff) << 53) < (rs1 << 1))\n') | |
2211 | file.write(' fccx = 2;\n') | |
2212 | file.write(' else {\n') | |
2213 | file.write(' int aSign = rs1 >> 63;\n') | |
2214 | file.write(' int bSign = rs2 >> 63;\n') | |
2215 | file.write(' if (aSign != bSign)\n') | |
2216 | file.write(' fccx = aSign && ((uint64_t)( (rs1|rs2) << 1) != 0);\n') | |
2217 | file.write(' else\n') | |
2218 | file.write(' fccx = (rs1 != rs2) && (aSign ^ (rs1 < rs2));\n') | |
2219 | file.write(' if (fccx == 0 && rs1 == 0x8000000000000000 && rs2 == 0)\n') | |
2220 | file.write(' fccx = 1;\n') | |
2221 | file.write(' }\n') | |
2222 | file.write(' ss->fpu.set_fcc(ss->fsr,SS_Fpu::ConditionField(i->rd),SS_Fpu::ConditionCode(fccx));\n') | |
2223 | file.write(' ss->set_fsr();\n') | |
2224 | file.write(' ss->npc = npc+4;\n') | |
2225 | file.write(' return npc;\n') | |
2226 | self.c_code_end(file) | |
2227 | ||
2228 | def run_dec_c(self,file): | |
2229 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
2230 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
2231 | file.write(' if (o.get_rd() < 4)\n') | |
2232 | file.write(' {\n') | |
2233 | self.ill_ibe(file) | |
2234 | if self.name == 'flcmps': | |
2235 | self.dec_nff(file,' ','idx_exe_'+self.name) | |
2236 | else: | |
2237 | self.dec_ndd(file,' ','idx_exe_'+self.name) | |
2238 | file.write(' }\n') | |
2239 | file.write(' else\n') | |
2240 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
2241 | self.c_code_end(file) | |
2242 | ||
2243 | def gen_exe_tbl(self,file,mode): | |
2244 | if mode == 'trc': | |
2245 | if self.name == 'flcmps': | |
2246 | file.write(' trc_exe_0ff, /* '+self.name+' */\n') | |
2247 | else: | |
2248 | file.write(' trc_exe_0dd, /* '+self.name+' */\n') | |
2249 | else: | |
2250 | if mode == 'v8_run': | |
2251 | mode = 'run' | |
2252 | file.write(' '+mode+'_exe_'+self.name+',\n') | |
2253 | ||
2254 | ||
2255 | ss_vis3[0x151] = SS_vis3_flcmp('flcmps') | |
2256 | ss_vis3[0x152] = SS_vis3_flcmp('flcmpd') | |
2257 | ||
2258 | #============================================================================ | |
2259 | # SS_vis3_lzd | |
2260 | #============================================================================ | |
2261 | ||
2262 | ||
2263 | class SS_vis3_lzd(SS_InstrCpp): | |
2264 | def __init__(self,name): | |
2265 | SS_InstrCpp.__init__(self,name) | |
2266 | self.out = ['rd', 'g0'] | |
2267 | ||
2268 | def run_exe_c(self,file): | |
2269 | for out in self.out: | |
2270 | self.c_code_beg_name(file,'run_exe_'+self.name+'_'+out) | |
2271 | if out == 'rd': | |
2272 | file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n') | |
2273 | file.write(' uint64_t rd = 0;\n') | |
2274 | file.write(' for (int n=0; n<16; n++) {\n') | |
2275 | file.write(' if ((rs2 & 0xf000000000000000) != 0)\n') | |
2276 | file.write(' break;\n') | |
2277 | file.write(' rd += 4;\n') | |
2278 | file.write(' rs2 <<= 4;\n') | |
2279 | file.write(' }\n') | |
2280 | file.write(' switch ((rs2 >> 60) & 0xf) {\n') | |
2281 | file.write(' case 1: rd += 3; break;\n') | |
2282 | file.write(' case 2: case 3: rd += 2; break;\n') | |
2283 | file.write(' case 4: case 5: case 6: case 7: rd += 1; break;\n') | |
2284 | file.write(' }\n') | |
2285 | file.write(' s->get_irf(i->rd) = rd;\n') | |
2286 | file.write(' s->npc = npc+4;\n') | |
2287 | file.write(' return npc;\n') | |
2288 | self.c_code_end(file) | |
2289 | ||
2290 | def run_dec_c(self,file): | |
2291 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
2292 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
2293 | file.write(' if (o.is_zero_18_14())\n') | |
2294 | file.write(' {\n') | |
2295 | self.ill_ibe(file) | |
2296 | file.write(' if (o.get_rd_irf())\n') | |
2297 | self.dec_r0r(file,' ','idx_exe_'+self.name+'_rd') | |
2298 | file.write(' else\n') | |
2299 | self.dec_00r(file,' ','idx_exe_'+self.name+'_g0') | |
2300 | file.write(' }\n') | |
2301 | file.write(' else\n') | |
2302 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
2303 | self.c_code_end(file) | |
2304 | ||
2305 | def gen_exe_tbl(self,file,mode): | |
2306 | for out in self.out: | |
2307 | if mode == 'trc': | |
2308 | file.write(' trc_exe_r0r, /* '+self.name+'_'+out+' */\n') | |
2309 | else: | |
2310 | if mode == 'v8_run': | |
2311 | mode = 'run' | |
2312 | file.write(' '+mode+'_exe_'+self.name+'_'+out+',\n') | |
2313 | ||
2314 | ||
2315 | ss_vis3[0x017] = SS_vis3_lzd('lzd') | |
2316 | ||
2317 | #============================================================================ | |
2318 | # SS_random | |
2319 | #============================================================================ | |
2320 | ||
2321 | class SS_random(SS_InstrCpp): | |
2322 | def __init__(self,name): | |
2323 | SS_InstrCpp.__init__(self,name) | |
2324 | ||
2325 | def run_exe_c(self,file): | |
2326 | self.c_code_beg_name(file,'run_exe_'+self.name) | |
2327 | file.write(' if (s->sim_state.fp_disabled())\n') | |
2328 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n') | |
2329 | file.write(' s->get_drf(i->rd) = (uint64_t(rand()) << 32) | uint64_t(rand());\n') | |
2330 | file.write(' s->npc = npc+4;\n') | |
2331 | file.write(' return npc;\n') | |
2332 | self.c_code_end(file) | |
2333 | ||
2334 | def run_dec_c(self,file): | |
2335 | self.c_code_dec_beg_name(file,'run_dec_'+self.name) | |
2336 | file.write(' i->flg = SS_Instr::NON_LSU;\n') | |
2337 | file.write(' if (o.is_zero_18_14() && o.is_zero_4_0())\n') | |
2338 | file.write(' {\n') | |
2339 | self.ill_ibe(file) | |
2340 | self.dec_d00(file,' ','idx_exe_'+self.name) | |
2341 | file.write(' }\n') | |
2342 | file.write(' else\n') | |
2343 | file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n') | |
2344 | self.c_code_end(file) | |
2345 | ||
2346 | def gen_exe_tbl(self,file,mode): | |
2347 | if mode == 'v8_run': | |
2348 | mode = 'run' | |
2349 | self.gen_exe_passthrough(file,mode) | |
2350 | ||
2351 | ss_vis3[0x015] = SS_random('random') |