Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / bin / SS_InstrAlu.py
CommitLineData
920dae64
AT
1# ========== Copyright Header Begin ==========================================
2#
3# OpenSPARC T2 Processor File: SS_InstrAlu.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# SS_Alu.py implements most of the op=2 instructions.
23#============================================================================
24
25from SS_Instr import *
26from SS_Setup import *
27
28setup = setups[sys.argv[1]]
29
30#============================================================================
31# sethi/nop
32#============================================================================
33
34class SS_nop(SS_InstrAsm):
35 def __init__(self):
36 SS_InstrAsm.__init__(self,'nop')
37
38 def run_exe_s(self,file):
39 self.s_code(file,'run_exe_')
40 self.mov(file,self.NPC,self.PC)
41 self.add(file,self.NPC,4,self.NPC)
42 self.retl_st_npc(file,self.NPC)
43
44 def run_exe_c(self,file):
45 file.write('#if defined(ARCH_X64)\n')
46 self.c_code_beg(file,'run_exe_')
47 file.write(' pc = npc;\n')
48 file.write(' s->npc = npc + 4;\n')
49 file.write(' return pc;\n')
50 self.c_code_end(file)
51 file.write('#else\n')
52 file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
53 file.write('#endif\n\n')
54
55 def run_dec_p(self):
56 return ''
57
58 def gen_exe_tbl(self,file,mode):
59 if mode == 'v8_run':
60 file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
61 else:
62 self.gen_exe_passthrough(file,mode)
63
64class SS_sethi(SS_InstrAsm):
65 def __init__(self):
66 SS_InstrAsm.__init__(self,'sethi')
67
68 def run_exe_s(self,file):
69 self.s_code(file,'run_exe_')
70 self.mov(file,self.NPC,self.PC)
71 self.add(file,self.NPC,4,self.NPC)
72 self.ld_rd(file,'%g1')
73 self.ld_rs2_32(file,'%g2')
74 self.st_npc(file,self.NPC)
75 self.retl(file)
76 self.st_irf(file,'%g1','%g2')
77
78 def run_exe_c(self,file):
79 file.write('#if defined(ARCH_X64)\n')
80 self.c_code_beg(file,'run_exe_')
81 file.write(' pc = npc;\n')
82 file.write(' s->npc = npc + 4;\n')
83 file.write(' s->get_irf(i->rd) = *(uint32_t *)(&i->rs2);\n')
84 file.write(' return pc;\n')
85 self.c_code_end(file)
86 file.write('#else\n')
87 file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
88 file.write('#endif\n\n')
89
90 def run_dec_c(self,file):
91 self.c_code_dec_beg(file,'run_dec_')
92 file.write(' i->flg = SS_Instr::NON_LSU;\n')
93 self.ill_ibe(file)
94 file.write(' if (o.get_rd())\n')
95 self.dec_r022(file,' ','idx_exe_sethi')
96 file.write(' else\n')
97 self.dec_000(file,' ','idx_exe_nop')
98 self.c_code_end(file)
99
100 def run_dec_p_count(self):
101 return 8
102
103 def gen_exe_tbl(self,file,mode):
104 if mode == 'trc':
105 file.write(' trc_exe_r00, /* '+self.name+' */\n')
106 elif mode == 'v8_run':
107 file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
108 else:
109 SS_InstrAsm.gen_exe_tbl(self,file,mode)
110
111
112#============================================================================
113# SS_alu(opc)
114#============================================================================
115
116class SS_alu(SS_InstrAsm):
117 def __init__(self,opc):
118 SS_InstrAsm.__init__(self,opc)
119 self.opc = opc
120 self.imm = ['i0' ,'i1']
121 self.out = ['rd' ,'g0']
122
123 def run_exe_c(self,file):
124 for out in self.out:
125 for imm in self.imm:
126 file.write('#if defined(ARCH_X64)\n')
127 self.c_code_beg_name(file,'run_exe_'+self.opc+'_'+imm+'_'+out)
128 file.write(' int64_t rs1 = s->get_irf(i->rs1);\n')
129 if (imm == 'i0'):
130 file.write(' int64_t rs2 = s->get_irf(i->rs2);\n')
131 else:
132 file.write(' int64_t rs2 = i->rs2;\n');
133 if (self.opc == 'add'):
134 file.write(' int64_t rd = rs1 + rs2;\n')
135 elif (self.opc == 'and'):
136 file.write(' int64_t rd = rs1 & rs2;\n')
137 elif (self.opc == 'or'):
138 file.write(' int64_t rd = rs1 | rs2;\n')
139 elif (self.opc == 'xor'):
140 file.write(' int64_t rd = rs1 ^ rs2;\n')
141 elif (self.opc == 'sub'):
142 file.write(' int64_t rd = rs1 - rs2;\n')
143 elif (self.opc == 'andn'):
144 file.write(' int64_t rd = rs1 & (~rs2);\n')
145 elif (self.opc == 'orn'):
146 file.write(' int64_t rd = rs1 | (~rs2);\n')
147 elif (self.opc == 'xnor'):
148 file.write(' int64_t rd = ~(rs1 ^ rs2);\n')
149 elif (self.opc == 'addc'):
150 file.write(' int64_t rd = rs1 + rs2 + (s->ccr.icc() & 0x1);\n')
151 elif (self.opc == 'mulx'):
152 file.write(' int64_t rd = rs1 * rs2;\n')
153 elif (self.opc == 'sdivx'):
154 file.write(' if (rs2 == 0)\n')
155 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::DIVISION_BY_ZERO);\n')
156 file.write(' int64_t rd = rs1 / rs2;\n')
157 elif (self.opc in ['umul','umulcc','smul','smulcc']):
158 if (self.opc in ['umul','umulcc']):
159 file.write(' uint32_t t1 = rs1;\n')
160 file.write(' uint32_t t2 = rs2;\n')
161 file.write(' uint64_t rd = (uint64_t)t1 * (uint64_t)t2;\n')
162 else:
163 file.write(' int32_t t1 = rs1;\n')
164 file.write(' int32_t t2 = rs2;\n')
165 file.write(' int64_t rd = (int64_t)t1 * (int64_t)t2;\n')
166 file.write(' s->y.set((uint32_t)(rd >> 32));\n')
167 if (self.opc in ['umulcc','smulcc']):
168 file.write(' uint32_t icc = ((rd >> 31) & 0x1) << 3;\n')
169 file.write(' uint32_t xcc = ((rd >> 63) & 0x1) << 3;\n')
170 file.write(' if (rd == 0)\n')
171 file.write(' xcc |= 0x4;\n')
172 file.write(' if ((rd & 0xffffffff) == 0)\n')
173 file.write(' icc |= 0x4;\n')
174 file.write(' s->ccr.set((xcc << 4) | icc);\n')
175 elif (self.opc == 'subc'):
176 file.write(' int64_t rd = rs1 - rs2 - (s->ccr.icc() & 0x1);\n')
177 elif (self.opc == 'udivx'):
178 file.write(' uint64_t t1 = *(uint64_t *)&rs1;\n')
179 file.write(' uint64_t t2 = *(uint64_t *)&rs2;\n')
180 file.write(' if (t2 == 0)\n')
181 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::DIVISION_BY_ZERO);\n')
182 file.write(' uint64_t rd = t1 / t2;\n')
183 elif (self.opc in ['udiv','udivcc','sdiv','sdivcc']):
184 if (self.opc in ['udiv','udivcc']):
185 file.write(' uint32_t t1 = rs1;\n')
186 file.write(' uint32_t t2 = rs2;\n')
187 file.write(' uint64_t t3 = s->y();\n')
188 file.write(' t3 = (t3 << 32) + t1;\n')
189 file.write(' if (t2 == 0)\n')
190 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::DIVISION_BY_ZERO);\n')
191 file.write(' uint64_t rd = t3 / t2;\n')
192 file.write(' int overflow = 0;\n')
193 file.write(' if (rd > 0xffffffffllu) {\n')
194 file.write(' rd = 0xffffffffllu;\n')
195 file.write(' overflow = 1;\n')
196 file.write(' }\n')
197 elif (self.opc in ['sdiv','sdivcc']):
198 file.write(' uint32_t t1 = rs1;\n')
199 file.write(' uint32_t t2 = rs2;\n')
200 file.write(' int64_t t3 = ((uint64_t)s->y() << 32) + t1;\n')
201 file.write(' int64_t rd;\n')
202 file.write(' if (t2 == 0)\n')
203 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::DIVISION_BY_ZERO);\n')
204 file.write(' int overflow = 0;\n')
205 file.write(' if ((t3 == 0x8000000000000000ULL) && (t2 == 0xffffffffUL)) {\n')
206 file.write(' rd = 0x7fffffffLL;\n')
207 file.write(' overflow = 1;\n')
208 file.write(' }\n')
209 file.write(' else\n')
210 file.write(' rd = t3 / (int32_t)t2;\n')
211 file.write(' if ((rd > 0LL) && (rd > 0x7fffffffLL)) {\n')
212 file.write(' rd = 0x7fffffffLL;\n')
213 file.write(' overflow = 1;\n')
214 file.write(' }\n')
215 file.write(' else if ((rd < 0LL) && (rd < 0xffffffff80000000LL)) {\n')
216 file.write(' rd = 0xffffffff80000000LL;\n')
217 file.write(' overflow = 1;\n')
218 file.write(' }\n')
219 if (self.opc in ['udivcc','sdivcc']):
220 file.write(' uint32_t icc = ((rd >> 31) & 0x1) << 3;\n')
221 file.write(' uint32_t xcc = ((rd >> 63) & 0x1) << 3;\n')
222 file.write(' if ((rd & 0xffffffff) == 0)\n')
223 file.write(' icc |= 0x4;\n')
224 file.write(' if (rd == 0)\n')
225 file.write(' xcc |= 0x4;\n')
226 file.write(' if (overflow)\n')
227 file.write(' icc |= 0x2;\n')
228 file.write(' s->ccr.set((xcc << 4) | icc);\n')
229 elif (self.opc in ['addcc','addccc','subcc','subccc']):
230 if (self.opc == 'addcc'):
231 file.write(' int64_t rd = rs1 + rs2;\n')
232 elif (self.opc == 'addccc'):
233 file.write(' int64_t rd = rs1 + rs2 + (s->ccr.icc() & 0x1);\n')
234 elif (self.opc == 'subcc'):
235 file.write(' int64_t rd = rs1 - rs2;\n')
236 else:
237 file.write(' int64_t rd = rs1 - rs2 - (s->ccr.icc() & 0x1);\n')
238 if (self.opc in ['addcc','addccc']):
239 file.write(' uint64_t v = (rs1 & rs2 & ~rd) | (~rs1 & ~rs2 & rd);\n')
240 file.write(' uint64_t c = (rs1 & rs2) | (~rd & (rs1 | rs2));\n')
241 else:
242 file.write(' uint64_t v = (rs1 & ~rs2 & ~rd) | (~rs1 & rs2 & rd);\n')
243 file.write(' uint64_t c = (~rs1 & rs2) | (rd & (~rs1 | rs2));\n')
244 file.write(' uint32_t icc = ((v >> 31) & 0x1) << 1;\n')
245 file.write(' uint32_t xcc = ((v >> 63) & 0x1) << 1;\n')
246 file.write(' icc |= ((c >> 31) & 0x1);\n')
247 file.write(' xcc |= ((c >> 63) & 0x1);\n')
248 file.write(' icc |= ((rd >> 31) & 0x1) << 3;\n')
249 file.write(' xcc |= ((rd >> 63) & 0x1) << 3;\n')
250 file.write(' if (rd == 0)\n')
251 file.write(' xcc |= 0x4;\n')
252 file.write(' if ((rd & 0xffffffff) == 0)\n')
253 file.write(' icc |= 0x4;\n')
254 file.write(' s->ccr.set((xcc << 4) | icc);\n')
255 elif (self.opc in ['andcc','orcc','xorcc','andncc','orncc','xnorcc']):
256 if (self.opc == 'andcc'):
257 file.write(' int64_t rd = rs1 & rs2;\n')
258 elif (self.opc == 'orcc'):
259 file.write(' int64_t rd = rs1 | rs2;\n')
260 elif (self.opc == 'xorcc'):
261 file.write(' int64_t rd = rs1 ^ rs2;\n')
262 elif (self.opc == 'andncc'):
263 file.write(' int64_t rd = rs1 & (~rs2);\n')
264 elif (self.opc == 'orncc'):
265 file.write(' int64_t rd = rs1 | (~rs2);\n')
266 elif (self.opc == 'xnorcc'):
267 file.write(' int64_t rd = ~(rs1 ^ rs2);\n')
268 file.write(' uint32_t icc = ((rd >> 31) & 0x1) << 3;\n')
269 file.write(' uint32_t xcc = ((rd >> 63) & 0x1) << 3;\n')
270 file.write(' if (rd == 0)\n')
271 file.write(' xcc |= 0x4;\n')
272 file.write(' if ((rd & 0xffffffff) == 0)\n')
273 file.write(' icc |= 0x4;\n')
274 file.write(' s->ccr.set((xcc << 4) | icc);\n')
275 elif (self.opc == 'mulscc'):
276 file.write(' /* step 1 */\n')
277 file.write(' uint64_t t1 = rs2 & 0xFFFFFFFFLLU;\n')
278 file.write(' /* step 2 */\n')
279 file.write(' uint32_t icc = s->ccr.icc();\n')
280 file.write(' uint32_t t0 = ((icc >> 3) ^ ((icc >> 1) & 1)) << 31;\n')
281 file.write(' uint64_t t2 = rs1 & 0xFFFFFFFFLLU;\n')
282 file.write(' t2 = (t2 >> 1) | t0;\n')
283 file.write(' /* step 3 */\n')
284 file.write(' uint32_t y = s->y();\n')
285 file.write(' uint64_t t3a = (y & 1) ? t1 : 0;\n')
286 file.write(' uint64_t rd = t2 + t3a;\n')
287 file.write(' /* step 5 */\n')
288 file.write(' s->y.set((y >> 1) | ((rs1 & 0x1) << 31));\n')
289 file.write(' /* step 4 */\n')
290 file.write(' uint32_t bit31_rs1 = (t2 >> 31) & 0x1;\n')
291 file.write(' uint32_t bit31_rs2 = (t3a >> 31) & 0x1;\n')
292 file.write(' uint32_t bit31_rd = (rd >> 31) & 0x1;\n')
293 file.write(' icc = bit31_rd << 3;\n')
294 file.write(' if ((rd & 0xffffffff) == 0)\n')
295 file.write(' icc |= 0x4;\n')
296 file.write(' if ((bit31_rs1 & bit31_rs2 & ~bit31_rd) ||\n')
297 file.write(' (~bit31_rs1 & ~bit31_rs2 & bit31_rd))\n')
298 file.write(' icc |= 0x2;\n')
299 file.write(' if ((bit31_rs1 & bit31_rs2) ||\n')
300 file.write(' (~bit31_rd & (bit31_rs1 | bit31_rs2)))\n')
301 file.write(' icc |= 0x1;\n')
302 file.write(' uint32_t xcc = (rd == 0) ? 0x4 : 0;\n')
303 file.write(' s->ccr.set((xcc << 4) | icc);\n')
304 if (out == 'rd'):
305 file.write(' s->get_irf(i->rd) = rd;\n')
306 file.write(' pc = npc;\n')
307 file.write(' s->npc = npc + 4;\n')
308 file.write(' return pc;\n')
309 self.c_code_end(file)
310 file.write('#else\n')
311 file.write('\nextern "C" SS_Vaddr run_exe_'+self.opc+'_'+imm+'_'+out+'( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );\n')
312 file.write('#endif\n\n')
313
314 def run_exe_s(self,file):
315 for out in self.out:
316 for imm in self.imm:
317 self.asm_function(file,'run_exe_'+self.opc+'_'+imm+'_'+out)
318 if self.is_usdiv():
319 self.ld_y(file,'%g4')
320 self.ld_rs1(file,'%g1')
321 if imm == 'i0':
322 self.ld_rs2(file,'%g2')
323 else:
324 self.ld_imm(file,'%g2')
325 self.wr_y(file,'%g4')
326 elif self.is_addci():
327 self.ld_ccr(file,'%g4')
328 self.ld_rs1(file,'%g1')
329 if imm == 'i0':
330 self.ld_rs2(file,'%g2')
331 else:
332 self.ld_imm(file,'%g2')
333 self.wr_ccr(file,'%g4')
334 elif self.is_mulscc():
335 self.ld_y(file,'%g4')
336 self.ld_rs1(file,'%g1')
337 if imm == 'i0':
338 self.ld_rs2(file,'%g2')
339 else:
340 self.ld_imm(file,'%g2')
341 self.wr_y(file,'%g4')
342 self.ld_ccr(file,'%g4')
343 else:
344 self.ld_rs1(file,'%g1')
345 if imm == 'i0':
346 self.ld_rs2(file,'%g2')
347 else:
348 self.ld_imm(file,'%g2')
349
350 if not self.is_div():
351 self.mov(file,self.NPC,self.PC)
352 self.add(file,self.NPC,4,self.NPC)
353
354 self.ld_irf(file,'%g1','%g1')
355 if imm == 'i0':
356 self.ld_irf(file,'%g2','%g2')
357
358 if self.is_mulscc():
359 self.wr_ccr(file,'%g4')
360
361 if not self.is_div():
362 self.st_npc(file,self.NPC)
363
364 if out == 'rd':
365 self.ld_rd(file,'%g3')
366
367 if self.is_div():
368 if self.is_usdiv():
369 self.opr(file,'srl','%g2','0','%g2') # clear rd[63:32]
370 self.branch(file,'rz','%g2','1f')
371 self.nop(file)
372 self.mov(file,self.NPC,self.PC)
373 self.add(file,self.NPC,4,self.NPC)
374 self.st_npc(file,self.NPC)
375
376 self.opr(file,self.opc,'%g1','%g2','%g1')
377 if self.is_cc():
378 self.rd_ccr(file,'%g4')
379
380 if ((setup.product in ['N2']) and self.is_mulscc()):
381 self.opr(file,'srl','%g1','0','%g1') # clear rd[63:32]
382 self.opr(file,'and','%g4','1','%g2') # get icc.c
383 self.opr(file,'sllx','%g2','32','%g2') #
384 self.opr(file,'orcc','%g1','%g2','%g1') # rd[32] = icc.c
385 self.opr(file,'and','%g4','0xf','%g4') # get icc of rd
386 self.rd_ccr(file,'%g2')
387 self.opr(file,'and','%g2','0xf0','%g2') # get xcc of rd
388 self.opr(file,'or','%g4','%g2','%g4') # the combined ccr
389
390 self.st_irf(file,'%g3','%g1')
391 if self.is_usmul() or self.is_mulscc():
392 self.rd_y(file,'%g5')
393 self.st_y(file,'%g5')
394 self.retl(file)
395 self.st_ccr(file,'%g4')
396 elif self.is_usmul():
397 self.rd_y(file,'%g5')
398 self.st_irf(file,'%g3','%g1')
399 self.retl(file)
400 self.st_y(file,'%g5')
401 else:
402 self.retl(file)
403 self.st_irf(file,'%g3','%g1')
404
405 elif self.is_cc(): # rd == %g0
406 if self.is_div():
407 if self.is_usdiv():
408 self.opr(file,'srl','%g2','0','%g2') # clear rd[63:32]
409 self.branch(file,'rz','%g2','1f')
410 self.nop(file)
411 self.mov(file,self.NPC,self.PC)
412 self.add(file,self.NPC,4,self.NPC)
413 self.st_npc(file,self.NPC)
414
415 self.opr(file,self.opc,'%g1','%g2','%g1')
416 self.rd_ccr(file,'%g4')
417
418 if ((setup.product in ['N2']) and self.is_mulscc()):
419 self.opr(file,'srl','%g1','0','%g1') # clear rd[63:32]
420 self.opr(file,'and','%g4','1','%g2') # get icc.c
421 self.opr(file,'sllx','%g2','32','%g2') #
422 self.opr(file,'orcc','%g1','%g2','%g1') # rd[32] = icc.c
423 self.opr(file,'and','%g4','0xf','%g4') # get icc of rd
424 self.rd_ccr(file,'%g2')
425 self.opr(file,'and','%g2','0xf0','%g2') # get xcc of rd
426 self.opr(file,'or','%g4','%g2','%g4') # the combined ccr
427
428 if self.is_usmul() or self.is_mulscc():
429 self.rd_y(file,'%g5')
430 self.st_y(file,'%g5')
431 self.retl(file)
432 self.st_ccr(file,'%g4')
433
434 elif self.is_usmul():
435 self.opr(file,self.opc,'%g1','%g2','%g0')
436 self.rd_y(file,'%g5')
437 self.retl(file)
438 self.st_y(file,'%g5')
439
440 else:
441 if self.is_div():
442 if self.is_usdiv():
443 self.opr(file,'srl','%g2','0','%g2') # clear rd[63:32]
444 self.branch(file,'rz','%g2','1f')
445 self.nop(file)
446 self.mov(file,self.NPC,self.PC)
447 self.add(file,self.NPC,4,self.NPC)
448 self.st_npc(file,self.NPC)
449
450 self.retl(file)
451 self.opr(file,self.opc,'%g1','%g2','%g0')
452
453 if self.is_div():
454 file.write('1:\n')
455 self.ld_trap(file,'%o5')
456 self.jmpl(file,'%o5','%g0','%g0')
457 self.mov(file,'T_DIVISION_BY_ZERO','%o4')
458
459 self.asm_codesize(file,'run_exe_'+self.opc+'_'+imm+'_'+out)
460
461 def run_dec_c(self,file):
462 self.c_code_dec_beg_name(file,'run_dec_'+self.opc)
463 file.write(' i->flg = SS_Instr::NON_LSU;\n')
464 file.write(' if (o.get_i())\n')
465 file.write(' {\n')
466 self.ill_ibe(file)
467 file.write(' if (o.get_rd_irf())\n')
468 self.dec_rr13(file,' ','idx_exe_'+self.opc+'_i0_rd + 1') # i1_rd
469 file.write(' else\n')
470 self.dec_0r13(file,' ','idx_exe_'+self.opc+'_i0_rd + 3') # i1_g0
471 file.write(' }\n')
472 file.write(' else if (o.is_zero_12_5())\n')
473 file.write(' {\n')
474 self.ill_ibe(file)
475 file.write(' if (o.get_rd_irf())\n')
476 self.dec_rrr(file,' ','idx_exe_'+self.opc+'_i0_rd')
477 file.write(' else\n')
478 self.dec_0rr(file,' ','idx_exe_'+self.opc+'_i0_rd + 2') # i0_g0
479 file.write(' }\n')
480 file.write(' else\n')
481 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
482 self.c_code_end(file)
483
484 def exe_idx_s(self,file):
485 for out in self.out:
486 for imm in self.imm:
487 self.exe_idx_s_name(file,self.name+'_'+imm+'_'+out)
488
489 def gen_exe_tbl(self,file,mode):
490 for out in self.out:
491 for imm in self.imm:
492 if mode == 'v8_run':
493 file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+'_'+imm+'_'+out+' */\n')
494 else:
495 self.gen_exe_rrI(file,mode,imm,out)
496
497 def run_dec_p(self):
498 return 'run_dec_%s' % self.opc
499
500 def is_mulscc(self):
501 return self.opc == 'mulscc'
502 def is_usmul(self):
503 return (self.opc == 'umul') or (self.opc == 'smul') or (self.opc == 'umulcc') or (self.opc == 'smulcc')
504 def is_div(self):
505 return self.is_usdiv() or (self.opc == 'udivx') or (self.opc == 'sdivx')
506 def is_usdiv(self):
507 return (self.opc == 'udiv') or (self.opc == 'sdiv') or (self.opc == 'udivcc') or (self.opc == 'sdivcc')
508 def is_addci(self):
509 return (self.opc == 'addc') or (self.opc == 'subc') or (self.opc == 'addccc') or (self.opc == 'subccc')
510 def is_cc(self):
511 return (self.opc[-2:] == 'cc')
512
513#============================================================================
514# SS_sft(opc,imm,out)
515#
516# ToDo: opc to %g0 that don't set %ccr or %y are nop
517# ToDo: (mov) or %g0,src,dst is a frequent used instruction
518# ToDo: (cmp) subcc src,src,%g0 is a frequent used instruction
519# ToDo: These are excelent candidates for some dynamic translation (33% faster)
520#============================================================================
521
522class SS_sft(SS_InstrAsm):
523 def __init__(self,opc,imm):
524 SS_InstrAsm.__init__(self,opc+'_'+imm)
525 self.opc = opc
526 self.imm = imm
527
528 def gen_exe_tbl(self,file,mode):
529 if mode == 'v8_run':
530 file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
531 else:
532 self.gen_exe_rrI(file,mode)
533
534 def run_exe_c(self,file):
535 file.write('#if defined(ARCH_X64)')
536 self.c_code_beg(file,'run_exe_')
537 file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n')
538 if (self.imm == 'i0'):
539 file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
540 else:
541 file.write(' uint64_t rs2 = i->rs2;\n');
542 if (self.opc in ['sll','srl','sra']):
543 file.write(' uint32_t shcnt = rs2 & 0x1f;\n')
544 if (self.opc == 'sll'):
545 file.write(' uint64_t rd = rs1 << shcnt;\n')
546 elif (self.opc == 'srl'):
547 file.write(' uint64_t rd = (rs1 & 0xffffffff) >> shcnt;\n')
548 else:
549 file.write(' int32_t t1 = rs1;\n')
550 file.write(' uint64_t rd = t1 >> shcnt;\n')
551 else:
552 file.write(' uint32_t shcnt = rs2 & 0x3f;\n')
553 if (self.opc == 'sllx'):
554 file.write(' uint64_t rd = rs1 << shcnt;\n')
555 elif (self.opc == 'srlx'):
556 file.write(' uint64_t rd = rs1 >> shcnt;\n')
557 else:
558 file.write(' uint64_t rd = ((int64_t)rs1) >> shcnt;\n')
559 file.write(' s->get_irf(i->rd) = rd;\n')
560 file.write(' pc = npc;\n')
561 file.write(' s->npc = npc + 4;\n')
562 file.write(' return pc;\n')
563 self.c_code_end(file)
564 file.write('#else\n')
565 file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
566 file.write('#endif\n\n')
567
568 def run_exe_s(self,file):
569 self.s_code(file,'run_exe_')
570 self.ld_rs1(file,'%g1')
571 if (self.imm == 'i0'):
572 self.ld_rs2(file,'%g2')
573 else:
574 self.ld_imm(file,'%g2')
575 self.mov(file,self.NPC,self.PC)
576 self.ld_irf(file,'%g1','%g1')
577 if (self.imm == 'i0'):
578 self.ld_irf(file,'%g2','%g2')
579 self.ld_rd(file,'%g3')
580 self.add(file,self.NPC,4,self.NPC)
581 self.opr(file,self.opc,'%g1','%g2','%g1')
582 self.st_npc(file,self.NPC)
583 self.retl(file)
584 self.st_irf(file,'%g3','%g1')
585
586 def run_dec_c(self,file):
587 self.c_code_dec_beg(file,'run_dec_')
588 file.write(' i->flg = SS_Instr::NON_LSU;\n')
589 if self.imm == 'i0':
590 file.write(' if (o.is_zero_11_5())\n')
591 file.write(' {\n')
592 self.ill_ibe(file)
593 file.write(' if (o.get_rd_irf())\n')
594 self.dec_rrr(file,' ','idx_exe_'+self.name)
595 file.write(' else\n')
596 self.dec_000(file,' ','idx_exe_nop')
597 file.write(' }\n')
598 file.write(' else\n')
599 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
600 else:
601 if self.is_x():
602 file.write(' if (o.is_zero_11_6())\n')
603 else:
604 file.write(' if (o.is_zero_11_5())\n')
605 file.write(' {\n')
606 self.ill_ibe(file)
607 file.write(' if (o.get_rd_irf())\n')
608 if self.is_x():
609 self.dec_rr6(file,' ','idx_exe_'+self.name)
610 else:
611 self.dec_rr5(file,' ','idx_exe_'+self.name)
612 file.write(' else\n')
613 self.dec_000(file,' ','idx_exe_nop')
614 file.write(' }\n')
615 file.write(' else\n')
616 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
617 self.c_code_end(file)
618
619 def is_x(self):
620 return len(self.opc) == 4 and self.opc[3] == 'x'
621
622
623#============================================================================
624# SS_tagged_alu(opc)
625#============================================================================
626
627class SS_tagged_alu(SS_InstrAsm):
628 def __init__(self,opc):
629 SS_InstrAsm.__init__(self,opc)
630 self.opc = opc
631 self.imm = ['i0' ,'i1']
632 self.out = ['rd' ,'g0']
633
634 def run_exe_s(self,file):
635 for imm in self.imm:
636 for out in self.out:
637 self.asm_function(file,'run_exe_'+self.opc+'_'+imm+'_'+out)
638 self.ld_rs1(file,'%g1')
639 if imm == 'i0':
640 self.ld_rs2(file,'%g2')
641 else:
642 self.ld_imm(file,'%g2')
643 if out == 'rd':
644 self.ld_rd(file,'%g3')
645 self.ld_irf(file,'%g1','%g1')
646 if imm == 'i0':
647 self.ld_irf(file,'%g2','%g2')
648 self.opr(file,'or','%g1','%g2','%g5')
649 if self.opc[0:6] == 'taddcc':
650 self.opr(file,'addcc','%g1','%g2','%g1')
651 else:
652 self.opr(file,'subcc','%g1','%g2','%g1')
653 self.opr(file,'and','%g5','3','%g5')
654 self.movr(file,'nz','%g5','2','%g5')
655 self.rd_ccr(file,'%g4')
656 self.opr(file,'or','%g4','%g5','%g4')
657 if self.opc[-2:] == 'tv':
658 self.opr(file,'and','%g4','2','%g2')
659 file.write('\tbrz\t%g2,1f\n')
660 file.write('\tnop\n')
661 self.ld_trap(file,'%o5')
662 self.jmpl(file,'%o5','%g0','%g0')
663 self.mov(file,'T_TAG_OVERFLOW','%o4')
664 file.write('1:\n')
665 self.mov(file,self.NPC,self.PC)
666 self.add(file,self.NPC,4,self.NPC)
667 self.st_npc(file,self.NPC)
668 if out == 'rd':
669 self.st_irf(file,'%g3','%g1')
670 self.retl(file)
671 self.st_ccr(file,'%g4')
672
673 def run_exe_c(self,file):
674 for imm in self.imm:
675 for out in self.out:
676 file.write('#if defined(ARCH_X64)\n')
677 self.c_code_beg_name(file,'run_exe_'+self.opc+'_'+imm+'_'+out)
678 file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n')
679 if (imm == 'i0'):
680 file.write(' int64_t rs2 = s->get_irf(i->rs2);\n')
681 else:
682 file.write(' int64_t rs2 = i->rs2;\n');
683 if (self.opc in ['taddcc','taddcctv']):
684 file.write(' uint64_t rd = rs1 + rs2;\n')
685 file.write(' uint64_t v = (rs1 & rs2 & ~rd) | (~rs1 & ~rs2 & rd);\n')
686 file.write(' uint64_t c = (rs1 & rs2) | (~rd & (rs1 | rs2));\n')
687 else:
688 file.write(' uint64_t rd = rs1 - rs2;\n')
689 file.write(' uint64_t v = (rs1 & ~rs2 & ~rd) | (~rs1 & rs2 & rd);\n')
690 file.write(' uint64_t c = (~rs1 & rs2) | (rd & (~rs1 | rs2));\n')
691 file.write(' uint32_t icc = ((rd >> 31) & 0x1) << 3;\n')
692 file.write(' uint32_t xcc = ((rd >> 63) & 0x1) << 3;\n')
693 file.write(' if ((rd & 0xffffffff) == 0)\n')
694 file.write(' icc |= 0x4;\n')
695 file.write(' if (rd == 0)\n')
696 file.write(' xcc |= 0x4;\n')
697 file.write(' icc |= ((v >> 31) & 0x1) << 1;\n')
698 file.write(' if ((rs1 | rs2) & 0x3)\n')
699 file.write(' icc |= 0x2;\n')
700 file.write(' xcc |= ((v >> 63) & 0x1) << 1;\n')
701 file.write(' icc |= (c >> 31) & 0x1;\n')
702 file.write(' xcc |= (c >> 63) & 0x1;\n')
703 if (self.opc in ['taddcctv','tsubcctv']):
704 file.write(' if (icc & 0x2)\n')
705 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::TAG_OVERFLOW);\n')
706 file.write(' s->ccr.set((xcc << 4) | icc);\n')
707 if (out == 'rd'):
708 file.write(' s->get_irf(i->rd) = rd;\n')
709 file.write(' pc = npc;\n')
710 file.write(' s->npc = npc + 4;\n')
711 file.write(' return pc;\n')
712 self.c_code_end(file)
713 file.write('#else\n')
714 file.write('extern "C" SS_Vaddr run_exe_'+self.opc+'_'+imm+'_'+out+'( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );\n')
715 file.write('#endif\n\n')
716
717 def run_dec_c(self,file):
718 self.c_code_dec_beg_name(file,'run_dec_'+self.opc)
719 file.write(' i->flg = SS_Instr::NON_LSU;\n')
720 file.write(' if (o.get_i())\n')
721 file.write(' {\n')
722 self.ill_ibe(file)
723 file.write(' if (o.get_rd_irf())\n')
724 self.dec_rr13(file,' ','idx_exe_'+self.opc+'_i1_rd')
725 file.write(' else\n')
726 self.dec_0r13(file,' ','idx_exe_'+self.opc+'_i1_g0')
727 file.write(' }\n')
728 file.write(' else if (o.is_zero_12_5())\n')
729 file.write(' {\n')
730 self.ill_ibe(file)
731 file.write(' if (o.get_rd_irf())\n')
732 self.dec_rrr(file,' ','idx_exe_'+self.opc+'_i0_rd')
733 file.write(' else\n')
734 self.dec_0rr(file,' ','idx_exe_'+self.opc+'_i0_g0')
735 file.write(' }\n')
736 file.write(' else\n')
737 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
738 self.c_code_end(file)
739
740 def exe_idx_s(self,file):
741 for imm in self.imm:
742 for out in self.out:
743 self.exe_idx_s_name(file,self.name+'_'+imm+'_'+out)
744
745 def gen_exe_tbl(self,file,mode):
746 for out in self.out:
747 for imm in self.imm:
748 if mode == 'v8_run':
749 file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+'_'+imm+'_'+out+' */\n')
750 else:
751 self.gen_exe_rrI(file,mode,imm,out)
752
753 def run_dec_p(self):
754 return 'run_dec_%s' % self.opc
755
756
757#============================================================================
758# SS_mov(cc,ccr,imm)
759#
760# ToDo: movn & mova can be optimised
761#============================================================================
762
763class SS_movcc(SS_InstrAsm):
764 def __init__(self,cc,ccr,imm):
765 SS_InstrAsm.__init__(self,'mov'+cc+'_'+ccr+'_'+imm)
766 self.opc = 'mov'+cc
767 self.cc = cc
768 self.ccr = ccr
769 self.imm = imm
770
771 def gen_exe_tbl(self,file,mode):
772 if mode == 'v8_run':
773 file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
774 else:
775 self.gen_exe_rrI(file,mode)
776
777 def run_exe_c(self,file):
778 file.write('#if defined(ARCH_X64)\n')
779 self.c_code_beg(file,'run_exe_')
780 if (self.ccr[:3] == 'fcc'):
781 file.write(' if (s->sim_state.fp_disabled())\n')
782 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n')
783 if (self.ccr[:3] == 'fcc'):
784 self.test_fcc(file,' ')
785 else:
786 self.test_icc(file,' ')
787 file.write(' {\n')
788 if (self.imm == 'i0'):
789 file.write(' int64_t rs2 = s->get_irf(i->rs2);\n')
790 else:
791 file.write(' int64_t rs2 = i->rs2;\n');
792 file.write(' s->get_irf(i->rd) = rs2;\n')
793 file.write(' }\n')
794 file.write(' pc = npc;\n')
795 file.write(' s->npc = npc + 4;\n')
796 file.write(' return pc;\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\n')
801
802 def run_exe_s(self,file):
803 self.s_code(file,'run_exe_')
804 if self.ccr[:3] == 'fcc':
805 self.ld_sim(file,'%g5')
806 self.st_fsr_cpu(file,'%fsr')
807 if self.imm == 'i0':
808 self.ld_rs2(file,'%g2')
809 else:
810 self.ld_imm(file,'%g2')
811 self.ld_rd(file,'%g3')
812 self.andcc(file,'%g5','F_FP_DISABLED','%g0')
813 self.branch(file,'ne','%xcc','fpop_disabled_trap_fsr')
814 self.ld_fsr_run(file,'%fsr')
815 self.mov(file,self.NPC,self.PC)
816 if self.imm == 'i0':
817 self.ld_irf(file,'%g2','%g2')
818 self.add(file,self.NPC,4,self.NPC)
819 self.ld_irf(file,'%g3','%g4')
820 self.st_npc(file,self.NPC)
821 self.movcc(file,self.cc,'%'+self.ccr,'%g2','%g4')
822 self.st_irf(file,'%g3','%g4')
823 self.retl(file)
824 self.ld_fsr_cpu(file,'%fsr')
825 else:
826 self.mov(file,self.NPC,self.PC)
827 if self.imm == 'i0':
828 self.ld_rs2(file,'%g2')
829 else:
830 self.ld_imm(file,'%g2')
831 self.ld_rd(file,'%g3')
832 self.add(file,self.NPC,4,self.NPC)
833 self.st_npc(file,self.NPC)
834 self.ld_ccr(file,'%g1')
835 if self.imm == 'i0':
836 self.ld_irf(file,'%g2','%g2')
837 self.ld_irf(file,'%g3','%g4')
838 self.wr_ccr(file,'%g1')
839 self.movcc(file,self.cc,'%'+self.ccr,'%g2','%g4')
840 self.retl(file)
841 self.st_irf(file,'%g3','%g4')
842
843 def run_dec_c(self,file):
844 self.c_code_dec_beg(file,'run_dec_')
845 file.write(' i->flg = SS_Instr::NON_LSU;\n')
846 if self.imm == 'i1':
847 self.ill_ibe(file)
848 file.write(' if (o.get_rd_irf())\n')
849 self.dec_rr11(file,' ','idx_exe_'+self.name)
850 file.write(' else\n')
851 self.dec_000(file,' ','idx_exe_nop')
852 else:
853 file.write(' if (o.is_zero_10_5())\n')
854 file.write(' {\n')
855 self.ill_ibe(file)
856 file.write(' if (o.get_rd_irf())\n')
857 self.dec_rrr(file,' ','idx_exe_'+self.name)
858 file.write(' else\n')
859 self.dec_000(file,' ','idx_exe_nop')
860 file.write(' }\n')
861 file.write(' else\n')
862 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
863 self.c_code_end(file)
864
865
866#============================================================================
867# SS_movr(cc,imm)
868#============================================================================
869
870class SS_movr(SS_InstrAsm):
871 def __init__(self,cc,imm):
872 SS_InstrAsm.__init__(self,'movr'+cc+'_'+imm)
873 self.opc = 'movr'+cc
874 self.cc = cc
875 self.imm = imm
876
877 def run_exe_c(self,file):
878 file.write('#if defined(ARCH_X64)\n')
879 self.c_code_beg(file,'run_exe_')
880 self.test_r(file,' ')
881 file.write(' {\n')
882 if (self.imm == 'i0'):
883 file.write(' int64_t rs2 = s->get_irf(i->rs2);\n')
884 else:
885 file.write(' int64_t rs2 = i->rs2;\n');
886 file.write(' s->get_irf(i->rd) = rs2;\n')
887 file.write(' }\n')
888 file.write(' pc = npc;\n')
889 file.write(' s->npc = npc + 4;\n')
890 file.write(' return pc;\n')
891 self.c_code_end(file)
892 file.write('#else\n')
893 file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
894 file.write('#endif\n\n')
895
896 def run_exe_s(self,file):
897 self.s_code(file,'run_exe_')
898 self.mov(file,self.NPC,self.PC)
899 self.ld_rs1(file,'%g1')
900 if self.imm == 'i0':
901 self.ld_rs2(file,'%g2')
902 else:
903 self.ld_imm(file,'%g2')
904 self.ld_rd(file,'%g3')
905 self.add(file,self.NPC,4,self.NPC)
906 self.st_npc(file,self.NPC)
907 self.ld_irf(file,'%g1','%g1')
908 if self.imm == 'i0':
909 self.ld_irf(file,'%g2','%g2')
910 self.ld_irf(file,'%g3','%g4')
911 self.movr(file,self.cc,'%g1','%g2','%g4')
912 self.retl(file)
913 self.st_irf(file,'%g3','%g4')
914
915 def run_dec_c(self,file):
916 self.c_code_dec_beg(file,'run_dec_')
917 file.write(' i->flg = SS_Instr::NON_LSU;\n')
918 if self.imm == 'i1':
919 self.ill_ibe(file)
920 file.write(' if (o.get_rd_irf())\n')
921 self.dec_rr10(file,' ','idx_exe_'+self.name)
922 file.write(' else\n')
923 self.dec_000(file,' ','idx_exe_nop')
924 else:
925 file.write(' if (o.is_zero_9_5())\n')
926 file.write(' {\n')
927 self.ill_ibe(file)
928 file.write(' if (o.get_rd_irf())\n')
929 self.dec_rrr(file,' ','idx_exe_'+self.name)
930 file.write(' else\n')
931 self.dec_000(file,' ','idx_exe_nop')
932 file.write(' }\n')
933 file.write(' else\n')
934 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
935 self.c_code_end(file)
936
937 def gen_exe_tbl(self,file,mode):
938 if mode == 'v8_run':
939 file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
940 else:
941 self.gen_exe_rrI(file,mode)
942
943
944#============================================================================
945# SS_save()
946#============================================================================
947
948class SS_save(SS_InstrCpp):
949 def __init__(self):
950 SS_InstrCpp.__init__(self,'save')
951 self.opc = 'save'
952 self.imm = ['i0','i1']
953 self.out = ['rd','g0']
954
955 def run_exe_c(self,file):
956 for imm in self.imm:
957 for out in self.out:
958 self.c_code_beg_name(file,'run_exe_'+self.name+'_'+imm+'_'+out)
959 self.fail_chkpt(file)
960 file.write('uint64_t cansave = s->cansave();')
961 file.write('uint64_t cwp = s->cwp();')
962 file.write(' if (cansave == 0)\n')
963 file.write(' {\n')
964 file.write(' if (s->otherwin())\n')
965 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::spill_other(s->wstate.other()));\n')
966 file.write(' else\n')
967 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::spill_normal(s->wstate.normal()));\n')
968 file.write(' }\n')
969 file.write(' else if ((s->cleanwin() - s->canrestore()) == 0)\n')
970 file.write(' {\n')
971 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CLEAN_WINDOW);\n')
972 file.write(' }\n')
973 file.write(' else\n')
974 file.write(' {\n')
975 if out == 'g0':
976 file.write(' s->do_save_inst();\n')
977 elif imm == 'i0':
978 file.write(' uint64_t val = s->get_irf(i->rs1) + s->get_irf(i->rs2);\n')
979 file.write(' s->do_save_inst();\n')
980 file.write(' s->get_irf(i->rd) = val;\n')
981 else:
982 file.write(' uint64_t val = s->get_irf(i->rs1) + i->rs2;\n')
983 file.write(' s->do_save_inst();\n')
984 file.write(' s->get_irf(i->rd) = val;\n')
985 file.write(' s->npc = npc+4;\n')
986 file.write(' return npc;\n')
987 file.write(' }\n')
988 file.write('}\n\n')
989
990 def run_dec_c(self,file):
991 self.c_code_dec_beg(file,'run_dec_')
992 file.write(' i->flg = SS_Instr::NON_LSU;\n')
993 file.write(' if (o.get_i())\n')
994 file.write(' {\n')
995 self.ill_ibe(file)
996 file.write(' if (o.get_rd_irf())\n')
997 self.dec_rr13(file,' ','idx_exe_'+self.name+'_i1_rd')
998 file.write(' else\n')
999 self.dec_0r13(file,' ','idx_exe_'+self.name+'_i1_g0')
1000 file.write(' }\n')
1001 file.write(' else if (o.is_zero_12_5())\n')
1002 file.write(' {\n')
1003 self.ill_ibe(file)
1004 file.write(' if (o.get_rd_irf())\n')
1005 self.dec_rrr(file,' ','idx_exe_'+self.name+'_i0_rd')
1006 file.write(' else\n')
1007 self.dec_0rr(file,' ','idx_exe_'+self.name+'_i0_g0')
1008 file.write(' }\n')
1009 file.write(' else\n')
1010 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
1011 self.c_code_end(file)
1012
1013 def exe_idx_s(self,file):
1014 for imm in self.imm:
1015 for out in self.out:
1016 self.exe_idx_s_name(file,self.name+'_'+imm+'_'+out)
1017
1018 def gen_exe_tbl(self,file,mode):
1019 if mode == 'v8_run':
1020 mode = 'run'
1021 for imm in self.imm:
1022 for out in self.out:
1023 self.gen_exe_rrI(file,mode,imm,out)
1024
1025
1026#============================================================================
1027# SS_restore()
1028#============================================================================
1029
1030class SS_restore(SS_InstrCpp):
1031 def __init__(self):
1032 SS_InstrCpp.__init__(self,'restore')
1033 self.opc = 'restore'
1034 self.imm = ['i0','i1']
1035 self.out = ['rd','g0']
1036
1037 def run_exe_c(self,file):
1038 for imm in self.imm:
1039 for out in self.out:
1040 self.c_code_beg_name(file,'run_exe_'+self.name+'_'+imm+'_'+out)
1041 self.fail_chkpt(file)
1042 file.write(' if (s->canrestore())\n')
1043 file.write(' {\n')
1044 if out == 'g0':
1045 file.write(' s->do_restore_inst();\n')
1046
1047 elif imm == 'i0':
1048 file.write(' uint64_t val = s->get_irf(i->rs1) + s->get_irf(i->rs2);\n')
1049 file.write(' s->do_restore_inst();\n')
1050 file.write(' s->get_irf(i->rd) = val;\n')
1051 else:
1052 file.write(' uint64_t val = s->get_irf(i->rs1) + i->rs2;\n')
1053 file.write(' s->do_restore_inst();\n')
1054 file.write(' s->get_irf(i->rd) = val;\n')
1055
1056 file.write(' s->npc = npc+4;\n')
1057 file.write(' return npc;\n')
1058 file.write(' }\n')
1059 file.write(' else if (s->otherwin())\n')
1060 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::fill_other(s->wstate.other()));\n')
1061 file.write(' else\n')
1062 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::fill_normal(s->wstate.normal()));\n')
1063 file.write('}\n\n')
1064
1065 def run_dec_c(self,file):
1066 self.c_code_dec_beg(file,'run_dec_')
1067 file.write(' i->flg = SS_Instr::NON_LSU;\n')
1068 file.write(' if (o.get_i())\n')
1069 file.write(' {\n')
1070 self.ill_ibe(file)
1071 file.write(' if (o.get_rd_irf())\n')
1072 self.dec_rr13(file,' ','idx_exe_'+self.name+'_i1_rd')
1073 file.write(' else\n')
1074 self.dec_0r13(file,' ','idx_exe_'+self.name+'_i1_g0')
1075 file.write(' }\n')
1076 file.write(' else if (o.is_zero_12_5())\n')
1077 file.write(' {\n')
1078 self.ill_ibe(file)
1079 file.write(' if (o.get_rd_irf())\n')
1080 self.dec_rrr(file,' ','idx_exe_'+self.name+'_i0_rd')
1081 file.write(' else\n')
1082 self.dec_0rr(file,' ','idx_exe_'+self.name+'_i0_g0')
1083 file.write(' }\n')
1084 file.write(' else\n')
1085 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
1086 self.c_code_end(file)
1087
1088 def exe_idx_s(self,file):
1089 for imm in self.imm:
1090 for out in self.out:
1091 self.exe_idx_s_name(file,self.name+'_'+imm+'_'+out)
1092
1093 def gen_exe_tbl(self,file,mode):
1094 if mode == 'v8_run':
1095 mode = 'run'
1096 for imm in self.imm:
1097 for out in self.out:
1098 self.gen_exe_rrI(file,mode,imm,out)
1099
1100#============================================================================
1101# SS_110001()
1102#============================================================================
1103
1104class SS_110001(SS_InstrCpp):
1105 def __init__(self,name):
1106 SS_InstrCpp.__init__(self,name)
1107
1108 def run_dec_c(self,file):
1109 self.c_code_dec_beg(file,'run_dec_')
1110 file.write(' i->flg = SS_Instr::NON_LSU;\n')
1111 file.write(' if (o.is_zero_18_0())\n')
1112 file.write(' {\n')
1113 self.ill_ibe(file)
1114 self.dec_000(file,' ','idx_exe_'+self.name)
1115 file.write(' }\n')
1116 file.write(' else\n')
1117 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
1118 self.c_code_end(file)
1119
1120
1121#============================================================================
1122# SS_saved()
1123#============================================================================
1124
1125class SS_saved(SS_110001):
1126 def __init__(self):
1127 SS_110001.__init__(self,'saved')
1128
1129 def run_exe_c(self,file):
1130 self.c_code_beg_name(file,'run_exe_'+self.name)
1131 file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n')
1132 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n')
1133 file.write(' else\n')
1134 file.write(' {\n')
1135 file.write(' s->cansave = (s->cansave() < s->max_wp()) ? (s->cansave() + 1) : 0;\n')
1136 file.write(' if (s->otherwin())\n')
1137 file.write(' s->otherwin = s->otherwin() - 1;\n')
1138 file.write(' else\n')
1139 file.write(' s->canrestore = s->canrestore() ? (s->canrestore() - 1) : s->max_wp();\n')
1140 file.write(' s->npc = npc+4; return npc;\n')
1141 file.write(' }\n')
1142 file.write('}\n\n')
1143
1144 def gen_exe_tbl(self,file,mode):
1145 self.gen_exe_passthrough(file,mode)
1146
1147#============================================================================
1148# SS_restored()
1149#============================================================================
1150
1151class SS_restored(SS_110001):
1152 def __init__(self):
1153 SS_110001.__init__(self,'restored')
1154
1155 def run_exe_c(self,file):
1156 self.c_code_beg_name(file,'run_exe_'+self.name)
1157 file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n')
1158 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n')
1159 file.write(' else\n')
1160 file.write(' {\n')
1161 file.write(' s->canrestore = (s->canrestore() < s->max_wp()) ? (s->canrestore() + 1) : 0;\n')
1162 file.write(' if (s->otherwin())\n')
1163 file.write(' s->otherwin = s->otherwin() - 1;\n')
1164 file.write(' else\n')
1165 file.write(' s->cansave = s->cansave() ? (s->cansave() - 1) : s->max_wp();\n')
1166 file.write(' if (s->cleanwin() < s->max_wp())\n')
1167 file.write(' s->cleanwin = s->cleanwin() + 1;\n')
1168 file.write(' s->npc = npc+4; return npc;\n')
1169 file.write(' }\n')
1170 file.write('}\n\n')
1171
1172 def gen_exe_tbl(self,file,mode):
1173 self.gen_exe_passthrough(file,mode)
1174
1175#============================================================================
1176# SS_allclean()
1177#============================================================================
1178
1179class SS_allclean(SS_110001):
1180 def __init__(self):
1181 SS_110001.__init__(self,'allclean')
1182
1183 def run_exe_c(self,file):
1184 self.c_code_beg_name(file,'run_exe_'+self.name)
1185 file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n')
1186 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n')
1187 file.write(' else\n')
1188 file.write(' {\n')
1189 file.write(' s->cleanwin = s->max_wp();\n')
1190 file.write(' s->npc = npc+4; return npc;\n')
1191 file.write(' }\n')
1192 file.write('}\n\n')
1193
1194 def gen_exe_tbl(self,file,mode):
1195 self.gen_exe_passthrough(file,mode)
1196
1197#============================================================================
1198# SS_otherw()
1199#============================================================================
1200
1201class SS_otherw(SS_110001):
1202 def __init__(self):
1203 SS_110001.__init__(self,'otherw')
1204
1205 def run_exe_c(self,file):
1206 self.c_code_beg_name(file,'run_exe_'+self.name)
1207 file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n')
1208 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n')
1209 file.write(' else\n')
1210 file.write(' {\n')
1211 file.write(' s->otherwin = s->canrestore();\n')
1212 file.write(' s->canrestore = 0;\n')
1213 file.write(' s->npc = npc+4; return npc;\n')
1214 file.write(' }\n')
1215 file.write('}\n\n')
1216
1217 def gen_exe_tbl(self,file,mode):
1218 self.gen_exe_passthrough(file,mode)
1219
1220
1221#============================================================================
1222# SS_normalw()
1223#============================================================================
1224
1225class SS_normalw(SS_110001):
1226 def __init__(self):
1227 SS_110001.__init__(self,'normalw')
1228
1229 def run_exe_c(self,file):
1230 self.c_code_beg_name(file,'run_exe_'+self.name)
1231 file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n')
1232 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n')
1233 file.write(' else\n')
1234 file.write(' {\n')
1235 file.write(' s->canrestore = s->otherwin();\n')
1236 file.write(' s->otherwin = 0;\n')
1237 file.write(' s->npc = npc+4; return npc;\n')
1238 file.write(' }\n')
1239 file.write('}\n\n')
1240
1241 def gen_exe_tbl(self,file,mode):
1242 self.gen_exe_passthrough(file,mode)
1243
1244#============================================================================
1245# SS_invalw()
1246#============================================================================
1247
1248class SS_invalw(SS_110001):
1249 def __init__(self):
1250 SS_110001.__init__(self,'invalw')
1251
1252 def run_exe_c(self,file):
1253 self.c_code_beg_name(file,'run_exe_'+self.name)
1254 file.write(' if (s->sim_state.priv() == SS_Strand::SS_USER)\n')
1255 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n')
1256 file.write(' else\n')
1257 file.write(' {\n')
1258 file.write(' s->cansave = s->max_wp() - 1;\n')
1259 file.write(' s->canrestore = 0;\n')
1260 file.write(' s->otherwin = 0;\n')
1261 file.write(' s->npc = npc+4; return npc;\n')
1262 file.write(' }\n')
1263 file.write('}\n\n')
1264
1265 def gen_exe_tbl(self,file,mode):
1266 self.gen_exe_passthrough(file,mode)
1267
1268#============================================================================
1269# SS_flushw()
1270#============================================================================
1271
1272class SS_flushw(SS_InstrCpp):
1273 def __init__(self):
1274 SS_InstrCpp.__init__(self,'flushw')
1275
1276 def run_exe_c(self,file):
1277 self.c_code_beg_name(file,'run_exe_'+self.name)
1278 file.write(' if (s->cansave() == (s->max_wp() - 1))\n')
1279 file.write(' { s->npc = npc+4; return npc; }\n')
1280 file.write(' else if (s->otherwin())\n')
1281 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::spill_other(s->wstate.other()));\n')
1282 file.write(' else\n')
1283 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::spill_normal(s->wstate.normal()));\n')
1284 file.write('}\n\n')
1285
1286 def run_dec_c(self,file):
1287 self.c_code_dec_beg(file,'run_dec_')
1288 file.write(' i->flg = SS_Instr::NON_LSU;\n')
1289 file.write(' if (o.is_zero_18_0() && o.get_rd() == 0)\n')
1290 file.write(' {\n')
1291 self.ill_ibe(file)
1292 self.dec_000(file,' ','idx_exe_flushw')
1293 file.write(' }\n')
1294 file.write(' else\n')
1295 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
1296 self.c_code_end(file)
1297
1298 def gen_exe_tbl(self,file,mode):
1299 self.gen_exe_passthrough(file,mode)
1300
1301
1302#============================================================================
1303# SS_popc
1304#============================================================================
1305
1306class SS_popc(SS_InstrAsm):
1307 def __init__(self):
1308 SS_InstrAsm.__init__(self,'popc')
1309 self.imm = ['i0' ,'i1']
1310 self.out = ['rd' ,'g0']
1311
1312 def run_exe_c(self,file):
1313 for imm in self.imm:
1314 self.c_code_beg_name(file,'run_exe_'+self.name+'_'+imm)
1315 if imm == 'i0':
1316 file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
1317 else:
1318 file.write(' uint64_t rs2 = int64_t(i->rs2);\n')
1319 file.write(' uint64_t n = 0;\n')
1320 file.write(' for (int i=0; rs2 && i < 64; i++)\n')
1321 file.write(' {\n')
1322 file.write(' n += (rs2 & 1);\n')
1323 file.write(' rs2 >>= 1;\n')
1324 file.write(' }\n')
1325 file.write(' s->get_irf(i->rd) = n;\n')
1326 file.write(' s->npc = npc+4;\n')
1327 file.write(' return npc;\n')
1328 file.write('}\n\n')
1329
1330 def run_dec_c(self,file):
1331 self.c_code_dec_beg_name(file,'run_dec_'+self.name)
1332 file.write(' i->flg = SS_Instr::NON_LSU;\n')
1333 file.write(' if (o.get_rs1())\n')
1334 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
1335 file.write(' else if (o.get_i())\n')
1336 file.write(' {\n')
1337 self.ill_ibe(file)
1338 file.write(' if (o.get_rd_irf())\n')
1339 self.dec_r013(file,' ','idx_exe_'+self.name+'_i1') # i1_rd
1340 file.write(' else\n')
1341 self.dec_000(file,' ','idx_exe_nop') # i1_g0
1342 file.write(' }\n')
1343 file.write(' else if (o.is_zero_12_5())\n')
1344 file.write(' {\n')
1345 self.ill_ibe(file)
1346 file.write(' if (o.get_rd_irf())\n')
1347 self.dec_r0r(file,' ','idx_exe_'+self.name+'_i0')
1348 file.write(' else\n')
1349 self.dec_000(file,' ','idx_exe_nop') # i0_g0
1350 file.write(' }\n')
1351 file.write(' else\n')
1352 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
1353 self.c_code_end(file)
1354
1355 def exe_idx_s(self,file):
1356 for imm in self.imm:
1357 self.exe_idx_s_name(file,self.name+'_'+imm)
1358
1359 def gen_exe_tbl(self,file,mode):
1360 for imm in self.imm:
1361 if mode == 'trc':
1362 if self.imm == 'i0':
1363 file.write(' trc_exe_r0r, /* '+self.name+'_'+imm+' */\n')
1364 else:
1365 file.write(' trc_exe_r00, /* '+self.name+'_'+imm+' */\n')
1366 elif mode == 'v8_run':
1367 file.write(' run_exe_'+self.name+'_'+imm+',\n')
1368 else:
1369 file.write(' '+mode+'_exe_'+self.name+'_'+imm+',\n')
1370
1371 def run_dec_p(self):
1372 return 'run_dec_%s' % self.name
1373
1374
1375#============================================================================
1376#============================================================================
1377# sll, srl, sra
1378
1379ss_sll = SS_InstrGroup('10_100101_sll',12,3)
1380ss_srl = SS_InstrGroup('10_100110_srl',12,3)
1381ss_sra = SS_InstrGroup('10_100111_sra',12,3)
1382
1383ss_sll.append(SS_sft('sll','i0'))
1384ss_sll.append(SS_sft('sllx','i0'))
1385ss_sll.append(SS_sft('sll','i1'))
1386ss_sll.append(SS_sft('sllx','i1'))
1387
1388ss_srl.append(SS_sft('srl','i0'))
1389ss_srl.append(SS_sft('srlx','i0'))
1390ss_srl.append(SS_sft('srl','i1'))
1391ss_srl.append(SS_sft('srlx','i1'))
1392
1393ss_sra.append(SS_sft('sra','i0'))
1394ss_sra.append(SS_sft('srax','i0'))
1395ss_sra.append(SS_sft('sra','i1'))
1396ss_sra.append(SS_sft('srax','i1'))
1397
1398# movcc
1399
1400ss_movcc = SS_InstrGroup('10_101100_movcc',11,0xff)
1401for cc,x in fcond:
1402 ss_movcc.append(SS_movcc(cc,'fcc0','i0'))
1403 ss_movcc.append(SS_movcc(cc,'fcc1','i0'))
1404 ss_movcc.append(SS_movcc(cc,'fcc2','i0'))
1405 ss_movcc.append(SS_movcc(cc,'fcc3','i0'))
1406 ss_movcc.append(SS_movcc(cc,'fcc0','i1'))
1407 ss_movcc.append(SS_movcc(cc,'fcc1','i1'))
1408 ss_movcc.append(SS_movcc(cc,'fcc2','i1'))
1409 ss_movcc.append(SS_movcc(cc,'fcc3','i1'))
1410for cc,x in cond:
1411 ss_movcc.append(SS_movcc(cc,'icc','i0'))
1412 ss_movcc.append(SS_ill())
1413 ss_movcc.append(SS_movcc(cc,'xcc','i0'))
1414 ss_movcc.append(SS_ill())
1415 ss_movcc.append(SS_movcc(cc,'icc','i1'))
1416 ss_movcc.append(SS_ill())
1417 ss_movcc.append(SS_movcc(cc,'xcc','i1'))
1418 ss_movcc.append(SS_ill())
1419
1420# movr
1421
1422ss_movr = SS_InstrGroup('10_101111_movr',10,0xf)
1423for cc,x in rcond8:
1424 if (cc != ''):
1425 ss_movr.append(SS_movr(cc,'i0'))
1426 else:
1427 ss_movr.append(SS_ill())
1428for cc,x in rcond8:
1429 if (cc != ''):
1430 ss_movr.append(SS_movr(cc,'i1'))
1431 else:
1432 ss_movr.append(SS_ill())
1433
1434# saved/restored
1435
1436ss_saved = SS_InstrGroup('10_110001_saved',25,0x1f)
1437ss_saved.append(SS_saved())
1438ss_saved.append(SS_restored())
1439ss_saved.append(SS_allclean())
1440ss_saved.append(SS_otherw())
1441ss_saved.append(SS_normalw())
1442ss_saved.append(SS_invalw())
1443for i in range(0,26):
1444 ss_saved.append(SS_ill())