# ========== Copyright Header Begin ==========================================
# OpenSPARC T2 Processor File: SS_InstrCti.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 ============================================
#============================================================================
# All Control Transfer Instruction (CTI) decode and implementation
#============================================================================
setup
= setups
[sys
.argv
[1]]
#============================================================================
# The not-annulled versions (_a0) of the branches do
# n : pc = npc , npc = npc+4
# a : pc = npc , npc = ea
# c : pc = npc , npc = c ? ea : npc+4
# annulled versions (_a1) of the branches do
# n : pc = npc+4 , npc = npc+8
# a : pc = ea , npc = ea+4
# c : pc = c ? npc : npc+4 , npc = c ? ea : npc+8
#============================================================================
#============================================================================
#============================================================================
class SS_bp_a0(SS_InstrAsm
):
def __init__(self
,cc
,ccr
):
SS_InstrAsm
.__init
__(self
,'bp'+cc
+'_'+ccr
+'_a0')
def run_exe_s(self
,file):
self
.asm_function(file,'run_exe_'+self
.name
)
self
.mov(file,self
.NPC
,self
.PC
)
self
.add(file,self
.NPC
,4,self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.mov(file,self
.NPC
,self
.PC
)
self
.ld_ea_rd(file,self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.mov(file,self
.NPC
,self
.PC
)
self
.add(file,self
.NPC
,4,self
.NPC
)
self
.ld_ea_rd(file,'%g2')
self
.movcc(file,self
.cc
,'%'+self
.ccr
,'%g2',self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.asm_codesize(file,'run_exe_'+self
.name
)
self
.asm_function(file,'run_tct_'+self
.name
)
self
.mov(file,self
.NPC
,self
.PC
)
self
.add(file,self
.NPC
,'4',self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.jmpl(file,'%g5','%g0','%g0')
self
.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4')
self
.add(file,self
.NPC
,4,'%g4')
self
.branch(file,self
.cc
,'%'+self
.ccr
,'1f')
self
.mov(file,self
.NPC
,self
.PC
)
self
.jmpl(file,'%g5','%g0','%g0')
self
.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4')
self
.asm_codesize(file,'run_tct_'+self
.name
)
def gen_exe_tbl(self
,file,mode
):
file.write(' trc_exe_passthrough, /* exe_'+self
.name
+' */\n')
file.write(' trc_exe_passthrough, /* tct_'+self
.name
+' */\n')
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self
.name
+' */\n')
file.write(' run_exe_v8plus_to_v9, /* run_tct_'+self
.name
+' */\n')
file.write(' %s_exe_%s,\n' % (mode
,self
.name
))
file.write(' %s_tct_%s,\n' % (mode
,self
.name
))
def idx_exe_s(self
,file):
self
.idx_exe_s_name(file,'exe_'+self
.name
)
self
.idx_exe_s_name(file,'tct_'+self
.name
)
def run_exe_c(self
,file):
file.write('#if defined(ARCH_X64)\n')
self
.c_code_beg(file,'run_exe_')
file.write(' pc = npc;\n')
file.write(' s->npc = (SS_Vaddr&)i->rd;\n')
file.write(' s->npc = npc+4;\n')
file.write(' return pc;\n')
self
.c_code_beg(file,'run_tct_')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n')
file.write(' pc = npc;\n')
file.write(' s->npc = npc+4;\n')
file.write(' return pc;\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self
.name
)
file.write('extern "C" SS_Vaddr run_tct_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self
.name
)
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (s->pstate.tct())\n')
file.write(' idx = idx_tct_%s;\n' % self
.name
)
file.write(' idx = idx_exe_%s;\n' % self
.name
)
file.write(' i->exe_tbl_idx = idx;\n')
file.write(' i->exe = s->exe_table[idx];\n')
file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp19();\n')
self
.c_code_dec_end(file)
#============================================================================
#============================================================================
class SS_bp_a1(SS_InstrAsm
):
def __init__(self
,cc
,ccr
):
SS_InstrAsm
.__init
__(self
,'bp'+cc
+'_'+ccr
+'_a1')
def run_exe_s(self
,file):
self
.asm_function(file,'run_exe_'+self
.name
)
self
.add(file,self
.NPC
,4,self
.PC
)
self
.add(file,self
.NPC
,8,self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.ld_ea_rd(file,self
.PC
)
self
.add(file,self
.PC
,4,self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.add(file,self
.NPC
,4,self
.PC
)
self
.ld_ea_rd(file,'%g2')
self
.movcc(file,self
.cc
,'%'+self
.ccr
,self
.NPC
,self
.PC
)
self
.add(file,self
.NPC
,8,self
.NPC
)
self
.movcc(file,self
.cc
,'%'+self
.ccr
,'%g2',self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.asm_codesize(file,'run_exe_'+self
.name
)
self
.asm_function(file,'run_tct_'+self
.name
)
self
.add(file,self
.NPC
,4,self
.PC
)
self
.add(file,self
.NPC
,8,self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.jmpl(file,'%g5','%g0','%g0')
self
.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4')
self
.add(file,self
.NPC
,8,'%g4')
self
.branch(file,self
.cc
,'%'+self
.ccr
,'1f')
self
.add(file,self
.NPC
,4,self
.PC
)
self
.jmpl(file,'%g5','%g0','%g0')
self
.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4')
self
.asm_codesize(file,'run_tct_'+self
.name
)
def gen_exe_tbl(self
,file,mode
):
file.write(' trc_exe_passthrough, /* exe_'+self
.name
+' */\n')
file.write(' trc_exe_passthrough, /* tct_'+self
.name
+' */\n')
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self
.name
+' */\n')
file.write(' run_exe_v8plus_to_v9, /* run_tct_'+self
.name
+' */\n')
file.write(' %s_exe_%s,\n' % (mode
,self
.name
))
file.write(' %s_tct_%s,\n' % (mode
,self
.name
))
def idx_exe_s(self
,file):
self
.idx_exe_s_name(file,'exe_'+self
.name
)
self
.idx_exe_s_name(file,'tct_'+self
.name
)
def run_exe_c(self
,file):
file.write('#if defined(ARCH_X64)\n')
self
.c_code_beg(file,'run_exe_')
file.write(' SS_Vaddr target = (SS_Vaddr&)i->rd;\n')
file.write(' pc = target;\n')
file.write(' s->npc = target+4;\n')
file.write(' pc = npc;\n')
file.write(' s->npc = (SS_Vaddr&)i->rd;\n')
file.write(' pc = npc + 4;\n')
file.write(' s->npc = npc + 8;\n')
file.write(' return pc;\n')
self
.c_code_beg(file,'run_tct_')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n')
file.write(' pc = npc + 4;\n')
file.write(' s->npc = npc + 8;\n')
file.write(' return pc;\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self
.name
)
file.write('extern "C" SS_Vaddr run_tct_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self
.name
)
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (s->pstate.tct())\n')
file.write(' idx = idx_tct_%s;\n' % self
.name
)
file.write(' idx = idx_exe_%s;\n' % self
.name
)
file.write(' i->exe_tbl_idx = idx;\n')
file.write(' i->exe = s->exe_table[idx];\n')
file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp19();\n')
self
.c_code_dec_end(file)
#============================================================================
#============================================================================
class SS_bi_a0(SS_InstrAsm
):
SS_InstrAsm
.__init
__(self
,'bi'+cc
+'_a0')
def idx_exe_s(self
,file):
def gen_exe_tbl(self
,file,mode
):
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (s->pstate.tct())\n')
file.write(' idx = idx_tct_bp%s_icc_a0;\n' % self
.cc
)
file.write(' idx = idx_exe_bp%s_icc_a0;\n' % self
.cc
)
file.write(' i->exe_tbl_idx = idx;\n')
file.write(' i->exe = s->exe_table[idx];\n')
file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp22();\n')
self
.c_code_dec_end(file)
#============================================================================
#============================================================================
class SS_bi_a1(SS_InstrAsm
):
SS_InstrAsm
.__init
__(self
,'bi'+cc
+'_a1')
def idx_exe_s(self
,file):
def gen_exe_tbl(self
,file,mode
):
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (s->pstate.tct())\n')
file.write(' idx = idx_tct_bp%s_icc_a1;\n' % self
.cc
)
file.write(' idx = idx_exe_bp%s_icc_a1;\n' % self
.cc
)
file.write(' i->exe_tbl_idx = idx;\n')
file.write(' i->exe = s->exe_table[idx];\n')
file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp22();\n')
self
.c_code_dec_end(file)
#============================================================================
#============================================================================
class SS_br_a0(SS_InstrAsm
):
SS_InstrAsm
.__init
__(self
,'br'+cc
+'_a0')
def run_exe_s(self
,file):
self
.asm_function(file,'run_exe_'+self
.name
)
self
.mov(file,self
.PC
,'%g3')
self
.mov(file,self
.NPC
,self
.PC
)
self
.add(file,self
.PC
,4,self
.NPC
)
self
.ld_irf(file,'%g1','%g1')
self
.opr(file,'sllx','%g2','2','%g2')
self
.add(file,'%g2','%g3','%g2')
self
.movr(file,self
.cc
,'%g1','%g2',self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.asm_codesize(file,'run_exe_'+self
.name
)
self
.asm_function(file,'run_tct_'+self
.name
)
self
.ld_irf(file,'%g1','%g1')
self
.add(file,self
.NPC
,4,'%g4')
self
.branch(file,'r'+self
.cc
,'%g1','1f')
self
.mov(file,self
.NPC
,self
.PC
)
self
.jmpl(file,'%g5','%g0','%g0')
self
.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4')
self
.asm_codesize(file,'run_tct_'+self
.name
)
def gen_exe_tbl(self
,file,mode
):
file.write(' trc_exe_passthrough, /* exe_'+self
.name
+' */\n')
file.write(' trc_exe_passthrough, /* tct_'+self
.name
+' */\n')
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self
.name
+' */\n')
file.write(' run_exe_v8plus_to_v9, /* run_tct_'+self
.name
+' */\n')
file.write(' %s_exe_%s,\n' % (mode
,self
.name
))
file.write(' %s_tct_%s,\n' % (mode
,self
.name
))
def idx_exe_s(self
,file):
self
.idx_exe_s_name(file,'exe_'+self
.name
)
self
.idx_exe_s_name(file,'tct_'+self
.name
)
def run_exe_c(self
,file):
file.write('#if defined(ARCH_X64)\n')
self
.c_code_beg(file,'run_exe_')
file.write(' int off = i->rs2;\n')
file.write(' off <<= 2;\n')
file.write(' uint64_t ea = pc + off;\n')
file.write(' pc = npc;\n')
file.write(' s->npc = ea;\n')
file.write(' pc = npc;\n')
file.write(' s->npc = npc + 4;\n')
file.write(' return pc;\n')
self
.c_code_beg(file,'run_tct_')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n')
file.write(' pc = npc;\n')
file.write(' s->npc = npc + 4;\n')
file.write(' return pc;\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self
.name
)
file.write('extern "C" SS_Vaddr run_tct_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self
.name
)
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (s->pstate.tct())\n')
self
.dec_0r16(file,' ','idx_tct_'+self
.name
)
self
.dec_0r16(file,' ','idx_exe_'+self
.name
)
#============================================================================
#============================================================================
class SS_br_a1(SS_InstrAsm
):
SS_InstrAsm
.__init
__(self
,'br'+cc
+'_a1')
def run_exe_s(self
,file):
self
.asm_function(file,'run_exe_'+self
.name
)
self
.mov(file,self
.PC
,'%g3')
self
.add(file,self
.NPC
,4,self
.PC
)
self
.ld_irf(file,'%g1','%g1')
self
.movr(file,self
.cc
,'%g1',self
.NPC
,self
.PC
)
self
.add(file,self
.NPC
,8,self
.NPC
)
self
.opr(file,'sllx','%g2','2','%g2')
self
.add(file,'%g2','%g3','%g2')
self
.movr(file,self
.cc
,'%g1','%g2',self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.asm_codesize(file,'run_exe_'+self
.name
)
self
.asm_function(file,'run_tct_'+self
.name
)
self
.ld_irf(file,'%g1','%g1')
self
.add(file,self
.NPC
,8,'%g4')
self
.branch(file,'r'+self
.cc
,'%g1','1f')
self
.add(file,self
.NPC
,4,self
.PC
)
self
.jmpl(file,'%g5','%g0','%g0')
self
.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4')
self
.asm_codesize(file,'run_tct_'+self
.name
)
def gen_exe_tbl(self
,file,mode
):
file.write(' trc_exe_passthrough, /* exe_'+self
.name
+' */\n')
file.write(' trc_exe_passthrough, /* tct_'+self
.name
+' */\n')
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self
.name
+' */\n')
file.write(' run_exe_v8plus_to_v9, /* run_tct_'+self
.name
+' */\n')
file.write(' %s_exe_%s,\n' % (mode
,self
.name
))
file.write(' %s_tct_%s,\n' % (mode
,self
.name
))
def idx_exe_s(self
,file):
self
.idx_exe_s_name(file,'exe_'+self
.name
)
self
.idx_exe_s_name(file,'tct_'+self
.name
)
def run_exe_c(self
,file):
file.write('#if defined(ARCH_X64)\n')
self
.c_code_beg(file,'run_exe_')
file.write(' int off = i->rs2;\n')
file.write(' off <<= 2;\n')
file.write(' uint64_t ea = pc + off;\n')
file.write(' pc = npc;\n')
file.write(' s->npc = ea;\n')
file.write(' pc = npc + 4;\n')
file.write(' s->npc = npc + 8;\n')
file.write(' return pc;\n')
self
.c_code_beg(file,'run_tct_')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n')
file.write(' pc = npc + 4;\n')
file.write(' s->npc = npc + 8;\n')
file.write(' return pc;\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self
.name
)
file.write('extern "C" SS_Vaddr run_tct_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self
.name
)
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (s->pstate.tct())\n')
self
.dec_0r16(file,' ','idx_tct_'+self
.name
)
self
.dec_0r16(file,' ','idx_exe_'+self
.name
)
#============================================================================
#============================================================================
class SS_fbp_a0(SS_InstrAsm
):
def __init__(self
,cc
,ccr
):
SS_InstrAsm
.__init
__(self
,'fbp'+cc
+'_'+ccr
+'_a0')
def run_exe_s(self
,file):
self
.asm_function(file,'run_exe_'+self
.name
)
self
.andcc(file,'%g5','F_FP_DISABLED','%g0')
self
.branch(file,'ne,a','%xcc','fpop_disabled_trap')
self
.mov(file,self
.NPC
,self
.PC
)
self
.add(file,self
.NPC
,4,self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.andcc(file,'%g5','F_FP_DISABLED','%g0')
self
.branch(file,'ne,a','%xcc','fpop_disabled_trap')
self
.mov(file,self
.NPC
,self
.PC
)
self
.ld_ea_rd(file,self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.st_fsr_cpu(file,'%fsr')
self
.ld_ea_rd(file,'%g2')
self
.ld_fsr_run(file,'%fsr')
self
.andcc(file,'%g5','F_FP_DISABLED','%g0')
self
.branch(file,'ne,a','%xcc','fpop_disabled_trap_fsr')
self
.mov(file,self
.NPC
,self
.PC
)
self
.add(file,self
.NPC
,4,self
.NPC
)
self
.movcc(file,self
.cc
,'%'+self
.ccr
,'%g2',self
.NPC
)
self
.ld_fsr_cpu(file,'%fsr')
self
.retl_st_npc(file,self
.NPC
)
self
.asm_codesize(file,'run_exe_'+self
.name
)
self
.asm_function(file,'run_tct_'+self
.name
)
self
.andcc(file,'%g5','F_FP_DISABLED','%g0')
self
.branch(file,'ne,a','%xcc','fpop_disabled_trap')
self
.mov(file,self
.NPC
,self
.PC
)
self
.add(file,self
.NPC
,4,self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.andcc(file,'%g5','F_FP_DISABLED','%g0')
self
.branch(file,'ne,a','%xcc','fpop_disabled_trap')
self
.jmpl(file,'%g4','%g0','%g0')
self
.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4')
self
.st_fsr_cpu(file,'%fsr')
self
.ld_fsr_run(file,'%fsr')
self
.andcc(file,'%g5','F_FP_DISABLED','%g0')
self
.branch(file,'ne,a','%xcc','fpop_disabled_trap_fsr')
self
.branch(file,self
.cc
,'%'+self
.ccr
,'1f')
self
.ld_fsr_cpu(file,'%fsr')
self
.mov(file,self
.NPC
,self
.PC
)
self
.add(file,self
.NPC
,4,self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.jmpl(file,'%g4','%g0','%g0')
self
.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4')
self
.asm_codesize(file,'run_tct_'+self
.name
)
def gen_exe_tbl(self
,file,mode
):
file.write(' trc_exe_passthrough, /* exe_'+self
.name
+' */\n')
file.write(' trc_exe_passthrough, /* tct_'+self
.name
+' */\n')
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self
.name
+' */\n')
file.write(' run_exe_v8plus_to_v9, /* run_tct_'+self
.name
+' */\n')
file.write(' %s_exe_%s,\n' % (mode
,self
.name
))
file.write(' %s_tct_%s,\n' % (mode
,self
.name
))
def idx_exe_s(self
,file):
self
.idx_exe_s_name(file,'exe_'+self
.name
)
self
.idx_exe_s_name(file,'tct_'+self
.name
)
def run_exe_c(self
,file):
file.write('#if defined(ARCH_X64)\n')
self
.c_code_beg(file,'run_exe_')
file.write(' if (s->sim_state.fp_disabled())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n')
file.write(' pc = npc;\n')
file.write(' s->npc = (SS_Vaddr&)i->rd;\n')
file.write(' s->npc = npc + 4;\n')
file.write(' return pc;\n')
self
.c_code_beg(file,'run_tct_')
file.write(' if (s->sim_state.fp_disabled())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n')
file.write(' pc = npc;\n')
file.write(' s->npc = npc + 4;\n')
file.write(' return pc;\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self
.name
)
file.write('extern "C" SS_Vaddr run_tct_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self
.name
)
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (s->pstate.tct())\n')
file.write(' idx = idx_tct_%s;\n' % self
.name
)
file.write(' idx = idx_exe_%s;\n' % self
.name
)
file.write(' i->exe_tbl_idx = idx;\n')
file.write(' i->exe = s->exe_table[idx];\n')
file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp19();\n')
self
.c_code_dec_end(file)
#============================================================================
#============================================================================
class SS_fbp_a1(SS_InstrAsm
):
def __init__(self
,cc
,ccr
):
SS_InstrAsm
.__init
__(self
,'fbp'+cc
+'_'+ccr
+'_a1')
def run_exe_s(self
,file):
self
.asm_function(file,'run_exe_'+self
.name
)
self
.andcc(file,'%g5','F_FP_DISABLED','%g0')
self
.branch(file,'ne,a','%xcc','fpop_disabled_trap')
self
.add(file,self
.NPC
,4,self
.PC
)
self
.add(file,self
.NPC
,8,self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.ld_ea_rd(file,'%g2')
self
.andcc(file,'%g5','F_FP_DISABLED','%g0')
self
.branch(file,'ne,a','%xcc','fpop_disabled_trap')
self
.mov(file,'%g2',self
.PC
)
self
.add(file,'%g2',4,self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.st_fsr_cpu(file,'%fsr')
self
.ld_ea_rd(file,'%g2')
self
.ld_fsr_run(file,'%fsr')
self
.andcc(file,'%g5','F_FP_DISABLED','%g0')
self
.branch(file,'ne,a','%xcc','fpop_disabled_trap_fsr')
self
.add(file,self
.NPC
,4,self
.PC
)
self
.movcc(file,self
.cc
,'%'+self
.ccr
,self
.NPC
,self
.PC
)
self
.add(file,self
.NPC
,8,self
.NPC
)
self
.movcc(file,self
.cc
,'%'+self
.ccr
,'%g2',self
.NPC
)
self
.ld_fsr_cpu(file,'%fsr')
self
.retl_st_npc(file,self
.NPC
)
self
.asm_codesize(file,'run_exe_'+self
.name
)
self
.asm_function(file,'run_tct_'+self
.name
)
self
.andcc(file,'%g5','F_FP_DISABLED','%g0')
self
.branch(file,'ne,a','%xcc','fpop_disabled_trap')
self
.add(file,self
.NPC
,4,self
.PC
)
self
.add(file,self
.NPC
,8,self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.andcc(file,'%g5','F_FP_DISABLED','%g0')
self
.branch(file,'ne,a','%xcc','fpop_disabled_trap')
self
.jmpl(file,'%g4','%g0','%g0')
self
.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4')
self
.st_fsr_cpu(file,'%fsr')
self
.ld_fsr_run(file,'%fsr')
self
.andcc(file,'%g5','F_FP_DISABLED','%g0')
self
.branch(file,'ne,a','%xcc','fpop_disabled_trap_fsr')
self
.branch(file,self
.cc
,'%'+self
.ccr
,'1f')
self
.ld_fsr_cpu(file,'%fsr')
self
.add(file,self
.NPC
,4,self
.PC
)
self
.add(file,self
.NPC
,8,self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.jmpl(file,'%g4','%g0','%g0')
self
.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4')
self
.asm_codesize(file,'run_tct_'+self
.name
)
def gen_exe_tbl(self
,file,mode
):
file.write(' trc_exe_passthrough, /* exe_'+self
.name
+' */\n')
file.write(' trc_exe_passthrough, /* tct_'+self
.name
+' */\n')
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self
.name
+' */\n')
file.write(' run_exe_v8plus_to_v9, /* run_tct_'+self
.name
+' */\n')
file.write(' %s_exe_%s,\n' % (mode
,self
.name
))
file.write(' %s_tct_%s,\n' % (mode
,self
.name
))
def idx_exe_s(self
,file):
self
.idx_exe_s_name(file,'exe_'+self
.name
)
self
.idx_exe_s_name(file,'tct_'+self
.name
)
def run_exe_c(self
,file):
file.write('#if defined(ARCH_X64)\n')
self
.c_code_beg(file,'run_exe_')
file.write(' if (s->sim_state.fp_disabled())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n')
file.write(' SS_Vaddr target = (SS_Vaddr&)i->rd;\n')
file.write(' pc = target;\n')
file.write(' s->npc = target + 4;\n')
file.write(' pc = npc;\n')
file.write(' s->npc = (SS_Vaddr&)i->rd;\n')
file.write(' pc = npc + 4;\n')
file.write(' s->npc = npc + 8;\n')
file.write(' return pc;\n')
self
.c_code_beg(file,'run_tct_')
file.write(' if (s->sim_state.fp_disabled())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n')
file.write(' pc = npc + 4;\n')
file.write(' s->npc = npc + 8;\n')
file.write(' return pc;\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self
.name
)
file.write('extern "C" SS_Vaddr run_tct_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % self
.name
)
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (s->pstate.tct())\n')
file.write(' idx = idx_tct_%s;\n' % self
.name
)
file.write(' idx = idx_exe_%s;\n' % self
.name
)
file.write(' i->exe_tbl_idx = idx;\n')
file.write(' i->exe = s->exe_table[idx];\n')
file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp19();\n')
self
.c_code_dec_end(file)
#============================================================================
#============================================================================
class SS_fbi_a0(SS_InstrAsm
):
SS_InstrAsm
.__init
__(self
,'fbi'+cc
+'_a0')
def idx_exe_s(self
,file):
def gen_exe_tbl(self
,file,mode
):
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (s->pstate.tct())\n')
file.write(' idx = idx_tct_fbp%s_fcc0_a0;\n' % self
.cc
)
file.write(' idx = idx_exe_fbp%s_fcc0_a0;\n' % self
.cc
)
file.write(' i->exe_tbl_idx = idx;\n')
file.write(' i->exe = s->exe_table[idx];\n')
file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp22();\n')
self
.c_code_dec_end(file)
#============================================================================
#============================================================================
class SS_fbi_a1(SS_InstrAsm
):
SS_InstrAsm
.__init
__(self
,'fbi'+cc
+'_a1')
def idx_exe_s(self
,file):
def gen_exe_tbl(self
,file,mode
):
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (s->pstate.tct())\n')
file.write(' idx = idx_tct_fbp%s_fcc0_a1;\n' % self
.cc
)
file.write(' idx = idx_exe_fbp%s_fcc0_a1;\n' % self
.cc
)
file.write(' i->exe_tbl_idx = idx;\n')
file.write(' i->exe = s->exe_table[idx];\n')
file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp22();\n')
self
.c_code_dec_end(file)
#============================================================================
#============================================================================
class SS_call(SS_InstrAsm
):
SS_InstrAsm
.__init
__(self
,'call')
def run_exe_s(self
,file):
self
.asm_function(file,'run_exe_'+self
.name
)
self
.ld_mask_pstate_am(file,'%g5')
self
.mov(file,self
.PC
,'%g4')
self
.mov(file,self
.NPC
,self
.PC
)
self
.ld_ea_rd(file,self
.NPC
)
self
.opr(file,'and','%g4','%g5','%g5')
# ToDo do we need to sign extend the pc ... ironically that case should be a mem range trap
self
.opr(file,'sllx','%g5',str(64 - setup
.va_bits
),'%g5')
self
.opr(file,'srax','%g5',str(64 - setup
.va_bits
),'%g5')
self
.st_npc(file,self
.NPC
)
self
.asm_codesize(file,'run_exe_'+self
.name
)
def run_exe_c(self
,file):
file.write('#if defined(ARCH_X64)\n')
self
.c_code_beg(file,'run_exe_')
file.write(' pc &= s->mask_pstate_am;\n')
file.write(' pc = ((((int64_t)pc) << '+str(64-setup
.va_bits
)+') >> '+str(64-setup
.va_bits
)+');\n')
file.write(' s->irf[15] = pc;\n')
file.write(' s->npc = (SS_Vaddr&)i->rd;\n')
file.write(' return npc;\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self
.name
))
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (s->pstate.tct())\n')
file.write(' idx = idx_tct_bpa_icc_a0;\n')
file.write(' idx = idx_exe_%s;\n' % self
.name
)
file.write(' i->exe_tbl_idx = idx;\n')
file.write(' i->exe = s->exe_table[idx];\n')
file.write(' (SS_Vaddr&)i->rd = pc + o.get_disp30();\n')
self
.c_code_dec_end(file)
def run_dec_p_count(self
):
def gen_exe_tbl(self
,file,mode
):
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self
.name
+' */\n')
file.write(' %s_exe_%s,\n' % (mode
,self
.name
))
#============================================================================
#=================================t===========================================
class SS_illtrap(SS_InstrCpp
):
SS_InstrCpp
.__init
__(self
,'illtrap')
def run_exe_c(self
,file):
self
.c_code_beg(file,'run_exe_')
file.write(' assert(0);\n')
file.write(' return -SS_Vaddr(1);\n')
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self
.c_code_dec_end(file)
def run_dec_p_count(self
):
def gen_exe_tbl(self
,file,mode
):
self
.gen_exe_passthrough(file,mode
)
#============================================================================
# ToDo: optimize common patters (retl) jmpl %o7+8,%g0, (call) jmpl %r,%o7
# and (tailcall) jmpl %r,%g0
#============================================================================
class SS_jmpl(SS_InstrAsm
):
SS_InstrAsm
.__init
__(self
,'jmpl')
def run_exe_c(self
,file):
file.write('#if defined(ARCH_X64)\n')
self
.c_code_beg_name(file,'run_exe_jmpl_'+imm
+'_'+out
)
file.write(' uint64_t mask = s->mask_pstate_am;\n')
file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n')
file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n')
file.write(' int rs2 = i->rs2;\n');
# First check for aligned address
file.write(' uint64_t target = rs1 + rs2;\n')
file.write(' if (target & 0x3)\n')
file.write(' return (s->inst_trap)(pc,npc,s,i,target,SS_Trap::MEM_ADDRESS_NOT_ALIGNED);\n')
# Then check for address range if va_bits != 64
file.write(' uint64_t t1 = target & mask;\n')
file.write(' uint64_t t = (((int64_t)t1) << '+str(64 - setup
.va_bits
)+') >> '+str(64 - setup
.va_bits
)+';\n')
file.write(' if (t != t1)\n')
file.write(' // Do not generate trap in HPRV or RED mode (IMMU bypass)\n')
file.write(' if (s->sim_state.mode() < 2)\n')
file.write(' return (s->inst_trap)(pc,npc,s,i,target,SS_Trap::MEM_ADDRESS_RANGE);\n')
file.write(' pc &= mask;\n')
file.write(' pc = (((int64_t)pc) << '+str(64-setup
.va_bits
)+') >> '+str(64-setup
.va_bits
)+';\n')
file.write(' s->get_irf(i->rd) = pc;\n')
file.write(' s->npc = target;\n')
file.write(' return npc;\n')
file.write('\nextern "C" SS_Vaddr run_exe_'+self
.opc
+'_'+imm
+'_'+out
+'( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );\n')
file.write('#if defined(ARCH_X64)\n')
self
.c_code_beg_name(file,'run_tct_jmpl_'+imm
)
file.write(' uint64_t mask = s->mask_pstate_am;\n')
file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n')
file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n')
file.write(' int rs2 = i->rs2;\n');
# First check for aligned address
file.write(' uint64_t target = rs1 + rs2;\n')
file.write(' if (target & 0x3)\n')
file.write(' return (s->inst_trap)(pc,npc,s,i,target,SS_Trap::MEM_ADDRESS_NOT_ALIGNED);\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n')
file.write('\nextern "C" SS_Vaddr run_tct_'+self
.opc
+'_'+imm
+'( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i );\n')
def run_exe_s(self
,file):
self
.asm_function(file,'run_exe_'+self
.opc
+'_'+imm
+'_'+out
)
self
.ld_mask_pstate_am(file,'%g4')
self
.ld_irf(file,'%g1','%g1')
self
.ld_irf(file,'%g2','%g2')
self
.ld_mask_pstate_am(file,'%g4')
self
.ld_irf(file,'%g1','%g1')
self
.opr(file,'and',self
.PC
,'%g4','%g5')
self
.opr(file,'sllx','%g5',str(64 - setup
.va_bits
),'%g5')
self
.opr(file,'srax','%g5',str(64 - setup
.va_bits
),'%g5')
# First check for aligned address
# Then check for address range if va_bits != 64
self
.add(file,'%g1','%g2','%g1')
self
.opr(file,'andcc','%g1',3,'%g0')
self
.opr(file,'and','%g1','%g4','%g4')
self
.branch(file,'e','%icc','1f')
self
.opr(file,'srax','%g4',str(setup
.va_bits
- 1),'%g4')
self
.branch(file,'e,a','%icc','1f')
self
.st_irf(file,'%g3','%g5')
self
.branch(file,'e,a','%icc','1f')
self
.ld_inst_trap(file,'%g2')
self
.mov(file,'%g1','%o4')
self
.jmpl(file,'%g2','%g0','%g0')
self
.mov(file,'T_MEM_ADDRESS_NOT_ALIGNED','%o5')
self
.add(file,'%g4','1','%g4')
self
.opr(file,'subcc','%g4','1','%g0')
self
.branch(file,'leu','%xcc','2f')
# Don't generate the MEM_ADDRESS_RANGE trap in HPRV or RED mode (IMMU bypass)
self
.opr(file,'and','%g2','7','%g2') # priv() and red() -> sim_state.mode()
self
.opr(file,'subcc','%g2','2','%g0')
self
.branch(file,'ge,a','%xcc','2f')
self
.ld_inst_trap(file,'%g2')
self
.mov(file,'%g1','%o4')
self
.jmpl(file,'%g2','%g0','%g0')
self
.mov(file,'T_MEM_ADDRESS_RANGE','%o5')
self
.mov(file,self
.NPC
,self
.PC
)
if out
== 'rd' and setup
.va_bits
!= 64:
self
.st_irf(file,'%g3','%g5')
self
.mov(file,'%g1',self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.asm_codesize(file,'run_exe_'+self
.opc
+'_'+imm
+'_'+out
)
self
.asm_function(file,'run_tct_'+self
.opc
+'_'+imm
)
self
.ld_irf(file,'%g1','%g1')
self
.ld_irf(file,'%g2','%g2')
self
.ld_irf(file,'%g1','%g1')
self
.add(file,'%g1','%g2','%g1')
self
.opr(file,'andcc','%g1',3,'%g0')
self
.branch(file,'e,a','%icc','1f')
self
.ld_inst_trap(file,'%g2')
self
.mov(file,'%g1','%o4')
self
.jmpl(file,'%g2','%g0','%g0')
self
.mov(file,'T_MEM_ADDRESS_NOT_ALIGNED','%o5')
self
.jmpl(file,'%g4','%g0','%g0')
self
.mov(file,'T_CONTROL_TRANSFER_INSTRUCTION','%o4')
self
.asm_codesize(file,'run_tct_'+self
.opc
+'_'+imm
)
def run_dec_c(self
,file):
self
.c_code_dec_beg_name(file,'run_dec_jmpl')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.get_i())\n')
file.write(' if (s->pstate.tct())\n')
self
.dec_0r13(file,' ','idx_tct_jmpl_i1')
file.write(' if (o.get_rd_irf())\n')
self
.dec_rr13(file,' ','idx_exe_jmpl_i1_rd')
self
.dec_0r13(file,' ','idx_exe_jmpl_i1_g0')
file.write(' else if (o.is_zero_12_5())\n')
file.write(' if (s->pstate.tct())\n')
self
.dec_0rr(file,' ','idx_tct_jmpl_i0')
file.write(' if (o.get_rd_irf())\n')
self
.dec_rrr(file,' ','idx_exe_jmpl_i0_rd')
self
.dec_0rr(file,' ','idx_exe_jmpl_i0_g0')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
def gen_exe_tbl(self
,file,mode
):
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self
.name
+'_'+imm
+'_'+out
+' */\n')
self
.gen_exe_rrI(file,mode
,imm
,out
)
self
.gen_exe_rrI(file,mode
,imm
)
file.write(' run_exe_v8plus_to_v9, /* run_tct_'+self
.name
+'_'+imm
+' */\n')
file.write(' '+mode
+'_tct_jmpl_'+imm
+',\n')
def idx_exe_s(self
,file):
self
.idx_exe_s_name(file,'exe_'+self
.opc
+'_'+imm
+'_'+out
)
self
.idx_exe_s_name(file,'tct_'+self
.opc
+'_'+imm
)
#============================================================================
# Note: tcc in usermode only allows for trapno: 0..127, checked in trap handle
# Note: control transfer traps for tcc behave the same as bpcc with no annul.
#============================================================================
class SS_tcc(SS_InstrAsm
):
def __init__(self
,cc
,ccr
,imm
):
SS_InstrAsm
.__init
__(self
,'t'+cc
+'_'+ccr
+'_'+imm
)
def run_exe_c(self
,file):
file.write('#if defined(ARCH_X64)\n')
self
.c_code_beg(file,'run_exe_')
file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n')
file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
file.write(' int rs2 = i->rs2;\n');
file.write(' int trap = (rs1 + rs2) & 0xFF;\n')
file.write(' return (s->trap)(pc,npc,s,i,(SS_Trap::Type)(trap+0x100));\n')
file.write(' pc = npc;\n')
file.write(' s->npc = npc + 4;\n')
file.write(' return pc;\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self
.name
))
def run_exe_s(self
,file):
self
.asm_function(file,'run_exe_'+self
.name
)
self
.mov(file,self
.NPC
,self
.PC
)
self
.add(file,self
.NPC
,4,self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.ld_irf(file,'%g1','%g1')
self
.ld_irf(file,'%g2','%g2')
self
.add(file,'%g1','%g2','%o4')
self
.opr(file,'and','%o4',255,'%o4')
self
.jmpl(file,'%g5','%g0','%g0')
self
.add(file,'%o4',256,'%o4')
self
.ld_irf(file,'%g1','%g1')
self
.ld_irf(file,'%g2','%g2')
self
.branch(file,self
.cc
+',a','%'+self
.ccr
,'1f')
self
.add(file,'%g1','%g2','%o4')
self
.mov(file,self
.NPC
,self
.PC
)
self
.add(file,self
.NPC
,4,self
.NPC
)
self
.retl_st_npc(file,self
.NPC
)
self
.opr(file,'and','%o4',255,'%o4')
self
.jmpl(file,'%g5','%g0','%g0')
self
.add(file,'%o4',256,'%o4')
self
.asm_codesize(file,'run_exe_'+self
.name
)
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_10_8())\n')
file.write(' if (s->pstate.tct())\n')
self
.dec_0r8(file,' ','idx_tct_bp'+self
.name
[1:-2]+'a0')
self
.dec_0r8(file,' ','idx_exe_'+self
.name
)
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
file.write(' if (o.is_zero_10_5())\n')
file.write(' if (s->pstate.tct())\n')
self
.dec_0rr(file,' ','idx_tct_bp'+self
.name
[1:-2]+'a0')
self
.dec_0rr(file,' ','idx_exe_'+self
.name
)
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
def gen_exe_tbl(self
,file,mode
):
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self
.name
+' */\n')
self
.gen_exe_0rI(file,mode
)
#============================================================================
#============================================================================
class SS_done(SS_InstrCpp
):
SS_InstrCpp
.__init
__(self
,'done')
def run_exe_c(self
,file):
self
.c_code_beg(file,'run_exe_')
file.write(' if (s->sim_state.priv() < SS_Strand::SS_PRIV)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n')
file.write(' else if (s->tl() == 0)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
file.write(' else if (s->pstate.tct())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n')
file.write(' s->do_retry();\n')
file.write(' SS_Vaddr _npc = s->npc();\n')
file.write(' s->npc = _npc + 4;\n')
file.write(' return _npc;\n')
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_18_0())\n')
self
.dec_000(file,' ','idx_exe_'+self
.name
)
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
def gen_exe_tbl(self
,file,mode
):
self
.gen_exe_passthrough(file,mode
)
#============================================================================
#============================================================================
class SS_retry(SS_InstrCpp
):
SS_InstrCpp
.__init
__(self
,'retry')
def run_exe_c(self
,file):
self
.c_code_beg(file,'run_exe_')
file.write(' if (s->sim_state.priv() < SS_Strand::SS_PRIV)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::PRIVILEGED_OPCODE);\n')
file.write(' else if (s->tl() == 0)\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
file.write(' else if (s->pstate.tct())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n')
file.write(' s->do_retry();\n')
file.write(' return s->pc();\n')
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_18_0())\n')
self
.dec_000(file,' ','idx_exe_'+self
.name
)
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
def gen_exe_tbl(self
,file,mode
):
self
.gen_exe_passthrough(file,mode
)
#============================================================================
#============================================================================
class SS_return(SS_InstrCpp
):
SS_InstrCpp
.__init
__(self
,'return')
def run_exe_c(self
,file):
self
.c_code_beg_name(file,'run_exe_'+self
.name
+'_'+imm
)
file.write('uint64_t r0,r1,r2,r3,r4,r5,r6,r7;')
file.write('uint64_t cwp = s->cwp();')
file.write('uint64_t canrestore = s->canrestore();')
file.write('r7 = s->irf[23];')
file.write('r6 = s->irf[22];')
file.write(' if (canrestore)\n')
file.write(' uint64_t ea = s->get_irf(i->rs1) + s->get_irf(i->rs2);\n')
file.write(' uint64_t ea = s->get_irf(i->rs1) + i->rs2;\n')
file.write(' if (ea & 3)\n')
file.write(' return (s->inst_trap)(pc,npc,s,i,ea,SS_Trap::MEM_ADDRESS_NOT_ALIGNED);\n')
file.write(' else if (s->pstate.tct())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::CONTROL_TRANSFER_INSTRUCTION);\n')
file.write(' s->cwp_save();\n')
file.write(' cwp = cwp ? (cwp - 1) : s->max_wp();\n')
file.write(' s->cansave = (s->cansave() < s->max_wp()) ? (s->cansave() + 1) : 0;\n')
file.write(' s->canrestore = canrestore ? (canrestore - 1) : s->max_wp();\n')
file.write(' s->cwp = cwp;\n')
file.write(' s->cwp_load();')
file.write(' s->npc = ea; return npc;\n')
file.write(' else if (s->otherwin())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::fill_other(s->wstate.other()));\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::fill_normal(s->wstate.normal()));\n')
def run_dec_c(self
,file):
self
.c_code_dec_beg(file,'run_dec_')
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.get_rd())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
file.write(' else if (o.get_i())\n')
self
.dec_0r13(file,' ','idx_exe_'+self
.name
+'_i1')
file.write(' else if (o.is_zero_12_5())\n')
self
.dec_0rr(file,' ','idx_exe_'+self
.name
+'_i0')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
def gen_exe_tbl(self
,file,mode
):
self
.gen_exe_0rI(file,mode
,imm
)
#============================================================================
#============================================================================
ss_bp_icc
= SS_InstrGroup('00_00100x_bp_icc',25,0x1f,2)
ss_bp_c01
= SS_InstrGroup('00_001011',25,0x1f,2)
ss_bp_xcc
= SS_InstrGroup('00_00110x_bp_xcc',25,0x1f,2)
ss_bp_c11
= SS_InstrGroup('00_00111x',25,0x1f,2)
ss_bi
= SS_InstrGroup('00_010xxx_bi',25,0x1f,8)
ss_br
= SS_InstrGroup('00_011xxx_br',25,0x1f,8)
ss_fbp_fcc0
= SS_InstrGroup('00_10100x_fbp_fcc0',25,0x1f,2)
ss_fbp_fcc1
= SS_InstrGroup('00_10101x_fbp_fcc1',25,0x1f,2)
ss_fbp_fcc2
= SS_InstrGroup('00_10110x_fbp_fcc2',25,0x1f,2)
ss_fbp_fcc3
= SS_InstrGroup('00_10111x_fbp_fcc3',25,0x1f,2)
ss_fbi
= SS_InstrGroup('00_110xxx_fbi',25,0x1f,8)
ss_bp_icc
.append(SS_bp_a0(cc
,'icc'))
ss_bp_c01
.append(SS_ill())
ss_bp_xcc
.append(SS_bp_a0(cc
,'xcc'))
ss_bp_c11
.append(SS_ill())
ss_bi
.append(SS_bi_a0(cc
))
ss_bp_icc
.append(SS_bp_a1(cc
,'icc'))
if setup
.product
== 'N2':
ss_bp_c01
.append(SS_ill())
ss_bp_xcc
.append(SS_bp_a1(cc
,'xcc'))
ss_bp_c11
.append(SS_ill())
ss_bi
.append(SS_bi_a1(cc
))
ss_br
.append(SS_br_a0(cc
))
ss_br
.append(SS_br_a1(cc
))
ss_fbp_fcc0
.append(SS_fbp_a0(cc
,'fcc0'))
ss_fbp_fcc1
.append(SS_fbp_a0(cc
,'fcc1'))
ss_fbp_fcc2
.append(SS_fbp_a0(cc
,'fcc2'))
ss_fbp_fcc3
.append(SS_fbp_a0(cc
,'fcc3'))
ss_fbi
.append(SS_fbi_a0(cc
))
ss_fbp_fcc0
.append(SS_fbp_a1(cc
,'fcc0'))
ss_fbp_fcc1
.append(SS_fbp_a1(cc
,'fcc1'))
ss_fbp_fcc2
.append(SS_fbp_a1(cc
,'fcc2'))
ss_fbp_fcc3
.append(SS_fbp_a1(cc
,'fcc3'))
ss_fbi
.append(SS_fbi_a1(cc
))
ss_done
= SS_InstrGroup('10_111110_done',25,0x1f)
ss_done
.append(SS_done())
ss_done
.append(SS_retry())
if setup
.product
== 'N2':
if setup
.product
== 'N2':
ss_tcc
= SS_InstrGroup('10_111010_tcc',25,0x1f)
ss_tcc_iccr
= SS_InstrGroup('10_111010_tcc_'+cc
,11,7)
ss_tcc_iccr
.append(SS_tcc(cc
,'icc','i0'))
ss_tcc_iccr
.append(SS_ill())
ss_tcc_iccr
.append(SS_tcc(cc
,'xcc','i0'))
ss_tcc_iccr
.append(SS_ill())
ss_tcc_iccr
.append(SS_tcc(cc
,'icc','i1'))
ss_tcc_iccr
.append(SS_ill())
ss_tcc_iccr
.append(SS_tcc(cc
,'xcc','i1'))
ss_tcc_iccr
.append(SS_ill())
ss_tcc
.append(ss_tcc_iccr
)