Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / bin / SS_InstrLsu.py
# ========== Copyright Header Begin ==========================================
#
# OpenSPARC T2 Processor File: SS_InstrLsu.py
# Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
#
# The above named program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License version 2 as published by the Free Software Foundation.
#
# The above named program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this work; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ========== Copyright Header End ============================================
from SS_Instr import *
from SS_Instr import _if_
from SS_Setup import *
setup = setups[sys.argv[1]]
#============================================================================
# SS_lsu_exe(opc)
#============================================================================
class SS_lsu_exe(SS_InstrAsm):
def __init__(self,opc):
SS_InstrAsm.__init__(self,opc)
self.opc = opc
self.asi = ['dft', 'reg', 'imm']
self.imm = ['i0' ,'i1']
self.out = ['rd' ,'g0', 'ia']
def is_float(self):
return self.opc == 'ldf' or self.opc == 'lddf' or self.opc == 'stf' or self.opc == 'stdf' or \
self.opc[2:7] == 'short' or self.opc[2:7] == 'block' or self.opc[2:7] == 'parti' or \
self.opc[-3:] == 'fsr'
def is_sgl_fp(self):
'''
Is load or store a simple single precision FP operation
'''
return self.opc == 'ldf' or self.opc == 'stf'
def is_dbl_fp(self):
'''
Is load or store a simple double precision FP operation
'''
return self.opc == 'lddf' or self.opc == 'stdf'
def is_atomic(self):
return self.opc[:6] == 'ldstub' or self.opc[:4] == 'swap' or self.opc[:3] == 'cas'
def run_exe_c(self,file):
for asi in self.asi:
for out in self.out:
if self.is_float() or self.opc == 'prefetch' or self.opc == 'flush':
if out == 'g0':
continue
if out == 'rd':
if self.is_float():
out = 'fp'
else:
out = 'fn'
# ldfsr, stfsr, ldxfsr, stxfsr, and ldxefsr don't have alternative space versions
if self.opc[-3:] == 'fsr' and asi != 'dft':
continue
for imm in self.imm:
file.write('#if defined(ARCH_X64)\n')
self.c_code_beg_name(file,'run_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out)
if out == 'rd' or out == 'g0' or out == 'fp' or out == 'fn':
alignment=self.va_lower_bits()
mmu_access = not (self.opc == 'flush')
if out == 'fp':
file.write(' if (s->sim_state.fp_disabled())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n')
if asi=='reg':
file.write(' if (i->asi != s->asi())\n')
file.write(' return (s->inst_dec)(pc,npc,s,i);\n')
if (self.opc[:3] == 'cas'):
file.write(' uint64_t ea = s->get_irf(i->rs1);\n')
elif (self.opc == 'stpartial8'):
file.write(' uint64_t ea = s->get_irf(i->rs1);\n')
file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
file.write(' s->mem_mask = rs2 & 0xff;\n')
elif (self.opc == 'stpartial16'):
file.write(' uint64_t ea = s->get_irf(i->rs1);\n')
file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
file.write(' s->mem_mask = s->stpartial16[rs2 & 0xf];\n')
elif (self.opc == 'stpartial32'):
file.write(' uint64_t ea = s->get_irf(i->rs1);\n')
file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
file.write(' s->mem_mask = s->stpartial32[rs2 & 0x3];\n')
else:
file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n')
if (imm == 'i0'):
file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
else:
file.write(' int64_t rs2 = i->rs2;\n')
file.write(' uint64_t ea = rs1 + rs2;\n')
if (alignment != '0'):
file.write(' if (ea & '+alignment+') {\n')
if (self.opc[:4] == 'lddf'):
file.write(' if ((ea & 7) == 4)\n')
file.write(' return (s->data_trap)(pc,npc,s,i,ea,SS_Trap::LDDF_MEM_ADDRESS_NOT_ALIGNED);\n')
elif (self.opc[:4] == 'stdf'):
file.write(' if ((ea & 7) == 4)\n')
file.write(' return (s->data_trap)(pc,npc,s,i,ea,SS_Trap::STDF_MEM_ADDRESS_NOT_ALIGNED);\n')
file.write(' return (s->data_trap)(pc,npc,s,i,ea,SS_Trap::MEM_ADDRESS_NOT_ALIGNED);\n')
file.write(' }\n')
file.write(' uint_t mem = idx_mem_'+self.opc+'_'+out+';\n')
if mmu_access:
file.write(' SS_Tte *_tte = i->get_tte();\n')
file.write(' if (!_tte->match(ea))\n')
file.write(' return (s->data_mmu)(pc,npc,s,i,ea,mem);\n')
file.write(' SS_Memop exe = s->mem_table[mem][((uint64_t)i->tte & 3)];\n')
file.write(' return (exe)(pc,npc,s,i,ea,i->tte);\n')
else:
#--------------------------------------------------------------------------
# invalid asi.
#--------------------------------------------------------------------------
if self.is_float():
file.write(' if (s->sim_state.fp_disabled())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n')
if asi=='reg':
file.write(' if (i->asi != s->asi())\n')
file.write(' return (s->inst_dec)(pc,npc,s,i);\n')
file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n')
if (self.opc[:3] == 'cas' or self.opc[:9] == 'stpartial'):
file.write(' SS_Vaddr ea = rs1;\n');
else:
if (imm == 'i0'):
file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
else:
file.write(' int64_t rs2 = i->rs2;\n');
file.write(' SS_Vaddr ea = rs1 + rs2;\n');
file.write(' return (s->invalid_asi)(pc,npc,s,i,ea);\n')
self.c_code_end(file)
file.write('#else\n')
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')
file.write('#endif\n')
def run_exe_s(self,file):
global setup
if self.opc == 'ldtd':
self_opc = 'ldd'
else:
self_opc = self.opc
for asi in self.asi:
for out in self.out:
if self.is_float() or self.opc == 'prefetch' or self.opc == 'flush':
if out == 'g0':
continue
if out == 'rd':
if self.is_float():
out = 'fp'
else:
out = 'fn'
# ldfsr, stfsr, ldxfsr, stxfsr, and ldxefsr don't have alternative space versions
if self.opc[-3:] == 'fsr' and asi != 'dft':
continue
for imm in self.imm:
#----------------------------------------------------------------------------
#
#----------------------------------------------------------------------------
if out == 'rd' or out == 'g0' or out == 'fp' or out == 'fn':
self.asm_function(file,'run_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out)
alignment=self.va_lower_bits()
mmu_access = not (self.opc == 'flush')
byte_mask=self.wp_byte_mask()
if out == 'fp':
for l in [
' ldx [S_PTR + S_SIM_STATE],%g5',
' andcc %g5,F_FP_DISABLED,%g0',
' bne %xcc,fpop_disabled_trap'
]:
file.write('%s\n' % l)
if mmu_access:
for l in [
_if_(asi=='reg',
' lduh [I_PTR + I_ASI],%g1\n' # check for %asi change
' ldub [S_PTR + S_ASI],%g2', # change uh when asi changes ToDo
''
),
' ldptr [I_PTR + I_TTE],%o5', # o0 o1 o2 o3 -- o5 -- -- -- -- --
' lduh [I_PTR + I_RS1],%o4', # .. .. .. .. o4 .. -- -- -- -- --
_if_(imm=='i0',
' lduh [I_PTR + I_RS2],%g5' # .. .. .. .. .. .. -- -- -- -- g5
,
' ldsh [I_PTR + I_RS2],%g5'
),
_if_(asi=='reg',
' subcc %g1,%g2,%g0',
''
),
' and %o5,-4,%g2', # .. .. .. .. .. .. -- g2 -- -- ..
_if_(asi=='reg',
' bne %xcc,2f', # Oops, -> redecode instruction
''
),
' ldptr [S_PTR + S_MEM_TABLE],%g3', # .. .. .. .. .. .. -- .. g3 -- ..
' ldx [S_PTR + %o4],%o4',
_if_(imm=='i0',
' ldx [S_PTR + %g5],%g5', ''
),
' and %o5,3,%g4', # mem b, mem l, io b, io l?
' ldx [%g2 + X_VIRT_MASK],%g1', # .. .. .. .. .. .. g1 .. .. -- ..
' sll %g4,PTR_SIZE_BITS,%g4',
' ldx [%g2 + X_VIRT_PAGE],%g2', # .. .. .. .. .. .. .. .. .. -- ..
' add %g3,%g4,%g3',
_if_(self_opc[:3] == 'cas',
'',
_if_(self_opc == 'stpartial8',
' and %g5,0xff,%g5\n'
' stx %g5,[S_PTR + S_MEM_MASK]',
_if_(self_opc == 'stpartial16',
' and %g5,0xf,%g5\n'
' add %g5,S_STPARTIAL16,%g5\n'
' ldub [S_PTR + %g5],%g5\n'
' stx %g5,[S_PTR + S_MEM_MASK]',
_if_(self_opc == 'stpartial32',
' and %g5,0x3,%g5\n'
' add %g5,S_STPARTIAL32,%g5\n'
' ldub [S_PTR + %g5],%g5\n'
' stx %g5,[S_PTR + S_MEM_MASK]',
' add %o4,%g5,%o4'
)))), # .. .. .. .. .. .. .. .. -- -- --
' and %o4,%g1,%g1', # .. .. .. .. .. .. .. .. -- -- --
_if_(alignment != '0',
' andcc %o4,'+alignment+',%g0',
''
),
' ldptr [%g3 + IDX_MEM_'+self.opc.upper()+'_'+out.upper()+'*4*PTR_SIZE],%g5',
_if_(alignment != '0',
_if_(self.opc[:4] == 'lddf',
' bne %xcc,ss_data_trap_lddf_mem_address_not_aligned',
_if_(self.opc[:4] == 'stdf' or self.opc[:9] == 'stpartial',
' bne %xcc,ss_data_trap_stdf_mem_address_not_aligned',
' bne %xcc,ss_data_trap_mem_address_not_aligned',
)),
''
),
'1:',
' cmp %g1,%g2',
' bne %xcc,3f',
' nop',
'#ifdef ARCH_V8',
' st %o5,[%sp + 100]',
' st %o4,[%sp + 96]',
' srlx %o4,32,%o4',
' st %o4,[%sp + 92]',
' sra %o3,0,%o5',
' sra %o2,0,%o4',
' srl %o1,0,%o3',
' srlx %o1,32,%o2',
' srl %o0,0,%o1',
' srlx %o0,32,%o0',
'#endif',
' jmpl %g5,%g0',
' nop',
'3:\n'
' ldptr [S_PTR + DATA_MMU],%g1',
' jmpl %g1,%g0',
' mov IDX_MEM_'+self.opc.upper()+'_'+out.upper()+',%o5',
]:
file.write('%s\n' % l)
else:
for l in [
_if_(asi=='reg',
' lduh [I_PTR + I_ASI],%g1\n' # check for %asi change
' ldub [S_PTR + S_ASI],%g2', # change uh when asi changes ToDo
''
),
' lduh [I_PTR + I_RS1],%o4', # .. .. .. .. o4 .. -- -- -- -- --
_if_(imm=='i0',
' lduh [I_PTR + I_RS2],%g5' # .. .. .. .. .. .. -- -- -- -- g5
,
' ldsh [I_PTR + I_RS2],%g5'
),
_if_(asi=='reg',
' subcc %g1,%g2,%g0\n'
' bne %xcc,2f', # Oops, -> redecode instruction
''
),
' ldptr [S_PTR + S_MEM_TABLE],%g3', # .. .. .. .. .. .. -- .. g3 -- ..
' ldx [S_PTR + %o4],%o4',
_if_(imm=='i0',
' ldx [S_PTR + %g5],%g5', ''
),
' ldptr [%g3 + IDX_MEM_'+self.opc.upper()+'_'+out.upper()+'*4*PTR_SIZE],%g1',
'#ifdef ARCH_V9',
' jmpl %g1,%g0',
' add %o4,%g5,%o4',
'#else',
' add %o4,%g5,%o4',
' st %o5,[%sp + 100]',
' st %o4,[%sp + 96]',
' srlx %o4,32,%o4',
' st %o4,[%sp + 92]',
' sra %o3,0,%o5',
' sra %o2,0,%o4',
' srl %o1,0,%o3',
' srlx %o1,32,%o2',
' srl %o0,0,%o1',
' jmpl %g1,%g0',
' srlx %o0,32,%o0',
'#endif'
]:
file.write('%s\n' % l)
# %asi changed compared to last time we executed the instruction.
# The instruction needs to be redecoded to correct for that change
# through recursion ... keep it simple (but avoid infinite loops!)
if asi == 'reg':
file.write('2:\n')
file.write(' ldptr [S_PTR + INST_DEC],%g1\n')
file.write(' jmpl %g1,%g0\n')
file.write(' nop\n')
file.write('\n')
#----------------------------------------------------------------------------
# invalid asi, check all the things in a C routine ... could do effective
# address calculation there too .... ToDo
#----------------------------------------------------------------------------
else:
self.asm_function(file,'run_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out)
alignment=self.va_lower_bits()
if self.is_float():
for l in [
' ldx [S_PTR + S_SIM_STATE],%g5',
' andcc %g5,F_FP_DISABLED,%g0',
' bne %xcc,fpop_disabled_trap']:
file.write('%s\n' % l)
if asi=='reg':
file.write(' lduh [I_PTR + I_ASI],%g1\n')
file.write(' ldub [S_PTR + S_ASI],%g2\n')
file.write(' subcc %g1,%g2,%g0\n')
file.write(' bne %xcc,2f\n')
if self.opc[:3] == 'cas' or self_opc[:9] == 'stpartial':
for l in [
' ldptr [S_PTR + INVALID_ASI],%g1',
' lduh [I_PTR + I_RS1],%o4',
' jmpl %g1+%g0,%g0',
' ldx [S_PTR + %o4],%o4']:
file.write('%s\n' % l)
elif imm == 'i0':
for l in [
' lduh [I_PTR + I_RS1],%o4',
' lduh [I_PTR + I_RS2],%g5',
' ldptr [S_PTR + INVALID_ASI],%g1',
' ldx [S_PTR + %o4],%o4',
' ldx [S_PTR + %g5],%g5',
' jmpl %g1+%g0,%g0',
' add %o4,%g5,%o4']:
file.write('%s\n' % l)
else:
for l in [
' lduh [I_PTR + I_RS1],%o4',
' ldsh [I_PTR + I_RS2],%g5',
' ldptr [S_PTR + INVALID_ASI],%g1',
' ldx [S_PTR + %o4],%o4',
' jmpl %g1+%g0,%g0',
' add %o4,%g5,%o4']:
file.write('%s\n' % l)
if asi == 'reg':
file.write('2:\n')
file.write(' ldptr [S_PTR + INST_DEC],%g1\n')
file.write(' jmpl %g1,%g0\n')
file.write(' nop\n')
file.write('\n')
def gen_exe_tbl(self,file,mode):
for asi in self.asi:
for out in self.out:
if self.is_float() or self.opc == 'prefetch' or self.opc == 'flush':
if out == 'g0':
continue
if out == 'rd':
if self.is_float():
out = 'fp'
else:
out = 'fn'
if self.opc[-3:] == 'fsr' and asi != 'dft':
continue
for imm in self.imm:
if mode == 'trc':
# handle loads -- first std FP, then odd FP, then IRF
if self.opc[:2] == 'ld':
if self.is_sgl_fp():
self.gen_exe_frI(file,mode,imm,out)
elif self.is_dbl_fp():
self.gen_exe_drI(file,mode,imm,out)
elif self.opc[-3:] == 'fsr':
self.gen_exe_0rI(file,mode,imm,out)
elif self.opc[2:7] == 'block':
self.gen_exe_brI(file,mode,imm,out)
elif self.opc[2:7] == 'short' or self.opc[2:7] == 'parti':
self.gen_exe_drI(file,mode,imm,out)
elif self.is_float():
file.write(' '+mode+'_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out+',\n')
elif self.opc[:3] == 'ldd' or self.opc[:4] == 'ldtd':
self.gen_exe_prI(file,mode,imm,out)
else:
self.gen_exe_rrI(file,mode,imm,out)
# handle stores -- first std FP, then odd FP, then IRF
elif self.opc[:2] == 'st':
if self.is_sgl_fp():
self.gen_exe_FrI(file,mode,imm,out)
elif self.is_dbl_fp():
self.gen_exe_DrI(file,mode,imm,out)
elif self.opc[-3:] == 'fsr':
self.gen_exe_0rI(file,mode,imm,out)
elif self.opc[2:7] == 'block':
self.gen_exe_BrI(file,mode,imm,out)
elif self.opc[2:7] == 'short' or self.opc[2:7] == 'parti':
self.gen_exe_DrI(file,mode,imm,out)
elif self.is_float():
file.write(' '+mode+'_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out+',\n')
elif self.opc[:3] == 'std' or self.opc[:4] == 'sttd':
self.gen_exe_PrI(file,mode,imm,out)
else:
self.gen_exe_rrI(file,mode,imm,out)
# handle cas, swap, and ldstub
elif self.is_atomic():
if mode == 'trc':
file.write(' trc_exe_cas_'+imm+',\n')
else:
file.write(' '+mode+'_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out+',\n')
# handle prefetch
elif self.opc[:8] == 'prefetch':
self.gen_exe_0rI(file,mode,imm,out)
elif self.opc == 'flush':
self.gen_exe_0rI(file,mode,imm,out)
# everything is just trc_exe_<opc>_...
else:
file.write(' '+mode+'_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out+',\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out+' */\n')
else:
file.write(' '+mode+'_exe_'+self.opc+'_'+asi+'_'+imm+'_'+out+',\n')
def exe_idx_s(self,file):
for asi in self.asi:
for out in self.out:
if self.is_float() or self.opc == 'prefetch' or self.opc == 'flush':
if out == 'g0':
continue
if out == 'rd':
if self.is_float():
out = 'fp'
else:
out = 'fn'
if self.opc[-3:] == 'fsr' and asi != 'dft':
continue
for imm in self.imm:
self.exe_idx_s_name(file,self.opc+'_'+asi+'_'+imm+'_'+out)
def run_dec_p(self):
return ''
def va_lower_bits(self):
if self.opc[-1] == 'a':
opc = self.opc[:-1]
else:
opc = self.opc
if opc == 'ldsb' or opc == 'ldub' or opc == 'stb' or opc == 'ldstub' or opc == 'ldshortf8' or \
opc == 'stshortf8' or opc =='prefetch' or opc == 'flush':
return '0'
elif opc == 'ldsh' or opc == 'lduh' or opc == 'sth' or opc == 'ldshortf16' or opc == 'stshortf16':
return '1'
elif opc == 'ldsw' or opc == 'lduw' or opc == 'stw' or opc == 'swap' or opc == 'cas' or \
opc == 'ldf' or opc == 'stf' or opc == 'ldfsr' or opc == 'stfsr':
return '3'
elif opc == 'ldx' or opc == 'ldd' or opc == 'stx' or opc == 'std' or opc == 'casx' or \
opc == 'lddf' or opc == 'stdf' or opc[:9] == 'stpartial' or opc == 'ldxfsr' or opc == 'stxfsr' or \
opc == 'ldxefsr':
return '7'
elif opc == 'ldtd':
return '15'
elif opc == 'ldblockf' or opc == 'stblockf':
return '63'
else:
return 'va_lower_bits unknown'
def wp_byte_mask(self):
if self.opc[-1] == 'a':
opc = self.opc[:-1]
else:
opc = self.opc
if opc == 'ldsb' or opc == 'ldub' or opc == 'stb' or opc == 'ldstub' or opc == 'ldshortf8' or \
opc == 'stshortf8' or opc == 'prefetch':
return '1'
elif opc == 'ldsh' or opc == 'lduh' or opc == 'sth' or opc == 'ldshortf16' or opc == 'stshortf16':
return '3'
elif opc == 'ldsw' or opc == 'lduw' or opc == 'stw' or opc == 'swap' or opc == 'cas' or \
opc == 'ldf' or opc == 'stf' or opc == 'ldfsr' or opc == 'stfsr':
return '15'
elif opc == 'ldx' or opc == 'ldd' or opc == 'stx' or opc == 'std' or opc == 'casx' or \
opc == 'lddf' or opc == 'stdf' or opc[:9] == 'stpartial' or opc == 'ldxfsr' or opc == 'stxfsr' or \
opc == 'ldxefsr':
return '255'
elif opc == 'ldtd':
return '255'
elif opc == 'ldblockf' or opc == 'stblockf':
return '255'
else:
return 'wp_byte_mask'
#============================================================================
# SS_lsu_dec(opc)
#----------------------------------------------------------------------------
# N2 verification revealed a corner case that is not being dealt with properly
# An ASI can be translating or non-translating. When it is translating it can
# be an invalid ASI for the instruction and the MEM_ADDRESS_RANGE (MEM_REAL_RANGE)
# trap has higher priority so that needs to be checked first. The code below
# combines unimplemented ASIs (will cause INVALID_ASI trap when used) and invalid
# (translating) ASI for an instruction in one routine ... ToDo, this should
# be reengineered - at the moment we path the trap type in xx_data_trap().
#============================================================================
class SS_lsu_dec(SS_InstrCpp):
def __init__(self,opc):
SS_InstrCpp.__init__(self,opc)
self.opc = opc
def cond_index(self,test,true_index,false_index):
return '(('+test+') ? ' + true_index+' : '+false_index+')'
def run_dec_c(self,file):
opc = self.opc
# prefetcha?_tmp is only a placeholder to prefetch_dec ... only onde decoder needed
if opc[:8] == 'prefetch':
if opc[-4:] == '_tmp':
return
opc = opc[:-4]
self.c_code_dec_beg_name(file,'run_dec_'+opc)
if opc[-1] != 'a':
#----------------------------------------------------------------------
# DFT_ASI
#----------------------------------------------------------------------
file.write(' i->asi = s->data_dft_asi();\n')
file.write(' i->tte = s->fail_tte;\n')
if self.is_atomic():
file.write(' i->flg = SS_Instr::DFT_ASI|SS_Instr::READ|SS_Instr::WRITE;\n')
elif self.is_store():
file.write(' i->flg = SS_Instr::DFT_ASI|SS_Instr::WRITE;\n')
elif opc == 'prefetch':
file.write(' i->flg = SS_Instr::DFT_ASI|SS_Instr::FETCH;\n')
elif opc == 'flush':
file.write(' i->flg = SS_Instr::DFT_ASI|SS_Instr::FLUSH;\n')
else:
file.write(' i->flg = SS_Instr::DFT_ASI|SS_Instr::READ;\n')
file.write(' i->len = '+self.mem_len()+';\n')
if opc == 'ldd' or opc == 'std':
file.write(' if (o.get_rd_irf() & 8)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
file.write(' if (o.get_i())\n')
file.write(' {\n')
self.ill_ibe(file,' ')
asi_test = 's->sim_state.priv() < s->asi_info[i->asi].get_protection()'
asi_index = 'idx_exe_'+opc+'_dft_i1_ia'
if opc[-3:] == 'fsr':
cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i1_fp')
self.dec_0r13(file,' ',cidx)
elif self.is_double():
cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i1_fp')
self.dec_dr13(file,' ',cidx)
elif self.is_single():
cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i1_fp')
self.dec_fr13(file,' ',cidx)
elif opc == 'prefetch':
cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i1_fn')
self.dec_nr13(file,' ',cidx)
elif opc == 'flush':
cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i1_fn')
self.dec_nr13(file,' ',cidx)
else:
file.write(' if (o.get_rd_irf())\n')
cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i1_rd')
self.dec_rr13(file,' ',cidx)
file.write(' else\n')
cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i1_g0')
self.dec_0r13(file,' ',cidx)
file.write(' }\n')
file.write(' else if (o.is_zero_12_5())\n')
file.write(' {\n')
self.ill_ibe(file,' ')
asi_test = 's->sim_state.priv() < s->asi_info[i->asi].get_protection()'
asi_index = 'idx_exe_'+opc+'_dft_i0_ia'
if opc[-3:] == 'fsr':
cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i0_fp')
self.dec_0rr(file,' ',cidx)
elif self.is_double():
cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i0_fp')
self.dec_drr(file,' ',cidx)
elif self.is_single():
cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i0_fp')
self.dec_frr(file,' ',cidx)
elif opc == 'prefetch':
cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i0_fn')
self.dec_nrr(file,' ',cidx)
elif opc == 'flush':
cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i0_fn')
self.dec_nrr(file,' ',cidx)
else:
file.write(' if (o.get_rd_irf())\n')
cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i0_rd')
self.dec_rrr(file,' ',cidx)
file.write(' else\n')
cidx = self.cond_index(asi_test,asi_index,'idx_exe_'+opc+'_dft_i0_g0')
self.dec_0rr(file,' ',cidx)
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
else:
#----------------------------------------------------------------------
# REG_ASI , note casa and casxa are still rrr iso rri
#----------------------------------------------------------------------
file.write(' i->tte = s->fail_tte;\n')
if opc == 'ldda' or opc == 'stda':
file.write(' if (o.get_rd_irf() & 8)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
file.write(' if (o.get_i())\n')
file.write(' {\n')
file.write(' i->asi = s->asi();\n')
if self.is_atomic():
file.write(' i->flg = SS_Instr::REG_ASI|SS_Instr::READ|SS_Instr::WRITE;\n')
elif self.is_store():
file.write(' i->flg = SS_Instr::REG_ASI|SS_Instr::WRITE;\n')
elif opc == 'prefetcha':
file.write(' i->flg = SS_Instr::REG_ASI|SS_Instr::FETCH;\n')
elif opc == 'flusha':
file.write(' i->flg = SS_Instr::REG_ASI|SS_Instr::FLUSH;\n')
else:
file.write(' i->flg = SS_Instr::REG_ASI|SS_Instr::READ;\n')
file.write(' i->len = '+self.mem_len()+';\n')
file.write(' SS_AsiInfo asi_info = s->asi_info[i->asi];\n')
if self.is_atomic():
if opc[:3] == 'cas':
file.write(' if (!o.is_zero_12_5())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i0_ia')
file.write(' if (!asi_info.is_valid_atomic_asi())\n')
self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i0_ia')
else:
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' if (!asi_info.is_valid_atomic_asi())\n')
self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
elif opc == 'prefetcha':
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_nr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' if (!asi_info.is_valid_prefetch_asi())\n')
self.dec_nr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
elif opc == 'flusha':
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' if (!asi_info.is_valid_flush_asi())\n')
self.dec_nr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
elif opc == 'ldda':
file.write(' if (asi_info.is_quad_load_asi())\n')
file.write(' {\n')
if setup.product == 'N2':
file.write(' i->len = 16;\n')
file.write(' if (o.get_rd_irf() & 0x8)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' if (o.get_rd_irf())\n')
self.dec_rr13(file,' ','idx_exe_ldtd_reg_i1_rd')
file.write(' else\n')
self.dec_0r13(file,' ','idx_exe_ldtd_reg_i1_g0')
file.write(' }\n')
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' if (!asi_info.is_valid_ld_asi())\n')
self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
elif opc[:3] == 'ldx':
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' if (!asi_info.is_valid_ldx_asi())\n')
file.write(' {\n')
self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' }\n')
file.write(' if (!asi_info.is_translating())\n')
file.write(' {\n')
file.write(' if (o.get_rd_irf())\n')
self.dec_rr13(file,' ','idx_exe_rdasi_i1_rd')
file.write(' else\n')
self.dec_0r13(file,' ','idx_exe_rdasi_i1_g0')
file.write(' }\n')
elif opc == 'lddfa':
file.write(' if (asi_info.is_shortf8_asi())\n')
file.write(' {\n')
file.write(' i->len = 1;\n')
self.ill_ibe(file,' ')
self.dec_dr13(file,' ','idx_exe_ldshortf8_reg_i1_fp')
file.write(' }\n')
file.write(' else if (asi_info.is_shortf16_asi())\n')
file.write(' {\n')
file.write(' i->len = 2;\n')
self.ill_ibe(file,' ')
self.dec_dr13(file,' ','idx_exe_ldshortf16_reg_i1_fp')
file.write(' }\n')
file.write(' else if (asi_info.is_block_init_asi())\n')
file.write(' {\n')
self.ill_ibe(file,' ')
self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' }\n')
file.write(' else if (asi_info.is_block_load_asi())\n')
file.write(' {\n')
file.write(' {\n')
file.write(' i->len = 64;\n')
file.write(' if (o.get_rd_drf() & 0x38)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' else\n')
self.dec_dr13(file,' ','idx_exe_ldblockf_reg_i1_fp')
file.write(' }\n')
file.write(' }\n')
file.write(' else if (asi_info.is_block_store_asi())\n') # block commit are write only
file.write(' {\n')
file.write(' i->len = 64;\n')
file.write(' if (o.get_rd_drf() & 0x38)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.ill_ibe(file,' ')
self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' }\n')
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' if (!asi_info.is_valid_ld_asi())\n')
self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
elif self.is_load():
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' if (!asi_info.is_valid_ld_asi())\n')
self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
elif opc[:3] == 'stx':
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' if (!asi_info.is_valid_stx_asi())\n')
self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' if (!asi_info.is_translating())\n')
file.write(' {\n')
file.write(' if (o.get_rd_irf())\n')
self.dec_rr13(file,' ','idx_exe_wrasi_i1_rd')
file.write(' else\n')
self.dec_0r13(file,' ','idx_exe_wrasi_i1_g0')
file.write(' }\n')
elif opc == 'stdfa':
file.write(' if (asi_info.is_shortf8_asi())\n')
file.write(' {\n')
file.write(' i->len = 1;\n')
self.ill_ibe(file,' ')
self.dec_dr13(file,' ','idx_exe_stshortf8_reg_i1_fp')
file.write(' }\n')
file.write(' else if (asi_info.is_shortf16_asi())\n')
file.write(' {\n')
file.write(' i->len = 2;\n')
self.ill_ibe(file,' ')
self.dec_dr13(file,' ','idx_exe_stshortf16_reg_i1_fp')
file.write(' }\n')
file.write(' else if (asi_info.is_partial8_asi())\n')
file.write(' {\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
file.write(' }\n')
file.write(' else if (asi_info.is_partial16_asi())\n')
file.write(' {\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
file.write(' }\n')
file.write(' else if (asi_info.is_partial32_asi())\n')
file.write(' {\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
file.write(' }\n')
file.write(' else if (asi_info.is_block_store_asi())\n')
file.write(' {\n')
file.write(' {\n')
file.write(' i->len = 64;\n')
file.write(' if (o.get_rd_drf() & 0x38)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_dr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' else\n')
self.dec_dr13(file,' ','idx_exe_stblockf_reg_i1_fp')
file.write(' }\n')
file.write(' }\n')
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_dr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' if (!asi_info.is_valid_stf_asi())\n')
self.dec_dr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
elif opc == 'stda':
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' if (!asi_info.is_valid_st_asi())\n')
self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
elif opc == 'stfa':
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_fr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' if (!asi_info.is_valid_stf_asi())\n')
self.dec_fr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
elif self.is_store():
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_dr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
file.write(' if (!asi_info.is_valid_st_asi())\n')
self.dec_dr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_ia')
if self.is_double():
file.write(' else\n')
self.dec_dr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_fp')
elif self.is_single():
file.write(' else\n')
self.dec_fr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_fp')
elif opc == 'prefetcha':
file.write(' else if (asi_info.is_translating())\n')
self.dec_nr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_fn')
file.write(' else\n')
self.dec_000(file,' ','idx_exe_nop')
elif opc == 'flusha':
file.write(' else\n')
self.dec_nr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_fn')
else:
file.write(' else\n')
file.write(' {\n')
file.write(' if (o.get_rd_irf())\n')
if opc[:3] == 'cas':
self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_reg_i0_rd')
else:
self.dec_rr13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_rd')
file.write(' else\n')
if opc[:3] == 'cas':
self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_reg_i0_g0')
else:
self.dec_0r13(file,' ','idx_exe_'+opc[:-1]+'_reg_i1_g0')
file.write(' }\n')
file.write(' }\n')
#----------------------------------------------------------------------
# IMM_ASI
#----------------------------------------------------------------------
file.write(' else\n')
file.write(' {\n')
file.write(' i->asi = o.get_imm_asi();\n')
if self.is_atomic():
file.write(' i->flg = SS_Instr::IMM_ASI|SS_Instr::READ|SS_Instr::WRITE;\n')
elif self.is_store():
file.write(' i->flg = SS_Instr::IMM_ASI|SS_Instr::WRITE;\n')
elif opc == 'prefetcha':
file.write(' i->flg = SS_Instr::IMM_ASI|SS_Instr::FETCH;\n')
elif opc == 'flusha':
file.write(' i->flg = SS_Instr::IMM_ASI|SS_Instr::FLUSH;\n')
else:
file.write(' i->flg = SS_Instr::IMM_ASI|SS_Instr::READ;\n')
file.write(' i->len = '+self.mem_len()+';\n')
file.write(' SS_AsiInfo asi_info = s->asi_info[i->asi];\n')
if self.is_atomic():
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' if (!asi_info.is_valid_atomic_asi())\n')
self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
elif opc == 'prefetcha':
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' if (!asi_info.is_valid_prefetch_asi())\n')
self.dec_nrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
elif opc == 'flusha':
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' if (!asi_info.is_valid_flush_asi())\n')
self.dec_nrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
elif opc == 'ldda':
file.write(' if (asi_info.is_quad_load_asi())\n')
file.write(' {\n')
file.write(' i->len = 16;\n')
file.write(' if (o.get_rd_irf() & 0x8)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' if (o.get_rd_irf())\n')
self.dec_rrr(file,' ','idx_exe_ldtd_imm_i0_rd')
file.write(' else\n')
self.dec_0rr(file,' ','idx_exe_ldtd_imm_i0_g0')
file.write(' }\n')
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' if (!asi_info.is_valid_ld_asi())\n')
self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
elif opc[:3] == 'ldx':
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' if (!asi_info.is_valid_ldx_asi())\n')
file.write(' {\n')
self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' }\n')
file.write(' if (!asi_info.is_translating())\n')
file.write(' {\n')
file.write(' if (o.get_rd_irf())\n')
self.dec_rrr(file,' ','idx_exe_rdasi_i0_rd')
file.write(' else\n')
self.dec_0rr(file,' ','idx_exe_rdasi_i0_g0')
file.write(' }\n')
elif opc == 'lddfa':
file.write(' if (asi_info.is_shortf8_asi())\n')
file.write(' {\n')
file.write(' i->len = 1;\n')
self.ill_ibe(file,' ')
self.dec_drr(file,' ','idx_exe_ldshortf8_imm_i0_fp')
file.write(' }\n')
file.write(' else if (asi_info.is_shortf16_asi())\n')
file.write(' {\n')
file.write(' i->len = 2;\n')
self.ill_ibe(file,' ')
self.dec_drr(file,' ','idx_exe_ldshortf16_imm_i0_fp')
file.write(' }\n')
file.write(' else if (asi_info.is_block_init_asi())\n')
file.write(' {\n')
self.ill_ibe(file,' ')
self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' }\n')
file.write(' else if (asi_info.is_block_load_asi())\n')
file.write(' {\n')
file.write(' i->len = 64;\n')
file.write(' if (o.get_rd_drf() & 0x38)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_drr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' else\n')
self.dec_drr(file,' ','idx_exe_ldblockf_imm_i0_fp')
file.write(' }\n')
file.write(' else if (asi_info.is_block_store_asi())\n') # block commit are write only
file.write(' {\n')
file.write(' i->len = 64;\n')
file.write(' if (o.get_rd_drf() & 0x38)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.ill_ibe(file,' ')
self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' }\n')
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' if (!asi_info.is_valid_ld_asi())\n')
self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
elif self.is_load():
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' if (!asi_info.is_valid_ld_asi())\n')
self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
elif opc[:3] == 'stx':
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' if (!asi_info.is_valid_stx_asi())\n')
self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' if (!asi_info.is_translating())\n')
file.write(' {\n')
file.write(' if (o.get_rd_irf())\n')
self.dec_rrr(file,' ','idx_exe_wrasi_i0_rd')
file.write(' else\n')
self.dec_rrr(file,' ','idx_exe_wrasi_i0_g0')
file.write(' }\n')
elif opc == 'stdfa':
file.write(' if (asi_info.is_shortf8_asi())\n')
file.write(' {\n')
file.write(' i->len = 1;\n')
self.ill_ibe(file,' ')
self.dec_drr(file,' ','idx_exe_stshortf8_imm_i0_fp')
file.write(' }\n')
file.write(' else if (asi_info.is_shortf16_asi())\n')
file.write(' {\n')
file.write(' i->len = 2;\n')
self.ill_ibe(file,' ')
self.dec_drr(file,' ','idx_exe_stshortf16_imm_i0_fp')
file.write(' }\n')
file.write(' else if (asi_info.is_partial8_asi())\n')
file.write(' {\n')
self.ill_ibe(file,' ')
self.dec_drr(file,' ','idx_exe_stpartial8_imm_i0_fp')
file.write(' }\n')
file.write(' else if (asi_info.is_partial16_asi())\n')
file.write(' {\n')
self.ill_ibe(file,' ')
self.dec_drr(file,' ','idx_exe_stpartial16_imm_i0_fp')
file.write(' }\n')
file.write(' else if (asi_info.is_partial32_asi())\n')
file.write(' {\n')
self.ill_ibe(file,' ')
self.dec_drr(file,' ','idx_exe_stpartial32_imm_i0_fp')
file.write(' }\n')
file.write(' else if (asi_info.is_block_store_asi())\n')
file.write(' {\n')
file.write(' i->len = 64;\n')
file.write(' if (o.get_rd_drf() & 0x38)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_drr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' else\n')
self.dec_drr(file,' ','idx_exe_stblockf_imm_i0_fp')
file.write(' }\n')
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_drr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' if (!asi_info.is_valid_stf_asi())\n')
self.dec_drr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
elif opc == 'stda':
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' if (!asi_info.is_valid_st_asi())\n')
self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
elif opc == 'stfa':
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_frr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' if (!asi_info.is_valid_stf_asi())\n')
self.dec_frr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
elif self.is_store():
self.ill_ibe(file,' ')
file.write(' if (s->sim_state.priv() < asi_info.get_protection())\n')
self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
file.write(' if (!asi_info.is_valid_st_asi())\n')
self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_ia')
if self.is_double():
file.write(' else\n')
self.dec_drr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_fp')
elif self.is_single():
file.write(' else\n')
self.dec_frr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_fp')
elif opc == 'prefetcha':
file.write(' else if (asi_info.is_translating())\n')
self.dec_nrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_fn')
file.write(' else\n')
self.dec_000(file,' ','idx_exe_nop')
elif opc == 'flusha':
file.write(' else\n')
self.dec_nrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_fn')
else:
file.write(' else\n')
file.write(' {\n')
file.write(' if (o.get_rd_irf())\n')
self.dec_rrr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_rd')
file.write(' else\n')
self.dec_0rr(file,' ','idx_exe_'+opc[:-1]+'_imm_i0_g0')
file.write(' }\n')
file.write(' }\n')
self.c_code_end(file)
def is_load(self):
return self.opc[0:2] == 'ld'
def is_store(self):
return self.opc[0:2] == 'st'
def is_atomic(self):
return self.opc[:6] == 'ldstub' or self.opc[:4] == 'swap' or self.opc[:3] == 'cas'
def is_double(self):
return self.opc[:4] == 'lddf' or self.opc[:4] == 'stdf'
def is_single(self):
return self.opc[:3] == 'ldf' or self.opc[:3] == 'stf'
def exe_idx_s_name(self,file,n):
pass
def gen_exe_tbl(self,file,mode):
pass
def idx_mem_s(self,file):
pass
def run_dec_p(self):
if self.opc[:8] == 'prefetch':
return 'run_dec_%s' % self.opc[:-4]
else:
return 'run_dec_%s' % self.opc
def mem_len(self):
if self.opc[-1] == 'a':
opc = self.opc[:-1]
else:
opc = self.opc
if opc == 'ldsb' or opc == 'ldub' or opc == 'stb' or opc == 'ldstub':
return '1'
elif opc == 'ldsh' or opc == 'lduh' or opc == 'sth':
return '2'
elif opc == 'ldsw' or opc == 'lduw' or opc == 'stw' or opc == 'swap' or opc == 'cas' or \
opc == 'ldf' or opc == 'stf' or opc == 'ldfsr' or opc == 'stfsr':
return '4'
elif opc == 'ldx' or opc == 'ldd' or opc == 'stx' or opc == 'std' or opc == 'casx' or \
opc == 'lddf' or opc == 'stdf' or opc == 'ldxfsr' or opc == 'stxfsr' or opc == 'ldxefsr' or \
opc[:8] == 'prefetch' or opc == 'flush':
return '8'
else:
return 'mem_len() missed opc '+self.opc
#============================================================================
# SS_ld_mem(opc)
#============================================================================
class SS_ld_mem(SS_InstrCpp):
def __init__(self,opc,out):
SS_InstrCpp.__init__(self,opc+'_'+out)
self.opc = opc
self.out = out # 'rd' ,'g0', 'fp', 'fn'
def mem_c(self,file):
for mode in ['run','trc','ras']:
for src in ['memory','io']:
for endian in ['b','l']:
args = '( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, SS_Vaddr va, SS_Tte* tte )\n'
name = endian+'_'+self.opc+'_'+self.out
if src == 'memory':
sid = ''
file.write('\nextern "C" SS_Vaddr mem_'+mode+'_'+name+args)
else:
sid = 's->strand_id(),'
file.write('\nextern "C" SS_Vaddr io_'+mode+'_'+name+args)
file.write('{\n')
file.write(' SS_Tte* _tte = (SS_Tte*)(long(tte) &~ 3);\n')
file.write(' SS_Paddr pa = _tte->trans(va);\n')
file.write('#if defined(MEMORY_MSYNC)\n')
file.write(' ((SS_MsyncMemory*)(s->'+src+'))->msync_info(s->strand_id(),va);\n')
file.write('#elif defined(MEMORY_EXTERNAL)\n')
if src == 'memory':
file.write(' ((SS_ExternalMemory*)(s->'+src+'))->set_strand_id(s->strand_id());\n')
file.write('#endif\n')
if self.opc == 'prefetch':
# ToDo: prefetch is not part of the memory interface standard yet
#file.write(' s->'+src+'->prefetch('+sid+'pa,1);\n')
if mode == 'trc':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::PREFETCH,va,_tte,0,0);\n')
elif mode == 'ras':
if setup.product == 'N2':
file.write(' if (s->sim_state.ras_enabled())\n')
file.write(' {\n')
cpu_strand = setup.product.lower()+'_strand'
file.write(' '+setup.product+'_Strand* '+cpu_strand+' = ('+setup.product+'_Strand*)s;\n')
cpu_mem_err_detector = setup.product.lower()+'_mem_err_detector'
file.write(' '+setup.product+'_MemErrDetector& '+cpu_mem_err_detector+' = ('+setup.product+'_MemErrDetector&)'+cpu_strand+'->mem_err_detector;\n')
file.write(' if ('+cpu_mem_err_detector+'.is_prefetchICE(i->opc))\n')
file.write(' '+cpu_mem_err_detector+'.prefetchICE(pa);\n')
file.write(' }\n')
else:
file.write(' uint64_t val;\n')
if mode == 'run' and src == 'memory':
if self.opc == 'ldsb':
file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ld8s('+sid+'pa);\n')
elif self.opc == 'ldub' or self.opc == 'ldshortf8':
file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ld8u('+sid+'pa);\n')
elif self.opc == 'ldsh':
file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ld16s('+sid+'pa);\n')
elif self.opc == 'lduh' or self.opc == 'ldshortf16':
file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ld16u('+sid+'pa);\n')
elif self.opc == 'ldsw':
file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ld32s('+sid+'pa);\n')
elif self.opc == 'lduw' or self.opc == 'ldf' or self.opc == 'ldfsr':
file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ld32u('+sid+'pa);\n')
elif self.opc == 'ldx' or self.opc == 'ldd' or self.opc == 'lddf' or self.opc == 'ldxfsr' or self.opc == 'ldxefsr':
file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ld64('+sid+'pa);\n')
elif self.opc == 'ldtd':
file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::ld128atomic('+sid+'pa,s->mem_data);\n')
elif self.opc == 'ldblockf':
file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::ld512('+sid+'pa,s->mem_data);\n')
else:
file.write(' val = ???;\n')
else:
if self.opc == 'ldsb':
file.write(' val = s->'+src+'->ld8s('+sid+'pa);\n')
elif self.opc == 'ldub' or self.opc == 'ldshortf8':
file.write(' val = s->'+src+'->ld8u('+sid+'pa);\n')
elif self.opc == 'ldsh':
file.write(' val = s->'+src+'->ld16s('+sid+'pa);\n')
elif self.opc == 'lduh' or self.opc == 'ldshortf16':
file.write(' val = s->'+src+'->ld16u('+sid+'pa);\n')
elif self.opc == 'ldsw':
file.write(' val = s->'+src+'->ld32s('+sid+'pa);\n')
elif self.opc == 'lduw' or self.opc == 'ldf' or self.opc == 'ldfsr':
file.write(' val = s->'+src+'->ld32u('+sid+'pa);\n')
elif self.opc == 'ldx' or self.opc == 'ldd' or self.opc == 'lddf' or self.opc == 'ldxfsr' or self.opc == 'ldxefsr':
file.write(' val = s->'+src+'->ld64('+sid+'pa);\n')
elif self.opc == 'ldtd':
file.write(' s->'+src+'->ld128atomic('+sid+'pa,s->mem_data);\n')
elif self.opc == 'ldblockf':
file.write(' s->'+src+'->ld512('+sid+'pa,s->mem_data);\n')
else:
file.write(' val = ???;\n')
if mode == 'ras' and src == 'memory':
file.write(' if (s->sim_state.ras_enabled())\n')
file.write(' {\n')
file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
file.write(' SS_Trap::Type tt = med.detect_load_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa);\n')
file.write(' if (tt != SS_Trap::NO_TRAP)\n')
file.write(' return (s->trap)(pc,npc,s,i,tt);\n')
file.write(' }\n')
if mode == 'trc':
if self.opc == 'ldsb' or self.opc == 'ldub' or self.opc == 'ldshortf8':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_DATA,va,_tte,1,&val);\n')
elif self.opc == 'ldsh' or self.opc == 'lduh' or self.opc == 'ldshortf16':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_DATA,va,_tte,2,&val);\n')
elif self.opc == 'ldsw' or self.opc == 'lduw' or self.opc == 'ldf' or self.opc == 'ldfsr':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_DATA,va,_tte,4,&val);\n')
elif self.opc == 'ldx' or self.opc == 'ldd' or self.opc == 'lddf' or self.opc == 'ldxfsr' or self.opc == 'ldxefsr':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_DATA,va,_tte,8,&val);\n')
elif self.opc == 'ldtd':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_DATA,va,_tte,16,s->mem_data);\n')
elif self.opc == 'ldblockf':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_DATA,va,_tte,64,s->mem_data);\n')
else:
file.write(' ???\n')
if endian == 'b':
if self.out == 'g0':
if self.opc == 'ldtd':
file.write(' s->get_irf(i->rd + 8) = s->mem_data[1];\n')
elif self.opc == 'ldd':
file.write(' s->get_irf(i->rd + 8) = uint32_t(val);\n')
else:
file.write(' s->mmu_scratch = val;\n')
else:
if self.opc == 'ldtd':
file.write(' s->get_irf(i->rd) = s->mem_data[0];\n')
file.write(' s->get_irf(i->rd + 8) = s->mem_data[1];\n')
elif self.opc == 'ldd':
file.write(' s->get_irf(i->rd ) = val >> 32;\n')
file.write(' s->get_irf(i->rd + 8) = uint32_t(val);\n')
elif self.opc == 'lddf' or self.opc[:8] == 'ldshortf':
file.write(' s->get_drf(i->rd) = val;\n')
file.write(' s->set_fprs(i->rd);\n')
elif self.opc == 'ldf':
file.write(' s->get_frf(i->rd) = val;\n')
file.write(' s->set_fprs(i->rd);\n')
elif self.opc == 'ldblockf':
file.write(' s->get_drf(i->rd ) = s->mem_data[0];\n')
file.write(' s->get_drf(i->rd + 8) = s->mem_data[1];\n')
file.write(' s->get_drf(i->rd + 16) = s->mem_data[2];\n')
file.write(' s->get_drf(i->rd + 24) = s->mem_data[3];\n')
file.write(' s->get_drf(i->rd + 32) = s->mem_data[4];\n')
file.write(' s->get_drf(i->rd + 40) = s->mem_data[5];\n')
file.write(' s->get_drf(i->rd + 48) = s->mem_data[6];\n')
file.write(' s->get_drf(i->rd + 56) = s->mem_data[7];\n')
file.write(' s->set_fprs(i->rd);\n')
elif self.opc == 'ldfsr':
# fsr.ftt is written only by ldxefsr
file.write(' val = (val & ~(0x7llu << 14)) | (s->fsr.ftt() << 14); // preserve ftt\n')
file.write(' s->fsr.set(((s->fsr() >> 32) << 32) + ((val << 32) >> 32));\n')
file.write(' s->set_fsr();\n')
elif self.opc == 'ldxfsr':
# fsr.ftt is written only by ldxefsr
file.write(' val = (val & ~(0x7llu << 14)) | (s->fsr.ftt() << 14); // preserve ftt\n')
file.write(' s->fsr.set(val);\n')
file.write(' s->set_fsr();\n')
elif self.opc == 'ldxefsr':
file.write(' s->fsr.set(val);\n')
if setup.product in ['xx']:
# ditto xx FSR.NS
file.write(' s->fsr.ns(0);\n')
file.write(' s->set_fsr();\n')
else:
file.write(' s->get_irf(i->rd) = val;\n')
else: # endian == 'l'
if self.out == 'g0':
if self.opc == 'ldtd':
file.write(' s->get_irf(i->rd + 8) = endianess_convert_64(s->mem_data[1]);\n')
elif self.opc == 'ldd':
file.write(' s->get_irf(i->rd + 8) = endianess_convert_32u(val);\n')
else:
file.write(' s->mmu_scratch = val;\n')
elif self.opc == 'ldub' or self.opc == 'ldsb':
file.write(' s->get_irf(i->rd) = val;\n')
elif self.opc == 'lduh':
file.write(' s->get_irf(i->rd) = endianess_convert_16u(val);\n')
elif self.opc == 'ldsh':
file.write(' s->get_irf(i->rd) = endianess_convert_16s(val);\n')
elif self.opc == 'lduw':
file.write(' s->get_irf(i->rd) = endianess_convert_32u(val);\n')
elif self.opc == 'ldsw':
file.write(' s->get_irf(i->rd) = endianess_convert_32s(val);\n')
elif self.opc == 'ldshortf8':
file.write(' s->get_drf(i->rd) = val;\n')
file.write(' s->set_fprs(i->rd);\n')
elif self.opc == 'ldshortf16':
file.write(' s->get_drf(i->rd) = endianess_convert_16u(val);\n')
file.write(' s->set_fprs(i->rd);\n')
elif self.opc == 'ldf':
file.write(' s->get_frf(i->rd) = endianess_convert_32s(val);\n')
file.write(' s->set_fprs(i->rd);\n')
elif self.opc == 'lddf':
file.write(' s->get_drf(i->rd) = endianess_convert_64(val);\n')
file.write(' s->set_fprs(i->rd);\n')
elif self.opc == 'ldx':
file.write(' s->get_irf(i->rd) = endianess_convert_64(val);\n')
elif self.opc == 'ldd':
file.write(' s->get_irf(i->rd ) = endianess_convert_32u(val >> 32);\n')
file.write(' s->get_irf(i->rd + 8) = endianess_convert_32u(val);\n')
elif self.opc == 'ldtd':
file.write(' s->get_irf(i->rd ) = endianess_convert_64(s->mem_data[0]);\n')
file.write(' s->get_irf(i->rd + 8) = endianess_convert_64(s->mem_data[1]);\n')
elif self.opc == 'ldblockf':
file.write(' s->get_drf(i->rd ) = endianess_convert_64(s->mem_data[0]);\n')
file.write(' s->get_drf(i->rd + 8) = endianess_convert_64(s->mem_data[1]);\n')
file.write(' s->get_drf(i->rd + 16) = endianess_convert_64(s->mem_data[2]);\n')
file.write(' s->get_drf(i->rd + 24) = endianess_convert_64(s->mem_data[3]);\n')
file.write(' s->get_drf(i->rd + 32) = endianess_convert_64(s->mem_data[4]);\n')
file.write(' s->get_drf(i->rd + 40) = endianess_convert_64(s->mem_data[5]);\n')
file.write(' s->get_drf(i->rd + 48) = endianess_convert_64(s->mem_data[6]);\n')
file.write(' s->get_drf(i->rd + 56) = endianess_convert_64(s->mem_data[7]);\n')
file.write(' s->set_fprs(i->rd);\n')
elif self.opc == 'ldfsr':
file.write(' val = endianess_convert_32u(val);\n')
# fsr.ftt is written only by ldxefsr
file.write(' val = (val & ~(0x7llu << 14)) | (s->fsr.ftt() << 14); // preserve ftt\n')
file.write(' s->fsr.set(((s->fsr() >> 32) << 32) + ((val << 32) >> 32));\n')
file.write(' s->set_fsr();\n')
elif self.opc == 'ldxfsr':
file.write(' val = endianess_convert_64(val);\n')
# fsr.ftt is written only by ldxefsr
file.write(' val = (val & ~(0x7llu << 14)) | (s->fsr.ftt() << 14); // preserve ftt\n')
file.write(' s->fsr.set(val);\n')
file.write(' s->set_fsr();\n')
elif self.opc == 'ldxefsr':
file.write(' val = endianess_convert_64(val);\n')
file.write(' s->fsr.set(val);\n')
if setup.product in ['xx']:
# ditto xx FSR.NS
file.write(' s->fsr.ns(0);\n')
file.write(' s->set_fsr();\n')
file.write(' s->npc = npc+4; return npc;\n')
file.write('}\n')
def run_dec_c(self,file):
pass
def run_dec_p(self):
return ''
#============================================================================
# SS_st_mem(opc)
#============================================================================
class SS_st_mem(SS_InstrAsm):
def __init__(self,opc,out):
SS_InstrAsm.__init__(self,opc+'_'+out)
self.opc = opc
self.out = out
def mem_c(self,file):
for mode in ['run','trc','ras']:
for src in ['memory','io']:
for endian in ['b','l']:
args = '( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, SS_Vaddr va, SS_Tte* tte )\n'
name = endian+'_'+self.opc+'_'+self.out
if src == 'memory':
sid = ''
file.write('\nextern "C" SS_Vaddr mem_'+mode+'_'+name+args)
else:
sid = 's->strand_id(),'
file.write('\nextern "C" SS_Vaddr io_'+mode+'_'+name+args)
file.write('{\n')
file.write(' uint64_t val;\n')
if self.opc[:9] == 'stpartial':
file.write(' uint64_t msk;\n')
file.write(' SS_Tte* _tte = (SS_Tte*)(long(tte) &~ 3);\n')
file.write(' SS_Paddr pa = _tte->trans(va);\n')
file.write('#if defined(MEMORY_MSYNC)\n')
file.write(' ((SS_MsyncMemory*)(s->'+src+'))->msync_info(s->strand_id(),va);\n')
file.write('#elif defined(MEMORY_EXTERNAL)\n')
if src == 'memory':
file.write(' ((SS_ExternalMemory*)(s->'+src+'))->set_strand_id(s->strand_id());\n')
file.write('#endif\n')
if self.out == 'g0':
if self.opc == 'std':
if endian == 'b':
file.write(' val = uint32_t(s->get_irf(i->rd + 8));\n')
else:
file.write(' val = s->get_irf(i->rd + 8) << 32;\n')
else:
file.write(' val = 0;\n')
else:
if self.opc == 'std':
if endian == 'b':
file.write(' val = (s->get_irf(i->rd) << 32) | uint32_t(s->get_irf(i->rd + 8));\n')
else:
file.write(' val = (s->get_irf(i->rd + 8) << 32) | uint32_t(s->get_irf(i->rd));\n')
elif self.opc == 'stf':
file.write(' val = s->get_frf(i->rd);\n')
elif self.opc == 'stdf' or self.opc[:8] == 'stshortf':
file.write(' val = s->get_drf(i->rd);\n')
elif self.opc[:9] == 'stpartial':
file.write(' val = s->get_drf(i->rd);\n')
file.write(' msk = s->mem_mask;\n')
elif self.opc == 'stblockf':
file.write(' s->mem_data[0] = s->get_drf(i->rd );\n')
file.write(' s->mem_data[1] = s->get_drf(i->rd + 8);\n')
file.write(' s->mem_data[2] = s->get_drf(i->rd + 16);\n')
file.write(' s->mem_data[3] = s->get_drf(i->rd + 24);\n')
file.write(' s->mem_data[4] = s->get_drf(i->rd + 32);\n')
file.write(' s->mem_data[5] = s->get_drf(i->rd + 40);\n')
file.write(' s->mem_data[6] = s->get_drf(i->rd + 48);\n')
file.write(' s->mem_data[7] = s->get_drf(i->rd + 56);\n')
elif self.opc[-3:] == 'fsr':
file.write(' s->get_fsr();\n')
file.write(' val = s->fsr();\n')
file.write(' s->fsr.ftt(0);\n')
file.write(' s->set_fsr();\n')
else:
file.write(' val = s->get_irf(i->rd);\n')
if endian == 'l':
if self.opc == 'sth' or self.opc == 'stshortf16':
file.write(' val = endianess_convert_16u(val);\n')
elif self.opc == 'stw' or self.opc == 'stf' or self.opc == 'stfsr':
file.write(' val = endianess_convert_32u(val);\n')
elif self.opc == 'stx' or self.opc == 'std' or self.opc == 'stdf' or self.opc == 'stxfsr':
file.write(' val = endianess_convert_64(val);\n')
elif self.opc[:9] == 'stpartial':
file.write(' val = endianess_convert_64(val);\n')
file.write(' msk = endianess_partial(s->mem_mask);\n')
elif self.opc == 'stblockf':
file.write(' s->mem_data[0] = endianess_convert_64(s->mem_data[0]);\n')
file.write(' s->mem_data[1] = endianess_convert_64(s->mem_data[1]);\n')
file.write(' s->mem_data[2] = endianess_convert_64(s->mem_data[2]);\n')
file.write(' s->mem_data[3] = endianess_convert_64(s->mem_data[3]);\n')
file.write(' s->mem_data[4] = endianess_convert_64(s->mem_data[4]);\n')
file.write(' s->mem_data[5] = endianess_convert_64(s->mem_data[5]);\n')
file.write(' s->mem_data[6] = endianess_convert_64(s->mem_data[6]);\n')
file.write(' s->mem_data[7] = endianess_convert_64(s->mem_data[7]);\n')
if mode == 'trc':
if self.opc == 'stb' or self.opc == 'stshortf8':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_DATA,va,_tte,1,&val);\n')
elif self.opc == 'sth' or self.opc == 'stshortf16':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_DATA,va,_tte,2,&val);\n')
elif self.opc == 'stw' or self.opc == 'stf' or self.opc == 'stfsr':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_DATA,va,_tte,4,&val);\n')
elif self.opc == 'stx' or self.opc == 'std' or self.opc == 'stdf' or self.opc == 'stxfsr':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_DATA,va,_tte,8,&val);\n')
elif self.opc[:9] == 'stpartial':
file.write(' s->mem_data[0] = val;\n');
file.write(' s->mem_data[1] = msk;\n');
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_DATA,va,_tte,8,s->mem_data);\n')
file.write(' val = s->mem_data[0];\n');
file.write(' msk = s->mem_data[1];\n');
elif self.opc == 'stblockf':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_DATA,va,_tte,64,s->mem_data);\n')
if mode == 'run' and src == 'memory':
if self.opc == 'stb' or self.opc == 'stshortf8':
file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::st8('+sid+'pa,val);\n')
elif self.opc == 'sth' or self.opc == 'stshortf16':
file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::st16('+sid+'pa,val);\n')
elif self.opc == 'stw' or self.opc == 'stf' or self.opc == 'stfsr':
file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::st32('+sid+'pa,val);\n')
elif self.opc == 'stx' or self.opc == 'std' or self.opc == 'stdf' or self.opc == 'stxfsr':
file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::st64('+sid+'pa,val);\n')
elif self.opc[:9] == 'stpartial':
file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::st64partial('+sid+'pa,val,msk);\n')
elif self.opc == 'stblockf':
file.write(' ((SS_Memory*)(s->'+src+'))->SS_Memory::st512('+sid+'pa,s->mem_data);\n')
else:
if self.opc == 'stb' or self.opc == 'stshortf8':
file.write(' s->'+src+'->st8('+sid+'pa,val);\n')
elif self.opc == 'sth' or self.opc == 'stshortf16':
file.write(' s->'+src+'->st16('+sid+'pa,val);\n')
elif self.opc == 'stw' or self.opc == 'stf' or self.opc == 'stfsr':
file.write(' s->'+src+'->st32('+sid+'pa,val);\n')
elif self.opc == 'stx' or self.opc == 'std' or self.opc == 'stdf' or self.opc == 'stxfsr':
file.write(' s->'+src+'->st64('+sid+'pa,val);\n')
elif self.opc[:9] == 'stpartial':
file.write(' s->'+src+'->st64partial('+sid+'pa,val,msk);\n')
elif self.opc == 'stblockf':
file.write(' s->'+src+'->st512('+sid+'pa,s->mem_data);\n')
if mode == 'ras' and src == 'memory':
file.write(' if (s->sim_state.ras_enabled())\n')
file.write(' {\n')
file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
file.write(' SS_Trap::Type tt = med.inject_store_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa, val);\n')
file.write(' /*Precise traps not generated by any current architectures*/\n')
file.write(' assert (tt == SS_Trap::NO_TRAP);\n')
file.write(' }\n')
file.write(' s->npc = npc+4; return npc;\n')
file.write('}\n')
def run_dec_c(self,file):
pass
def run_dec_p(self):
return ''
#============================================================================
# SS_swap_mem(opc,out)
#============================================================================
class SS_swap_mem(SS_InstrAsm):
def __init__(self,opc,out):
SS_InstrAsm.__init__(self,opc+'_'+out)
self.opc = opc
self.out = out
def mem_c(self,file):
for mode in ['run','trc','ras']:
for src in ['memory','io']:
for endian in ['b','l']:
args = '( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, SS_Vaddr va, SS_Tte* tte )\n'
name = endian+'_'+self.opc+'_'+self.out
if src == 'memory':
sid = ''
file.write('\nextern "C" SS_Vaddr mem_'+mode+'_'+name+args)
else:
sid = 's->strand_id(),'
file.write('\nextern "C" SS_Vaddr io_'+mode+'_'+name+args)
file.write('{\n')
self.fail_chkpt(file)
file.write(' uint64_t val;\n')
file.write(' SS_Tte* _tte = (SS_Tte*)(long(tte) &~ 3);\n')
file.write(' SS_Paddr pa = _tte->trans(va);\n')
file.write('#if defined(MEMORY_MSYNC)\n')
file.write(' ((SS_MsyncMemory*)(s->'+src+'))->msync_info(s->strand_id(),va);\n')
file.write('#elif defined(MEMORY_EXTERNAL)\n')
if src == 'memory':
file.write(' ((SS_ExternalMemory*)(s->'+src+'))->set_strand_id(s->strand_id());\n')
file.write('#endif\n')
if self.out == 'rd':
file.write(' val = s->get_irf(i->rd);\n')
else:
file.write(' val = 0;\n')
if endian == 'l':
file.write(' val = endianess_convert_32u(val);\n')
if mode == 'trc':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_SWAP,va,_tte,4,&val);\n')
if mode == 'run' and src == 'memory':
file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::swap('+sid+'pa,val);\n')
else:
file.write(' val = s->'+src+'->swap('+sid+'pa,val);\n')
if mode == 'ras' and src == 'memory':
file.write(' if (s->sim_state.ras_enabled())\n')
file.write(' {\n')
file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
file.write(' SS_Trap::Type tt = med.inject_store_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa, val);\n')
file.write(' /*Precise traps not generated by any current architectures*/\n')
file.write(' assert (tt == SS_Trap::NO_TRAP);\n')
file.write(' }\n')
if mode == 'trc':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_SWAP,va,_tte,4,&val);\n')
if mode == 'ras' and src == 'memory':
file.write(' if (s->sim_state.ras_enabled())\n')
file.write(' {\n')
file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
file.write(' SS_Trap::Type tt = med.detect_load_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa);\n')
file.write(' if (tt != SS_Trap::NO_TRAP)\n')
file.write(' return (s->trap)(pc,npc,s,i,tt);\n')
file.write(' }\n')
if endian == 'l':
file.write(' val = endianess_convert_32u(val);\n')
if self.out == 'rd':
file.write(' s->get_irf(i->rd) = val;\n')
else:
file.write(' s->mmu_scratch = val;\n')
file.write(' s->npc = npc+4; return npc;\n')
file.write('}\n')
def run_dec_c(self,file):
pass
def run_dec_p(self):
return ''
#============================================================================
# SS_cas_mem(opc,out)
#============================================================================
class SS_cas_mem(SS_InstrAsm):
def __init__(self,opc,out):
SS_InstrAsm.__init__(self,opc+'_'+out)
self.opc = opc
self.out = out
def mem_c(self,file):
for mode in ['run','trc','ras']:
for src in ['memory','io']:
for endian in ['b','l']:
args = '( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, SS_Vaddr va, SS_Tte* tte )\n'
name = endian+'_'+self.opc+'_'+self.out
if src == 'memory':
file.write('\nextern "C" SS_Vaddr mem_'+mode+'_'+name+args)
sid = ''
else:
sid = 's->strand_id(),'
file.write('\nextern "C" SS_Vaddr io_'+mode+'_'+name+args)
file.write('{\n')
self.fail_chkpt(file)
file.write(' uint64_t val;\n')
file.write(' uint64_t rs2;\n')
file.write(' SS_Tte* _tte = (SS_Tte*)(long(tte) &~ 3);\n')
file.write(' SS_Paddr pa = _tte->trans(va);\n')
file.write('#if defined(MEMORY_MSYNC)\n')
file.write(' ((SS_MsyncMemory*)(s->'+src+'))->msync_info(s->strand_id(),va);\n')
file.write('#elif defined(MEMORY_EXTERNAL)\n')
if src == 'memory':
file.write(' ((SS_ExternalMemory*)(s->'+src+'))->set_strand_id(s->strand_id());\n')
file.write('#endif\n')
if self.out == 'rd':
file.write(' val = s->get_irf(i->rd);\n')
else:
file.write(' val = 0;\n')
file.write(' rs2 = s->get_irf(i->rs2);\n')
if endian == 'l':
if self.opc == 'casx':
file.write(' val = endianess_convert_64(val);\n')
file.write(' rs2 = endianess_convert_64(rs2);\n')
else:
file.write(' val = endianess_convert_32u(val);\n')
file.write(' rs2 = endianess_convert_32u(rs2);\n')
if mode == 'trc':
file.write(' s->mem_data[0] = val;\n')
file.write(' s->mem_data[1] = rs2;\n')
if self.opc == 'casx':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_CAS,va,_tte,8,s->mem_data);\n')
else:
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_CAS,va,_tte,4,s->mem_data);\n')
file.write(' val = s->mem_data[0];\n')
file.write(' rs2 = s->mem_data[1];\n')
if mode == 'run' and src == 'memory':
file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::'+self.opc+'('+sid+'pa,val,rs2);\n')
else:
file.write(' val = s->'+src+'->'+self.opc+'('+sid+'pa,val,rs2);\n')
if mode == 'ras' and src == 'memory':
file.write(' if (s->sim_state.ras_enabled())\n')
file.write(' {\n')
file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
file.write(' SS_Trap::Type tt = med.inject_store_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa, val);\n')
file.write(' /*Precise traps not generated by any current architectures*/\n')
file.write(' assert (tt == SS_Trap::NO_TRAP);\n')
file.write(' }\n')
if mode == 'trc':
if self.opc == 'casx':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_CAS,va,_tte,8,&val);\n')
else:
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_CAS,va,_tte,4,&val);\n')
if mode == 'ras' and src == 'memory':
file.write(' if (s->sim_state.ras_enabled())\n')
file.write(' {\n')
file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
file.write(' SS_Trap::Type tt = med.detect_load_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa);\n')
file.write(' if (tt != SS_Trap::NO_TRAP)\n')
file.write(' return (s->trap)(pc,npc,s,i,tt);\n')
file.write(' }\n')
if endian == 'l':
if self.opc == 'casx':
file.write(' val = endianess_convert_64(val);\n')
else:
file.write(' val = endianess_convert_32u(val);\n')
if self.out == 'rd':
file.write(' s->get_irf(i->rd) = val;\n')
else:
file.write(' s->mmu_scratch = val;\n')
file.write(' s->npc = npc+4; return npc;\n')
file.write('}\n')
def run_dec_c(self,file):
pass
def run_dec_p(self):
return ''
#============================================================================
# SS_ldstub_mem(opc,out)
#============================================================================
class SS_ldstub_mem(SS_InstrAsm):
def __init__(self,opc,out):
SS_InstrAsm.__init__(self,opc+'_'+out)
self.opc = opc
self.out = out
def mem_c(self,file):
for mode in ['run','trc','ras']:
for src in ['memory','io']:
for endian in ['b','l']:
args = '( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, SS_Vaddr va, SS_Tte* tte )\n'
name = endian+'_'+self.opc+'_'+self.out
if src == 'memory':
file.write('\nextern "C" SS_Vaddr mem_'+mode+'_'+name+args)
sid = ''
else:
sid = 's->strand_id(),'
file.write('\nextern "C" SS_Vaddr io_'+mode+'_'+name+args)
file.write('{\n')
self.fail_chkpt(file)
file.write(' uint64_t val;\n')
file.write(' SS_Tte* _tte = (SS_Tte*)(long(tte) &~ 3);\n')
file.write(' SS_Paddr pa = _tte->trans(va);\n')
file.write('#if defined(MEMORY_MSYNC)\n')
file.write(' ((SS_MsyncMemory*)(s->'+src+'))->msync_info(s->strand_id(),va);\n')
file.write('#elif defined(MEMORY_EXTERNAL)\n')
if src == 'memory':
file.write(' ((SS_ExternalMemory*)(s->'+src+'))->set_strand_id(s->strand_id());\n')
file.write('#endif\n')
if mode == 'trc':
file.write(' val = 0xff;\n')
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::ST_LDST,va,_tte,1,&val);\n')
if mode == 'run' and src == 'memory':
file.write(' val = ((SS_Memory*)(s->'+src+'))->SS_Memory::ldstub('+sid+'pa);\n')
else:
file.write(' val = s->'+src+'->ldstub('+sid+'pa);\n')
if mode == 'ras' and src == 'memory':
file.write(' if (s->sim_state.ras_enabled())\n')
file.write(' {\n')
file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
file.write(' SS_Trap::Type tt = med.inject_store_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa, val);\n')
file.write(' /*Precise traps not generated by any current architectures*/\n')
file.write(' assert (tt == SS_Trap::NO_TRAP);\n')
file.write(' }\n')
if mode == 'trc':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::LD_LDST,va,_tte,1,&val);\n')
if mode == 'ras' and src == 'memory':
file.write(' if (s->sim_state.ras_enabled())\n')
file.write(' {\n')
file.write(' SS_MemErrDetector& med = s->mem_err_detector;\n')
file.write(' SS_Trap::Type tt = med.detect_load_err(SS_MemErrDetector::L1_CACHE_AND_STB, pc, npc, s, i, pa);\n')
file.write(' if (tt != SS_Trap::NO_TRAP)\n')
file.write(' return (s->trap)(pc,npc,s,i,tt);\n')
file.write(' }\n')
if self.out == 'rd':
file.write(' s->get_irf(i->rd) = val;\n')
else:
file.write(' s->mmu_scratch = val;\n')
file.write(' s->npc = npc+4; return npc;\n')
file.write('}\n')
def run_dec_c(self,file):
pass
def run_dec_p(self):
return ''
#============================================================================
# SS_flush_mem(opc,out)
#============================================================================
class SS_flush_mem(SS_InstrAsm):
def __init__(self,opc,out):
SS_InstrAsm.__init__(self,opc+'_'+out)
self.opc = opc
self.out = out
def mem_c(self,file):
for mode in ['run','trc','ras']:
args = '( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, SS_Vaddr va, SS_Tte* tte )\n'
name = self.opc+'_'+self.out
file.write('\nextern "C" SS_Vaddr mem_'+mode+'_'+name+args)
file.write('{\n')
self.fail_chkpt(file)
# In cosim mode the flush is just ignored
file.write(' if (s->sim_state.cosim())\n')
file.write(' {\n')
file.write(' s->npc = npc + 4;\n')
file.write(' return npc;\n')
file.write(' }\n')
if setup.product == 'N2':
# On N2 say the TTE is not valid so we use an identity TTE (va == pa that is)
file.write(' SS_Tte* _tte = s->phys_tte_mem;\n')
file.write(' SS_Paddr pa = va;\n')
if mode == 'trc':
file.write(' if (s->trc_hook)\n s->trc_hook->mem_access(SS_Tracer::FLUSH,va,_tte,0,0);\n')
# In execution driven mode we do not do flush operations, we
# just nop the flush. We don't do decode caching in this mode.
file.write(' if (s->sim_state.exec_driven())\n')
file.write(' {\n')
file.write(' s->npc = npc + 4;\n')
file.write(' return pc;\n')
file.write(' }\n')
# The flush is broadcasted to all the strands. A strand will see the flush
# request and the next instruction will be refetched.
if setup.product == 'N2':
# Products like USIII and N2 have coherent instruction caches,
# which means flush is just draining the storebuffer. For us it means
# nuke the decode caches, infinite size (~0).
file.write(' s->model->flush(s,pa,~0);\n')
file.write(' s->npc = npc + 4;\n')
file.write(' return npc;\n')
file.write('}\n')
def run_dec_c(self,file):
pass
def run_dec_p(self):
return ''
def gen_mem_tbl(self,file,mode):
if mode == 'idx':
return SS_Instr. gen_mem_tbl(self,file,mode)
file.write(' mem_%s_%s,\n' % (mode,self.name))
file.write(' mem_%s_%s,\n' % (mode,self.name))
file.write(' mem_%s_%s,\n' % (mode,self.name))
file.write(' mem_%s_%s,\n' % (mode,self.name))
#============================================================================
# SS_rdasi(imm,out)
#============================================================================
class SS_rdasi(SS_InstrAsm):
def __init__(self,imm,out):
SS_InstrAsm.__init__(self,'rdasi_'+imm+'_'+out)
self.opc = 'rdasi'
self.imm = imm
self.out = out
def run_exe_c(self,file):
self.c_code_beg(file,'run_exe_')
if self.imm == 'i0':
file.write(' SS_Vaddr va = s->get_irf(i->rs1) + s->get_irf(i->rs2);\n')
else:
file.write(' if (i->asi != s->asi())\n')
file.write(' return (s->inst_dec)(pc,npc,s,i);\n')
file.write(' SS_Vaddr va = s->get_irf(i->rs1) + i->rs2;\n')
file.write(' va &= s->mask_pstate_am;\n')
file.write(' \n')
file.write(' if (va & 7)\n')
file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::MEM_ADDRESS_NOT_ALIGNED);\n')
file.write(' if (s->sim_state.priv() < s->asi_info[i->asi].get_protection())\n')
file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::PRIVILEGED_ACTION);\n')
if self.out == 'g0':
file.write(' SS_AsiSpace::Error ok = s->asi_map.ld64(s,i->asi,va,&s->mmu_scratch);\n')
else:
file.write(' SS_AsiSpace::Error ok = s->asi_map.ld64(s,i->asi,va,&s->get_irf(i->rd));\n')
file.write(' switch (ok)\n')
file.write(' {\n')
file.write(' case SS_AsiSpace::OK:\n')
file.write(' s->npc = npc+4; return npc;\n')
file.write(' case SS_AsiSpace::TRAP_PA:\n')
file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::PRIVILEGED_ACTION);\n')
file.write(' case SS_AsiSpace::TRAP_IA:\n')
file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::DAE_INVALID_ASI);\n')
file.write(' case SS_AsiSpace::TRAP_IPE:\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::INTERNAL_PROCESSOR_ERROR);\n')
file.write(' case SS_AsiSpace::RETRY:\n')
file.write(' return pc;\n')
file.write(' default:\n')
file.write(' return (s->invalid_asi)(pc,npc,s,i,va);\n')
file.write(' }\n')
self.c_code_end(file)
def run_dec_c(self,file):
pass
def run_dec_p(self):
return ''
def gen_exe_tbl(self,file,mode):
if mode == 'v8_run':
mode = 'run'
self.gen_exe_rrI(file,mode,self.imm,self.out)
#============================================================================
# SS_wrasi(imm,out)
#============================================================================
class SS_wrasi(SS_InstrAsm):
def __init__(self,imm,out):
SS_InstrAsm.__init__(self,'wrasi_'+imm+'_'+out)
self.opc = 'wrasi'
self.imm = imm
self.out = out
def run_exe_c(self,file):
self.c_code_beg(file,'run_exe_')
if setup.product == 'N2':
file.write(' N2_Strand* _s = (N2_Strand*)s;\n')
self.fail_chkpt(file)
if self.imm == 'i0':
file.write(' SS_Vaddr va = s->get_irf(i->rs1) + s->get_irf(i->rs2);\n')
else:
file.write(' if (i->asi != s->asi())\n')
file.write(' return (s->inst_dec)(pc,npc,s,i);\n')
file.write(' SS_Vaddr va = s->get_irf(i->rs1) + i->rs2;\n')
file.write(' va &= s->mask_pstate_am;\n')
file.write(' \n')
file.write(' if (va & 7)\n')
file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::MEM_ADDRESS_NOT_ALIGNED);\n')
file.write(' if (s->sim_state.priv() < s->asi_info[i->asi].get_protection())\n')
file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::PRIVILEGED_ACTION);\n')
file.write(' uint64_t rd;\n')
if self.out == 'rd':
file.write(' SS_AsiSpace::Error ok = s->asi_map.st64(s,i->asi,va,s->get_irf(i->rd));\n')
else:
file.write(' SS_AsiSpace::Error ok = s->asi_map.st64(s,i->asi,va,0);\n')
file.write(' switch (ok)\n')
file.write(' {\n')
file.write(' case SS_AsiSpace::OK:\n')
if setup.product == 'N2':
file.write(' //fill store buffer call for non-translating asi store\n')
file.write(' if (s->sim_state.ras_enabled())\n')
file.write(' _s->fill_store_buffer_asi(va,i->asi,s->get_irf(i->rd));\n')
file.write(' s->npc = npc+4; return npc;\n')
file.write(' case SS_AsiSpace::TRAP_PA:\n')
file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::PRIVILEGED_ACTION);\n')
file.write(' case SS_AsiSpace::TRAP_IA:\n')
file.write(' return (s->data_trap)(pc,npc,s,i,va,SS_Trap::DAE_INVALID_ASI);\n')
file.write(' case SS_AsiSpace::TRAP_IPE:\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::INTERNAL_PROCESSOR_ERROR);\n')
file.write(' case SS_AsiSpace::RETRY:\n')
file.write(' return pc;\n')
file.write(' default:\n')
file.write(' return (s->invalid_asi)(pc,npc,s,i,va);\n')
file.write(' }\n')
self.c_code_end(file)
def run_dec_c(self,file):
pass
def run_dec_p(self):
return ''
def gen_exe_tbl(self,file,mode):
if mode == 'v8_run':
mode = 'run'
self.gen_exe_RrI(file,mode,self.imm,self.out)
#============================================================================
#============================================================================
ss_flush = SS_InstrGroup('10_111011_flush',25,0x1f)
ss_ldxfsr = SS_InstrGroup('11_100001_ldxfsr',25,0x1f)
ss_stxfsr = SS_InstrGroup('11_100101_stxfsr',25,0x1f)
ss_prefetch = SS_InstrGroup('11_101101_prefetch',25,0x1f)
ss_prefetcha = SS_InstrGroup('11_111101_prefetcha',25,0x1f)
ss_flush.append(SS_lsu_dec('flush'))
if setup.product == 'N2':
ss_flush.append(SS_ill())
for i in range(0,30):
ss_flush.append(SS_ill())
ss_ldxfsr.append(SS_lsu_dec('ldfsr'))
ss_ldxfsr.append(SS_lsu_dec('ldxfsr'))
if setup.product == 'N2':
for i in range(0,30):
ss_ldxfsr.append(SS_ill())
ss_stxfsr.append(SS_lsu_dec('stfsr'))
ss_stxfsr.append(SS_lsu_dec('stxfsr'))
for i in range(0,30):
ss_stxfsr.append(SS_ill())
ss_prefetch.append(SS_lsu_dec('prefetch_dec'))
for i in range(0,4):
ss_prefetch.append(SS_lsu_dec('prefetch_tmp'))
for i in range(0,11):
ss_prefetch.append(SS_ill())
for i in range(0,16):
ss_prefetch.append(SS_lsu_dec('prefetch_tmp'))
ss_prefetcha.append(SS_lsu_dec('prefetcha_dec'))
for i in range(0,4):
ss_prefetcha.append(SS_lsu_dec('prefetcha_tmp'))
for i in range(0,11):
ss_prefetcha.append(SS_ill())
for i in range(0,16):
ss_prefetcha.append(SS_lsu_dec('prefetcha_tmp'))