Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / bin / SS_Instr.py
# ========== Copyright Header Begin ==========================================
#
# OpenSPARC T2 Processor File: SS_Instr.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 ============================================
import sys
from SS_Setup import *
setup = setups[sys.argv[1]]
#============================================================================
# _if_(cond,then,else) is a workaround for the lack of a conditional
# expression syntax ala 'c ? t : e' in Python ...
#============================================================================
def _if_(c,t,e):
if c:
return t
else:
return e
#============================================================================
# class SS_Instr
#============================================================================
# We astart at two as the first two are for fetching code from
# memory or from io. Code fetches are always big endian
exe_idx_s_count = 4 # exe table index
idx_mem_s_count = 1 # mem table index
class SS_Instr:
def __init__(self,name):
self.name = name
# run_exe_s() is for instructions that have an assembly code execute body
def run_exe_s(self,file):
pass
# run_exe_c() is for instructions that have a c-code execute body
def run_exe_c(self,file):
pass
# run_dec_s() is the assembly code for decoding instructions
def run_dec_s(self,file):
pass
# run_dec_c() is the c code for decoding this instruction
def run_dec_c(self,file):
pass
# run_dec_p() is the decode function name or decode table name
def run_dec_p(self):
return 'run_dec_%s' % self.name
# run_dec_p_count() is the number or time the name should appear in a table
# From example the branch opcodes use op2 .. so lower 3 bits of op3 are ...
def run_dec_p_count(self):
return 1
def exe_idx_s_name(self,file,n):
global exe_idx_s_count
file.write('#define IDX_'+n.upper()+'\t'+str(exe_idx_s_count)+'\n')
exe_idx_s_count += 8
def exe_idx_s(self,file):
self.exe_idx_s_name(file,self.name)
def gen_exe_tbl(self,file,mode):
'''
gen_exe_tbl(), for SS_Instr and all its children, produces entries
for various execution tables, e.g. the idx, run, and trc
exe_tables. Each entry corresponds to a decoded instruction
action -- a function that simulates the instruction's behavior.
gen_exe_tbl() writes its output to 'file'.
Which kind of entry is controlled by 'mode', which can be either
'idx', 'run', or 'trc', for index, fast (or run) mode, or
tracing/ras mode. 'idx' populates the ExeIdx enum, 'run' fills
run_exe_table[], and 'trc' fills trc_exe_table[]. gen_exe_tbl()
guarantees that the order and size of these tables will all match
so that a ExeIdx enum can be used to index either exe table and
the corresponding table entries will refer to the same instruction
behavior.
Note that at each level in the class hierarchy, gen_exe_tbl()
produces *all* the table entries for the class' instance. This
may involve some list traversal, multiple entry generation, or
emitting nothing -- the behavior is ad hoc.
'''
file.write(' %s_exe_%s,\n' % (mode,self.name))
def gen_exe_passthrough(self,file,mode):
if mode == 'trc':
file.write(' trc_exe_passthrough, /* '+self.name+' */\n')
elif mode == 'v8_run':
file.write(' run_exe_%s,\n' % self.name)
else:
file.write(' %s_exe_%s,\n' % (mode,self.name))
# The following family of gen_exe_ZZZ() routines generate tracing exe
# functions that invoke the correct IRF/FRF RAS routines for the
# various source and destination register sets.
#
# The naming convention for ZZZ is each 'Z' corresponds to:
# rd rs1 rs2
# or
# desintation, source1, source2
#
# This order matches the appearance of the register fields in the
# opcodes themselves.
#
# The legend for 'Z' is as follows:
#
# r integer register
# p (N,N+1) integer register pair
# f single precision FP reg
# d double precision FP reg
# b block FP reg (group of 8)
# I either rs2 or an immediate
# determined by imm
# 0 no register
#
# The first letter may be captialized. This indicates that rd is used
# as a source instead of a destination.
def gen_exe_rrI(self,file,mode,imm='',out=''):
self.gen_exe_XrI(file,mode,'r',imm,out)
def gen_exe_RrI(self,file,mode,imm='',out=''):
self.gen_exe_XrI(file,mode,'R',imm,out)
def gen_exe_prI(self,file,mode,imm='',out=''):
self.gen_exe_XrI(file,mode,'p',imm,out)
def gen_exe_PrI(self,file,mode,imm='',out=''):
self.gen_exe_XrI(file,mode,'P',imm,out)
def gen_exe_frI(self,file,mode,imm='',out=''):
self.gen_exe_XrI(file,mode,'f',imm,out)
def gen_exe_FrI(self,file,mode,imm='',out=''):
self.gen_exe_XrI(file,mode,'F',imm,out)
def gen_exe_drI(self,file,mode,imm='',out=''):
self.gen_exe_XrI(file,mode,'d',imm,out)
def gen_exe_DrI(self,file,mode,imm='',out=''):
self.gen_exe_XrI(file,mode,'D',imm,out)
def gen_exe_brI(self,file,mode,imm='',out=''):
self.gen_exe_XrI(file,mode,'b',imm,out)
def gen_exe_BrI(self,file,mode,imm='',out=''):
self.gen_exe_XrI(file,mode,'B',imm,out)
def gen_exe_0rI(self,file,mode,imm='',out=''):
self.gen_exe_XrI(file,mode,'0',imm,out)
def gen_exe_XrI(self,file,mode,dest,imm,out):
'''
Generate a call to either trc_exe_Xrr() or trc_exe_Xr0() depending on
whether self.imm == 'i0'. 'X' is one of '0', 'r', 'p', 'f', or 'd'
(or the upper case variants).
'''
try:
ccr = '_'+self.ccr
except AttributeError:
ccr = ''
if out != '':
out = '_'+out
if imm == '':
imm = self.imm
if mode == 'trc':
if imm == 'i0':
file.write(' trc_exe_'+dest+'rr, /* '+self.opc+ccr+'_'+imm+out+' */\n')
else:
file.write(' trc_exe_'+dest+'r0, /* '+self.opc+ccr+'_'+imm+out+' */\n')
else:
file.write(' '+mode+'_exe_'+self.opc+ccr+'_'+imm+out+',\n')
def gen_mem_tbl(self,file,mode):
if mode == 'idx':
if file == None:
return 'idx_mem_' + self.name
file.write(' %s,\n' % self.gen_mem_tbl(None,'idx'))
else:
file.write(' mem_%s_b_%s,\n' % (mode,self.name))
file.write(' mem_%s_l_%s,\n' % (mode,self.name))
file.write(' io_%s_b_%s,\n' % (mode,self.name))
file.write(' io_%s_l_%s,\n' % (mode,self.name))
def idx_mem_s(self,file):
global idx_mem_s_count
file.write('#define %s\t%d\n' % (self.gen_mem_tbl(None,'idx').upper(),idx_mem_s_count))
idx_mem_s_count += 1
def c_code_beg_name(self,file,name):
file.write('\n')
file.write('extern "C" SS_Vaddr %s( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i )\n' % name)
file.write('{\n')
def c_code_beg(self,file,prefix):
self.c_code_beg_name(file,prefix + self.name)
def c_code_end(self,file):
file.write('}\n')
def c_code_dec_extern(self,file,name):
file.write('\n')
file.write('extern "C" SS_Vaddr %s( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, uint32_t opc );\n' % name)
def c_code_dec_header(self,file,name):
file.write('\n')
file.write('extern "C" SS_Vaddr %s( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i, uint32_t opc )\n' % name)
file.write('{\n')
file.write(' uint32_t idx;\n')
file.write(' SS_Opcode o;\n')
file.write(' o = opc;\n')
def c_code_dec_beg_name(self,file,name):
self.c_code_dec_header(file,name)
def c_code_dec_beg(self,file,prefix):
self.c_code_dec_header(file,prefix + self.name)
def c_code_dec_end(self,file):
file.write(' return (i->exe)(pc,npc,s,i);\n')
self.c_code_end(file)
def ill_ibe(self,file,indent=' '):
if setup.ill_ibe:
file.write(indent+'if (s->inst_breakpoint_hit(opc))\n')
file.write(indent+' return (s->trap)(pc,npc,s,i,SS_Trap::INSTRUCTION_BREAKPOINT);\n')
def dec_000(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_g0(file,indent)
self.dec_tailcall(file,indent)
def dec_r00(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_irf(file,indent)
self.dec_tailcall(file,indent)
def dec_f00(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_frf(file,indent)
self.dec_tailcall(file,indent)
def dec_d00(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_drf(file,indent)
self.dec_tailcall(file,indent)
def dec_r022(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_irf(file,indent)
self.dec_ea_22(file,indent)
self.dec_tailcall(file,indent)
def dec_rrr(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_irf(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_irf(file,indent)
self.dec_tailcall(file,indent)
def dec_nrr(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_fun(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_irf(file,indent)
self.dec_tailcall(file,indent)
def dec_nff(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_fun(file,indent)
self.dec_rs1_frf(file,indent)
self.dec_rs2_frf(file,indent)
self.dec_tailcall(file,indent)
def dec_dff(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_drf(file,indent)
self.dec_rs1_frf(file,indent)
self.dec_rs2_frf(file,indent)
self.dec_tailcall(file,indent)
def dec_0ff(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_g0(file,indent)
self.dec_rs1_frf(file,indent)
self.dec_rs2_frf(file,indent)
self.dec_tailcall(file,indent)
def dec_0dd(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_g0(file,indent)
self.dec_rs1_drf(file,indent)
self.dec_rs2_drf(file,indent)
self.dec_tailcall(file,indent)
def dec_fff(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_frf(file,indent)
self.dec_rs1_frf(file,indent)
self.dec_rs2_frf(file,indent)
self.dec_tailcall(file,indent)
def dec_ndd(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_fun(file,indent)
self.dec_rs1_drf(file,indent)
self.dec_rs2_drf(file,indent)
self.dec_tailcall(file,indent)
def dec_rdd(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_irf(file,indent)
self.dec_rs1_drf(file,indent)
self.dec_rs2_drf(file,indent)
self.dec_tailcall(file,indent)
def dec_ddd(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_drf(file,indent)
self.dec_rs1_drf(file,indent)
self.dec_rs2_drf(file,indent)
self.dec_tailcall(file,indent)
def dec_dfd(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_drf(file,indent)
self.dec_rs1_frf(file,indent)
self.dec_rs2_drf(file,indent)
self.dec_tailcall(file,indent)
def dec_r0r(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_irf(file,indent)
self.dec_rs2_irf(file,indent)
self.dec_tailcall(file,indent)
def dec_r0f(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_irf(file,indent)
self.dec_rs2_frf(file,indent)
self.dec_tailcall(file,indent)
def dec_r0d(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_irf(file,indent)
self.dec_rs2_drf(file,indent)
self.dec_tailcall(file,indent)
def dec_f0r(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_frf(file,indent)
self.dec_rs2_irf(file,indent)
self.dec_tailcall(file,indent)
def dec_f0f(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_frf(file,indent)
self.dec_rs2_frf(file,indent)
self.dec_tailcall(file,indent)
def dec_frf(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_frf(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_frf(file,indent)
self.dec_tailcall(file,indent)
def dec_f0d(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_frf(file,indent)
self.dec_rs2_drf(file,indent)
self.dec_tailcall(file,indent)
def dec_d0r(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_drf(file,indent)
self.dec_rs2_irf(file,indent)
self.dec_tailcall(file,indent)
def dec_d0d(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_drf(file,indent)
self.dec_rs2_drf(file,indent)
self.dec_tailcall(file,indent)
def dec_drd(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_drf(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_drf(file,indent)
self.dec_tailcall(file,indent)
def dec_d0f(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_drf(file,indent)
self.dec_rs2_frf(file,indent)
self.dec_tailcall(file,indent)
def dec_ff0(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_frf(file,indent)
self.dec_rs1_frf(file,indent)
self.dec_tailcall(file,indent)
def dec_dd0(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_drf(file,indent)
self.dec_rs1_drf(file,indent)
self.dec_tailcall(file,indent)
def dec_frr(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_frf(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_irf(file,indent)
self.dec_tailcall(file,indent)
def dec_drr(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_drf(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_irf(file,indent)
self.dec_tailcall(file,indent)
def dec_rr5(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_irf(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_u5(file,indent)
self.dec_tailcall(file,indent)
def dec_rr6(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_irf(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_u6(file,indent)
self.dec_tailcall(file,indent)
def dec_rr10(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_irf(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_s10(file,indent)
self.dec_tailcall(file,indent)
def dec_rr11(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_irf(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_s11(file,indent)
self.dec_tailcall(file,indent)
def dec_rr13(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_irf(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_s13(file,indent)
self.dec_tailcall(file,indent)
def dec_nr13(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_fun(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_s13(file,indent)
self.dec_tailcall(file,indent)
def dec_r013(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_irf(file,indent)
self.dec_rs2_s13(file,indent)
self.dec_tailcall(file,indent)
def dec_fr13(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_frf(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_s13(file,indent)
self.dec_tailcall(file,indent)
def dec_dr13(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_drf(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_s13(file,indent)
self.dec_tailcall(file,indent)
def dec_0rr(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_g0(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_irf(file,indent)
self.dec_tailcall(file,indent)
def dec_0r8(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_g0(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_u8(file,indent)
self.dec_tailcall(file,indent)
def dec_0r13(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_g0(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_rs2_s13(file,indent)
self.dec_tailcall(file,indent)
def dec_0r16(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_g0(file,indent)
self.dec_rs1_irf(file,indent)
self.dec_ea_16(file,indent)
self.dec_tailcall(file,indent)
def dec_00r(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_g0(file,indent)
self.dec_rs2_irf(file,indent)
self.dec_tailcall(file,indent)
def dec_003(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_g0(file,indent)
self.dec_rs2_u3(file,indent)
self.dec_tailcall(file,indent)
def dec_007(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_g0(file,indent)
self.dec_rs2_u7(file,indent)
self.dec_tailcall(file,indent)
def dec_008(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_g0(file,indent)
self.dec_rs2_u8(file,indent)
self.dec_tailcall(file,indent)
def dec_0013(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_g0(file,indent)
self.dec_rs2_s13(file,indent)
self.dec_tailcall(file,indent)
def dec_ffff(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_frf(file,indent)
self.dec_rs1_frf(file,indent)
self.dec_rs2_frf(file,indent)
self.dec_rs3_frf(file,indent)
self.dec_tailcall(file,indent)
def dec_dddd(self,file,indent,index):
self.dec_exe(file,indent,index)
self.dec_rd_drf(file,indent)
self.dec_rs1_drf(file,indent)
self.dec_rs2_drf(file,indent)
self.dec_rs3_drf(file,indent)
self.dec_tailcall(file,indent)
def dec_exe(self,file,indent,index):
file.write('%s{\n' % indent)
file.write('%s i->exe_tbl_idx = %s;\n' % (indent,index))
file.write('%s i->exe = s->exe_table[i->exe_tbl_idx];\n' % (indent))
def dec_ea_16(self,file,indent):
file.write('%s i->rs2 = o.get_imm16();\n' % indent)
def dec_ea_22(self,file,indent):
file.write('%s (uint32_t&)(i->rs2) = o.get_imm22();\n' % indent)
def dec_rs3_frf(self,file,indent):
file.write('%s i->rs3 = ptr_ofs(SS_Strand,drf[0]) + o.get_rs3_frf();\n' % indent)
def dec_rs3_drf(self,file,indent):
file.write('%s i->rs3 = ptr_ofs(SS_Strand,drf[0]) + o.get_rs3_drf();\n' % indent)
def dec_rs2_u3(self,file,indent):
file.write('%s i->rs2 = o.get_imm3();\n' % indent)
def dec_rs2_u5(self,file,indent):
file.write('%s i->rs2 = o.get_imm5();\n' % indent)
def dec_rs2_u6(self,file,indent):
file.write('%s i->rs2 = o.get_imm6();\n' % indent)
def dec_rs2_u7(self,file,indent):
file.write('%s i->rs2 = o.get_imm7();\n' % indent)
def dec_rs2_u8(self,file,indent):
file.write('%s i->rs2 = o.get_imm8();\n' % indent)
def dec_rs2_s10(self,file,indent):
file.write('%s i->rs2 = o.get_simm10();\n' % indent)
def dec_rs2_s11(self,file,indent):
file.write('%s i->rs2 = o.get_simm11();\n' % indent)
def dec_rs2_s13(self,file,indent):
file.write('%s i->rs2 = o.get_simm13();\n' % indent)
def dec_rs2_irf(self,file,indent):
file.write('%s i->rs2 = ptr_ofs(SS_Strand,irf[0]) + o.get_rs2_irf();\n' % indent)
def dec_rs2_frf(self,file,indent):
file.write('%s i->rs2 = ptr_ofs(SS_Strand,drf[0]) + o.get_rs2_frf();\n' % indent)
def dec_rs2_drf(self,file,indent):
file.write('%s i->rs2 = ptr_ofs(SS_Strand,drf[0]) + o.get_rs2_drf();\n' % indent)
def dec_rs1_irf(self,file,indent):
file.write('%s i->rs1 = ptr_ofs(SS_Strand,irf[0]) + o.get_rs1_irf();\n' % indent)
def dec_rs1_frf(self,file,indent):
file.write('%s i->rs1 = ptr_ofs(SS_Strand,drf[0]) + o.get_rs1_frf();\n' % indent)
def dec_rs1_drf(self,file,indent):
file.write('%s i->rs1 = ptr_ofs(SS_Strand,drf[0]) + o.get_rs1_drf();\n' % indent)
def dec_rd_fun(self,file,indent):
file.write('%s i->rd = o.get_rd();\n' % indent)
def dec_rd_irf(self,file,indent):
file.write('%s i->rd = ptr_ofs(SS_Strand,irf[0]) + o.get_rd_irf();\n' % indent)
def dec_rd_g0(self,file,indent):
file.write('%s i->rd = 0;\n' % indent)
def dec_rd_frf(self,file,indent):
file.write('%s i->rd = ptr_ofs(SS_Strand,drf[0]) + o.get_rd_frf();\n' % indent)
def dec_rd_drf(self,file,indent):
file.write('%s i->rd = ptr_ofs(SS_Strand,drf[0]) + o.get_rd_drf();\n' % indent)
def dec_tailcall(self,file,indent):
file.write('%s return (i->exe)(pc,npc,s,i);\n' % indent)
file.write('%s}\n' % indent)
def fail_chkpt(self,file):
pass
def test_icc(self,file,indent):
if (self.cc == 'a'):
file.write('%sif (1)\n' % indent)
elif (self.cc == 'n'):
file.write('%sif (0)\n' % indent)
else:
if (self.ccr == 'icc'):
file.write('%suint8_t cc = s->ccr.icc();\n' % indent)
else:
file.write('%suint8_t cc = s->ccr.xcc();\n' % indent)
if (self.cc == 'e'):
file.write('%sif (cc&0x4)\n' % indent)
elif (self.cc == 'le'):
file.write('%sif ((cc&0x4) || (((cc&0x8)>>3)^((cc&0x2)>>1)))\n' % indent)
elif (self.cc == 'l'):
file.write('%sif (((cc&0x8)>>3)^((cc&0x2)>>1))\n' % indent)
elif (self.cc == 'leu'):
file.write('%sif (cc&0x5)\n' % indent)
elif (self.cc == 'cs'):
file.write('%sif (cc&0x1)\n' % indent)
elif (self.cc == 'neg'):
file.write('%sif (cc&0x8)\n' % indent)
elif (self.cc == 'vs'):
file.write('%sif (cc&0x2)\n' % indent)
elif (self.cc == 'ne'):
file.write('%sif ((cc&0x4)==0)\n' % indent)
elif (self.cc == 'g'):
file.write('%sif (((cc&0x4) || (((cc&0x8)>>3)^((cc&0x2)>>1)))==0)\n' % indent)
elif (self.cc == 'ge'):
file.write('%sif ((((cc&0x8)>>3)^((cc&0x2)>>1))==0)\n' % indent)
elif (self.cc == 'gu'):
file.write('%sif ((cc&0x5)==0)\n' % indent)
elif (self.cc == 'cc'):
file.write('%sif ((cc&0x1)==0)\n' % indent)
elif (self.cc == 'pos'):
file.write('%sif ((cc&0x8)==0)\n' % indent)
elif (self.cc == 'vc'):
file.write('%sif ((cc&0x2)==0)\n' % indent)
def test_r(self,file,indent):
file.write('%sint64_t rs1 = s->get_irf(i->rs1);\n' % indent)
if (self.cc == 'z'):
file.write('%sif (rs1 == 0)\n' % indent)
elif (self.cc == 'lez'):
file.write('%sif (rs1 <= 0)\n' % indent)
elif (self.cc == 'lz'):
file.write('%sif (rs1 < 0)\n' % indent)
elif (self.cc == 'nz'):
file.write('%sif (rs1 != 0)\n' % indent)
elif (self.cc == 'gz'):
file.write('%sif (rs1 > 0)\n' % indent)
elif (self.cc == 'gez'):
file.write('%sif (rs1 >= 0)\n' % indent)
def test_fcc(self,file,indent):
if (self.cc == 'a'):
file.write('%sif (1)\n' % indent)
elif (self.cc == 'n'):
file.write('%sif (0)\n' % indent)
else:
file.write(('%suint64_t cc = s->fsr_run.' % indent)+self.ccr+'();\n')
if (self.cc == 'ne'):
file.write('%sif (cc!=0)\n' % indent)
elif (self.cc == 'lg'):
file.write('%sif ((cc==1) || (cc==2))\n' % indent)
elif (self.cc == 'ul'):
file.write('%sif ((cc==1) || (cc==3))\n' % indent)
elif (self.cc == 'l'):
file.write('%sif (cc==1)\n' % indent)
elif (self.cc == 'ug'):
file.write('%sif ((cc==2) || (cc==3))\n' % indent)
elif (self.cc == 'g'):
file.write('%sif (cc==2)\n' % indent)
elif (self.cc == 'u'):
file.write('%sif (cc==3)\n' % indent)
elif (self.cc == 'e'):
file.write('%sif (cc==0)\n' % indent)
elif (self.cc == 'ue'):
file.write('%sif ((cc==0) || (cc==3))\n' % indent)
elif (self.cc == 'ge'):
file.write('%sif ((cc==0) || (cc==2))\n' % indent)
elif (self.cc == 'uge'):
file.write('%sif (cc!=1)\n' % indent)
elif (self.cc == 'le'):
file.write('%sif ((cc==0) || (cc==1))\n' % indent)
elif (self.cc == 'ule'):
file.write('%sif (cc!=2)\n' % indent)
elif (self.cc == 'o'):
file.write('%sif (cc!=3)\n' % indent)
#============================================================================
# class SS_InstrCpp
#============================================================================
class SS_InstrCpp(SS_Instr):
def __init__(self,name):
SS_Instr.__init__(self,name)
#============================================================================
# class SS_InstrAsm
#============================================================================
class SS_InstrAsm(SS_Instr):
def __init__(self,name):
SS_Instr.__init__(self,name)
def run_exe_c(self,file,product="run"):
file.write('extern "C" SS_Vaddr %s_exe_%s( SS_Vaddr, SS_Vaddr, SS_Strand*, SS_Instr* );\n' % (product,self.name))
def s_code(self,file,prefix):
name = prefix + self.name
file.write('\n')
file.write('.align 8\n')
file.write('.global %s\n' % name)
file.write('.type %s, #function\n' % name)
file.write('%s:\n' % name)
def asm_function(self,file,name):
file.write('\n')
file.write('.align 8\n')
file.write('.global %s\n' % name)
file.write('.type %s, #function\n' % name)
file.write('%s:\n' % name)
def asm_codesize(self,file,name):
file.write('.size '+name+',(.-'+name+')\n')
PC = '%o0'
NPC = '%o1'
S_PTR = '%o2'
I_PTR = '%o3'
TT = '%o4' # for call to (s->trap)(pc,npc,s,i,tt)
def ld_rs1(self,file,rd):
file.write('\tlduh\t[%s + I_RS1],%s\n' % (self.I_PTR,rd))
def ld_rs2(self,file,rd):
file.write('\tlduh\t[%s + I_RS2],%s\n' % (self.I_PTR,rd))
def ld_rs2_32(self,file,rd):
file.write('\tlduw\t[%s + I_RS2],%s\n' % (self.I_PTR,rd))
def ld_imm(self,file,rd):
file.write('\tldsh\t[%s + I_RS2],%s\n' % (self.I_PTR,rd))
def ld_rs3(self,file,rd):
file.write('\tlduh\t[%s + I_RS3],%s\n' % (self.I_PTR,rd))
def ld_rd(self,file,rd):
file.write('\tlduh\t[%s + I_RD],%s\n' % (self.I_PTR,rd))
def ld_ea_rd(self,file,rd):
file.write('\tldx\t[%s + I_RD],%s\n' % (self.I_PTR,rd))
def ld_tte(self,file,rd):
file.write('\tldx\t[%s + I_TTE],%s\n' % (self.I_PTR,rd))
def ld_irf(self,file,rs2,rd):
file.write('\tldx\t[%s + %s],%s\n' % (self.S_PTR,rs2,rd))
def st_irf(self,file,rs2,rd):
file.write('\tstx\t%s,[%s + %s]\n' % (rd,self.S_PTR,rs2))
def st_o7(self,file,rd):
file.write('\tstx\t%s,[%s + S_O7]\n' % (rd,self.S_PTR))
def lduw_frf(self,file,rs2,rd):
file.write('\tldsw\t[%s + %s],%s\n' % (self.S_PTR,rs2,rd))
def lduw_frf(self,file,rs2,rd):
file.write('\tlduw\t[%s + %s],%s\n' % (self.S_PTR,rs2,rd))
def stw_frf(self,file,rs2,rd):
file.write('\tstw\t%s,[%s + %s]\n' % (rd,self.S_PTR,rs2))
def ld_frf(self,file,rs2,rd):
file.write('\tld\t[%s + %s],%s\n' % (self.S_PTR,rs2,rd))
def st_frf(self,file,rs2,rd):
file.write('\tst\t%s,[%s + %s]\n' % (rd,self.S_PTR,rs2))
def ldx_drf(self,file,rs2,rd):
file.write('\tldx\t[%s + %s],%s\n' % (self.S_PTR,rs2,rd))
def stx_drf(self,file,rs2,rd):
file.write('\tstx\t%s,[%s + %s]\n' % (rd,self.S_PTR,rs2))
def ld_drf(self,file,rs2,rd):
file.write('\tldd\t[%s + %s],%s\n' % (self.S_PTR,rs2,rd))
def st_drf(self,file,rs2,rd):
file.write('\tstd\t%s,[%s + %s]\n' % (rd,self.S_PTR,rs2))
def ld_npc(self,file,rd):
file.write('\tldx\t[%s + S_NPC],%s\n' % (self.S_PTR,rd))
def st_npc(self,file,rd):
file.write('\tstx\t%s,[%s + S_NPC]\n' % (rd,self.S_PTR))
def ld_sim(self,file,rd):
file.write('\tldx\t[%s + S_SIM_STATE],%s\n' % (self.S_PTR,rd))
def ld_pstate(self,file,rd):
file.write('\tldub\t[%s + S_PSTATE],%s\n' % (self.S_PTR,rd))
def ld_mask_pstate_am(self,file,rd):
file.write('\tldx\t[%s + S_MASK_PSTATE_AM],%s\n' % (self.S_PTR,rd))
def ld_fsr_cpu(self,file,rd):
file.write('\tldx\t[%s + S_FSR_CPU],%s\n' % (self.S_PTR,rd))
def st_fsr_cpu(self,file,rd):
file.write('\tstx\t%s,[%s + S_FSR_CPU]\n' % (rd,self.S_PTR))
def ld_fsr_run(self,file,rd):
file.write('\tldx\t[%s + S_FSR_RUN],%s\n' % (self.S_PTR,rd))
def st_fsr_run(self,file,rd):
file.write('\tstx\t%s,[%s + S_FSR_RUN]\n' % (rd,self.S_PTR))
def ld_fsr(self,file,rd):
file.write('\tldx\t[%s + S_FSR],%s\n' % (self.S_PTR,rd))
def st_fsr(self,file,rd):
file.write('\tstx\t%s,[%s + S_FSR]\n' % (rd,self.S_PTR))
def ld_gsr(self,file,rd):
file.write('\tldx\t[%s + S_GSR],%s\n' % (self.S_PTR,rd))
def st_gsr(self,file,rd):
file.write('\tstx\t%s,[%s + S_GSR]\n' % (rd,self.S_PTR))
def rd_gsr(self,file,rd):
file.write('\trd\t%%gsr,%s\n' % rd)
def wr_gsr(self,file,rd):
file.write('\twr\t%s,%%gsr\n' % rd)
def ld_ccr(self,file,rd):
file.write('\tldub\t[%s + S_CCR],%s\n' % (self.S_PTR,rd))
def st_ccr(self,file,rd):
file.write('\tstb\t%s,[%s + S_CCR]\n' % (rd,self.S_PTR))
def rd_ccr(self,file,rd):
file.write('\trd\t%%ccr,%s\n' % rd)
def wr_ccr(self,file,rd):
file.write('\twr\t%s,%%ccr\n' % rd)
def ld_y(self,file,rd):
file.write('\tlduw\t[%s + S_Y],%s\n' % (self.S_PTR,rd))
def st_y(self,file,rd):
file.write('\tstw\t%s,[%s + S_Y]\n' % (rd,self.S_PTR))
def rd_y(self,file,rd):
file.write('\trd\t%%y,%s\n' % rd)
def wr_y(self,file,rd):
file.write('\twr\t%s,%%y\n' % rd)
def ld_trap(self,file,rd):
file.write('\tldptr\t[%s + TRAP],%s\n' % (self.S_PTR,rd))
def ld_inst_trap(self,file,rd):
file.write('\tldptr\t[%s + INST_TRAP],%s\n' % (self.S_PTR,rd))
def ldx(self,file,rs1,rs2,rd):
file.write('\tldx\t[%s + %s],%s\n' % (rs1,rs2,rd))
def stx(self,file,rs1,rs2,rd):
file.write('\tstx\t%s,[%s + %s]\n' % (rd,rs1,rs2))
def mov(self,file,rs2,rd):
self.opr(file,'or','%g0',rs2,rd)
def opr(self,file,opc,rs1,rs2,rd):
file.write('\t%s\t%s,%s,%s\n' % (opc,rs1,rs2,rd))
def op2(self,file,opc,rs2,rd):
file.write('\t%s\t%s,%s\n' % (opc,rs2,rd))
def op1(self,file,opc,rd):
file.write('\t%s\t%s\n' % (opc,rd))
def sra(self,file,rs1,rs2,rd):
self.opr(file,'sra',rs1,rs2,rd)
def add(self,file,rs1,rs2,rd):
self.opr(file,'add',rs1,rs2,rd)
def andcc(self,file,rs1,rs2,rd):
self.opr(file,'andcc',rs1,rs2,rd)
def movcc(self,file,cc,ccr,rs2,rd):
file.write('\tmov%s\t%s,%s,%s\n' % (cc,ccr,rs2,rd))
def movr(self,file,cc,rs1,rs2,rd):
file.write('\tmovr%s\t%s,%s,%s\n' % (cc,rs1,rs2,rd))
def nop(self,file):
file.write('\tnop\n')
def branch(self,file,cc,ccr,label):
if ccr[1:4] == 'fcc':
file.write('\tfb%s\t%s,%s\n' % (cc,ccr,label))
else:
file.write('\tb%s\t%s,%s\n' % (cc,ccr,label))
def jmpl(self,file,rs1,rs2,rd):
file.write('\tjmpl\t'+rs1+'+'+rs2+','+rd+'\n')
def retl(self,file):
file.write('#ifdef ARCH_V8\n')
file.write('\tsrl\t%o0,0,%o1\n')
file.write('\tsrlx\t%o0,32,%o0\n')
file.write('#endif\n')
file.write('\tretl\n')
# retl_st_npc is a store of rd to s->npc and a return.
# The reason for a merge sequence is the difference
# between v8 and v9 mode.
def retl_st_npc(self,file,rd):
file.write('#ifdef ARCH_V8\n')
file.write('\tstx\t%s,[%s + S_NPC]\n' % (rd,self.S_PTR))
file.write('\tsrl\t%o0,0,%o1\n')
file.write('\tretl\n')
file.write('\tsrlx\t%o0,32,%o0\n')
file.write('#else\n')
file.write('\tretl\n')
file.write('\tstx\t%s,[%s + S_NPC]\n' % (rd,self.S_PTR))
file.write('#endif\n')
#============================================================================
# class SS_InstrGroup
#============================================================================
class SS_InstrGroup(SS_Instr):
def __init__(self,name,opc_sft,opc_msk,repeat=1):
SS_Instr.__init__(self,name)
self.name = name
self.opc_sft = opc_sft
self.opc_msk = opc_msk
self.list = []
self.repeat = repeat
def append(self,i):
self.list.append(i)
def extend(self,l):
self.list.extend(l)
def run_exe_s(self,file):
for i in self.list:
i.run_exe_s(file)
def run_exe_c(self,file):
for i in self.list:
i.run_exe_c(file)
def run_dec_s(self,file):
for i in self.list:
i.run_dec_s(file)
def run_dec_c(self,file):
for i in self.list:
i.run_dec_c(file)
file.write('\nSS_DecodeGroup<%d> run_dec_%s = \n' % (len(self.list),self.name))
file.write('{\n')
file.write(' ptr_sft(%d), ptr_msk(%d),\n' % (self.opc_sft,self.opc_msk))
o = 0
for i in self.list:
s = i.run_dec_p()
if s != '':
for x in range(0,i.run_dec_p_count()):
if o == 0:
file.write(' { /* %2x */ %s\n' % (o,s))
else:
file.write(' , /* %2x */ %s\n' % (o,s))
o = o + 1
file.write(' }\n')
file.write('};\n')
def run_dec_p(self):
return 'ss_dec_tbl(run_dec_%s)' % self.name
def run_dec_p_count(self):
return self.repeat
def gen_exe_tbl(self,file,mode):
for i in self.list:
i.gen_exe_tbl(file,mode)
def exe_idx_s(self,file):
for i in self.list:
i.exe_idx_s(file)
#============================================================================
# class SS_InstrTable
#============================================================================
class SS_InstrTable(SS_InstrGroup):
def __init__(self,setup,name):
SS_InstrGroup.__init__(self,name,0,0,1)
def run_dec_c(self,file):
for i in self.list:
i.run_dec_c(file)
file.write('\nSS_DecodeTable '+setup.product+'_Strand::run_dec_%s = \n' % self.name)
file.write('{\n')
o = 0
for i in self.list:
s = i.run_dec_p()
if s != '':
for x in range(0,i.run_dec_p_count()):
if o == 0:
file.write(' { /* %2x */ %s\n' % (o,s))
else:
file.write(' , /* %2x */ %s\n' % (o,s))
o = o + 1
file.write(' }\n')
file.write('};\n')
#============================================================================
# SS_ill() - a place holder for decoded as illegal instruction trap
#============================================================================
class SS_ill(SS_InstrCpp):
def __init__(self):
SS_InstrCpp.__init__(self,'ill')
def exe_idx_s(self,file):
pass
def gen_exe_tbl(self,file,mode):
pass
def run_dec_p(self):
return 'run_dec_illtrap'
#============================================================================
# condition codes
#============================================================================
cond=[
('n' , 0),
('e' , 1),
('le' , 2),
('l' , 3),
('leu', 4),
('cs' , 5),
('neg', 6),
('vs' , 7),
('a' , 8),
('ne' , 9),
('g' , 10),
('ge' , 11),
('gu' , 12),
('cc' , 13),
('pos', 14),
('vc' , 15)
]
inv_rcond = {
'z' :'nz',
'lez':'gz',
'lz' :'gez',
'nz' :'z',
'gz' :'lez',
'gez':'lz'
}
rcond = [
('' , 0),
('z' , 1),
('lez', 2),
('lz' , 3),
('' , 4),
('nz' , 5),
('gz' , 6),
('gez', 7),
('' , 8),
('' , 9),
('' , 10),
('' , 11),
('' , 12),
('' , 13),
('' , 14),
('' , 15)
]
rcond8 = [
('' , 0),
('z' , 1),
('lez', 2),
('lz' , 3),
('' , 4),
('nz' , 5),
('gz' , 6),
('gez', 7)
]
fcond = [
('n' , 0),
('ne' , 1),
('lg' , 2),
('ul' , 3),
('l' , 4),
('ug' , 5),
('g' , 6),
('u' , 7),
('a' , 8),
('e' , 9),
('ue' , 10),
('ge' , 11),
('uge', 12),
('le' , 13),
('ule', 14),
('o' , 15)
]