Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / bin / SS_InstrFormat.py
# ========== Copyright Header Begin ==========================================
#
# OpenSPARC T2 Processor File: SS_InstrFormat.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 *
ss_vis1 = {}
ss_vis2 = {}
ss_vis3 = {}
#============================================================================
# SS_opf_fff
#============================================================================
class SS_opf_fff(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rs1(file,'%g1')
self.ld_rs2(file,'%g2')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne','%xcc','fpop_disabled_trap')
self.nop(file)
self.ld_frf(file,'%g1','%f0')
self.ld_frf(file,'%g2','%f4')
self.opr(file,self.name,'%f0','%f4','%f8')
self.branch(file,'a,a','%xcc','opf_fprs_f')
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(' uint32_t rs1 = s->get_frf(i->rs1);\n')
file.write(' uint32_t rs2 = s->get_frf(i->rs2);\n')
file.write(' uint32_t r32;\n')
file.write(' uint64_t v64;\n')
if (self.name in ['fpadd16s','fpsub16s']):
file.write(' r32 = 0;\n')
file.write(' for (int n = 0; n < 2; n++) {\n')
if (self.name == 'fpadd16s'):
file.write(' v64 = (rs1 & 0xffff) + (rs2 & 0xffff);\n')
else:
file.write(' v64 = (rs1 & 0xffff) - (rs2 & 0xffff);\n')
file.write(' r32 |= ((v64 & 0xffff) << (n << 4));\n')
file.write(' rs1 >>= 16;\n')
file.write(' rs2 >>= 16;\n')
file.write(' }\n')
elif (self.name in ['fpadd32s','fpsub32s']):
if (self.name == 'fpadd32s'):
file.write(' v64 = rs1 + rs2;\n')
else:
file.write(' v64 = rs1 - rs2;\n')
file.write(' r32 = v64;\n')
elif (self.name == 'fors'):
file.write(' r32 = rs1 | rs2;\n')
elif (self.name == 'fnors'):
file.write(' r32 = ~(rs1 | rs2);\n')
elif (self.name == 'fands'):
file.write(' r32 = rs1 & rs2;\n')
elif (self.name == 'fnands'):
file.write(' r32 = ~(rs1 & rs2);\n')
elif (self.name == 'fxors'):
file.write(' r32 = rs1 ^ rs2;\n')
elif (self.name == 'fxnors'):
file.write(' r32 = ~(rs1 ^ rs2);\n')
elif (self.name == 'fornot1s'):
file.write(' r32 = (~rs1) | rs2;\n')
elif (self.name == 'fornot2s'):
file.write(' r32 = rs1 | (~rs2);\n')
elif (self.name == 'fandnot1s'):
file.write(' r32 = (~rs1) & rs2;\n')
elif (self.name == 'fandnot2s'):
file.write(' r32 = rs1 & (~rs2);\n')
file.write(' s->get_frf(i->rd) = r32;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
self.ill_ibe(file)
self.dec_fff(file,'','idx_exe_'+self.name)
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_fff, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x051] = SS_opf_fff('fpadd16s')
ss_vis1[0x053] = SS_opf_fff('fpadd32s')
ss_vis1[0x055] = SS_opf_fff('fpsub16s')
ss_vis1[0x057] = SS_opf_fff('fpsub32s')
ss_vis1[0x07d] = SS_opf_fff('fors')
ss_vis1[0x063] = SS_opf_fff('fnors')
ss_vis1[0x071] = SS_opf_fff('fands')
ss_vis1[0x06f] = SS_opf_fff('fnands')
ss_vis1[0x06d] = SS_opf_fff('fxors')
ss_vis1[0x073] = SS_opf_fff('fxnors')
ss_vis1[0x07b] = SS_opf_fff('fornot1s')
ss_vis1[0x077] = SS_opf_fff('fornot2s')
ss_vis1[0x069] = SS_opf_fff('fandnot1s')
ss_vis1[0x065] = SS_opf_fff('fandnot2s')
#============================================================================
# SS_opf_ddd
#============================================================================
class SS_opf_ddd(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rs1(file,'%g1')
self.ld_rs2(file,'%g2')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne','%xcc','fpop_disabled_trap')
self.nop(file)
self.ld_drf(file,'%g1','%f0')
self.ld_drf(file,'%g2','%f4')
self.opr(file,self.name,'%f0','%f4','%f8')
self.branch(file,'a,a','%xcc','opf_fprs_d')
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(' uint64_t rs1 = s->get_drf(i->rs1);\n')
file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n')
file.write(' uint64_t r64,v64;\n')
if (self.name in ['fmul8sux16','fmul8ulx16']):
file.write(' int32_t s32_0, s32_1;\n')
file.write(' uint32_t r32;\n')
file.write(' r64 = 0;\n')
if (self.name == 'fmul8sux16'):
file.write(' rs1 >>= 8;\n')
file.write(' for (int n = 0; n < 4; n++) {\n')
file.write(' s32_0 = (int32_t)rs1;\n')
if (self.name == 'fmul8ulx16'):
file.write(' s32_0 &= 0xff;\n')
else:
file.write(' s32_0 = (s32_0 << 24) >> 24;\n')
file.write(' s32_1 = (int32_t)rs2;\n')
file.write(' s32_1 = (s32_1 << 16) >> 16;\n')
file.write(' r32 = s32_0 * s32_1;\n')
if (self.name == 'fmul8sux16'):
file.write(' if ((r32 & 0x80) != 0)\n')
file.write(' r32 += (0x80 << 1);\n')
file.write(' r32 >>= 8;\n')
else:
file.write(' if ((r32 & 0x8000) != 0)\n')
file.write(' r32 += (0x8000 << 1);\n')
file.write(' r32 >>= 16;\n')
file.write(' r64 |= (((uint64_t)(r32 & 0xffff)) << (n << 4));\n')
file.write(' rs1 >>= 16;\n')
file.write(' rs2 >>= 16;\n')
file.write(' }\n')
elif (self.name in ['fpadd16','fpsub16']):
file.write(' r64 = 0;\n')
file.write(' for (int n = 0; n < 4; n++) {\n')
if (self.name == 'fpadd16'):
file.write(' v64 = (rs1 & 0xffff) + (rs2 & 0xffff);\n')
else:
file.write(' v64 = (rs1 & 0xffff) - (rs2 & 0xffff);\n')
file.write(' r64 |= ((v64 & 0xffff) << (n << 4));\n')
file.write(' rs1 >>= 16;\n')
file.write(' rs2 >>= 16;\n')
file.write(' }\n')
elif (self.name in ['fpadd32','fpsub32']):
file.write(' r64 = 0;\n')
file.write(' for (int n = 0; n < 2; n++) {\n')
if (self.name == 'fpadd32'):
file.write(' v64 = (rs1 & 0xffffffff) + (rs2 & 0xffffffff);\n')
else:
file.write(' v64 = (rs1 & 0xffffffff) - (rs2 & 0xffffffff);\n')
file.write(' r64 |= ((v64 & 0xffffffff) << (n << 5));\n')
file.write(' rs1 >>= 32;\n')
file.write(' rs2 >>= 32;\n')
file.write(' }\n')
elif (self.name == 'for'):
file.write(' r64 = rs1 | rs2;\n')
elif (self.name == 'fnor'):
file.write(' r64 = ~(rs1 | rs2);\n')
elif (self.name == 'fand'):
file.write(' r64 = rs1 & rs2;\n')
elif (self.name == 'fnand'):
file.write(' r64 = ~(rs1 & rs2);\n')
elif (self.name == 'fxor'):
file.write(' r64 = rs1 ^ rs2;\n')
elif (self.name == 'fxnor'):
file.write(' r64 = ~(rs1 ^ rs2);\n')
elif (self.name == 'fornot1'):
file.write(' r64 = (~rs1) | rs2;\n')
elif (self.name == 'fornot2'):
file.write(' r64 = rs1 | (~rs2);\n')
elif (self.name == 'fandnot1'):
file.write(' r64 = (~rs1) & rs2;\n')
elif (self.name == 'fandnot2'):
file.write(' r64 = rs1 & (~rs2);\n')
file.write(' s->get_drf(i->rd) = r64;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
self.ill_ibe(file)
self.dec_ddd(file,'','idx_exe_'+self.name)
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_ddd, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x036] = SS_opf_ddd('fmul8sux16')
ss_vis1[0x037] = SS_opf_ddd('fmul8ulx16')
ss_vis1[0x050] = SS_opf_ddd('fpadd16')
ss_vis1[0x052] = SS_opf_ddd('fpadd32')
ss_vis1[0x054] = SS_opf_ddd('fpsub16')
ss_vis1[0x056] = SS_opf_ddd('fpsub32')
ss_vis1[0x07c] = SS_opf_ddd('for')
ss_vis1[0x062] = SS_opf_ddd('fnor')
ss_vis1[0x070] = SS_opf_ddd('fand')
ss_vis1[0x06e] = SS_opf_ddd('fnand')
ss_vis1[0x06c] = SS_opf_ddd('fxor')
ss_vis1[0x072] = SS_opf_ddd('fxnor')
ss_vis1[0x07a] = SS_opf_ddd('fornot1')
ss_vis1[0x076] = SS_opf_ddd('fornot2')
ss_vis1[0x068] = SS_opf_ddd('fandnot1')
ss_vis1[0x064] = SS_opf_ddd('fandnot2')
#============================================================================
# SS_opf_ddd3
#============================================================================
class SS_opf_ddd3(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rs1(file,'%g1')
self.ld_rs2(file,'%g2')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne','%xcc','fpop_disabled_trap')
self.nop(file)
self.ld_drf(file,'%g1','%f0')
self.ld_drf(file,'%g2','%f4')
self.ld_drf(file,'%g3','%f8')
self.opr(file,self.name,'%f0','%f4','%f8')
self.branch(file,'a,a','%xcc','opf_fprs_d')
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(' uint64_t rs1 = s->get_drf(i->rs1);\n')
file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n')
file.write(' uint64_t rd = s->get_drf(i->rd);\n')
file.write(' uint64_t sum = 0;\n')
file.write(' uint64_t v64;\n')
file.write(' for (int n = 0; n < 8; n++) {\n')
file.write(' v64 = (rs1 & 0xff) - (rs2 & 0xff);\n')
file.write(' if (v64 >> 63)\n')
file.write(' v64 = -v64;\n')
file.write(' sum += v64;\n')
file.write(' rs1 >>= 8;\n')
file.write(' rs2 >>= 8;\n')
file.write(' }\n')
file.write(' s->get_drf(i->rd) = rd + sum;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
self.ill_ibe(file)
self.dec_ddd(file,'','idx_exe_'+self.name)
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x03e] = SS_opf_ddd3('pdist')
#============================================================================
# SS_opf_dfd
#============================================================================
class SS_opf_dfd(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rs1(file,'%g1')
self.ld_rs2(file,'%g2')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne','%xcc','fpop_disabled_trap')
self.nop(file)
self.ld_frf(file,'%g1','%f0')
self.ld_drf(file,'%g2','%f4')
self.opr(file,self.name,'%f0','%f4','%f8')
self.branch(file,'a,a','%xcc','opf_fprs_d')
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(' uint32_t rs1 = s->get_frf(i->rs1);\n')
file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n')
file.write(' uint64_t rd = 0;\n')
file.write(' for (int n = 0; n < 4; n++) {\n')
file.write(' uint32_t v32 = rs1 & 0xff;\n')
file.write(' int32_t s32_0 = (int32_t)rs2;\n')
file.write(' s32_0 = (s32_0 << 16) >> 16;\n')
file.write(' uint32_t r32 = s32_0 * v32;\n')
file.write(' if ((r32 & 0x80) != 0)\n')
file.write(' r32 += 0x100;\n')
file.write(' r32 >>= 8;\n')
file.write(' rd |= (((uint64_t)(r32 & 0xffff)) << (n << 4));\n')
file.write(' rs1 >>= 8;\n')
file.write(' rs2 >>= 16;\n')
file.write(' }\n')
file.write(' s->get_drf(i->rd) = rd;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
self.ill_ibe(file)
self.dec_dfd(file,'','idx_exe_'+self.name)
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_dfd, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x031] = SS_opf_dfd('fmul8x16')
#============================================================================
# SS_opf_dff
#============================================================================
class SS_opf_dff(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rs1(file,'%g1')
self.ld_rs2(file,'%g2')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne','%xcc','fpop_disabled_trap')
self.nop(file)
self.ld_frf(file,'%g1','%f0')
self.ld_frf(file,'%g2','%f4')
self.opr(file,self.name,'%f0','%f4','%f8')
self.branch(file,'a,a','%xcc','opf_fprs_d')
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(' uint32_t rs1 = s->get_frf(i->rs1);\n')
file.write(' uint32_t rs2 = s->get_frf(i->rs2);\n')
if (self.name in ['fmul8x16au','fmul8x16al']):
if (self.name == 'fmul8x16au'):
file.write(' int32_t s32_0 = (rs2 >> 16);\n')
else:
file.write(' int32_t s32_0 = rs2;\n')
file.write(' uint64_t rd = 0;\n')
file.write(' for (int n = 0; n < 4; n++) {\n')
file.write(' uint32_t v32 = rs1 & 0xff;\n')
file.write(' s32_0 = (s32_0 << 16) >> 16;\n')
file.write(' uint32_t r32 = s32_0 * v32;\n')
file.write(' if ((r32 & 0x80) != 0)\n')
file.write(' r32 += 0x100;\n')
file.write(' r32 >>= 8;\n')
file.write(' rd |= (((uint64_t)(r32 & 0xffff)) << (n << 4));\n')
file.write(' rs1 >>= 8;\n')
file.write(' rs2 >>= 16;\n')
file.write(' }\n')
elif (self.name in ['fmuld8sux16','fmuld8ulx16']):
file.write(' uint64_t rd = 0;\n')
if (self.name == 'fmuld8sux16'):
file.write(' rs1 >>= 8;\n')
file.write(' for (int n = 0; n < 2; n++) {\n')
file.write(' int32_t s32_0 = rs1;\n')
if (self.name == 'fmuld8ulx16'):
file.write(' s32_0 &= 0xff;\n')
else:
file.write(' s32_0 = (s32_0 << 24) >> 24;\n')
file.write(' int32_t s32_1 = rs2;\n')
file.write(' s32_1 = (s32_1 << 16) >> 16;\n')
file.write(' uint32_t r32 = s32_0 * s32_1;\n')
if (self.name == 'fmuld8sux16'):
file.write(' rd |= (((uint64_t)(r32 & 0xffffff)) << ((n << 5) + 8));\n')
else:
file.write(' rd |= (((uint64_t)r32) << (n << 5));\n')
file.write(' rs1 >>= 16;\n')
file.write(' rs2 >>= 16;\n')
file.write(' }\n')
elif (self.name == 'fpmerge'):
file.write(' uint64_t rd = 0;\n')
file.write(' uint64_t d0 = rs1;\n')
file.write(' uint64_t d1 = rs2;\n')
file.write(' for (int n = 0; n < 4; n++) {\n')
file.write(' rd |= ((d0 & 0xff) << ((n << 4) + 8));\n')
file.write(' rd |= ((d1 & 0xff) << (n << 4));\n')
file.write(' d0 >>= 8;\n')
file.write(' d1 >>= 8;\n')
file.write(' }\n')
file.write(' s->get_drf(i->rd) = rd;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
self.ill_ibe(file)
self.dec_dff(file,'','idx_exe_'+self.name)
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_dff, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x033] = SS_opf_dff('fmul8x16au')
ss_vis1[0x035] = SS_opf_dff('fmul8x16al')
ss_vis1[0x038] = SS_opf_dff('fmuld8sux16')
ss_vis1[0x039] = SS_opf_dff('fmuld8ulx16')
ss_vis1[0x04b] = SS_opf_dff('fpmerge')
#============================================================================
# SS_opf_d0d
#============================================================================
class SS_opf_d0d(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rs2(file,'%g2')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne','%xcc','fpop_disabled_trap')
self.nop(file)
self.ld_drf(file,'%g2','%f4')
self.op2(file,self.name,'%f4','%f8')
self.branch(file,'a,a','%xcc','opf_fprs_d')
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(' uint64_t rs2 = s->get_drf(i->rs2);\n')
if (self.name == 'fsrc2'):
file.write(' s->get_drf(i->rd) = rs2;\n')
elif (self.name == 'fnot2'):
file.write(' s->get_drf(i->rd) = ~rs2;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_18_14())\n')
file.write(' {\n')
self.ill_ibe(file)
self.dec_d0d(file,' ','idx_exe_'+self.name)
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_d0d, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x078] = SS_opf_d0d('fsrc2')
ss_vis1[0x066] = SS_opf_d0d('fnot2')
#============================================================================
# SS_opf_dd0
#============================================================================
class SS_opf_dd0(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rs1(file,'%g1')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne','%xcc','fpop_disabled_trap')
self.nop(file)
self.ld_drf(file,'%g1','%f0')
self.op2(file,self.name,'%f0','%f8')
self.branch(file,'a,a','%xcc','opf_fprs_d')
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(' uint64_t rs1 = s->get_drf(i->rs1);\n')
if (self.name == 'fsrc1'):
file.write(' s->get_drf(i->rd) = rs1;\n')
elif (self.name == 'fnot1'):
file.write(' s->get_drf(i->rd) = ~rs1;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_4_0())\n')
file.write(' {\n')
self.ill_ibe(file)
self.dec_dd0(file,' ','idx_exe_'+self.name)
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_dd0, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x074] = SS_opf_dd0('fsrc1')
ss_vis1[0x06a] = SS_opf_dd0('fnot1')
#============================================================================
# SS_opf_f0f
#============================================================================
class SS_opf_f0f(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rs2(file,'%g2')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne','%xcc','fpop_disabled_trap')
self.nop(file)
self.ld_frf(file,'%g2','%f4')
self.op2(file,self.name,'%f4','%f8')
self.branch(file,'a,a','%xcc','opf_fprs_f')
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(' uint32_t rs2 = s->get_frf(i->rs2);\n')
if (self.name == 'fsrc2s'):
file.write(' s->get_frf(i->rd) = rs2;\n')
elif (self.name == 'fnot2s'):
file.write(' s->get_frf(i->rd) = ~rs2;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_18_14())\n')
file.write(' {\n')
self.ill_ibe(file)
self.dec_f0f(file,' ','idx_exe_'+self.name)
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_f0f, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x079] = SS_opf_f0f('fsrc2s')
ss_vis1[0x067] = SS_opf_f0f('fnot2s')
#============================================================================
# SS_opf_ff0
#============================================================================
class SS_opf_ff0(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rs1(file,'%g1')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne','%xcc','fpop_disabled_trap')
self.nop(file)
self.ld_frf(file,'%g1','%f0')
self.op2(file,self.name,'%f0','%f8')
self.branch(file,'a,a','%xcc','opf_fprs_f')
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(' uint32_t rs1 = s->get_frf(i->rs1);\n')
if (self.name == 'fsrc1s'):
file.write(' s->get_frf(i->rd) = rs1;\n')
elif (self.name == 'fnot1s'):
file.write(' s->get_frf(i->rd) = ~rs1;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_4_0())\n')
file.write(' {\n')
self.ill_ibe(file)
self.dec_ff0(file,' ','idx_exe_'+self.name)
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_ff0, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x075] = SS_opf_ff0('fsrc1s')
ss_vis1[0x06b] = SS_opf_ff0('fnot1s')
#============================================================================
# SS_opf_d0f
#============================================================================
class SS_opf_d0f(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rs2(file,'%g2')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne','%xcc','fpop_disabled_trap')
self.nop(file)
self.ld_frf(file,'%g2','%f4')
self.op2(file,self.name,'%f4','%f8')
self.branch(file,'a,a','%xcc','opf_fprs_d')
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(' uint32_t rs2 = s->get_frf(i->rs2);\n')
file.write(' uint64_t rd = 0;\n')
file.write(' for (int n = 0; n < 4; n++) {\n')
file.write(' uint64_t v64 = (rs2 & 0xff) << 4;\n')
file.write(' rd |= (v64 << (n << 4));\n')
file.write(' rs2 >>= 8;\n')
file.write(' }\n')
file.write(' s->get_drf(i->rd) = rd;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_18_14())\n')
file.write(' {\n')
self.ill_ibe(file)
self.dec_d0f(file,' ','idx_exe_'+self.name)
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_d0f, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x04d] = SS_opf_d0f('fexpand')
#============================================================================
# SS_opf_d00
#============================================================================
class SS_opf_d00(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne','%xcc','fpop_disabled_trap')
self.nop(file)
self.op1(file,self.name,'%f8')
self.branch(file,'a,a','%xcc','opf_fprs_d')
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')
if (self.name == 'fzero'):
file.write(' s->get_drf(i->rd) = 0;\n')
elif (self.name == 'fone'):
file.write(' s->get_drf(i->rd) = ~(uint64_t)0;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_4_0() && o.is_zero_18_14())\n')
file.write(' {\n')
self.ill_ibe(file)
self.dec_d00(file,' ','idx_exe_'+self.name)
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_d00, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x060] = SS_opf_d00('fzero')
ss_vis1[0x07e] = SS_opf_d00('fone')
#============================================================================
# SS_opf_f00
#============================================================================
class SS_opf_f00(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne','%xcc','fpop_disabled_trap')
self.nop(file)
self.op1(file,self.name,'%f8')
self.branch(file,'a,a','%xcc','opf_fprs_f')
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')
if (self.name == 'fzeros'):
file.write(' s->get_frf(i->rd) = 0;\n')
elif (self.name == 'fones'):
file.write(' s->get_frf(i->rd) = ~(uint32_t)0;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_4_0() && o.is_zero_18_14())\n')
file.write(' {\n')
self.ill_ibe(file)
self.dec_f00(file,' ','idx_exe_'+self.name)
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_f00, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x061] = SS_opf_f00('fzeros')
ss_vis1[0x07f] = SS_opf_f00('fones')
#============================================================================
# SS_opf_rdd
#============================================================================
class SS_opf_rdd(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rs1(file,'%g1')
self.ld_rs2(file,'%g2')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne','%xcc','fpop_disabled_trap')
self.nop(file)
self.ld_drf(file,'%g1','%f0')
self.mov(file,self.NPC,self.PC)
self.ld_drf(file,'%g2','%f4')
self.add(file,self.NPC,4,self.NPC)
self.opr(file,self.name,'%f0','%f4','%g4')
self.branch(file,'rnz,a','%g3','1f') # irf[rd] = val when rd != 0
self.st_irf(file,'%g3','%g4')
file.write('1:\n')
self.retl_st_npc(file,self.NPC)
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(' if (SS_Strand::reg_off2idx(i->rd) != 0) {\n')
file.write(' uint64_t rs1 = s->get_drf(i->rs1);\n')
file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n')
file.write(' uint64_t r64;\n')
file.write(' int32_t s32_0, s32_1;\n')
if (self.name in ['fcmple16','fcmpne16','fcmpgt16','fcmpeq16']):
file.write(' uint32_t v32;\n')
file.write(' r64 = 0;\n')
file.write(' for (int n = 0; n < 4; n++) {\n')
file.write(' s32_0 = (int32_t)rs1;\n')
file.write(' s32_0 = (s32_0 << 16) >> 16;\n')
file.write(' s32_1 = (int32_t)rs2;\n')
file.write(' s32_1 = (s32_1 << 16) >> 16;\n')
if (self.name == 'fcmple16'):
file.write(' v32 = (s32_0 <= s32_1) ? 1 : 0;\n')
elif (self.name == 'fcmpne16'):
file.write(' v32 = (s32_0 != s32_1) ? 1 : 0;\n')
elif (self.name == 'fcmpgt16'):
file.write(' v32 = (s32_0 > s32_1) ? 1 : 0;\n')
elif (self.name == 'fcmpeq16'):
file.write(' v32 = (s32_0 == s32_1) ? 1 : 0;\n')
file.write(' r64 |= (((uint64_t)v32) << n);\n')
file.write(' rs1 >>= 16;\n')
file.write(' rs2 >>= 16;\n')
file.write(' }\n')
elif (self.name in ['fcmple32','fcmpne32','fcmpgt32','fcmpeq32']):
file.write(' uint64_t v64;\n')
file.write(' r64 = 0;\n')
file.write(' for (int n = 0; n < 2; n++) {\n')
file.write(' s32_0 = (int32_t)rs1;\n')
file.write(' s32_1 = (int32_t)rs2;\n')
if (self.name == 'fcmple32'):
file.write(' v64 = (s32_0 <= s32_1) ? 1 : 0;\n')
elif (self.name == 'fcmpne32'):
file.write(' v64 = (s32_0 != s32_1) ? 1 : 0;\n')
elif (self.name == 'fcmpgt32'):
file.write(' v64 = (s32_0 > s32_1) ? 1 : 0;\n')
elif (self.name == 'fcmpeq32'):
file.write(' v64 = (s32_0 == s32_1) ? 1 : 0;\n')
file.write(' r64 |= (v64 << n);\n')
file.write(' rs1 >>= 32;\n')
file.write(' rs2 >>= 32;\n')
file.write(' }\n')
file.write(' s->get_irf(i->rd) = r64;\n')
file.write(' }\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
self.ill_ibe(file)
self.dec_rdd(file,'','idx_exe_'+self.name)
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_rdd, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x020] = SS_opf_rdd('fcmple16')
ss_vis1[0x022] = SS_opf_rdd('fcmpne16')
ss_vis1[0x024] = SS_opf_rdd('fcmple32')
ss_vis1[0x026] = SS_opf_rdd('fcmpne32')
ss_vis1[0x028] = SS_opf_rdd('fcmpgt16')
ss_vis1[0x02a] = SS_opf_rdd('fcmpeq16')
ss_vis1[0x02c] = SS_opf_rdd('fcmpgt32')
ss_vis1[0x02e] = SS_opf_rdd('fcmpeq32')
#============================================================================
# SS_opf_rrr_nofdis
#============================================================================
class SS_opf_rrr_nofdis(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_rs1(file,'%g1')
self.ld_rs2(file,'%g2')
self.ld_rd(file,'%g3')
self.ld_irf(file,'%g1','%g1')
self.mov(file,self.NPC,self.PC)
self.ld_irf(file,'%g2','%g2')
self.add(file,self.NPC,4,self.NPC)
self.opr(file,self.name,'%g1','%g2','%g4')
self.branch(file,'rnz,a','%g3','1f') # irf[rd] = val when rd != 0
self.st_irf(file,'%g3','%g4')
file.write('1:\n')
self.retl_st_npc(file,self.NPC)
def run_exe_c(self,file):
file.write('#if defined(ARCH_X64)\n')
self.c_code_beg(file,'run_exe_')
file.write(' if (SS_Strand::reg_off2idx(i->rd) != 0) {\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 r64 = 0;\n')
file.write(' r64 |= (((rs1 >> 11) & 0x3) << 0);\n')
file.write(' r64 |= (((rs1 >> 33) & 0x3) << 2);\n')
file.write(' r64 |= (((rs1 >> 55) & 0x1) << 4);\n')
file.write(' r64 |= (((rs1 >> 13) & 0xf) << 5);\n')
file.write(' r64 |= (((rs1 >> 35) & 0xf) << 9);\n')
file.write(' r64 |= (((rs1 >> 56) & 0xf) << 13);\n')
file.write(' uint32_t n;\n')
file.write(' uint64_t v64;\n')
file.write(' switch (rs2 & 0x7) {\n')
file.write(' case 0: n = 0; v64 = 0; break;\n')
file.write(' case 1: n = 1; v64 = 0x1; break;\n')
file.write(' case 2: n = 2; v64 = 0x3; break;\n')
file.write(' case 3: n = 3; v64 = 0x7; break;\n')
file.write(' case 4: n = 4; v64 = 0xf; break;\n')
file.write(' default: n = 5; v64 = 0x1f; break;\n')
file.write(' }\n')
file.write(' r64 |= (((rs1 >> 17) & v64) << 17);\n')
file.write(' r64 |= (((rs1 >> 39) & v64) << (17 + n));\n')
file.write(' r64 |= (((rs1 >> 60) & 0xf) << (17 + (n << 1)));\n')
if (self.name == 'array16'):
file.write(' r64 <<= 1;\n')
elif (self.name == 'array32'):
file.write(' r64 <<= 2;\n')
file.write(' s->get_irf(i->rd) = r64;\n')
file.write(' }\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
self.ill_ibe(file)
self.dec_rrr(file,'','idx_exe_'+self.name)
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_rrr, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x010] = SS_opf_rrr_nofdis('array8')
ss_vis1[0x012] = SS_opf_rrr_nofdis('array16')
ss_vis1[0x014] = SS_opf_rrr_nofdis('array32')
#============================================================================
# SS_edge
#============================================================================
class SS_edge(SS_InstrCpp):
def __init__(self,name):
SS_InstrCpp.__init__(self,name)
self.out = ['rd', 'g0']
def run_exe_c(self,file):
for out in self.out:
self.c_code_beg_name(file,'run_exe_'+self.name+'_'+out)
if (out == 'rd'):
file.write(' uint64_t rs1 = s->get_irf(i->rs1);\n')
file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
if (self.name[:5] == 'edge8'):
file.write(' uint32_t result32 = 0xff;\n')
file.write(' uint32_t value32 = rs1 & 0x7;\n')
elif (self.name[:6] == 'edge16'):
file.write(' uint32_t result32 = 0xf;\n')
file.write(' uint32_t value32 = (rs1 >> 1) & 0x3;\n')
elif (self.name[:6] == 'edge32'):
file.write(' uint32_t result32 = 0x3;\n')
file.write(' uint32_t value32 = (rs1 >> 2) & 0x1;\n')
if (self.name[-1] == 'l' or self.name[-2] == 'l'):
file.write(' uint32_t s0 = (result32 << value32) & result32;\n')
else:
file.write(' uint32_t s0 = result32 >> value32;\n')
if (self.name[:5] == 'edge8'):
file.write(' value32 = 7 - (rs2 & 0x7);\n')
elif (self.name[:6] == 'edge16'):
file.write(' value32 = 3 - ((rs2 >> 1) & 0x3);\n')
elif (self.name[:6] == 'edge32'):
file.write(' value32 = 1 - ((rs2 >> 2) & 0x1);\n')
if (self.name[-1] == 'l' or self.name[-2] == 'l'):
file.write(' uint32_t s1 = result32 >> value32;\n')
else:
file.write(' uint32_t s1 = (result32 << value32) & result32;\n')
file.write(' if (s->pstate.am()) {\n')
file.write(' if (((rs1 & s->mask_pstate_am) >> 3) == ((rs2 & s->mask_pstate_am) >> 3))\n')
file.write(' s0 &= s1;\n')
file.write(' }\n')
file.write(' else {\n')
file.write(' if ((rs1 >> 3) == (rs2 >> 3))\n')
file.write(' s0 &= s1;\n')
file.write(' }\n')
file.write(' s->get_irf(i->rd) = s0;\n')
if (self.name[-1] != 'n'):
if (out == 'g0'):
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 rd = rs1 - rs2;\n')
file.write(' uint64_t v = (rs1 & ~rs2 & ~rd) | (~rs1 & rs2 & rd);\n')
file.write(' uint64_t c = (~rs1 & rs2) | (rd & (~rs1 | rs2));\n')
file.write(' uint32_t xcc = ((v >> 63) & 0x1) << 1;\n')
file.write(' uint32_t icc = ((v >> 31) & 0x1) << 1;\n')
file.write(' icc |= ((c >> 31) & 0x1);\n')
file.write(' xcc |= ((c >> 63) & 0x1);\n')
file.write(' icc |= ((rd >> 31) & 0x1) << 3;\n')
file.write(' xcc |= ((rd >> 63) & 0x1) << 3;\n')
file.write(' if (rd == 0)\n')
file.write(' xcc |= 0x4;\n')
file.write(' if ((rd & 0xffffffff) == 0)\n')
file.write(' icc |= 0x4;\n')
file.write(' s->ccr.set((xcc << 4) | icc);\n')
file.write(' s->pc = s->npc();\n')
file.write(' s->npc = s->npc() + 4;\n')
file.write(' return s->pc();\n')
self.c_code_end(file)
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rrr(file,' ','idx_exe_'+self.name+'_rd')
file.write(' else\n')
self.dec_0rr(file,' ','idx_exe_'+self.name+'_g0')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'v8_run':
mode = 'run'
for out in self.out:
if mode == 'trc':
file.write(' trc_exe_rrr, /* '+self.name+'_'+out+' */\n')
else:
file.write(' '+mode+'_exe_'+self.name+'_'+out+',\n')
ss_vis1[0x000] = SS_edge('edge8')
ss_vis1[0x002] = SS_edge('edge8l')
ss_vis1[0x004] = SS_edge('edge16')
ss_vis1[0x006] = SS_edge('edge16l')
ss_vis1[0x008] = SS_edge('edge32')
ss_vis1[0x00a] = SS_edge('edge32l')
ss_vis2[0x001] = SS_edge('edge8n')
ss_vis2[0x003] = SS_edge('edge8ln')
ss_vis2[0x005] = SS_edge('edge16n')
ss_vis2[0x007] = SS_edge('edge16ln')
ss_vis2[0x009] = SS_edge('edge32n')
ss_vis2[0x00b] = SS_edge('edge32ln')
#============================================================================
# SS_opf_ddd_gsr
#============================================================================
class SS_opf_ddd_gsr(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rs1(file,'%g1')
self.ld_rs2(file,'%g2')
self.ld_gsr(file,'%g4')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne,a','%xcc','fpop_disabled_trap')
self.rd_gsr(file,'%g5')
self.wr_gsr(file,'%g4')
self.ld_drf(file,'%g1','%f0')
self.ld_drf(file,'%g2','%f4')
self.opr(file,self.name,'%f0','%f4','%f8')
self.branch(file,'a,a','%xcc','opf_fprs_gsr_d')
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(' uint64_t rs1 = s->get_drf(i->rs1);\n')
file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n')
file.write(' uint64_t rd = 0;\n')
file.write(' uint64_t v64;\n')
file.write(' uint32_t v32;\n')
if (self.name == 'fpack32'):
file.write(' v32 = s->gsr.scale();\n')
file.write(' for (int n = 0; n < 2; n++) {\n')
file.write(' if ((rs2 & 0x80000000) != 0)\n')
file.write(' v64 = 0;\n')
file.write(' else {\n')
file.write(' v64 = ((rs2 & 0xffffffff) << v32) >> 23;\n')
file.write(' if ((v64 & 0xffffffffffffff00llu) != 0)\n')
file.write(' v64 = 255;\n')
file.write(' }\n')
file.write(' rd |= ((v64 & 0xff) << (n << 5));\n')
file.write(' rd |= ((rs1 & 0xffffff) << ((n << 5) + 8));\n')
file.write(' rs1 >>= 32;\n')
file.write(' rs2 >>= 32;\n')
file.write(' }\n')
elif (self.name == 'bshuffle'):
file.write(' v64 = s->gsr.mask();\n')
file.write(' for (int n = 0; n < 8; n++) {\n')
file.write(' uint_t index = (v64 >> (n << 2)) & 0xf;\n')
file.write(' switch (index) {\n')
file.write(' case 0: v32 = rs1 >> 56; break;\n')
file.write(' case 1: v32 = rs1 >> 48; break;\n')
file.write(' case 2: v32 = rs1 >> 40; break;\n')
file.write(' case 3: v32 = rs1 >> 32; break;\n')
file.write(' case 4: v32 = rs1 >> 24; break;\n')
file.write(' case 5: v32 = rs1 >> 16; break;\n')
file.write(' case 6: v32 = rs1 >> 8; break;\n')
file.write(' case 7: v32 = rs1 ; break;\n')
file.write(' case 8: v32 = rs2 >> 56; break;\n')
file.write(' case 9: v32 = rs2 >> 48; break;\n')
file.write(' case 10: v32 = rs2 >> 40; break;\n')
file.write(' case 11: v32 = rs2 >> 32; break;\n')
file.write(' case 12: v32 = rs2 >> 24; break;\n')
file.write(' case 13: v32 = rs2 >> 16; break;\n')
file.write(' case 14: v32 = rs2 >> 8; break;\n')
file.write(' case 15: v32 = rs2 ; break;\n')
file.write(' }\n')
file.write(' rd |= (((uint64_t)(v32 & 0xff)) << (n << 3));\n')
file.write(' }\n')
elif (self.name == 'faligndata'):
file.write(' v64 = s->gsr.align();\n')
file.write(' if (v64 != 0)\n')
file.write(' rd = (rs1 << (v64 << 3)) | (rs2 >> ((8 - v64) << 3));\n')
file.write(' else\n')
file.write(' rd = rs1;\n')
file.write(' s->get_drf(i->rd) = rd;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
self.ill_ibe(file)
self.dec_ddd(file,'','idx_exe_'+self.name)
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_ddd, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x03a] = SS_opf_ddd_gsr('fpack32')
ss_vis2[0x04c] = SS_opf_ddd_gsr('bshuffle')
ss_vis1[0x048] = SS_opf_ddd_gsr('faligndata')
#============================================================================
# SS_opf_f0d_gsr
#============================================================================
class SS_opf_f0d_gsr(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rs2(file,'%g2')
self.ld_gsr(file,'%g4')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne,a','%xcc','fpop_disabled_trap')
self.nop(file)
self.rd_gsr(file,'%g5')
self.wr_gsr(file,'%g4')
self.ld_drf(file,'%g2','%f4')
self.op2(file,self.name,'%f4','%f8')
self.branch(file,'a,a','%xcc','opf_fprs_gsr_f')
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(' uint64_t rs2 = s->get_drf(i->rs2);\n')
file.write(' uint32_t rd = 0;\n')
if (self.name == 'fpack16'):
file.write(' uint64_t v64 = s->gsr.scale() & 0xf;\n')
file.write(' uint64_t r64;\n')
file.write(' for (int n = 0; n < 4; n++) {\n')
file.write(' if ((rs2 & 0x8000) != 0)\n')
file.write(' r64 = 0;\n')
file.write(' else {\n')
file.write(' r64 = ((rs2 & 0xffff) << v64) >> 7;\n')
file.write(' if ((r64 & 0xffffffffffffff00llu) != 0)\n')
file.write(' r64 = 255;\n')
file.write(' }\n')
file.write(' rd |= ((r64 & 0xff) << (n << 3));\n')
file.write(' rs2 >>= 16;\n')
file.write(' }\n')
elif (self.name == 'fpackfix'):
file.write(' uint64_t v64 = s->gsr.scale() & 0x1f;\n')
file.write(' int64_t s64;\n')
file.write(' for (int n = 0; n < 2; n++) {\n')
file.write(' if ((rs2 & 0x80000000) == 0)\n')
file.write(' s64 = rs2 & 0xffffffff;\n')
file.write(' else\n')
file.write(' s64 = rs2 | 0xffffffff00000000llu;\n')
file.write(' s64 = (s64 << v64) >> 16;\n')
file.write(' if (s64 < -32768)\n')
file.write(' s64 = -32768;\n')
file.write(' else if (s64 > 32767)\n')
file.write(' s64 = 32767;\n')
file.write(' rd |= ((s64 & 0xffff) << (n << 4));\n')
file.write(' rs2 >>= 32;\n')
file.write(' }\n')
file.write(' s->get_frf(i->rd) = rd;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_18_14())\n')
file.write(' {\n')
self.ill_ibe(file)
self.dec_f0d(file,' ','idx_exe_'+self.name)
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_f0d, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis1[0x03b] = SS_opf_f0d_gsr('fpack16')
ss_vis1[0x03d] = SS_opf_f0d_gsr('fpackfix')
#============================================================================
# SS_opf_rrr_gsr
#============================================================================
class SS_opf_rrr_gsr(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_s(self,file):
self.s_code(file,'run_exe_')
self.ld_sim(file,'%g5')
self.ld_rs1(file,'%g1')
self.ld_rs2(file,'%g2')
self.ld_gsr(file,'%g4')
self.ld_rd(file,'%g3')
self.andcc(file,'%g5','F_FP_DISABLED','%g0')
self.branch(file,'ne,a','%xcc','fpop_disabled_trap')
self.nop(file)
self.rd_gsr(file,'%g5')
self.wr_gsr(file,'%g4')
self.ld_irf(file,'%g1','%g1')
self.mov(file,self.NPC,self.PC)
self.ld_irf(file,'%g2','%g2')
self.add(file,self.NPC,4,self.NPC)
self.opr(file,self.name,'%g1','%g2','%g4')
self.rd_gsr(file,'%g1')
self.branch(file,'rnz,a','%g3','1f')
self.st_irf(file,'%g3','%g4')
file.write('1:\n')
self.st_gsr(file,'%g1')
self.st_npc(file,self.NPC)
self.retl(file)
self.wr_gsr(file,'%g5')
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(' uint64_t rs1 = s->get_irf(i->rs1);\n')
file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
file.write(' uint64_t r64 = rs1 + rs2;\n')
if (self.name in ['alignaddr','alignaddrl']):
file.write(' if (SS_Strand::reg_off2idx(i->rd) != 0)\n')
file.write(' s->get_irf(i->rd) = r64 & 0xfffffffffffffff8llu;\n')
file.write(' r64 &= 0x7;\n')
if (self.name == 'alignaddrl'):
file.write(' r64 = (-r64) & 0x7;\n')
file.write(' s->gsr.align(r64);\n')
elif (self.name == 'bmask'):
file.write(' if (SS_Strand::reg_off2idx(i->rd) != 0)\n')
file.write(' s->get_irf(i->rd) = r64;\n')
file.write(' s->gsr.mask(r64 & 0xffffffff);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
file.write('#else\n')
file.write('extern "C" SS_Vaddr run_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (self.name))
file.write('#endif\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
self.ill_ibe(file)
self.dec_rrr(file,'','idx_exe_'+self.name)
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_rrr, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_v8plus_to_v9, /* run_exe_'+self.name+' */\n')
else:
file.write(' '+mode+'_exe_'+self.name+',\n')
ss_vis1[0x018] = SS_opf_rrr_gsr('alignaddr')
ss_vis2[0x019] = SS_opf_rrr_gsr('bmask')
ss_vis1[0x01a] = SS_opf_rrr_gsr('alignaddrl')
#============================================================================
# SS_opf_003_gsr
#============================================================================
class SS_opf_003_gsr(SS_InstrAsm):
def __init__(self,name):
SS_InstrAsm.__init__(self,name)
def run_exe_c(self,file):
self.c_code_beg_name(file,'run_exe_'+self.name)
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(' uint64_t mode = i->rs2;\n')
file.write(' s->gsr.im(mode >> 2);\n')
file.write(' s->gsr.irnd(mode);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
file.write('}\n')
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_29_25() && o.is_zero_18_14() && o.is_zero_4_3())\n')
file.write(' {\n')
self.ill_ibe(file)
self.dec_003(file,' ','idx_exe_'+self.name)
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'v8_run':
mode = 'run'
self.gen_exe_passthrough(file,mode)
ss_vis2[0x081] = SS_opf_003_gsr('siam')
#============================================================================
# SS_vis3_rrr
#============================================================================
class SS_vis3_rrr(SS_InstrCpp):
def __init__(self,name):
SS_InstrCpp.__init__(self,name)
self.out = ['rd', 'g0']
def run_exe_c(self,file):
for out in self.out:
self.c_code_beg_name(file,'run_exe_'+self.name+'_'+out)
if self.name == 'addxccc':
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 rd = 0;\n')
file.write(' uint64_t cc = s->ccr.xcc() & 0x1;\n')
file.write(' rd = rs1 + rs2 + cc;\n')
file.write(' uint8_t ccr = 0;\n')
file.write(' /* xcc.n */\n')
file.write(' if (rd >> 63)\n')
file.write(' ccr = 0x80;\n')
file.write(' /* icc.n */\n')
file.write(' if ((rd << 32) >> 63)\n')
file.write(' ccr |= 0x08;\n')
file.write(' /* xcc.z */\n')
file.write(' if (rd == 0)\n')
file.write(' ccr |= 0x44;\n')
file.write(' /* icc.z */\n')
file.write(' if (((rd << 32) >> 32) == 0)\n')
file.write(' ccr |= 0x4;\n')
file.write(' uint64_t m = 0x80000000;\n')
file.write(' uint64_t x = rs1 & m;\n')
file.write(' /* icc.v */\n')
file.write(' if ((x == (rs2 & m)) && (x != (rd & m)))\n')
file.write(' ccr |= 0x02;\n')
file.write(' m = 0x8000000000000000;\n')
file.write(' x = rs1 & m;\n')
file.write(' /* xcc.v */\n')
file.write(' if ((x == (rs2 & m)) && (x != (rd & m)))\n')
file.write(' ccr |= 0x20;\n')
file.write(' x = (rs1 & 0xffffffff) + (rs2 & 0xffffffff) + cc;\n')
file.write(' uint64_t icc_c = x >> 32;\n')
file.write(' /* icc.c */\n')
file.write(' if (icc_c == 1)\n')
file.write(' ccr |= 0x1;\n')
file.write(' x = (rs1 >> 32) + (rs2 >> 32) + icc_c;\n')
file.write(' /* xcc.c */\n')
file.write(' if ((x >> 32) == 1)\n')
file.write(' ccr |= 0x10;\n')
file.write(' s->ccr.set(ccr);\n')
elif out == 'rd':
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 rd = 0;\n')
if self.name in ['xmulx', 'xmulxhi']:
file.write(' for (int n=0; n<64; n++) {\n')
file.write(' if (rs1 & 1)\n')
file.write(' rd ^= rs2;\n')
file.write(' rs1 = (rs1 >> 1) | (rd << 63);\n')
file.write(' rd >>= 1;\n')
file.write(' }\n')
if self.name == 'xmulx':
file.write(' rd = rs1;\n')
elif self.name == 'addxc':
file.write(' uint64_t cc = s->ccr.xcc() & 0x1;\n')
file.write(' rd = rs1 + rs2 + cc;\n')
elif self.name == 'umulxhi':
file.write(' /* based on ab * cd = (ac<<64) + ((ad+cb)<<32) + bd ... */\n')
file.write(' uint64_t a = rs1 >> 32;\n')
file.write(' uint64_t b = rs1 & ((~0ull) >> 32);\n')
file.write(' uint64_t c = rs2 >> 32;\n')
file.write(' uint64_t d = rs2 & ((~0ull) >> 32);\n')
file.write(' uint64_t bd = b * d;\n')
file.write(' uint64_t ad = a * d;\n')
file.write(' uint64_t cb = c * b;\n')
file.write(' uint64_t ac = a * c;\n')
file.write(' uint64_t tmp = (ad & ((~0ull) >> 32)) + (bd >> 32);\n')
file.write(' uint64_t carry = ((tmp >> 32) != 0) ? 1 : 0;\n')
file.write(' tmp = (ad >> 32) + carry;\n')
file.write(' carry = ((tmp >> 32) != 0) ? 1 : 0;\n')
file.write(' if (carry)\n')
file.write(' ac += ( ( (uint64_t) 1 ) << 32 );\n')
file.write(' ad += (bd >> 32);\n')
file.write(' tmp = (cb & ((~0ull) >> 32)) + (ad & ((~0ull) >> 32));\n')
file.write(' carry = ((tmp >> 32) != 0) ? 1 : 0;\n')
file.write(' tmp = (cb >> 32) + (ad >> 32) + carry;\n')
file.write(' carry = ((tmp >> 32) != 0) ? 1 : 0;\n')
file.write(' if (carry)\n')
file.write(' ac += ( ( (uint64_t) 1 ) << 32 );\n')
file.write(' rd = ac + ( ( cb + ad ) >> 32 );\n')
if out == 'rd':
file.write(' s->get_irf(i->rd) = rd;\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rrr(file,' ','idx_exe_'+self.name+'_rd')
file.write(' else\n')
self.dec_0rr(file,' ','idx_exe_'+self.name+'_g0')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
for out in self.out:
if mode == 'trc':
file.write(' trc_exe_rrr, /* '+self.name+'_'+out+' */\n')
else:
if mode == 'v8_run':
mode = 'run'
file.write(' '+mode+'_exe_'+self.name+'_'+out+',\n')
ss_vis3[0x011] = SS_vis3_rrr('addxc')
ss_vis3[0x013] = SS_vis3_rrr('addxccc')
ss_vis3[0x016] = SS_vis3_rrr('umulxhi')
ss_vis3[0x115] = SS_vis3_rrr('xmulx')
ss_vis3[0x116] = SS_vis3_rrr('xmulxhi')
#============================================================================
# SS_cmask
#============================================================================
class SS_cmask(SS_InstrCpp):
def __init__(self,name):
SS_InstrCpp.__init__(self,name)
def run_exe_c(self,file):
self.c_code_beg_name(file,'run_exe_'+self.name)
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(' uint64_t mask;\n')
file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
if self.name == 'cmask8':
file.write(' mask = (rs2 & 0x1) ? 0x7 : 0xf;\n')
file.write(' mask |= (rs2 & 0x2) ? 0x60 : 0xe0;\n')
file.write(' mask |= (rs2 & 0x4) ? 0x500 : 0xd00;\n')
file.write(' mask |= (rs2 & 0x8) ? 0x4000 : 0xc000;\n')
file.write(' mask |= (rs2 & 0x10) ? 0x30000 : 0xb0000;\n')
file.write(' mask |= (rs2 & 0x20) ? 0x200000 : 0xa00000;\n')
file.write(' mask |= (rs2 & 0x40) ? 0x1000000 : 0x9000000;\n')
file.write(' mask |= (rs2 & 0x80) ? 0x00000000 : 0x80000000;\n')
elif self.name == 'cmask16':
file.write(' mask = (rs2 & 0x1) ? 0x67 : 0xef;\n')
file.write(' mask |= (rs2 & 0x2) ? 0x4500 : 0xcd00;\n')
file.write(' mask |= (rs2 & 0x4) ? 0x230000 : 0xab0000;\n')
file.write(' mask |= (rs2 & 0x8) ? 0x01000000 : 0x89000000;\n')
else:
file.write(' mask = (rs2 & 0x1) ? 0x4567 : 0xcdef;\n')
file.write(' mask |= (rs2 & 0x2) ? 0x01230000 : 0x89ab0000;\n')
file.write(' s->gsr.mask(mask);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_29_25() && o.is_zero_18_14())\n')
file.write(' {\n')
self.ill_ibe(file)
self.dec_00r(file,' ','idx_exe_'+self.name)
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_00r, /* '+self.name+' */\n')
else:
if mode == 'v8_run':
mode = 'run'
file.write(' '+mode+'_exe_'+self.name+',\n')
ss_vis3[0x01b] = SS_cmask('cmask8')
ss_vis3[0x01d] = SS_cmask('cmask16')
ss_vis3[0x01f] = SS_cmask('cmask32')
#============================================================================
# SS_vis3_ddd
#============================================================================
class SS_vis3_ddd(SS_InstrCpp):
def __init__(self,name):
SS_InstrCpp.__init__(self,name)
def run_exe_c(self,file):
self.c_code_beg_name(file,'run_exe_'+self.name)
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(' uint64_t rs1 = s->get_drf(i->rs1);\n')
file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n')
file.write(' uint64_t rd = 0;\n')
if self.name == 'fchksm16':
file.write(' uint64_t x;\n')
file.write(' for (int n=0; n<4; n++) {\n')
file.write(' x = (rs1 & 0xffff) + (rs2 & 0xffff);\n')
file.write(' x = x + (x >> 16);\n')
file.write(' rd |= ( (x & 0xffff) << (n << 4) );\n')
file.write(' rs1 >>= 16;\n')
file.write(' rs2 >>= 16;\n')
file.write(' }\n')
elif self.name == 'fmean16':
file.write(' int x1,x2;\n')
file.write(' for (int n=0; n<4; n++) {\n')
file.write(' x1 = ( (int) (rs1 << 16) ) >> 16;\n')
file.write(' x2 = ( (int) (rs2 << 16) ) >> 16;\n')
file.write(' x1 = x1 + x2 + 1;\n')
file.write(' rd |= ( ( (uint64_t) ( (x1 >> 1) & 0xffff ) ) << (n << 4) );\n')
file.write(' rs1 >>= 16;\n')
file.write(' rs2 >>= 16;\n')
file.write(' }\n')
elif self.name == 'fpadd64':
file.write(' rd = rs1 + rs2;\n')
elif self.name == 'fpsub64':
file.write(' rd = rs1 - rs2;\n')
elif self.name in ['fpadds16', 'fpsubs16', 'fpadds32', 'fpsubs32']:
file.write(' uint64_t x,x1,x2;\n')
if self.name in ['fpadds16', 'fpsubs16']:
file.write(' uint64_t sm = 0x8000;\n')
file.write(' uint64_t m = 0xffff;\n')
file.write(' for (int n=0; n<4; n++) {\n')
else:
file.write(' uint64_t sm = 0x80000000;\n')
file.write(' uint64_t m = 0xffffffff;\n')
file.write(' for (int n=0; n<2; n++) {\n')
file.write(' x1 = rs1 & m;\n')
file.write(' x2 = rs2 & m;\n')
if self.name in ['fpadds16', 'fpadds32']:
file.write(' x = (x1 + x2) & m;\n')
file.write(' if (((x1 & sm) == (x2 & sm)) && ((x & sm) != (x1 & sm)))\n')
else:
file.write(' x = (x1 - x2) & m;\n')
file.write(' if (((x1 & sm) != (x2 & sm)) && ((x & sm) != (x1 & sm)))\n')
file.write(' x = ( (x1 & sm) == 0 ) ? (sm - 1) : sm;\n')
if self.name in ['fpadds16', 'fpsubs16']:
file.write(' rd |= x << (n << 4);\n')
file.write(' rs1 >>= 16;\n')
file.write(' rs2 >>= 16;\n')
else:
file.write(' rd |= x << (n << 5);\n')
file.write(' rs1 >>= 32;\n')
file.write(' rs2 >>= 32;\n')
file.write(' }\n')
elif self.name in ['fsll16', 'fsrl16', 'fslas16', 'fsra16']:
file.write(' uint64_t sv;\n')
file.write(' int x0,x1;\n')
file.write(' for (int n=0; n<4; n++) {\n')
file.write(' sv = rs2 & 0xf;\n')
if self.name == 'fsll16':
file.write(' x0 = (rs1 & 0xffff) << sv;\n')
elif self.name == 'fsrl16':
file.write(' x0 = (rs1 & 0xffff) >> sv;\n')
elif self.name == 'fslas16':
file.write(' x1 = (int) rs1;\n')
file.write(' x1 = (x1 << 16) >> 16;\n')
file.write(' x0 = x1 << sv;\n')
file.write(' x1 = x0 >> 15;\n')
file.write(' if ((x1 != 0) && (x1 != 0xffffffff)) {\n');
file.write(' if ((x1 & 0x80000000) == 0)\n')
file.write(' x0 = 0x7fff;\n')
file.write(' else\n')
file.write(' x0 = 0x8000;\n')
file.write(' }\n')
elif self.name == 'fsra16':
file.write(' x1 = (int) rs1;\n')
file.write(' x1 = (x1 << 16) >> 16;\n')
file.write(' x0 = x1 >> sv;\n')
file.write(' rd |= (((uint64_t) (x0 & 0xffff)) << (n << 4));\n')
file.write(' rs1 >>= 16;\n')
file.write(' rs2 >>= 16;\n')
file.write(' }\n')
elif self.name in ['fsll32', 'fsrl32', 'fslas32', 'fsra32']:
file.write(' uint64_t sv;\n')
file.write(' int64_t y0,y1;\n')
file.write(' int x0,x1;\n')
file.write(' for (int n=0; n<2; n++) {\n')
file.write(' sv = rs2 & 0x1f;\n')
if self.name == 'fsll32':
file.write(' x0 = (rs1 & 0xffffffff) << sv;\n')
elif self.name == 'fsrl32':
file.write(' x0 = (rs1 & 0xffffffff) >> sv;\n')
elif self.name == 'fslas32':
file.write(' y1 = rs1;\n')
file.write(' y1 = (y1 << 32) >> 32;\n')
file.write(' y0 = y1 << sv;\n')
file.write(' y1 = y0 >> 31;\n')
file.write(' if ((y1 != 0) && (y1 != 0xffffffffffffffff)) {\n');
file.write(' if ((y1 & 0x8000000000000000) == 0)\n')
file.write(' x0 = 0x7fffffff;\n')
file.write(' else\n')
file.write(' x0 = 0x80000000;\n')
file.write(' }\n')
file.write(' else\n')
file.write(' x0 = y0;\n')
elif self.name == 'fsra32':
file.write(' x1 = (int) rs1;\n')
file.write(' x0 = x1 >> sv;\n')
file.write(' rd |= ((((uint64_t) x0) & 0xffffffff) << (n << 5));\n')
file.write(' rs1 >>= 32;\n')
file.write(' rs2 >>= 32;\n')
file.write(' }\n')
file.write(' s->get_drf(i->rd) = rd;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
self.ill_ibe(file)
self.dec_ddd(file,' ','idx_exe_'+self.name)
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_ddd, /* '+self.name+' */\n')
else:
if mode == 'v8_run':
mode = 'run'
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis3[0x021] = SS_vis3_ddd('fsll16')
ss_vis3[0x023] = SS_vis3_ddd('fsrl16')
ss_vis3[0x025] = SS_vis3_ddd('fsll32')
ss_vis3[0x027] = SS_vis3_ddd('fsrl32')
ss_vis3[0x029] = SS_vis3_ddd('fslas16')
ss_vis3[0x02b] = SS_vis3_ddd('fsra16')
ss_vis3[0x02d] = SS_vis3_ddd('fslas32')
ss_vis3[0x02f] = SS_vis3_ddd('fsra32')
ss_vis3[0x040] = SS_vis3_ddd('fmean16')
ss_vis3[0x042] = SS_vis3_ddd('fpadd64')
ss_vis3[0x044] = SS_vis3_ddd('fchksm16')
ss_vis3[0x046] = SS_vis3_ddd('fpsub64')
ss_vis3[0x058] = SS_vis3_ddd('fpadds16')
ss_vis3[0x05a] = SS_vis3_ddd('fpadds32')
ss_vis3[0x05c] = SS_vis3_ddd('fpsubs16')
ss_vis3[0x05e] = SS_vis3_ddd('fpsubs32')
#============================================================================
# SS_vis3_fff
#============================================================================
class SS_vis3_fff(SS_InstrCpp):
def __init__(self,name):
SS_InstrCpp.__init__(self,name)
def run_exe_c(self,file):
self.c_code_beg_name(file,'run_exe_'+self.name)
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(' uint32_t rs1 = s->get_frf(i->rs1);\n')
file.write(' uint32_t rs2 = s->get_frf(i->rs2);\n')
file.write(' uint32_t rd = 0;\n')
if self.name in ['fpadds16s', 'fpsubs16s', 'fpadds32s', 'fpsubs32s']:
file.write(' uint64_t x;\n')
if self.name in ['fpadds16s', 'fpsubs16s']:
file.write(' uint64_t x1,x2;\n')
file.write(' uint64_t sm = 0x8000;\n')
file.write(' uint64_t m = 0xffff;\n')
file.write(' for (int n=0; n<2; n++) {\n')
file.write(' x1 = rs1 & m;\n')
file.write(' x2 = rs2 & m;\n')
if self.name == 'fpadds16s':
file.write(' x = (x1 + x2) & m;\n')
file.write(' if (((x1 & sm) == (x2 & sm)) && ((x & sm) != (x1 & sm)))\n')
else:
file.write(' x = (x1 - x2) & m;\n')
file.write(' if (((x1 & sm) != (x2 & sm)) && ((x & sm) != (x1 & sm)))\n')
file.write(' x = ( (x1 & sm) == 0 ) ? (sm - 1) : sm;\n')
file.write(' rd |= x << (n << 4);\n')
file.write(' rs1 >>= 16;\n')
file.write(' rs2 >>= 16;\n')
file.write(' }\n')
else:
file.write(' uint64_t sm = 0x80000000;\n')
if self.name == 'fpadds32s':
file.write(' x = rs1 + rs2;\n')
file.write(' if (((rs1 & sm) == (rs2 & sm)) && ((x & sm) != (rs1 & sm)))\n')
else:
file.write(' x = rs1 - rs2;\n')
file.write(' if (((rs1 & sm) != (rs2 & sm)) && ((x & sm) != (rs1 & sm)))\n')
file.write(' x = ( (rs1 & sm) == 0 ) ? (sm - 1) : sm;\n')
file.write(' rd = x;\n')
file.write(' s->get_frf(i->rd) = rd;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
self.ill_ibe(file)
self.dec_fff(file,' ','idx_exe_'+self.name)
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_fff, /* '+self.name+' */\n')
else:
if mode == 'v8_run':
mode = 'run'
file.write(' %s_exe_%s,\n' % (mode,self.name))
ss_vis3[0x059] = SS_vis3_fff('fpadds16s')
ss_vis3[0x05b] = SS_vis3_fff('fpadds32s')
ss_vis3[0x05d] = SS_vis3_fff('fpsubs16s')
ss_vis3[0x05f] = SS_vis3_fff('fpsubs32s')
#============================================================================
# SS_vis3_rdd
#============================================================================
class SS_vis3_rdd(SS_InstrCpp):
def __init__(self,name):
SS_InstrCpp.__init__(self,name)
self.out = ['rd', 'g0']
def run_exe_c(self,file):
for out in self.out:
self.c_code_beg_name(file,'run_exe_'+self.name+'_'+out)
file.write(' if (s->sim_state.fp_disabled())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n')
if out == 'rd':
file.write(' uint64_t rs1 = s->get_drf(i->rs1);\n')
file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n')
file.write(' uint64_t rd = 0;\n');
if self.name == 'pdistn':
file.write(' for (int n=0; n<8; n++) {\n')
file.write(' uint64_t v = (rs1 & 0xff) - (rs2 & 0xff);\n')
file.write(' if ((v & 0x8000000000000000) != 0)\n')
file.write(' v = -v;\n')
file.write(' rd += v;\n')
file.write(' rs1 >>= 8;\n')
file.write(' rs2 >>= 8;\n')
file.write(' }\n');
elif self.name in ['fucmple8', 'fucmpne8', 'fucmpgt8', 'fucmpeq8']:
file.write(' for (int n=0; n<8; n++) {\n')
file.write(' uint16_t s1 = (uint16_t) rs1 & 0xff;\n')
file.write(' uint16_t s2 = (uint16_t) rs2 & 0xff;\n')
if self.name == 'fucmple8':
file.write(' uint64_t v = (s1 <= s2) ? 1 : 0;\n')
elif self.name == 'fucmpne8':
file.write(' uint64_t v = (s1 != s2) ? 1 : 0;\n')
elif self.name == 'fucmpgt8':
file.write(' uint64_t v = (s1 > s2) ? 1 : 0;\n')
elif self.name == 'fucmpeq8':
file.write(' uint64_t v = (s1 == s2) ? 1 : 0;\n')
file.write(' rd |= (v << n);\n')
file.write(' rs1 >>= 8;\n')
file.write(' rs2 >>= 8;\n')
file.write(' }\n');
file.write(' s->get_irf(i->rd) = rd;\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_rdd(file,' ','idx_exe_'+self.name+'_rd')
file.write(' else\n')
self.dec_0dd(file,' ','idx_exe_'+self.name+'_g0')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
for out in self.out:
if mode == 'trc':
file.write(' trc_exe_rdd, /* '+self.name+'_'+out+' */\n')
else:
if mode == 'v8_run':
mode = 'run'
file.write(' '+mode+'_exe_'+self.name+'_'+out+',\n')
ss_vis3[0x03f] = SS_vis3_rdd('pdistn')
ss_vis3[0x120] = SS_vis3_rdd('fucmple8')
ss_vis3[0x122] = SS_vis3_rdd('fucmpne8')
ss_vis3[0x128] = SS_vis3_rdd('fucmpgt8')
ss_vis3[0x12a] = SS_vis3_rdd('fucmpeq8')
#============================================================================
# SS_vis3_movitof
#============================================================================
class SS_vis3_movitof(SS_InstrCpp):
def __init__(self,name):
SS_InstrCpp.__init__(self,name)
def run_exe_c(self,file):
self.c_code_beg_name(file,'run_exe_'+self.name)
file.write(' if (s->sim_state.fp_disabled())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n')
if self.name == 'movxtod':
file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
file.write(' s->get_drf(i->rd) = rs2;\n')
elif self.name == 'movwtos':
file.write(' uint32_t rs2 = s->get_irf(i->rs2);\n')
file.write(' s->get_frf(i->rd) = rs2;\n')
file.write(' s->set_fprs(i->rd);\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_18_14())\n')
file.write(' {\n')
self.ill_ibe(file)
if self.name == 'movxtod':
self.dec_d0r(file,' ','idx_exe_'+self.name)
else:
self.dec_f0r(file,' ','idx_exe_'+self.name)
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
if self.name == 'movxtod':
file.write(' trc_exe_d0r, /* '+self.name+' */\n')
else:
file.write(' trc_exe_f0r, /* '+self.name+' */\n')
else:
if mode == 'v8_run':
mode = 'run'
file.write(' '+mode+'_exe_'+self.name+',\n')
ss_vis3[0x118] = SS_vis3_movitof('movxtod')
ss_vis3[0x119] = SS_vis3_movitof('movwtos')
#============================================================================
# SS_vis3_movftoi
#============================================================================
class SS_vis3_movftoi(SS_InstrCpp):
def __init__(self,name):
SS_InstrCpp.__init__(self,name)
self.out = ['rd', 'g0']
def run_exe_c(self,file):
for out in self.out:
self.c_code_beg_name(file,'run_exe_'+self.name+'_'+out)
file.write(' if (s->sim_state.fp_disabled())\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::FP_DISABLED);\n')
if out == 'rd':
if self.name == 'movdtox':
file.write(' uint64_t rs2 = s->get_drf(i->rs2);\n')
file.write(' s->get_irf(i->rd) = rs2;\n')
elif self.name == 'movstouw':
file.write(' uint32_t rs2 = s->get_frf(i->rs2);\n')
file.write(' s->get_irf(i->rd) = rs2;\n')
elif self.name == 'movstosw':
file.write(' uint32_t rs2 = s->get_frf(i->rs2);\n')
file.write(' s->get_irf(i->rd) = (int) rs2;\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_18_14())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
if self.name == 'movdtox':
self.dec_r0d(file,' ','idx_exe_'+self.name+'_rd')
elif self.name in ['movstouw', 'movstosw']:
self.dec_r0f(file,' ','idx_exe_'+self.name+'_rd')
file.write(' else\n')
self.dec_00r(file,' ','idx_exe_'+self.name+'_g0')
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
for out in self.out:
if mode == 'trc':
if self.name == 'movdtox':
file.write(' trc_exe_r0d, /* '+self.name+'_'+out+' */\n')
else:
file.write(' trc_exe_r0f, /* '+self.name+'_'+out+' */\n')
else:
if mode == 'v8_run':
mode = 'run'
file.write(' '+mode+'_exe_'+self.name+'_'+out+',\n')
ss_vis3[0x110] = SS_vis3_movftoi('movdtox')
ss_vis3[0x111] = SS_vis3_movftoi('movstouw')
ss_vis3[0x113] = SS_vis3_movftoi('movstosw')
#============================================================================
# SS_vis3_flcmp
#============================================================================
class SS_vis3_flcmp(SS_InstrCpp):
def __init__(self,name):
SS_InstrCpp.__init__(self,name)
def run_exe_c(self,file):
self.c_code_beg_name(file,'run_exe_'+self.name)
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(' '+setup.product+'_Strand* ss = ('+setup.product+'_Strand*)s;\n')
file.write(' ss->get_fsr();\n')
file.write(' int fccx;\n')
if self.name == 'flcmps':
file.write(' uint32_t rs1 = ss->get_frf(i->rs1);\n')
file.write(' uint32_t rs2 = ss->get_frf(i->rs2);\n')
file.write(' if ((((uint32_t) 0xff) << 24) < (rs2 << 1))\n')
file.write(' fccx = 3;\n')
file.write(' else if ((((uint32_t) 0xff) << 24) < (rs1 << 1))\n')
file.write(' fccx = 2;\n')
file.write(' else {\n')
file.write(' int aSign = rs1 >> 31;\n')
file.write(' int bSign = rs2 >> 31;\n')
file.write(' if (aSign != bSign)\n')
file.write(' fccx = aSign && ((uint32_t)((rs1|rs2)<<1) != 0);\n')
file.write(' else\n')
file.write(' fccx = (rs1 != rs2) && (aSign ^ (rs1 < rs2));\n')
file.write(' if (fccx == 0 && rs1 == 0x80000000 && rs2 == 0)\n')
file.write(' fccx = 1;\n')
file.write(' }\n')
elif self.name == 'flcmpd':
file.write(' uint64_t rs1 = ss->get_drf(i->rs1);\n')
file.write(' uint64_t rs2 = ss->get_drf(i->rs2);\n')
file.write(' if ((((uint64_t) 0x7ff) << 53) < (rs2 << 1))\n')
file.write(' fccx = 3;\n')
file.write(' else if ((((uint64_t) 0x7ff) << 53) < (rs1 << 1))\n')
file.write(' fccx = 2;\n')
file.write(' else {\n')
file.write(' int aSign = rs1 >> 63;\n')
file.write(' int bSign = rs2 >> 63;\n')
file.write(' if (aSign != bSign)\n')
file.write(' fccx = aSign && ((uint64_t)( (rs1|rs2) << 1) != 0);\n')
file.write(' else\n')
file.write(' fccx = (rs1 != rs2) && (aSign ^ (rs1 < rs2));\n')
file.write(' if (fccx == 0 && rs1 == 0x8000000000000000 && rs2 == 0)\n')
file.write(' fccx = 1;\n')
file.write(' }\n')
file.write(' ss->fpu.set_fcc(ss->fsr,SS_Fpu::ConditionField(i->rd),SS_Fpu::ConditionCode(fccx));\n')
file.write(' ss->set_fsr();\n')
file.write(' ss->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.get_rd() < 4)\n')
file.write(' {\n')
self.ill_ibe(file)
if self.name == 'flcmps':
self.dec_nff(file,' ','idx_exe_'+self.name)
else:
self.dec_ndd(file,' ','idx_exe_'+self.name)
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'trc':
if self.name == 'flcmps':
file.write(' trc_exe_0ff, /* '+self.name+' */\n')
else:
file.write(' trc_exe_0dd, /* '+self.name+' */\n')
else:
if mode == 'v8_run':
mode = 'run'
file.write(' '+mode+'_exe_'+self.name+',\n')
ss_vis3[0x151] = SS_vis3_flcmp('flcmps')
ss_vis3[0x152] = SS_vis3_flcmp('flcmpd')
#============================================================================
# SS_vis3_lzd
#============================================================================
class SS_vis3_lzd(SS_InstrCpp):
def __init__(self,name):
SS_InstrCpp.__init__(self,name)
self.out = ['rd', 'g0']
def run_exe_c(self,file):
for out in self.out:
self.c_code_beg_name(file,'run_exe_'+self.name+'_'+out)
if out == 'rd':
file.write(' uint64_t rs2 = s->get_irf(i->rs2);\n')
file.write(' uint64_t rd = 0;\n')
file.write(' for (int n=0; n<16; n++) {\n')
file.write(' if ((rs2 & 0xf000000000000000) != 0)\n')
file.write(' break;\n')
file.write(' rd += 4;\n')
file.write(' rs2 <<= 4;\n')
file.write(' }\n')
file.write(' switch ((rs2 >> 60) & 0xf) {\n')
file.write(' case 1: rd += 3; break;\n')
file.write(' case 2: case 3: rd += 2; break;\n')
file.write(' case 4: case 5: case 6: case 7: rd += 1; break;\n')
file.write(' }\n')
file.write(' s->get_irf(i->rd) = rd;\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_18_14())\n')
file.write(' {\n')
self.ill_ibe(file)
file.write(' if (o.get_rd_irf())\n')
self.dec_r0r(file,' ','idx_exe_'+self.name+'_rd')
file.write(' else\n')
self.dec_00r(file,' ','idx_exe_'+self.name+'_g0')
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
for out in self.out:
if mode == 'trc':
file.write(' trc_exe_r0r, /* '+self.name+'_'+out+' */\n')
else:
if mode == 'v8_run':
mode = 'run'
file.write(' '+mode+'_exe_'+self.name+'_'+out+',\n')
ss_vis3[0x017] = SS_vis3_lzd('lzd')
#============================================================================
# SS_random
#============================================================================
class SS_random(SS_InstrCpp):
def __init__(self,name):
SS_InstrCpp.__init__(self,name)
def run_exe_c(self,file):
self.c_code_beg_name(file,'run_exe_'+self.name)
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(' s->get_drf(i->rd) = (uint64_t(rand()) << 32) | uint64_t(rand());\n')
file.write(' s->npc = npc+4;\n')
file.write(' return npc;\n')
self.c_code_end(file)
def run_dec_c(self,file):
self.c_code_dec_beg_name(file,'run_dec_'+self.name)
file.write(' i->flg = SS_Instr::NON_LSU;\n')
file.write(' if (o.is_zero_18_14() && o.is_zero_4_0())\n')
file.write(' {\n')
self.ill_ibe(file)
self.dec_d00(file,' ','idx_exe_'+self.name)
file.write(' }\n')
file.write(' else\n')
file.write(' return (s->trap)(pc,npc,s,i,SS_Trap::ILLEGAL_INSTRUCTION);\n')
self.c_code_end(file)
def gen_exe_tbl(self,file,mode):
if mode == 'v8_run':
mode = 'run'
self.gen_exe_passthrough(file,mode)
ss_vis3[0x015] = SS_random('random')