Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / bin / SS_InstrLsu.py
CommitLineData
920dae64
AT
1# ========== Copyright Header Begin ==========================================
2#
3# OpenSPARC T2 Processor File: SS_InstrLsu.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
22from SS_Instr import *
23from SS_Instr import _if_
24from SS_Setup import *
25
26setup = setups[sys.argv[1]]
27
28#============================================================================
29# SS_lsu_exe(opc)
30#============================================================================
31
32class SS_lsu_exe(SS_InstrAsm):
33 def __init__(self,opc):
34 SS_InstrAsm.__init__(self,opc)
35 self.opc = opc
36 self.asi = ['dft', 'reg', 'imm']
37 self.imm = ['i0' ,'i1']
38 self.out = ['rd' ,'g0', 'ia']
39
40 def is_float(self):
41 return self.opc == 'ldf' or self.opc == 'lddf' or self.opc == 'stf' or self.opc == 'stdf' or \
42 self.opc[2:7] == 'short' or self.opc[2:7] == 'block' or self.opc[2:7] == 'parti' or \
43 self.opc[-3:] == 'fsr'
44
45 def is_sgl_fp(self):
46 '''
47 Is load or store a simple single precision FP operation
48 '''
49 return self.opc == 'ldf' or self.opc == 'stf'
50
51 def is_dbl_fp(self):
52 '''
53 Is load or store a simple double precision FP operation
54 '''
55 return self.opc == 'lddf' or self.opc == 'stdf'
56
57 def is_atomic(self):
58 return self.opc[:6] == 'ldstub' or self.opc[:4] == 'swap' or self.opc[:3] == 'cas'
59
60 def run_exe_c(self,file):
61 for asi in self.asi:
62 for out in self.out:
63
64 if self.is_float() or self.opc == 'prefetch' or self.opc == 'flush':
65 if out == 'g0':
66 continue
67 if out == 'rd':
68 if self.is_float():
69 out = 'fp'
70 else:
71 out = 'fn'
72
73 # ldfsr, stfsr, ldxfsr, stxfsr, and ldxefsr don't have alternative space versions
74 if self.opc[-3:] == 'fsr' and asi != 'dft':
75 continue
76
77 for imm in self.imm:
78 file.write('#if defined(ARCH_X64)\n')
79 self.c_code_beg_name(file,'run_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out)
80 if out == 'rd' or out == 'g0' or out == 'fp' or out == 'fn':
81 alignment=self.va_lower_bits()
82 mmu_access = not (self.opc == 'flush')
83 if out == 'fp':
84 file.write(' if (s->sim_state.fp_disabled())\n')
85 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n')
86 if asi=='reg':
87 file.write(' if (i->asi != s->asi())\n')
88 file.write(' return (s->inst_dec)(pc,npc,s,i);\n')
89 if (self.opc[:3] == 'cas'):
90 file.write(' uint64_t ea = s->get_irf(i->rs1);\n')
91 elif (self.opc == 'stpartial8'):
92 file.write(' uint64_t ea = s->get_irf(i->rs1);\n')
93 file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
94 file.write(' s->mem_mask = rs2 & 0xff;\n')
95 elif (self.opc == 'stpartial16'):
96 file.write(' uint64_t ea = s->get_irf(i->rs1);\n')
97 file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
98 file.write(' s->mem_mask = s->stpartial16[rs2 & 0xf];\n')
99 elif (self.opc == 'stpartial32'):
100 file.write(' uint64_t ea = s->get_irf(i->rs1);\n')
101 file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
102 file.write(' s->mem_mask = s->stpartial32[rs2 & 0x3];\n')
103 else:
104 file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n')
105 if (imm == 'i0'):
106 file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
107 else:
108 file.write(' int64_t rs2 = i->rs2;\n')
109 file.write(' uint64_t ea = rs1 + rs2;\n')
110 if (alignment != '0'):
111 file.write(' if (ea & '+alignment+') {\n')
112 if (self.opc[:4] == 'lddf'):
113 file.write(' if ((ea & 7) == 4)\n')
114 file.write(' return (s->data_trap)(pc,npc,s,i,ea,SS_Trap::LDDF_MEM_ADDRESS_NOT_ALIGNED);\n')
115 elif (self.opc[:4] == 'stdf'):
116 file.write(' if ((ea & 7) == 4)\n')
117 file.write(' return (s->data_trap)(pc,npc,s,i,ea,SS_Trap::STDF_MEM_ADDRESS_NOT_ALIGNED);\n')
118 file.write(' return (s->data_trap)(pc,npc,s,i,ea,SS_Trap::MEM_ADDRESS_NOT_ALIGNED);\n')
119 file.write(' }\n')
120 file.write(' uint_t mem = idx_mem_'+self.opc+'_'+out+';\n')
121 if mmu_access:
122 file.write(' SS_Tte *_tte = i->get_tte();\n')
123 file.write(' if (!_tte->match(ea))\n')
124 file.write(' return (s->data_mmu)(pc,npc,s,i,ea,mem);\n')
125 file.write(' SS_Memop exe = s->mem_table[mem][((uint64_t)i->tte & 3)];\n')
126 file.write(' return (exe)(pc,npc,s,i,ea,i->tte);\n')
127 else:
128 #--------------------------------------------------------------------------
129 # invalid asi.
130 #--------------------------------------------------------------------------
131 if self.is_float():
132 file.write(' if (s->sim_state.fp_disabled())\n')
133 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n')
134 if asi=='reg':
135 file.write(' if (i->asi != s->asi())\n')
136 file.write(' return (s->inst_dec)(pc,npc,s,i);\n')
137 file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n')
138 if (self.opc[:3] == 'cas' or self.opc[:9] == 'stpartial'):
139 file.write(' SS_Vaddr ea = rs1;\n');
140 else:
141 if (imm == 'i0'):
142 file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
143 else:
144 file.write(' int64_t rs2 = i->rs2;\n');
145 file.write(' SS_Vaddr ea = rs1 + rs2;\n');
146 file.write(' return (s->invalid_asi)(pc,npc,s,i,ea);\n')
147 self.c_code_end(file)
148 file.write('#else\n')
149 file.write('extern "C" SS_Vaddr run_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out+'( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );\n')
150 file.write('#endif\n')
151
152 def run_exe_s(self,file):
153 global setup
154
155 if self.opc == 'ldtd':
156 self_opc = 'ldd'
157 else:
158 self_opc = self.opc
159
160 for asi in self.asi:
161 for out in self.out:
162
163 if self.is_float() or self.opc == 'prefetch' or self.opc == 'flush':
164 if out == 'g0':
165 continue
166 if out == 'rd':
167 if self.is_float():
168 out = 'fp'
169 else:
170 out = 'fn'
171
172 # ldfsr, stfsr, ldxfsr, stxfsr, and ldxefsr don't have alternative space versions
173 if self.opc[-3:] == 'fsr' and asi != 'dft':
174 continue
175
176 for imm in self.imm:
177 #----------------------------------------------------------------------------
178 #
179 #----------------------------------------------------------------------------
180 if out == 'rd' or out == 'g0' or out == 'fp' or out == 'fn':
181 self.asm_function(file,'run_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out)
182
183 alignment=self.va_lower_bits()
184
185 mmu_access = not (self.opc == 'flush')
186
187 byte_mask=self.wp_byte_mask()
188
189 if out == 'fp':
190 for l in [
191 ' ldx [S_PTR + S_SIM_STATE],%g5',
192 ' andcc %g5,F_FP_DISABLED,%g0',
193 ' bne %xcc,fpop_disabled_trap'
194 ]:
195 file.write('%s\n' % l)
196
197 if mmu_access:
198 for l in [
199 _if_(asi=='reg',
200 ' lduh [I_PTR + I_ASI],%g1\n' # check for %asi change
201 ' ldub [S_PTR + S_ASI],%g2', # change uh when asi changes ToDo
202 ''
203 ),
204 ' ldptr [I_PTR + I_TTE],%o5', # o0 o1 o2 o3 -- o5 -- -- -- -- --
205 ' lduh [I_PTR + I_RS1],%o4', # .. .. .. .. o4 .. -- -- -- -- --
206 _if_(imm=='i0',
207 ' lduh [I_PTR + I_RS2],%g5' # .. .. .. .. .. .. -- -- -- -- g5
208 ,
209 ' ldsh [I_PTR + I_RS2],%g5'
210 ),
211 _if_(asi=='reg',
212 ' subcc %g1,%g2,%g0',
213 ''
214 ),
215 ' and %o5,-4,%g2', # .. .. .. .. .. .. -- g2 -- -- ..
216 _if_(asi=='reg',
217 ' bne %xcc,2f', # Oops, -> redecode instruction
218 ''
219 ),
220 ' ldptr [S_PTR + S_MEM_TABLE],%g3', # .. .. .. .. .. .. -- .. g3 -- ..
221 ' ldx [S_PTR + %o4],%o4',
222 _if_(imm=='i0',
223 ' ldx [S_PTR + %g5],%g5', ''
224 ),
225
226 ' and %o5,3,%g4', # mem b, mem l, io b, io l?
227 ' ldx [%g2 + X_VIRT_MASK],%g1', # .. .. .. .. .. .. g1 .. .. -- ..
228 ' sll %g4,PTR_SIZE_BITS,%g4',
229 ' ldx [%g2 + X_VIRT_PAGE],%g2', # .. .. .. .. .. .. .. .. .. -- ..
230 ' add %g3,%g4,%g3',
231
232 _if_(self_opc[:3] == 'cas',
233 '',
234 _if_(self_opc == 'stpartial8',
235 ' and %g5,0xff,%g5\n'
236 ' stx %g5,[S_PTR + S_MEM_MASK]',
237 _if_(self_opc == 'stpartial16',
238 ' and %g5,0xf,%g5\n'
239 ' add %g5,S_STPARTIAL16,%g5\n'
240 ' ldub [S_PTR + %g5],%g5\n'
241 ' stx %g5,[S_PTR + S_MEM_MASK]',
242 _if_(self_opc == 'stpartial32',
243 ' and %g5,0x3,%g5\n'
244 ' add %g5,S_STPARTIAL32,%g5\n'
245 ' ldub [S_PTR + %g5],%g5\n'
246 ' stx %g5,[S_PTR + S_MEM_MASK]',
247 ' add %o4,%g5,%o4'
248 )))), # .. .. .. .. .. .. .. .. -- -- --
249
250 ' and %o4,%g1,%g1', # .. .. .. .. .. .. .. .. -- -- --
251
252 _if_(alignment != '0',
253 ' andcc %o4,'+alignment+',%g0',
254 ''
255 ),
256
257 ' ldptr [%g3 + IDX_MEM_'+self.opc.upper()+'_'+out.upper()+'*4*PTR_SIZE],%g5',
258
259 _if_(alignment != '0',
260 _if_(self.opc[:4] == 'lddf',
261 ' bne %xcc,ss_data_trap_lddf_mem_address_not_aligned',
262 _if_(self.opc[:4] == 'stdf' or self.opc[:9] == 'stpartial',
263 ' bne %xcc,ss_data_trap_stdf_mem_address_not_aligned',
264 ' bne %xcc,ss_data_trap_mem_address_not_aligned',
265 )),
266 ''
267 ),
268
269
270 '1:',
271
272 ' cmp %g1,%g2',
273 ' bne %xcc,3f',
274 ' nop',
275
276 '#ifdef ARCH_V8',
277 ' st %o5,[%sp + 100]',
278 ' st %o4,[%sp + 96]',
279 ' srlx %o4,32,%o4',
280 ' st %o4,[%sp + 92]',
281 ' sra %o3,0,%o5',
282 ' sra %o2,0,%o4',
283 ' srl %o1,0,%o3',
284 ' srlx %o1,32,%o2',
285 ' srl %o0,0,%o1',
286 ' srlx %o0,32,%o0',
287 '#endif',
288 ' jmpl %g5,%g0',
289 ' nop',
290
291 '3:\n'
292 ' ldptr [S_PTR + DATA_MMU],%g1',
293 ' jmpl %g1,%g0',
294 ' mov IDX_MEM_'+self.opc.upper()+'_'+out.upper()+',%o5',
295
296 ]:
297 file.write('%s\n' % l)
298
299 else:
300
301 for l in [
302 _if_(asi=='reg',
303 ' lduh [I_PTR + I_ASI],%g1\n' # check for %asi change
304 ' ldub [S_PTR + S_ASI],%g2', # change uh when asi changes ToDo
305 ''
306 ),
307 ' lduh [I_PTR + I_RS1],%o4', # .. .. .. .. o4 .. -- -- -- -- --
308 _if_(imm=='i0',
309 ' lduh [I_PTR + I_RS2],%g5' # .. .. .. .. .. .. -- -- -- -- g5
310 ,
311 ' ldsh [I_PTR + I_RS2],%g5'
312 ),
313 _if_(asi=='reg',
314 ' subcc %g1,%g2,%g0\n'
315 ' bne %xcc,2f', # Oops, -> redecode instruction
316 ''
317 ),
318 ' ldptr [S_PTR + S_MEM_TABLE],%g3', # .. .. .. .. .. .. -- .. g3 -- ..
319 ' ldx [S_PTR + %o4],%o4',
320 _if_(imm=='i0',
321 ' ldx [S_PTR + %g5],%g5', ''
322 ),
323 ' ldptr [%g3 + IDX_MEM_'+self.opc.upper()+'_'+out.upper()+'*4*PTR_SIZE],%g1',
324 '#ifdef ARCH_V9',
325 ' jmpl %g1,%g0',
326 ' add %o4,%g5,%o4',
327 '#else',
328 ' add %o4,%g5,%o4',
329 ' st %o5,[%sp + 100]',
330 ' st %o4,[%sp + 96]',
331 ' srlx %o4,32,%o4',
332 ' st %o4,[%sp + 92]',
333 ' sra %o3,0,%o5',
334 ' sra %o2,0,%o4',
335 ' srl %o1,0,%o3',
336 ' srlx %o1,32,%o2',
337 ' srl %o0,0,%o1',
338 ' jmpl %g1,%g0',
339 ' srlx %o0,32,%o0',
340 '#endif'
341 ]:
342 file.write('%s\n' % l)
343
344 # %asi changed compared to last time we executed the instruction.
345 # The instruction needs to be redecoded to correct for that change
346 # through recursion ... keep it simple (but avoid infinite loops!)
347
348 if asi == 'reg':
349 file.write('2:\n')
350 file.write(' ldptr [S_PTR + INST_DEC],%g1\n')
351 file.write(' jmpl %g1,%g0\n')
352 file.write(' nop\n')
353
354 file.write('\n')
355 #----------------------------------------------------------------------------
356 # invalid asi, check all the things in a C routine ... could do effective
357 # address calculation there too .... ToDo
358 #----------------------------------------------------------------------------
359 else:
360 self.asm_function(file,'run_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out)
361 alignment=self.va_lower_bits()
362 if self.is_float():
363 for l in [
364 ' ldx [S_PTR + S_SIM_STATE],%g5',
365 ' andcc %g5,F_FP_DISABLED,%g0',
366 ' bne %xcc,fpop_disabled_trap']:
367 file.write('%s\n' % l)
368
369 if asi=='reg':
370 file.write(' lduh [I_PTR + I_ASI],%g1\n')
371 file.write(' ldub [S_PTR + S_ASI],%g2\n')
372 file.write(' subcc %g1,%g2,%g0\n')
373 file.write(' bne %xcc,2f\n')
374
375 if self.opc[:3] == 'cas' or self_opc[:9] == 'stpartial':
376 for l in [
377 ' ldptr [S_PTR + INVALID_ASI],%g1',
378 ' lduh [I_PTR + I_RS1],%o4',
379 ' jmpl %g1+%g0,%g0',
380 ' ldx [S_PTR + %o4],%o4']:
381 file.write('%s\n' % l)
382 elif imm == 'i0':
383 for l in [
384 ' lduh [I_PTR + I_RS1],%o4',
385 ' lduh [I_PTR + I_RS2],%g5',
386 ' ldptr [S_PTR + INVALID_ASI],%g1',
387 ' ldx [S_PTR + %o4],%o4',
388 ' ldx [S_PTR + %g5],%g5',
389 ' jmpl %g1+%g0,%g0',
390 ' add %o4,%g5,%o4']:
391 file.write('%s\n' % l)
392 else:
393 for l in [
394 ' lduh [I_PTR + I_RS1],%o4',
395 ' ldsh [I_PTR + I_RS2],%g5',
396 ' ldptr [S_PTR + INVALID_ASI],%g1',
397 ' ldx [S_PTR + %o4],%o4',
398 ' jmpl %g1+%g0,%g0',
399 ' add %o4,%g5,%o4']:
400 file.write('%s\n' % l)
401
402 if asi == 'reg':
403 file.write('2:\n')
404 file.write(' ldptr [S_PTR + INST_DEC],%g1\n')
405 file.write(' jmpl %g1,%g0\n')
406 file.write(' nop\n')
407
408 file.write('\n')
409
410 def gen_exe_tbl(self,file,mode):
411 for asi in self.asi:
412 for out in self.out:
413
414 if self.is_float() or self.opc == 'prefetch' or self.opc == 'flush':
415 if out == 'g0':
416 continue
417 if out == 'rd':
418 if self.is_float():
419 out = 'fp'
420 else:
421 out = 'fn'
422
423 if self.opc[-3:] == 'fsr' and asi != 'dft':
424 continue
425
426 for imm in self.imm:
427 if mode == 'trc':
428 # handle loads -- first std FP, then odd FP, then IRF
429 if self.opc[:2] == 'ld':
430 if self.is_sgl_fp():
431 self.gen_exe_frI(file,mode,imm,out)
432 elif self.is_dbl_fp():
433 self.gen_exe_drI(file,mode,imm,out)
434 elif self.opc[-3:] == 'fsr':
435 self.gen_exe_0rI(file,mode,imm,out)
436 elif self.opc[2:7] == 'block':
437 self.gen_exe_brI(file,mode,imm,out)
438 elif self.opc[2:7] == 'short' or self.opc[2:7] == 'parti':
439 self.gen_exe_drI(file,mode,imm,out)
440 elif self.is_float():
441 file.write(' '+mode+'_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out+',\n')
442 elif self.opc[:3] == 'ldd' or self.opc[:4] == 'ldtd':
443 self.gen_exe_prI(file,mode,imm,out)
444 else:
445 self.gen_exe_rrI(file,mode,imm,out)
446
447 # handle stores -- first std FP, then odd FP, then IRF
448 elif self.opc[:2] == 'st':
449 if self.is_sgl_fp():
450 self.gen_exe_FrI(file,mode,imm,out)
451 elif self.is_dbl_fp():
452 self.gen_exe_DrI(file,mode,imm,out)
453 elif self.opc[-3:] == 'fsr':
454 self.gen_exe_0rI(file,mode,imm,out)
455 elif self.opc[2:7] == 'block':
456 self.gen_exe_BrI(file,mode,imm,out)
457 elif self.opc[2:7] == 'short' or self.opc[2:7] == 'parti':
458 self.gen_exe_DrI(file,mode,imm,out)
459 elif self.is_float():
460 file.write(' '+mode+'_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out+',\n')
461 elif self.opc[:3] == 'std' or self.opc[:4] == 'sttd':
462 self.gen_exe_PrI(file,mode,imm,out)
463 else:
464 self.gen_exe_rrI(file,mode,imm,out)
465
466 # handle cas, swap, and ldstub
467 elif self.is_atomic():
468 if mode == 'trc':
469 file.write(' trc_exe_cas_'+imm+',\n')
470 else:
471 file.write(' '+mode+'_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out+',\n')
472 # handle prefetch
473 elif self.opc[:8] == 'prefetch':
474 self.gen_exe_0rI(file,mode,imm,out)
475
476 elif self.opc == 'flush':
477 self.gen_exe_0rI(file,mode,imm,out)
478
479 # everything is just trc_exe_<opc>_...
480 else:
481 file.write(' '+mode+'_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out+',\n')
482 elif mode == 'v8_run':
483 file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out+' */\n')
484 else:
485 file.write(' '+mode+'_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out+',\n')
486
487 def exe_idx_s(self,file):
488 for asi in self.asi:
489 for out in self.out:
490
491 if self.is_float() or self.opc == 'prefetch' or self.opc == 'flush':
492 if out == 'g0':
493 continue
494 if out == 'rd':
495 if self.is_float():
496 out = 'fp'
497 else:
498 out = 'fn'
499
500 if self.opc[-3:] == 'fsr' and asi != 'dft':
501 continue
502
503 for imm in self.imm:
504 self.exe_idx_s_name(file,self.opc+'_'+asi+'_'+imm+'_'+out)
505
506 def run_dec_p(self):
507 return ''
508
509 def va_lower_bits(self):
510 if self.opc[-1] == 'a':
511 opc = self.opc[:-1]
512 else:
513 opc = self.opc
514 if opc == 'ldsb' or opc == 'ldub' or opc == 'stb' or opc == 'ldstub' or opc == 'ldshortf8' or \
515 opc == 'stshortf8' or opc =='prefetch' or opc == 'flush':
516 return '0'
517 elif opc == 'ldsh' or opc == 'lduh' or opc == 'sth' or opc == 'ldshortf16' or opc == 'stshortf16':
518 return '1'
519 elif opc == 'ldsw' or opc == 'lduw' or opc == 'stw' or opc == 'swap' or opc == 'cas' or \
520 opc == 'ldf' or opc == 'stf' or opc == 'ldfsr' or opc == 'stfsr':
521 return '3'
522 elif opc == 'ldx' or opc == 'ldd' or opc == 'stx' or opc == 'std' or opc == 'casx' or \
523 opc == 'lddf' or opc == 'stdf' or opc[:9] == 'stpartial' or opc == 'ldxfsr' or opc == 'stxfsr' or \
524 opc == 'ldxefsr':
525 return '7'
526 elif opc == 'ldtd':
527 return '15'
528 elif opc == 'ldblockf' or opc == 'stblockf':
529 return '63'
530 else:
531 return 'va_lower_bits unknown'
532
533 def wp_byte_mask(self):
534 if self.opc[-1] == 'a':
535 opc = self.opc[:-1]
536 else:
537 opc = self.opc
538 if opc == 'ldsb' or opc == 'ldub' or opc == 'stb' or opc == 'ldstub' or opc == 'ldshortf8' or \
539 opc == 'stshortf8' or opc == 'prefetch':
540 return '1'
541 elif opc == 'ldsh' or opc == 'lduh' or opc == 'sth' or opc == 'ldshortf16' or opc == 'stshortf16':
542 return '3'
543 elif opc == 'ldsw' or opc == 'lduw' or opc == 'stw' or opc == 'swap' or opc == 'cas' or \
544 opc == 'ldf' or opc == 'stf' or opc == 'ldfsr' or opc == 'stfsr':
545 return '15'
546 elif opc == 'ldx' or opc == 'ldd' or opc == 'stx' or opc == 'std' or opc == 'casx' or \
547 opc == 'lddf' or opc == 'stdf' or opc[:9] == 'stpartial' or opc == 'ldxfsr' or opc == 'stxfsr' or \
548 opc == 'ldxefsr':
549 return '255'
550 elif opc == 'ldtd':
551 return '255'
552 elif opc == 'ldblockf' or opc == 'stblockf':
553 return '255'
554 else:
555 return 'wp_byte_mask'
556
557
558#============================================================================
559# SS_lsu_dec(opc)
560#----------------------------------------------------------------------------
561# N2 verification revealed a corner case that is not being dealt with properly
562# An ASI can be translating or non-translating. When it is translating it can
563# be an invalid ASI for the instruction and the MEM_ADDRESS_RANGE (MEM_REAL_RANGE)
564# trap has higher priority so that needs to be checked first. The code below
565# combines unimplemented ASIs (will cause INVALID_ASI trap when used) and invalid
566# (translating) ASI for an instruction in one routine ... ToDo, this should
567# be reengineered - at the moment we path the trap type in xx_data_trap().
568#============================================================================
569
570class SS_lsu_dec(SS_InstrCpp):
571 def __init__(self,opc):
572 SS_InstrCpp.__init__(self,opc)
573 self.opc = opc
574
575 def cond_index(self,test,true_index,false_index):
576 return '(('+test+') ? ' + true_index+' : '+false_index+')'
577
578 def run_dec_c(self,file):
579 opc = self.opc
580
581 # prefetcha?_tmp is only a placeholder to prefetch_dec ... only onde decoder needed
582 if opc[:8] == 'prefetch':
583 if opc[-4:] == '_tmp':
584 return
585 opc = opc[:-4]
586
587 self.c_code_dec_beg_name(file,'run_dec_'+opc)
588 if opc[-1] != 'a':
589 #----------------------------------------------------------------------
590 # DFT_ASI
591 #----------------------------------------------------------------------
592
593 file.write(' i->asi = s->data_dft_asi();\n')
594 file.write(' i->tte = s->fail_tte;\n')
595
596 if self.is_atomic():
597 file.write(' i->flg = SS_Instr::DFT_ASI|SS_Instr::READ|SS_Instr::WRITE;\n')
598 elif self.is_store():
599 file.write(' i->flg = SS_Instr::DFT_ASI|SS_Instr::WRITE;\n')
600 elif opc == 'prefetch':
601 file.write(' i->flg = SS_Instr::DFT_ASI|SS_Instr::FETCH;\n')
602 elif opc == 'flush':
603 file.write(' i->flg = SS_Instr::DFT_ASI|SS_Instr::FLUSH;\n')
604 else:
605 file.write(' i->flg = SS_Instr::DFT_ASI|SS_Instr::READ;\n')
606 file.write(' i->len = '+self.mem_len()+';\n')
607
608 if opc == 'ldd' or opc == 'std':
609 file.write(' if (o.get_rd_irf() & 8)\n')
610 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
611
612 file.write(' if (o.get_i())\n')
613 file.write(' {\n')
614 self.ill_ibe(file,' ')
615
616 asi_test = 's->sim_state.priv() < s->asi_info[i->asi].get_protection()'
617 asi_index = 'idx_exe_'+opc+'_dft_i1_ia'
618
619 if opc[-3:] == 'fsr':
620 cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i1_fp')
621 self.dec_0r13(file,' ',cidx)
622 elif self.is_double():
623 cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i1_fp')
624 self.dec_dr13(file,' ',cidx)
625 elif self.is_single():
626 cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i1_fp')
627 self.dec_fr13(file,' ',cidx)
628 elif opc == 'prefetch':
629 cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i1_fn')
630 self.dec_nr13(file,' ',cidx)
631 elif opc == 'flush':
632 cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i1_fn')
633 self.dec_nr13(file,' ',cidx)
634 else:
635 file.write(' if (o.get_rd_irf())\n')
636 cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i1_rd')
637 self.dec_rr13(file,' ',cidx)
638 file.write(' else\n')
639 cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i1_g0')
640 self.dec_0r13(file,' ',cidx)
641
642 file.write(' }\n')
643 file.write(' else if (o.is_zero_12_5())\n')
644 file.write(' {\n')
645 self.ill_ibe(file,' ')
646
647 asi_test = 's->sim_state.priv() < s->asi_info[i->asi].get_protection()'
648 asi_index = 'idx_exe_'+opc+'_dft_i0_ia'
649
650 if opc[-3:] == 'fsr':
651 cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i0_fp')
652 self.dec_0rr(file,' ',cidx)
653 elif self.is_double():
654 cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i0_fp')
655 self.dec_drr(file,' ',cidx)
656 elif self.is_single():
657 cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i0_fp')
658 self.dec_frr(file,' ',cidx)
659 elif opc == 'prefetch':
660 cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i0_fn')
661 self.dec_nrr(file,' ',cidx)
662 elif opc == 'flush':
663 cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i0_fn')
664 self.dec_nrr(file,' ',cidx)
665 else:
666 file.write(' if (o.get_rd_irf())\n')
667 cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i0_rd')
668 self.dec_rrr(file,' ',cidx)
669 file.write(' else\n')
670 cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i0_g0')
671 self.dec_0rr(file,' ',cidx)
672
673 file.write(' }\n')
674 file.write(' else\n')
675 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
676
677 else:
678 #----------------------------------------------------------------------
679 # REG_ASI , note casa and casxa are still rrr iso rri
680 #----------------------------------------------------------------------
681
682 file.write(' i->tte = s->fail_tte;\n')
683
684 if opc == 'ldda' or opc == 'stda':
685 file.write(' if (o.get_rd_irf() & 8)\n')
686 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
687
688 file.write(' if (o.get_i())\n')
689 file.write(' {\n')
690 file.write(' i->asi = s->asi();\n')
691
692 if self.is_atomic():
693 file.write(' i->flg = SS_Instr::REG_ASI|SS_Instr::READ|SS_Instr::WRITE;\n')
694 elif self.is_store():
695 file.write(' i->flg = SS_Instr::REG_ASI|SS_Instr::WRITE;\n')
696 elif opc == 'prefetcha':
697 file.write(' i->flg = SS_Instr::REG_ASI|SS_Instr::FETCH;\n')
698 elif opc == 'flusha':
699 file.write(' i->flg = SS_Instr::REG_ASI|SS_Instr::FLUSH;\n')
700 else:
701 file.write(' i->flg = SS_Instr::REG_ASI|SS_Instr::READ;\n')
702 file.write(' i->len = '+self.mem_len()+';\n')
703 file.write(' SS_AsiInfo asi_info = s->asi_info[i->asi];\n')
704
705 if self.is_atomic():
706 if opc[:3] == 'cas':
707 file.write(' if (!o.is_zero_12_5())\n')
708 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
709 self.ill_ibe(file,' ')
710 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
711 self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i0_ia')
712 file.write(' if (!asi_info.is_valid_atomic_asi())\n')
713 self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i0_ia')
714 else:
715 self.ill_ibe(file,' ')
716 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
717 self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
718 file.write(' if (!asi_info.is_valid_atomic_asi())\n')
719 self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
720
721 elif opc == 'prefetcha':
722 self.ill_ibe(file,' ')
723 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
724 self.dec_nr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
725 file.write(' if (!asi_info.is_valid_prefetch_asi())\n')
726 self.dec_nr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
727
728 elif opc == 'flusha':
729 self.ill_ibe(file,' ')
730 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
731 self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
732 file.write(' if (!asi_info.is_valid_flush_asi())\n')
733 self.dec_nr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
734
735 elif opc == 'ldda':
736 file.write(' if (asi_info.is_quad_load_asi())\n')
737 file.write(' {\n')
738 if setup.product == 'N2':
739 file.write(' i->len = 16;\n')
740 file.write(' if (o.get_rd_irf() & 0x8)\n')
741 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
742 self.ill_ibe(file,' ')
743 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
744 self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
745 file.write(' if (o.get_rd_irf())\n')
746 self.dec_rr13(file,' ','idx_exe_ldtd_reg_i1_rd')
747 file.write(' else\n')
748 self.dec_0r13(file,' ','idx_exe_ldtd_reg_i1_g0')
749 file.write(' }\n')
750 self.ill_ibe(file,' ')
751 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
752 self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
753 file.write(' if (!asi_info.is_valid_ld_asi())\n')
754 self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
755
756 elif opc[:3] == 'ldx':
757 self.ill_ibe(file,' ')
758 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
759 self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
760 file.write(' if (!asi_info.is_valid_ldx_asi())\n')
761 file.write(' {\n')
762
763 self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
764 file.write(' }\n')
765 file.write(' if (!asi_info.is_translating())\n')
766 file.write(' {\n')
767 file.write(' if (o.get_rd_irf())\n')
768 self.dec_rr13(file,' ','idx_exe_rdasi_i1_rd')
769 file.write(' else\n')
770 self.dec_0r13(file,' ','idx_exe_rdasi_i1_g0')
771 file.write(' }\n')
772
773 elif opc == 'lddfa':
774 file.write(' if (asi_info.is_shortf8_asi())\n')
775 file.write(' {\n')
776 file.write(' i->len = 1;\n')
777 self.ill_ibe(file,' ')
778 self.dec_dr13(file,' ','idx_exe_ldshortf8_reg_i1_fp')
779 file.write(' }\n')
780 file.write(' else if (asi_info.is_shortf16_asi())\n')
781 file.write(' {\n')
782 file.write(' i->len = 2;\n')
783 self.ill_ibe(file,' ')
784 self.dec_dr13(file,' ','idx_exe_ldshortf16_reg_i1_fp')
785 file.write(' }\n')
786 file.write(' else if (asi_info.is_block_init_asi())\n')
787 file.write(' {\n')
788 self.ill_ibe(file,' ')
789 self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
790 file.write(' }\n')
791 file.write(' else if (asi_info.is_block_load_asi())\n')
792 file.write(' {\n')
793
794 file.write(' {\n')
795 file.write(' i->len = 64;\n')
796 file.write(' if (o.get_rd_drf() & 0x38)\n')
797 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
798 self.ill_ibe(file,' ')
799 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
800 self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
801 file.write(' else\n')
802 self.dec_dr13(file,' ','idx_exe_ldblockf_reg_i1_fp')
803 file.write(' }\n')
804 file.write(' }\n')
805 file.write(' else if (asi_info.is_block_store_asi())\n') # block commit are write only
806 file.write(' {\n')
807 file.write(' i->len = 64;\n')
808 file.write(' if (o.get_rd_drf() & 0x38)\n')
809 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
810 self.ill_ibe(file,' ')
811 self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
812 file.write(' }\n')
813 self.ill_ibe(file,' ')
814 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
815 self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
816 file.write(' if (!asi_info.is_valid_ld_asi())\n')
817 self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
818
819 elif self.is_load():
820 self.ill_ibe(file,' ')
821 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
822 self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
823 file.write(' if (!asi_info.is_valid_ld_asi())\n')
824 self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
825
826 elif opc[:3] == 'stx':
827 self.ill_ibe(file,' ')
828 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
829 self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
830 file.write(' if (!asi_info.is_valid_stx_asi())\n')
831 self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
832 file.write(' if (!asi_info.is_translating())\n')
833 file.write(' {\n')
834 file.write(' if (o.get_rd_irf())\n')
835 self.dec_rr13(file,' ','idx_exe_wrasi_i1_rd')
836 file.write(' else\n')
837 self.dec_0r13(file,' ','idx_exe_wrasi_i1_g0')
838 file.write(' }\n')
839
840 elif opc == 'stdfa':
841 file.write(' if (asi_info.is_shortf8_asi())\n')
842 file.write(' {\n')
843 file.write(' i->len = 1;\n')
844 self.ill_ibe(file,' ')
845 self.dec_dr13(file,' ','idx_exe_stshortf8_reg_i1_fp')
846 file.write(' }\n')
847 file.write(' else if (asi_info.is_shortf16_asi())\n')
848 file.write(' {\n')
849 file.write(' i->len = 2;\n')
850 self.ill_ibe(file,' ')
851 self.dec_dr13(file,' ','idx_exe_stshortf16_reg_i1_fp')
852 file.write(' }\n')
853 file.write(' else if (asi_info.is_partial8_asi())\n')
854 file.write(' {\n')
855 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
856 file.write(' }\n')
857 file.write(' else if (asi_info.is_partial16_asi())\n')
858 file.write(' {\n')
859 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
860 file.write(' }\n')
861 file.write(' else if (asi_info.is_partial32_asi())\n')
862 file.write(' {\n')
863 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
864 file.write(' }\n')
865 file.write(' else if (asi_info.is_block_store_asi())\n')
866 file.write(' {\n')
867
868 file.write(' {\n')
869 file.write(' i->len = 64;\n')
870 file.write(' if (o.get_rd_drf() & 0x38)\n')
871 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
872 self.ill_ibe(file,' ')
873 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
874 self.dec_dr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
875 file.write(' else\n')
876 self.dec_dr13(file,' ','idx_exe_stblockf_reg_i1_fp')
877 file.write(' }\n')
878 file.write(' }\n')
879 self.ill_ibe(file,' ')
880 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
881 self.dec_dr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
882 file.write(' if (!asi_info.is_valid_stf_asi())\n')
883 self.dec_dr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
884
885 elif opc == 'stda':
886 self.ill_ibe(file,' ')
887 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
888 self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
889 file.write(' if (!asi_info.is_valid_st_asi())\n')
890 self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
891
892 elif opc == 'stfa':
893 self.ill_ibe(file,' ')
894 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
895 self.dec_fr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
896 file.write(' if (!asi_info.is_valid_stf_asi())\n')
897 self.dec_fr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
898
899 elif self.is_store():
900 self.ill_ibe(file,' ')
901 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
902 self.dec_dr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
903 file.write(' if (!asi_info.is_valid_st_asi())\n')
904 self.dec_dr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
905
906 if self.is_double():
907 file.write(' else\n')
908 self.dec_dr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_fp')
909 elif self.is_single():
910 file.write(' else\n')
911 self.dec_fr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_fp')
912 elif opc == 'prefetcha':
913 file.write(' else if (asi_info.is_translating())\n')
914 self.dec_nr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_fn')
915 file.write(' else\n')
916 self.dec_000(file,' ','idx_exe_nop')
917 elif opc == 'flusha':
918 file.write(' else\n')
919 self.dec_nr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_fn')
920 else:
921 file.write(' else\n')
922 file.write(' {\n')
923 file.write(' if (o.get_rd_irf())\n')
924 if opc[:3] == 'cas':
925 self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_reg_i0_rd')
926 else:
927 self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_rd')
928 file.write(' else\n')
929 if opc[:3] == 'cas':
930 self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_reg_i0_g0')
931 else:
932 self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_g0')
933 file.write(' }\n')
934 file.write(' }\n')
935
936 #----------------------------------------------------------------------
937 # IMM_ASI
938 #----------------------------------------------------------------------
939
940 file.write(' else\n')
941 file.write(' {\n')
942 file.write(' i->asi = o.get_imm_asi();\n')
943
944 if self.is_atomic():
945 file.write(' i->flg = SS_Instr::IMM_ASI|SS_Instr::READ|SS_Instr::WRITE;\n')
946 elif self.is_store():
947 file.write(' i->flg = SS_Instr::IMM_ASI|SS_Instr::WRITE;\n')
948 elif opc == 'prefetcha':
949 file.write(' i->flg = SS_Instr::IMM_ASI|SS_Instr::FETCH;\n')
950 elif opc == 'flusha':
951 file.write(' i->flg = SS_Instr::IMM_ASI|SS_Instr::FLUSH;\n')
952 else:
953 file.write(' i->flg = SS_Instr::IMM_ASI|SS_Instr::READ;\n')
954 file.write(' i->len = '+self.mem_len()+';\n')
955
956 file.write(' SS_AsiInfo asi_info = s->asi_info[i->asi];\n')
957
958 if self.is_atomic():
959 self.ill_ibe(file,' ')
960 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
961 self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
962 file.write(' if (!asi_info.is_valid_atomic_asi())\n')
963 self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
964
965 elif opc == 'prefetcha':
966 self.ill_ibe(file,' ')
967 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
968 self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
969 file.write(' if (!asi_info.is_valid_prefetch_asi())\n')
970 self.dec_nrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
971
972 elif opc == 'flusha':
973 self.ill_ibe(file,' ')
974 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
975 self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
976 file.write(' if (!asi_info.is_valid_flush_asi())\n')
977 self.dec_nrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
978
979 elif opc == 'ldda':
980 file.write(' if (asi_info.is_quad_load_asi())\n')
981 file.write(' {\n')
982 file.write(' i->len = 16;\n')
983 file.write(' if (o.get_rd_irf() & 0x8)\n')
984 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
985 self.ill_ibe(file,' ')
986 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
987 self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
988 file.write(' if (o.get_rd_irf())\n')
989 self.dec_rrr(file,' ','idx_exe_ldtd_imm_i0_rd')
990 file.write(' else\n')
991 self.dec_0rr(file,' ','idx_exe_ldtd_imm_i0_g0')
992 file.write(' }\n')
993 self.ill_ibe(file,' ')
994 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
995 self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
996 file.write(' if (!asi_info.is_valid_ld_asi())\n')
997 self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
998
999 elif opc[:3] == 'ldx':
1000 self.ill_ibe(file,' ')
1001 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
1002 self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1003 file.write(' if (!asi_info.is_valid_ldx_asi())\n')
1004 file.write(' {\n')
1005
1006 self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1007 file.write(' }\n')
1008 file.write(' if (!asi_info.is_translating())\n')
1009 file.write(' {\n')
1010 file.write(' if (o.get_rd_irf())\n')
1011 self.dec_rrr(file,' ','idx_exe_rdasi_i0_rd')
1012 file.write(' else\n')
1013 self.dec_0rr(file,' ','idx_exe_rdasi_i0_g0')
1014 file.write(' }\n')
1015
1016 elif opc == 'lddfa':
1017 file.write(' if (asi_info.is_shortf8_asi())\n')
1018 file.write(' {\n')
1019 file.write(' i->len = 1;\n')
1020 self.ill_ibe(file,' ')
1021 self.dec_drr(file,' ','idx_exe_ldshortf8_imm_i0_fp')
1022 file.write(' }\n')
1023 file.write(' else if (asi_info.is_shortf16_asi())\n')
1024 file.write(' {\n')
1025 file.write(' i->len = 2;\n')
1026 self.ill_ibe(file,' ')
1027 self.dec_drr(file,' ','idx_exe_ldshortf16_imm_i0_fp')
1028 file.write(' }\n')
1029 file.write(' else if (asi_info.is_block_init_asi())\n')
1030 file.write(' {\n')
1031 self.ill_ibe(file,' ')
1032 self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1033 file.write(' }\n')
1034 file.write(' else if (asi_info.is_block_load_asi())\n')
1035 file.write(' {\n')
1036 file.write(' i->len = 64;\n')
1037 file.write(' if (o.get_rd_drf() & 0x38)\n')
1038 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
1039 self.ill_ibe(file,' ')
1040 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
1041 self.dec_drr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1042 file.write(' else\n')
1043 self.dec_drr(file,' ','idx_exe_ldblockf_imm_i0_fp')
1044 file.write(' }\n')
1045 file.write(' else if (asi_info.is_block_store_asi())\n') # block commit are write only
1046 file.write(' {\n')
1047 file.write(' i->len = 64;\n')
1048 file.write(' if (o.get_rd_drf() & 0x38)\n')
1049 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
1050 self.ill_ibe(file,' ')
1051 self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1052 file.write(' }\n')
1053 self.ill_ibe(file,' ')
1054 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
1055 self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1056 file.write(' if (!asi_info.is_valid_ld_asi())\n')
1057 self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1058
1059 elif self.is_load():
1060 self.ill_ibe(file,' ')
1061 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
1062 self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1063 file.write(' if (!asi_info.is_valid_ld_asi())\n')
1064 self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1065
1066 elif opc[:3] == 'stx':
1067 self.ill_ibe(file,' ')
1068 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
1069 self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1070 file.write(' if (!asi_info.is_valid_stx_asi())\n')
1071 self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1072 file.write(' if (!asi_info.is_translating())\n')
1073 file.write(' {\n')
1074 file.write(' if (o.get_rd_irf())\n')
1075 self.dec_rrr(file,' ','idx_exe_wrasi_i0_rd')
1076 file.write(' else\n')
1077 self.dec_rrr(file,' ','idx_exe_wrasi_i0_g0')
1078 file.write(' }\n')
1079
1080 elif opc == 'stdfa':
1081 file.write(' if (asi_info.is_shortf8_asi())\n')
1082 file.write(' {\n')
1083 file.write(' i->len = 1;\n')
1084 self.ill_ibe(file,' ')
1085 self.dec_drr(file,' ','idx_exe_stshortf8_imm_i0_fp')
1086 file.write(' }\n')
1087 file.write(' else if (asi_info.is_shortf16_asi())\n')
1088 file.write(' {\n')
1089 file.write(' i->len = 2;\n')
1090 self.ill_ibe(file,' ')
1091 self.dec_drr(file,' ','idx_exe_stshortf16_imm_i0_fp')
1092 file.write(' }\n')
1093 file.write(' else if (asi_info.is_partial8_asi())\n')
1094 file.write(' {\n')
1095 self.ill_ibe(file,' ')
1096 self.dec_drr(file,' ','idx_exe_stpartial8_imm_i0_fp')
1097 file.write(' }\n')
1098 file.write(' else if (asi_info.is_partial16_asi())\n')
1099 file.write(' {\n')
1100 self.ill_ibe(file,' ')
1101 self.dec_drr(file,' ','idx_exe_stpartial16_imm_i0_fp')
1102 file.write(' }\n')
1103 file.write(' else if (asi_info.is_partial32_asi())\n')
1104 file.write(' {\n')
1105 self.ill_ibe(file,' ')
1106 self.dec_drr(file,' ','idx_exe_stpartial32_imm_i0_fp')
1107 file.write(' }\n')
1108 file.write(' else if (asi_info.is_block_store_asi())\n')
1109 file.write(' {\n')
1110 file.write(' i->len = 64;\n')
1111 file.write(' if (o.get_rd_drf() & 0x38)\n')
1112 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
1113 self.ill_ibe(file,' ')
1114 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
1115 self.dec_drr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1116 file.write(' else\n')
1117 self.dec_drr(file,' ','idx_exe_stblockf_imm_i0_fp')
1118 file.write(' }\n')
1119 self.ill_ibe(file,' ')
1120 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
1121 self.dec_drr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1122 file.write(' if (!asi_info.is_valid_stf_asi())\n')
1123 self.dec_drr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1124
1125 elif opc == 'stda':
1126 self.ill_ibe(file,' ')
1127 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
1128 self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1129 file.write(' if (!asi_info.is_valid_st_asi())\n')
1130 self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1131
1132 elif opc == 'stfa':
1133 self.ill_ibe(file,' ')
1134 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
1135 self.dec_frr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1136 file.write(' if (!asi_info.is_valid_stf_asi())\n')
1137 self.dec_frr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1138
1139 elif self.is_store():
1140 self.ill_ibe(file,' ')
1141 file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
1142 self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1143 file.write(' if (!asi_info.is_valid_st_asi())\n')
1144 self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
1145
1146 if self.is_double():
1147 file.write(' else\n')
1148 self.dec_drr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_fp')
1149 elif self.is_single():
1150 file.write(' else\n')
1151 self.dec_frr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_fp')
1152 elif opc == 'prefetcha':
1153 file.write(' else if (asi_info.is_translating())\n')
1154 self.dec_nrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_fn')
1155 file.write(' else\n')
1156 self.dec_000(file,' ','idx_exe_nop')
1157 elif opc == 'flusha':
1158 file.write(' else\n')
1159 self.dec_nrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_fn')
1160 else:
1161 file.write(' else\n')
1162 file.write(' {\n')
1163 file.write(' if (o.get_rd_irf())\n')
1164 self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_rd')
1165 file.write(' else\n')
1166 self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_g0')
1167 file.write(' }\n')
1168
1169 file.write(' }\n')
1170 self.c_code_end(file)
1171
1172 def is_load(self):
1173 return self.opc[0:2] == 'ld'
1174 def is_store(self):
1175 return self.opc[0:2] == 'st'
1176 def is_atomic(self):
1177 return self.opc[:6] == 'ldstub' or self.opc[:4] == 'swap' or self.opc[:3] == 'cas'
1178
1179 def is_double(self):
1180 return self.opc[:4] == 'lddf' or self.opc[:4] == 'stdf'
1181 def is_single(self):
1182 return self.opc[:3] == 'ldf' or self.opc[:3] == 'stf'
1183
1184 def exe_idx_s_name(self,file,n):
1185 pass
1186
1187 def gen_exe_tbl(self,file,mode):
1188 pass
1189
1190 def idx_mem_s(self,file):
1191 pass
1192
1193 def run_dec_p(self):
1194 if self.opc[:8] == 'prefetch':
1195 return 'run_dec_%s' % self.opc[:-4]
1196 else:
1197 return 'run_dec_%s' % self.opc
1198
1199 def mem_len(self):
1200 if self.opc[-1] == 'a':
1201 opc = self.opc[:-1]
1202 else:
1203 opc = self.opc
1204 if opc == 'ldsb' or opc == 'ldub' or opc == 'stb' or opc == 'ldstub':
1205 return '1'
1206 elif opc == 'ldsh' or opc == 'lduh' or opc == 'sth':
1207 return '2'
1208 elif opc == 'ldsw' or opc == 'lduw' or opc == 'stw' or opc == 'swap' or opc == 'cas' or \
1209 opc == 'ldf' or opc == 'stf' or opc == 'ldfsr' or opc == 'stfsr':
1210 return '4'
1211 elif opc == 'ldx' or opc == 'ldd' or opc == 'stx' or opc == 'std' or opc == 'casx' or \
1212 opc == 'lddf' or opc == 'stdf' or opc == 'ldxfsr' or opc == 'stxfsr' or opc == 'ldxefsr' or \
1213 opc[:8] == 'prefetch' or opc == 'flush':
1214 return '8'
1215 else:
1216 return 'mem_len() missed opc '+self.opc
1217
1218
1219#============================================================================
1220# SS_ld_mem(opc)
1221#============================================================================
1222
1223class SS_ld_mem(SS_InstrCpp):
1224 def __init__(self,opc,out):
1225 SS_InstrCpp.__init__(self,opc+'_'+out)
1226 self.opc = opc
1227 self.out = out # 'rd' ,'g0', 'fp', 'fn'
1228
1229 def mem_c(self,file):
1230 for mode in ['run','trc','ras']:
1231 for src in ['memory','io']:
1232 for endian in ['b','l']:
1233 args = '( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, SS_Vaddr va, SS_Tte* tte )\n'
1234 name = endian+'_'+self.opc+'_'+self.out
1235 if src == 'memory':
1236 sid = ''
1237 file.write('\nextern "C" SS_Vaddr mem_'+mode+'_'+name+args)
1238 else:
1239 sid = 's->strand_id(),'
1240 file.write('\nextern "C" SS_Vaddr io_'+mode+'_'+name+args)
1241
1242 file.write('{\n')
1243 file.write(' SS_Tte* _tte = (SS_Tte*)(long(tte) &~ 3);\n')
1244 file.write(' SS_Paddr pa = _tte->trans(va);\n')
1245 file.write('#if defined(MEMORY_MSYNC)\n')
1246 file.write(' ((SS_MsyncMemory*)(s->'+src+'))->msync_info(s->strand_id(),va);\n')
1247 file.write('#elif defined(MEMORY_EXTERNAL)\n')
1248 if src == 'memory':
1249 file.write(' ((SS_ExternalMemory*)(s->'+src+'))->set_strand_id(s->strand_id());\n')
1250 file.write('#endif\n')
1251
1252 if self.opc == 'prefetch':
1253 # ToDo: prefetch is not part of the memory interface standard yet
1254 #file.write(' s->'+src+'->prefetch('+sid+'pa,1);\n')
1255 if mode == 'trc':
1256 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::PREFETCH,va,_tte,0,0);\n')
1257 elif mode == 'ras':
1258 if setup.product == 'N2':
1259 file.write(' if (s->sim_state.ras_enabled())\n')
1260 file.write(' {\n')
1261 cpu_strand = setup.product.lower()+'_strand'
1262 file.write(' '+setup.product+'_Strand* '+cpu_strand+' = ('+setup.product+'_Strand*)s;\n')
1263 cpu_mem_err_detector = setup.product.lower()+'_mem_err_detector'
1264 file.write(' '+setup.product+'_MemErrDetector& '+cpu_mem_err_detector+' = ('+setup.product+'_MemErrDetector&)'+cpu_strand+'->mem_err_detector;\n')
1265 file.write(' if ('+cpu_mem_err_detector+'.is_prefetchICE(i->opc))\n')
1266 file.write(' '+cpu_mem_err_detector+'.prefetchICE(pa);\n')
1267 file.write(' }\n')
1268 else:
1269
1270 file.write(' uint64_t val;\n')
1271
1272 if mode == 'run' and src == 'memory':
1273 if self.opc == 'ldsb':
1274 file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ld8s('+sid+'pa);\n')
1275 elif self.opc == 'ldub' or self.opc == 'ldshortf8':
1276 file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ld8u('+sid+'pa);\n')
1277 elif self.opc == 'ldsh':
1278 file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ld16s('+sid+'pa);\n')
1279 elif self.opc == 'lduh' or self.opc == 'ldshortf16':
1280 file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ld16u('+sid+'pa);\n')
1281 elif self.opc == 'ldsw':
1282 file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ld32s('+sid+'pa);\n')
1283 elif self.opc == 'lduw' or self.opc == 'ldf' or self.opc == 'ldfsr':
1284 file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ld32u('+sid+'pa);\n')
1285 elif self.opc == 'ldx' or self.opc == 'ldd' or self.opc == 'lddf' or self.opc == 'ldxfsr' or self.opc == 'ldxefsr':
1286 file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ld64('+sid+'pa);\n')
1287 elif self.opc == 'ldtd':
1288 file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::ld128atomic('+sid+'pa,s->mem_data);\n')
1289 elif self.opc == 'ldblockf':
1290 file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::ld512('+sid+'pa,s->mem_data);\n')
1291 else:
1292 file.write(' val = ???;\n')
1293 else:
1294 if self.opc == 'ldsb':
1295 file.write(' val = s->'+src+'->ld8s('+sid+'pa);\n')
1296 elif self.opc == 'ldub' or self.opc == 'ldshortf8':
1297 file.write(' val = s->'+src+'->ld8u('+sid+'pa);\n')
1298 elif self.opc == 'ldsh':
1299 file.write(' val = s->'+src+'->ld16s('+sid+'pa);\n')
1300 elif self.opc == 'lduh' or self.opc == 'ldshortf16':
1301 file.write(' val = s->'+src+'->ld16u('+sid+'pa);\n')
1302 elif self.opc == 'ldsw':
1303 file.write(' val = s->'+src+'->ld32s('+sid+'pa);\n')
1304 elif self.opc == 'lduw' or self.opc == 'ldf' or self.opc == 'ldfsr':
1305 file.write(' val = s->'+src+'->ld32u('+sid+'pa);\n')
1306 elif self.opc == 'ldx' or self.opc == 'ldd' or self.opc == 'lddf' or self.opc == 'ldxfsr' or self.opc == 'ldxefsr':
1307 file.write(' val = s->'+src+'->ld64('+sid+'pa);\n')
1308 elif self.opc == 'ldtd':
1309 file.write(' s->'+src+'->ld128atomic('+sid+'pa,s->mem_data);\n')
1310 elif self.opc == 'ldblockf':
1311 file.write(' s->'+src+'->ld512('+sid+'pa,s->mem_data);\n')
1312 else:
1313 file.write(' val = ???;\n')
1314
1315 if mode == 'ras' and src == 'memory':
1316 file.write(' if (s->sim_state.ras_enabled())\n')
1317 file.write(' {\n')
1318 file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
1319 file.write(' SS_Trap::Type tt = med.detect_load_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa);\n')
1320 file.write(' if (tt != SS_Trap::NO_TRAP)\n')
1321 file.write(' return (s->trap)(pc,npc,s,i,tt);\n')
1322 file.write(' }\n')
1323
1324 if mode == 'trc':
1325 if self.opc == 'ldsb' or self.opc == 'ldub' or self.opc == 'ldshortf8':
1326 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_DATA,va,_tte,1,&val);\n')
1327 elif self.opc == 'ldsh' or self.opc == 'lduh' or self.opc == 'ldshortf16':
1328 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_DATA,va,_tte,2,&val);\n')
1329 elif self.opc == 'ldsw' or self.opc == 'lduw' or self.opc == 'ldf' or self.opc == 'ldfsr':
1330 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_DATA,va,_tte,4,&val);\n')
1331 elif self.opc == 'ldx' or self.opc == 'ldd' or self.opc == 'lddf' or self.opc == 'ldxfsr' or self.opc == 'ldxefsr':
1332 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_DATA,va,_tte,8,&val);\n')
1333 elif self.opc == 'ldtd':
1334 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_DATA,va,_tte,16,s->mem_data);\n')
1335 elif self.opc == 'ldblockf':
1336 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_DATA,va,_tte,64,s->mem_data);\n')
1337 else:
1338 file.write(' ???\n')
1339
1340 if endian == 'b':
1341 if self.out == 'g0':
1342 if self.opc == 'ldtd':
1343 file.write(' s->get_irf(i->rd + 8) = s->mem_data[1];\n')
1344 elif self.opc == 'ldd':
1345 file.write(' s->get_irf(i->rd + 8) = uint32_t(val);\n')
1346 else:
1347 file.write(' s->mmu_scratch = val;\n')
1348 else:
1349 if self.opc == 'ldtd':
1350 file.write(' s->get_irf(i->rd) = s->mem_data[0];\n')
1351 file.write(' s->get_irf(i->rd + 8) = s->mem_data[1];\n')
1352 elif self.opc == 'ldd':
1353 file.write(' s->get_irf(i->rd ) = val >> 32;\n')
1354 file.write(' s->get_irf(i->rd + 8) = uint32_t(val);\n')
1355 elif self.opc == 'lddf' or self.opc[:8] == 'ldshortf':
1356 file.write(' s->get_drf(i->rd) = val;\n')
1357 file.write(' s->set_fprs(i->rd);\n')
1358 elif self.opc == 'ldf':
1359 file.write(' s->get_frf(i->rd) = val;\n')
1360 file.write(' s->set_fprs(i->rd);\n')
1361 elif self.opc == 'ldblockf':
1362 file.write(' s->get_drf(i->rd ) = s->mem_data[0];\n')
1363 file.write(' s->get_drf(i->rd + 8) = s->mem_data[1];\n')
1364 file.write(' s->get_drf(i->rd + 16) = s->mem_data[2];\n')
1365 file.write(' s->get_drf(i->rd + 24) = s->mem_data[3];\n')
1366 file.write(' s->get_drf(i->rd + 32) = s->mem_data[4];\n')
1367 file.write(' s->get_drf(i->rd + 40) = s->mem_data[5];\n')
1368 file.write(' s->get_drf(i->rd + 48) = s->mem_data[6];\n')
1369 file.write(' s->get_drf(i->rd + 56) = s->mem_data[7];\n')
1370 file.write(' s->set_fprs(i->rd);\n')
1371 elif self.opc == 'ldfsr':
1372 # fsr.ftt is written only by ldxefsr
1373 file.write(' val = (val & ~(0x7llu << 14)) | (s->fsr.ftt() << 14); // preserve ftt\n')
1374 file.write(' s->fsr.set(((s->fsr() >> 32) << 32) + ((val << 32) >> 32));\n')
1375 file.write(' s->set_fsr();\n')
1376 elif self.opc == 'ldxfsr':
1377 # fsr.ftt is written only by ldxefsr
1378 file.write(' val = (val & ~(0x7llu << 14)) | (s->fsr.ftt() << 14); // preserve ftt\n')
1379 file.write(' s->fsr.set(val);\n')
1380 file.write(' s->set_fsr();\n')
1381 elif self.opc == 'ldxefsr':
1382 file.write(' s->fsr.set(val);\n')
1383 if setup.product in ['xx']:
1384 # ditto xx FSR.NS
1385 file.write(' s->fsr.ns(0);\n')
1386 file.write(' s->set_fsr();\n')
1387 else:
1388 file.write(' s->get_irf(i->rd) = val;\n')
1389
1390 else: # endian == 'l'
1391 if self.out == 'g0':
1392 if self.opc == 'ldtd':
1393 file.write(' s->get_irf(i->rd + 8) = endianess_convert_64(s->mem_data[1]);\n')
1394 elif self.opc == 'ldd':
1395 file.write(' s->get_irf(i->rd + 8) = endianess_convert_32u(val);\n')
1396 else:
1397 file.write(' s->mmu_scratch = val;\n')
1398 elif self.opc == 'ldub' or self.opc == 'ldsb':
1399 file.write(' s->get_irf(i->rd) = val;\n')
1400 elif self.opc == 'lduh':
1401 file.write(' s->get_irf(i->rd) = endianess_convert_16u(val);\n')
1402 elif self.opc == 'ldsh':
1403 file.write(' s->get_irf(i->rd) = endianess_convert_16s(val);\n')
1404 elif self.opc == 'lduw':
1405 file.write(' s->get_irf(i->rd) = endianess_convert_32u(val);\n')
1406 elif self.opc == 'ldsw':
1407 file.write(' s->get_irf(i->rd) = endianess_convert_32s(val);\n')
1408 elif self.opc == 'ldshortf8':
1409 file.write(' s->get_drf(i->rd) = val;\n')
1410 file.write(' s->set_fprs(i->rd);\n')
1411 elif self.opc == 'ldshortf16':
1412 file.write(' s->get_drf(i->rd) = endianess_convert_16u(val);\n')
1413 file.write(' s->set_fprs(i->rd);\n')
1414 elif self.opc == 'ldf':
1415 file.write(' s->get_frf(i->rd) = endianess_convert_32s(val);\n')
1416 file.write(' s->set_fprs(i->rd);\n')
1417 elif self.opc == 'lddf':
1418 file.write(' s->get_drf(i->rd) = endianess_convert_64(val);\n')
1419 file.write(' s->set_fprs(i->rd);\n')
1420 elif self.opc == 'ldx':
1421 file.write(' s->get_irf(i->rd) = endianess_convert_64(val);\n')
1422 elif self.opc == 'ldd':
1423 file.write(' s->get_irf(i->rd ) = endianess_convert_32u(val >> 32);\n')
1424 file.write(' s->get_irf(i->rd + 8) = endianess_convert_32u(val);\n')
1425 elif self.opc == 'ldtd':
1426 file.write(' s->get_irf(i->rd ) = endianess_convert_64(s->mem_data[0]);\n')
1427 file.write(' s->get_irf(i->rd + 8) = endianess_convert_64(s->mem_data[1]);\n')
1428 elif self.opc == 'ldblockf':
1429 file.write(' s->get_drf(i->rd ) = endianess_convert_64(s->mem_data[0]);\n')
1430 file.write(' s->get_drf(i->rd + 8) = endianess_convert_64(s->mem_data[1]);\n')
1431 file.write(' s->get_drf(i->rd + 16) = endianess_convert_64(s->mem_data[2]);\n')
1432 file.write(' s->get_drf(i->rd + 24) = endianess_convert_64(s->mem_data[3]);\n')
1433 file.write(' s->get_drf(i->rd + 32) = endianess_convert_64(s->mem_data[4]);\n')
1434 file.write(' s->get_drf(i->rd + 40) = endianess_convert_64(s->mem_data[5]);\n')
1435 file.write(' s->get_drf(i->rd + 48) = endianess_convert_64(s->mem_data[6]);\n')
1436 file.write(' s->get_drf(i->rd + 56) = endianess_convert_64(s->mem_data[7]);\n')
1437 file.write(' s->set_fprs(i->rd);\n')
1438 elif self.opc == 'ldfsr':
1439 file.write(' val = endianess_convert_32u(val);\n')
1440 # fsr.ftt is written only by ldxefsr
1441 file.write(' val = (val & ~(0x7llu << 14)) | (s->fsr.ftt() << 14); // preserve ftt\n')
1442 file.write(' s->fsr.set(((s->fsr() >> 32) << 32) + ((val << 32) >> 32));\n')
1443 file.write(' s->set_fsr();\n')
1444 elif self.opc == 'ldxfsr':
1445 file.write(' val = endianess_convert_64(val);\n')
1446 # fsr.ftt is written only by ldxefsr
1447 file.write(' val = (val & ~(0x7llu << 14)) | (s->fsr.ftt() << 14); // preserve ftt\n')
1448 file.write(' s->fsr.set(val);\n')
1449 file.write(' s->set_fsr();\n')
1450 elif self.opc == 'ldxefsr':
1451 file.write(' val = endianess_convert_64(val);\n')
1452 file.write(' s->fsr.set(val);\n')
1453 if setup.product in ['xx']:
1454 # ditto xx FSR.NS
1455 file.write(' s->fsr.ns(0);\n')
1456 file.write(' s->set_fsr();\n')
1457
1458 file.write(' s->npc = npc+4; return npc;\n')
1459
1460 file.write('}\n')
1461
1462 def run_dec_c(self,file):
1463 pass
1464
1465 def run_dec_p(self):
1466 return ''
1467
1468
1469
1470#============================================================================
1471# SS_st_mem(opc)
1472#============================================================================
1473
1474class SS_st_mem(SS_InstrAsm):
1475 def __init__(self,opc,out):
1476 SS_InstrAsm.__init__(self,opc+'_'+out)
1477 self.opc = opc
1478 self.out = out
1479
1480 def mem_c(self,file):
1481 for mode in ['run','trc','ras']:
1482 for src in ['memory','io']:
1483 for endian in ['b','l']:
1484 args = '( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, SS_Vaddr va, SS_Tte* tte )\n'
1485 name = endian+'_'+self.opc+'_'+self.out
1486 if src == 'memory':
1487 sid = ''
1488 file.write('\nextern "C" SS_Vaddr mem_'+mode+'_'+name+args)
1489 else:
1490 sid = 's->strand_id(),'
1491 file.write('\nextern "C" SS_Vaddr io_'+mode+'_'+name+args)
1492 file.write('{\n')
1493 file.write(' uint64_t val;\n')
1494 if self.opc[:9] == 'stpartial':
1495 file.write(' uint64_t msk;\n')
1496 file.write(' SS_Tte* _tte = (SS_Tte*)(long(tte) &~ 3);\n')
1497 file.write(' SS_Paddr pa = _tte->trans(va);\n')
1498 file.write('#if defined(MEMORY_MSYNC)\n')
1499 file.write(' ((SS_MsyncMemory*)(s->'+src+'))->msync_info(s->strand_id(),va);\n')
1500 file.write('#elif defined(MEMORY_EXTERNAL)\n')
1501 if src == 'memory':
1502 file.write(' ((SS_ExternalMemory*)(s->'+src+'))->set_strand_id(s->strand_id());\n')
1503 file.write('#endif\n')
1504
1505 if self.out == 'g0':
1506 if self.opc == 'std':
1507 if endian == 'b':
1508 file.write(' val = uint32_t(s->get_irf(i->rd + 8));\n')
1509 else:
1510 file.write(' val = s->get_irf(i->rd + 8) << 32;\n')
1511 else:
1512 file.write(' val = 0;\n')
1513 else:
1514 if self.opc == 'std':
1515 if endian == 'b':
1516 file.write(' val = (s->get_irf(i->rd) << 32) | uint32_t(s->get_irf(i->rd + 8));\n')
1517 else:
1518 file.write(' val = (s->get_irf(i->rd + 8) << 32) | uint32_t(s->get_irf(i->rd));\n')
1519 elif self.opc == 'stf':
1520 file.write(' val = s->get_frf(i->rd);\n')
1521 elif self.opc == 'stdf' or self.opc[:8] == 'stshortf':
1522 file.write(' val = s->get_drf(i->rd);\n')
1523 elif self.opc[:9] == 'stpartial':
1524 file.write(' val = s->get_drf(i->rd);\n')
1525 file.write(' msk = s->mem_mask;\n')
1526 elif self.opc == 'stblockf':
1527 file.write(' s->mem_data[0] = s->get_drf(i->rd );\n')
1528 file.write(' s->mem_data[1] = s->get_drf(i->rd + 8);\n')
1529 file.write(' s->mem_data[2] = s->get_drf(i->rd + 16);\n')
1530 file.write(' s->mem_data[3] = s->get_drf(i->rd + 24);\n')
1531 file.write(' s->mem_data[4] = s->get_drf(i->rd + 32);\n')
1532 file.write(' s->mem_data[5] = s->get_drf(i->rd + 40);\n')
1533 file.write(' s->mem_data[6] = s->get_drf(i->rd + 48);\n')
1534 file.write(' s->mem_data[7] = s->get_drf(i->rd + 56);\n')
1535 elif self.opc[-3:] == 'fsr':
1536 file.write(' s->get_fsr();\n')
1537 file.write(' val = s->fsr();\n')
1538 file.write(' s->fsr.ftt(0);\n')
1539 file.write(' s->set_fsr();\n')
1540 else:
1541 file.write(' val = s->get_irf(i->rd);\n')
1542
1543 if endian == 'l':
1544
1545 if self.opc == 'sth' or self.opc == 'stshortf16':
1546 file.write(' val = endianess_convert_16u(val);\n')
1547 elif self.opc == 'stw' or self.opc == 'stf' or self.opc == 'stfsr':
1548 file.write(' val = endianess_convert_32u(val);\n')
1549 elif self.opc == 'stx' or self.opc == 'std' or self.opc == 'stdf' or self.opc == 'stxfsr':
1550 file.write(' val = endianess_convert_64(val);\n')
1551 elif self.opc[:9] == 'stpartial':
1552 file.write(' val = endianess_convert_64(val);\n')
1553 file.write(' msk = endianess_partial(s->mem_mask);\n')
1554 elif self.opc == 'stblockf':
1555 file.write(' s->mem_data[0] = endianess_convert_64(s->mem_data[0]);\n')
1556 file.write(' s->mem_data[1] = endianess_convert_64(s->mem_data[1]);\n')
1557 file.write(' s->mem_data[2] = endianess_convert_64(s->mem_data[2]);\n')
1558 file.write(' s->mem_data[3] = endianess_convert_64(s->mem_data[3]);\n')
1559 file.write(' s->mem_data[4] = endianess_convert_64(s->mem_data[4]);\n')
1560 file.write(' s->mem_data[5] = endianess_convert_64(s->mem_data[5]);\n')
1561 file.write(' s->mem_data[6] = endianess_convert_64(s->mem_data[6]);\n')
1562 file.write(' s->mem_data[7] = endianess_convert_64(s->mem_data[7]);\n')
1563
1564
1565 if mode == 'trc':
1566 if self.opc == 'stb' or self.opc == 'stshortf8':
1567 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_DATA,va,_tte,1,&val);\n')
1568 elif self.opc == 'sth' or self.opc == 'stshortf16':
1569 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_DATA,va,_tte,2,&val);\n')
1570 elif self.opc == 'stw' or self.opc == 'stf' or self.opc == 'stfsr':
1571 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_DATA,va,_tte,4,&val);\n')
1572 elif self.opc == 'stx' or self.opc == 'std' or self.opc == 'stdf' or self.opc == 'stxfsr':
1573 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_DATA,va,_tte,8,&val);\n')
1574 elif self.opc[:9] == 'stpartial':
1575 file.write(' s->mem_data[0] = val;\n');
1576 file.write(' s->mem_data[1] = msk;\n');
1577 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_DATA,va,_tte,8,s->mem_data);\n')
1578 file.write(' val = s->mem_data[0];\n');
1579 file.write(' msk = s->mem_data[1];\n');
1580 elif self.opc == 'stblockf':
1581 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_DATA,va,_tte,64,s->mem_data);\n')
1582
1583 if mode == 'run' and src == 'memory':
1584 if self.opc == 'stb' or self.opc == 'stshortf8':
1585 file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::st8('+sid+'pa,val);\n')
1586 elif self.opc == 'sth' or self.opc == 'stshortf16':
1587 file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::st16('+sid+'pa,val);\n')
1588 elif self.opc == 'stw' or self.opc == 'stf' or self.opc == 'stfsr':
1589 file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::st32('+sid+'pa,val);\n')
1590 elif self.opc == 'stx' or self.opc == 'std' or self.opc == 'stdf' or self.opc == 'stxfsr':
1591 file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::st64('+sid+'pa,val);\n')
1592 elif self.opc[:9] == 'stpartial':
1593 file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::st64partial('+sid+'pa,val,msk);\n')
1594 elif self.opc == 'stblockf':
1595 file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::st512('+sid+'pa,s->mem_data);\n')
1596 else:
1597 if self.opc == 'stb' or self.opc == 'stshortf8':
1598 file.write(' s->'+src+'->st8('+sid+'pa,val);\n')
1599 elif self.opc == 'sth' or self.opc == 'stshortf16':
1600 file.write(' s->'+src+'->st16('+sid+'pa,val);\n')
1601 elif self.opc == 'stw' or self.opc == 'stf' or self.opc == 'stfsr':
1602 file.write(' s->'+src+'->st32('+sid+'pa,val);\n')
1603 elif self.opc == 'stx' or self.opc == 'std' or self.opc == 'stdf' or self.opc == 'stxfsr':
1604 file.write(' s->'+src+'->st64('+sid+'pa,val);\n')
1605 elif self.opc[:9] == 'stpartial':
1606 file.write(' s->'+src+'->st64partial('+sid+'pa,val,msk);\n')
1607 elif self.opc == 'stblockf':
1608 file.write(' s->'+src+'->st512('+sid+'pa,s->mem_data);\n')
1609
1610 if mode == 'ras' and src == 'memory':
1611 file.write(' if (s->sim_state.ras_enabled())\n')
1612 file.write(' {\n')
1613 file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
1614 file.write(' SS_Trap::Type tt = med.inject_store_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa, val);\n')
1615 file.write(' /*Precise traps not generated by any current architectures*/\n')
1616 file.write(' assert (tt == SS_Trap::NO_TRAP);\n')
1617 file.write(' }\n')
1618
1619 file.write(' s->npc = npc+4; return npc;\n')
1620 file.write('}\n')
1621
1622 def run_dec_c(self,file):
1623 pass
1624
1625 def run_dec_p(self):
1626 return ''
1627
1628
1629#============================================================================
1630# SS_swap_mem(opc,out)
1631#============================================================================
1632
1633class SS_swap_mem(SS_InstrAsm):
1634 def __init__(self,opc,out):
1635 SS_InstrAsm.__init__(self,opc+'_'+out)
1636 self.opc = opc
1637 self.out = out
1638
1639 def mem_c(self,file):
1640 for mode in ['run','trc','ras']:
1641 for src in ['memory','io']:
1642 for endian in ['b','l']:
1643 args = '( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, SS_Vaddr va, SS_Tte* tte )\n'
1644 name = endian+'_'+self.opc+'_'+self.out
1645 if src == 'memory':
1646 sid = ''
1647 file.write('\nextern "C" SS_Vaddr mem_'+mode+'_'+name+args)
1648 else:
1649 sid = 's->strand_id(),'
1650 file.write('\nextern "C" SS_Vaddr io_'+mode+'_'+name+args)
1651 file.write('{\n')
1652 self.fail_chkpt(file)
1653 file.write(' uint64_t val;\n')
1654 file.write(' SS_Tte* _tte = (SS_Tte*)(long(tte) &~ 3);\n')
1655 file.write(' SS_Paddr pa = _tte->trans(va);\n')
1656 file.write('#if defined(MEMORY_MSYNC)\n')
1657 file.write(' ((SS_MsyncMemory*)(s->'+src+'))->msync_info(s->strand_id(),va);\n')
1658 file.write('#elif defined(MEMORY_EXTERNAL)\n')
1659 if src == 'memory':
1660 file.write(' ((SS_ExternalMemory*)(s->'+src+'))->set_strand_id(s->strand_id());\n')
1661 file.write('#endif\n')
1662
1663 if self.out == 'rd':
1664 file.write(' val = s->get_irf(i->rd);\n')
1665 else:
1666 file.write(' val = 0;\n')
1667
1668 if endian == 'l':
1669 file.write(' val = endianess_convert_32u(val);\n')
1670
1671 if mode == 'trc':
1672 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_SWAP,va,_tte,4,&val);\n')
1673 if mode == 'run' and src == 'memory':
1674 file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::swap('+sid+'pa,val);\n')
1675 else:
1676 file.write(' val = s->'+src+'->swap('+sid+'pa,val);\n')
1677
1678 if mode == 'ras' and src == 'memory':
1679 file.write(' if (s->sim_state.ras_enabled())\n')
1680 file.write(' {\n')
1681 file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
1682 file.write(' SS_Trap::Type tt = med.inject_store_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa, val);\n')
1683 file.write(' /*Precise traps not generated by any current architectures*/\n')
1684 file.write(' assert (tt == SS_Trap::NO_TRAP);\n')
1685 file.write(' }\n')
1686
1687
1688 if mode == 'trc':
1689 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_SWAP,va,_tte,4,&val);\n')
1690
1691 if mode == 'ras' and src == 'memory':
1692 file.write(' if (s->sim_state.ras_enabled())\n')
1693 file.write(' {\n')
1694 file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
1695 file.write(' SS_Trap::Type tt = med.detect_load_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa);\n')
1696 file.write(' if (tt != SS_Trap::NO_TRAP)\n')
1697 file.write(' return (s->trap)(pc,npc,s,i,tt);\n')
1698 file.write(' }\n')
1699
1700 if endian == 'l':
1701 file.write(' val = endianess_convert_32u(val);\n')
1702
1703 if self.out == 'rd':
1704 file.write(' s->get_irf(i->rd) = val;\n')
1705 else:
1706 file.write(' s->mmu_scratch = val;\n')
1707
1708 file.write(' s->npc = npc+4; return npc;\n')
1709 file.write('}\n')
1710
1711 def run_dec_c(self,file):
1712 pass
1713
1714 def run_dec_p(self):
1715 return ''
1716
1717
1718
1719#============================================================================
1720# SS_cas_mem(opc,out)
1721#============================================================================
1722
1723class SS_cas_mem(SS_InstrAsm):
1724 def __init__(self,opc,out):
1725 SS_InstrAsm.__init__(self,opc+'_'+out)
1726 self.opc = opc
1727 self.out = out
1728
1729 def mem_c(self,file):
1730 for mode in ['run','trc','ras']:
1731 for src in ['memory','io']:
1732 for endian in ['b','l']:
1733 args = '( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, SS_Vaddr va, SS_Tte* tte )\n'
1734 name = endian+'_'+self.opc+'_'+self.out
1735 if src == 'memory':
1736 file.write('\nextern "C" SS_Vaddr mem_'+mode+'_'+name+args)
1737 sid = ''
1738 else:
1739 sid = 's->strand_id(),'
1740 file.write('\nextern "C" SS_Vaddr io_'+mode+'_'+name+args)
1741 file.write('{\n')
1742 self.fail_chkpt(file)
1743 file.write(' uint64_t val;\n')
1744 file.write(' uint64_t rs2;\n')
1745 file.write(' SS_Tte* _tte = (SS_Tte*)(long(tte) &~ 3);\n')
1746 file.write(' SS_Paddr pa = _tte->trans(va);\n')
1747 file.write('#if defined(MEMORY_MSYNC)\n')
1748 file.write(' ((SS_MsyncMemory*)(s->'+src+'))->msync_info(s->strand_id(),va);\n')
1749 file.write('#elif defined(MEMORY_EXTERNAL)\n')
1750 if src == 'memory':
1751 file.write(' ((SS_ExternalMemory*)(s->'+src+'))->set_strand_id(s->strand_id());\n')
1752 file.write('#endif\n')
1753
1754 if self.out == 'rd':
1755 file.write(' val = s->get_irf(i->rd);\n')
1756 else:
1757 file.write(' val = 0;\n')
1758 file.write(' rs2 = s->get_irf(i->rs2);\n')
1759
1760 if endian == 'l':
1761 if self.opc == 'casx':
1762 file.write(' val = endianess_convert_64(val);\n')
1763 file.write(' rs2 = endianess_convert_64(rs2);\n')
1764 else:
1765 file.write(' val = endianess_convert_32u(val);\n')
1766 file.write(' rs2 = endianess_convert_32u(rs2);\n')
1767
1768 if mode == 'trc':
1769 file.write(' s->mem_data[0] = val;\n')
1770 file.write(' s->mem_data[1] = rs2;\n')
1771 if self.opc == 'casx':
1772 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_CAS,va,_tte,8,s->mem_data);\n')
1773 else:
1774 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_CAS,va,_tte,4,s->mem_data);\n')
1775 file.write(' val = s->mem_data[0];\n')
1776 file.write(' rs2 = s->mem_data[1];\n')
1777
1778 if mode == 'run' and src == 'memory':
1779 file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::'+self.opc+'('+sid+'pa,val,rs2);\n')
1780 else:
1781 file.write(' val = s->'+src+'->'+self.opc+'('+sid+'pa,val,rs2);\n')
1782
1783 if mode == 'ras' and src == 'memory':
1784 file.write(' if (s->sim_state.ras_enabled())\n')
1785 file.write(' {\n')
1786 file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
1787 file.write(' SS_Trap::Type tt = med.inject_store_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa, val);\n')
1788 file.write(' /*Precise traps not generated by any current architectures*/\n')
1789 file.write(' assert (tt == SS_Trap::NO_TRAP);\n')
1790 file.write(' }\n')
1791
1792 if mode == 'trc':
1793 if self.opc == 'casx':
1794 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_CAS,va,_tte,8,&val);\n')
1795 else:
1796 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_CAS,va,_tte,4,&val);\n')
1797
1798 if mode == 'ras' and src == 'memory':
1799 file.write(' if (s->sim_state.ras_enabled())\n')
1800 file.write(' {\n')
1801 file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
1802 file.write(' SS_Trap::Type tt = med.detect_load_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa);\n')
1803 file.write(' if (tt != SS_Trap::NO_TRAP)\n')
1804 file.write(' return (s->trap)(pc,npc,s,i,tt);\n')
1805 file.write(' }\n')
1806
1807 if endian == 'l':
1808 if self.opc == 'casx':
1809 file.write(' val = endianess_convert_64(val);\n')
1810 else:
1811 file.write(' val = endianess_convert_32u(val);\n')
1812
1813 if self.out == 'rd':
1814 file.write(' s->get_irf(i->rd) = val;\n')
1815 else:
1816 file.write(' s->mmu_scratch = val;\n')
1817
1818 file.write(' s->npc = npc+4; return npc;\n')
1819 file.write('}\n')
1820
1821 def run_dec_c(self,file):
1822 pass
1823
1824 def run_dec_p(self):
1825 return ''
1826
1827
1828
1829#============================================================================
1830# SS_ldstub_mem(opc,out)
1831#============================================================================
1832
1833class SS_ldstub_mem(SS_InstrAsm):
1834 def __init__(self,opc,out):
1835 SS_InstrAsm.__init__(self,opc+'_'+out)
1836 self.opc = opc
1837 self.out = out
1838
1839 def mem_c(self,file):
1840 for mode in ['run','trc','ras']:
1841 for src in ['memory','io']:
1842 for endian in ['b','l']:
1843 args = '( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, SS_Vaddr va, SS_Tte* tte )\n'
1844 name = endian+'_'+self.opc+'_'+self.out
1845 if src == 'memory':
1846 file.write('\nextern "C" SS_Vaddr mem_'+mode+'_'+name+args)
1847 sid = ''
1848 else:
1849 sid = 's->strand_id(),'
1850 file.write('\nextern "C" SS_Vaddr io_'+mode+'_'+name+args)
1851 file.write('{\n')
1852 self.fail_chkpt(file)
1853 file.write(' uint64_t val;\n')
1854 file.write(' SS_Tte* _tte = (SS_Tte*)(long(tte) &~ 3);\n')
1855 file.write(' SS_Paddr pa = _tte->trans(va);\n')
1856 file.write('#if defined(MEMORY_MSYNC)\n')
1857 file.write(' ((SS_MsyncMemory*)(s->'+src+'))->msync_info(s->strand_id(),va);\n')
1858 file.write('#elif defined(MEMORY_EXTERNAL)\n')
1859 if src == 'memory':
1860 file.write(' ((SS_ExternalMemory*)(s->'+src+'))->set_strand_id(s->strand_id());\n')
1861 file.write('#endif\n')
1862
1863 if mode == 'trc':
1864 file.write(' val = 0xff;\n')
1865 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_LDST,va,_tte,1,&val);\n')
1866
1867 if mode == 'run' and src == 'memory':
1868 file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ldstub('+sid+'pa);\n')
1869 else:
1870 file.write(' val = s->'+src+'->ldstub('+sid+'pa);\n')
1871
1872 if mode == 'ras' and src == 'memory':
1873 file.write(' if (s->sim_state.ras_enabled())\n')
1874 file.write(' {\n')
1875 file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
1876 file.write(' SS_Trap::Type tt = med.inject_store_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa, val);\n')
1877 file.write(' /*Precise traps not generated by any current architectures*/\n')
1878 file.write(' assert (tt == SS_Trap::NO_TRAP);\n')
1879 file.write(' }\n')
1880
1881
1882 if mode == 'trc':
1883 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_LDST,va,_tte,1,&val);\n')
1884
1885 if mode == 'ras' and src == 'memory':
1886 file.write(' if (s->sim_state.ras_enabled())\n')
1887 file.write(' {\n')
1888 file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
1889 file.write(' SS_Trap::Type tt = med.detect_load_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa);\n')
1890 file.write(' if (tt != SS_Trap::NO_TRAP)\n')
1891 file.write(' return (s->trap)(pc,npc,s,i,tt);\n')
1892 file.write(' }\n')
1893
1894 if self.out == 'rd':
1895 file.write(' s->get_irf(i->rd) = val;\n')
1896 else:
1897 file.write(' s->mmu_scratch = val;\n')
1898
1899 file.write(' s->npc = npc+4; return npc;\n')
1900 file.write('}\n')
1901
1902 def run_dec_c(self,file):
1903 pass
1904
1905 def run_dec_p(self):
1906 return ''
1907
1908
1909#============================================================================
1910# SS_flush_mem(opc,out)
1911#============================================================================
1912
1913class SS_flush_mem(SS_InstrAsm):
1914 def __init__(self,opc,out):
1915 SS_InstrAsm.__init__(self,opc+'_'+out)
1916 self.opc = opc
1917 self.out = out
1918
1919 def mem_c(self,file):
1920 for mode in ['run','trc','ras']:
1921 args = '( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, SS_Vaddr va, SS_Tte* tte )\n'
1922 name = self.opc+'_'+self.out
1923 file.write('\nextern "C" SS_Vaddr mem_'+mode+'_'+name+args)
1924 file.write('{\n')
1925 self.fail_chkpt(file)
1926
1927 # In cosim mode the flush is just ignored
1928
1929 file.write(' if (s->sim_state.cosim())\n')
1930 file.write(' {\n')
1931 file.write(' s->npc = npc + 4;\n')
1932 file.write(' return npc;\n')
1933 file.write(' }\n')
1934
1935 if setup.product == 'N2':
1936 # On N2 say the TTE is not valid so we use an identity TTE (va == pa that is)
1937 file.write(' SS_Tte* _tte = s->phys_tte_mem;\n')
1938 file.write(' SS_Paddr pa = va;\n')
1939
1940 if mode == 'trc':
1941 file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::FLUSH,va,_tte,0,0);\n')
1942
1943 # In execution driven mode we do not do flush operations, we
1944 # just nop the flush. We don't do decode caching in this mode.
1945
1946 file.write(' if (s->sim_state.exec_driven())\n')
1947 file.write(' {\n')
1948 file.write(' s->npc = npc + 4;\n')
1949 file.write(' return pc;\n')
1950 file.write(' }\n')
1951
1952 # The flush is broadcasted to all the strands. A strand will see the flush
1953 # request and the next instruction will be refetched.
1954
1955 if setup.product == 'N2':
1956 # Products like USIII and N2 have coherent instruction caches,
1957 # which means flush is just draining the storebuffer. For us it means
1958 # nuke the decode caches, infinite size (~0).
1959 file.write(' s->model->flush(s,pa,~0);\n')
1960 file.write(' s->npc = npc + 4;\n')
1961 file.write(' return npc;\n')
1962 file.write('}\n')
1963
1964 def run_dec_c(self,file):
1965 pass
1966
1967 def run_dec_p(self):
1968 return ''
1969
1970 def gen_mem_tbl(self,file,mode):
1971 if mode == 'idx':
1972 return SS_Instr. gen_mem_tbl(self,file,mode)
1973 file.write(' mem_%s_%s,\n' % (mode,self.name))
1974 file.write(' mem_%s_%s,\n' % (mode,self.name))
1975 file.write(' mem_%s_%s,\n' % (mode,self.name))
1976 file.write(' mem_%s_%s,\n' % (mode,self.name))
1977
1978
1979
1980
1981#============================================================================
1982# SS_rdasi(imm,out)
1983#============================================================================
1984
1985class SS_rdasi(SS_InstrAsm):
1986 def __init__(self,imm,out):
1987 SS_InstrAsm.__init__(self,'rdasi_'+imm+'_'+out)
1988 self.opc = 'rdasi'
1989 self.imm = imm
1990 self.out = out
1991
1992 def run_exe_c(self,file):
1993 self.c_code_beg(file,'run_exe_')
1994 if self.imm == 'i0':
1995 file.write(' SS_Vaddr va = s->get_irf(i->rs1) + s->get_irf(i->rs2);\n')
1996 else:
1997 file.write(' if (i->asi != s->asi())\n')
1998 file.write(' return (s->inst_dec)(pc,npc,s,i);\n')
1999 file.write(' SS_Vaddr va = s->get_irf(i->rs1) + i->rs2;\n')
2000 file.write(' va &= s->mask_pstate_am;\n')
2001 file.write(' \n')
2002 file.write(' if (va & 7)\n')
2003 file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::MEM_ADDRESS_NOT_ALIGNED);\n')
2004 file.write(' if (s->sim_state.priv() < s->asi_info[i->asi].get_protection())\n')
2005 file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::PRIVILEGED_ACTION);\n')
2006 if self.out == 'g0':
2007 file.write(' SS_AsiSpace::Error ok = s->asi_map.ld64(s,i->asi,va,&s->mmu_scratch);\n')
2008 else:
2009 file.write(' SS_AsiSpace::Error ok = s->asi_map.ld64(s,i->asi,va,&s->get_irf(i->rd));\n')
2010 file.write(' switch (ok)\n')
2011 file.write(' {\n')
2012 file.write(' case SS_AsiSpace::OK:\n')
2013 file.write(' s->npc = npc+4; return npc;\n')
2014 file.write(' case SS_AsiSpace::TRAP_PA:\n')
2015 file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::PRIVILEGED_ACTION);\n')
2016 file.write(' case SS_AsiSpace::TRAP_IA:\n')
2017 file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::DAE_INVALID_ASI);\n')
2018 file.write(' case SS_AsiSpace::TRAP_IPE:\n')
2019 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::INTERNAL_PROCESSOR_ERROR);\n')
2020 file.write(' case SS_AsiSpace::RETRY:\n')
2021 file.write(' return pc;\n')
2022 file.write(' default:\n')
2023 file.write(' return (s->invalid_asi)(pc,npc,s,i,va);\n')
2024 file.write(' }\n')
2025 self.c_code_end(file)
2026
2027 def run_dec_c(self,file):
2028 pass
2029
2030 def run_dec_p(self):
2031 return ''
2032
2033 def gen_exe_tbl(self,file,mode):
2034 if mode == 'v8_run':
2035 mode = 'run'
2036 self.gen_exe_rrI(file,mode,self.imm,self.out)
2037
2038#============================================================================
2039# SS_wrasi(imm,out)
2040#============================================================================
2041
2042class SS_wrasi(SS_InstrAsm):
2043 def __init__(self,imm,out):
2044 SS_InstrAsm.__init__(self,'wrasi_'+imm+'_'+out)
2045 self.opc = 'wrasi'
2046 self.imm = imm
2047 self.out = out
2048
2049 def run_exe_c(self,file):
2050 self.c_code_beg(file,'run_exe_')
2051 if setup.product == 'N2':
2052 file.write(' N2_Strand* _s = (N2_Strand*)s;\n')
2053 self.fail_chkpt(file)
2054 if self.imm == 'i0':
2055 file.write(' SS_Vaddr va = s->get_irf(i->rs1) + s->get_irf(i->rs2);\n')
2056 else:
2057 file.write(' if (i->asi != s->asi())\n')
2058 file.write(' return (s->inst_dec)(pc,npc,s,i);\n')
2059 file.write(' SS_Vaddr va = s->get_irf(i->rs1) + i->rs2;\n')
2060
2061 file.write(' va &= s->mask_pstate_am;\n')
2062 file.write(' \n')
2063 file.write(' if (va & 7)\n')
2064 file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::MEM_ADDRESS_NOT_ALIGNED);\n')
2065 file.write(' if (s->sim_state.priv() < s->asi_info[i->asi].get_protection())\n')
2066 file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::PRIVILEGED_ACTION);\n')
2067 file.write(' uint64_t rd;\n')
2068 if self.out == 'rd':
2069 file.write(' SS_AsiSpace::Error ok = s->asi_map.st64(s,i->asi,va,s->get_irf(i->rd));\n')
2070 else:
2071 file.write(' SS_AsiSpace::Error ok = s->asi_map.st64(s,i->asi,va,0);\n')
2072 file.write(' switch (ok)\n')
2073 file.write(' {\n')
2074 file.write(' case SS_AsiSpace::OK:\n')
2075
2076 if setup.product == 'N2':
2077 file.write(' //fill store buffer call for non-translating asi store\n')
2078 file.write(' if (s->sim_state.ras_enabled())\n')
2079 file.write(' _s->fill_store_buffer_asi(va,i->asi,s->get_irf(i->rd));\n')
2080
2081 file.write(' s->npc = npc+4; return npc;\n')
2082 file.write(' case SS_AsiSpace::TRAP_PA:\n')
2083 file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::PRIVILEGED_ACTION);\n')
2084 file.write(' case SS_AsiSpace::TRAP_IA:\n')
2085 file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::DAE_INVALID_ASI);\n')
2086 file.write(' case SS_AsiSpace::TRAP_IPE:\n')
2087 file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::INTERNAL_PROCESSOR_ERROR);\n')
2088 file.write(' case SS_AsiSpace::RETRY:\n')
2089 file.write(' return pc;\n')
2090 file.write(' default:\n')
2091 file.write(' return (s->invalid_asi)(pc,npc,s,i,va);\n')
2092 file.write(' }\n')
2093 self.c_code_end(file)
2094
2095 def run_dec_c(self,file):
2096 pass
2097
2098 def run_dec_p(self):
2099 return ''
2100
2101 def gen_exe_tbl(self,file,mode):
2102 if mode == 'v8_run':
2103 mode = 'run'
2104 self.gen_exe_RrI(file,mode,self.imm,self.out)
2105
2106#============================================================================
2107#============================================================================
2108
2109ss_flush = SS_InstrGroup('10_111011_flush',25,0x1f)
2110ss_ldxfsr = SS_InstrGroup('11_100001_ldxfsr',25,0x1f)
2111ss_stxfsr = SS_InstrGroup('11_100101_stxfsr',25,0x1f)
2112ss_prefetch = SS_InstrGroup('11_101101_prefetch',25,0x1f)
2113ss_prefetcha = SS_InstrGroup('11_111101_prefetcha',25,0x1f)
2114
2115ss_flush.append(SS_lsu_dec('flush'))
2116if setup.product == 'N2':
2117 ss_flush.append(SS_ill())
2118for i in range(0,30):
2119 ss_flush.append(SS_ill())
2120
2121ss_ldxfsr.append(SS_lsu_dec('ldfsr'))
2122ss_ldxfsr.append(SS_lsu_dec('ldxfsr'))
2123if setup.product == 'N2':
2124 for i in range(0,30):
2125 ss_ldxfsr.append(SS_ill())
2126
2127ss_stxfsr.append(SS_lsu_dec('stfsr'))
2128ss_stxfsr.append(SS_lsu_dec('stxfsr'))
2129for i in range(0,30):
2130 ss_stxfsr.append(SS_ill())
2131
2132ss_prefetch.append(SS_lsu_dec('prefetch_dec'))
2133for i in range(0,4):
2134 ss_prefetch.append(SS_lsu_dec('prefetch_tmp'))
2135for i in range(0,11):
2136 ss_prefetch.append(SS_ill())
2137for i in range(0,16):
2138 ss_prefetch.append(SS_lsu_dec('prefetch_tmp'))
2139
2140ss_prefetcha.append(SS_lsu_dec('prefetcha_dec'))
2141for i in range(0,4):
2142 ss_prefetcha.append(SS_lsu_dec('prefetcha_tmp'))
2143for i in range(0,11):
2144 ss_prefetcha.append(SS_ill())
2145for i in range(0,16):
2146 ss_prefetcha.append(SS_lsu_dec('prefetcha_tmp'))