Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / ras / bin / SS_TrcExe.py
# ========== Copyright Header Begin ==========================================
#
# OpenSPARC T2 Processor File: SS_TrcExe.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
# The SS_TrcExe class generates envelope functions for tracing and RAS
# register file injection/detection. These envelope functions capture
# which registers operands are used by an opcode and direct the
# operands to SS_Strand::*rf_rs[123] and SS_Strand::*rd_rd routines.
#
# The opcode classes use these envelope functions in the run_exe_tbl[]
# execution vector.
class SS_TrcExe:
def __init__(self,regs):
self.regs = regs
def run_exe_h(self,file):
file.write('extern "C" SS_Vaddr trc_exe_'+self.regs+'( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i);\n')
def run_exe_c(self,file):
file.write('extern "C" SS_Vaddr trc_exe_'+self.regs+'( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i)\n')
file.write('{\n')
file.write(' s->sim_state.trap_taken(0);\n')
self.gen_ras_src_reg_c(file,1)
self.gen_ras_src_reg_c(file,2)
self.gen_ras_src_reg_c(file,3)
file.write(' SS_Execute exe = s->run_exe_table_ref[i->exe_tbl_idx];\n')
file.write(' pc = (*exe)(pc, npc, s, i);\n')
self.gen_ras_dest_reg_c(file)
file.write(' return pc;\n')
file.write('}\n')
def gen_ras_reg_nr(self,file,reg,reg_nr):
reg = reg.lower()
if reg == 'r' or reg == 'p':
file.write(' int reg_nr%d = SS_Strand::reg_off2idx(i->rs%d);\n' \
% (reg_nr, reg_nr))
elif reg == 'f' or reg == 'd':
file.write(' int reg_nr%d = SS_Strand::freg_off2idx(i->rs%d);\n' \
% (reg_nr, reg_nr))
elif reg == '0':
pass
else:
raise RuntimeError, 'Bad regsiter type: '+reg
def gen_ras_src_reg_c(self,file,reg_nr):
if reg_nr == 1 or reg_nr == 2:
reg = self.regs[reg_nr]
self.gen_ras_reg_nr(file,reg,reg_nr)
elif reg_nr == 3:
if self.regs == 'ffff' or self.regs == 'dddd':
reg = self.regs[3]
self.gen_ras_reg_nr(file,reg,reg_nr)
elif self.regs[0].isupper():
reg = self.regs[0].lower()
if reg == 'r' or reg == 'p':
file.write(' int reg_nr3 = SS_Strand::reg_off2idx(i->rd); /* rd as source */\n')
elif reg == 'f' or reg == 'd' or reg == 'b':
file.write(' int reg_nr3 = SS_Strand::freg_off2idx(i->rd); /* rd as source */\n')
elif reg == '0':
pass
else:
raise RuntimeError, 'Bad regsiter type: '+reg
else:
reg = '0'
else:
raise RuntimeError, 'Bad regsiter number: '+reg_nr
if reg == 'r' or reg == 'p':
file.write(' if (s->ras_rs%d)\n' % (reg_nr))
file.write(' {\n')
file.write(' SS_Vaddr trap_pc = (*s->ras_rs%d)(pc, npc, s, i, reg_nr%d);\n' % (reg_nr, reg_nr))
file.write(' if (s->sim_state.trap_taken())\n')
file.write(' return trap_pc;\n')
file.write(' }\n')
if reg == 'p':
file.write(' if (s->ras_rs%d)\n' % (reg_nr))
file.write(' {\n')
file.write(' SS_Vaddr trap_pc = (*s->ras_rs%d)(pc, npc, s, i, reg_nr%d+1);\n' % (reg_nr, reg_nr))
file.write(' if (s->sim_state.trap_taken())\n')
file.write(' return trap_pc;\n')
file.write(' }\n')
elif reg == 'f':
file.write(' if (s->ras_frs%d)\n' % (reg_nr))
file.write(' {\n')
file.write(' SS_Vaddr trap_pc = (*s->ras_frs%d)(pc, npc, s, i, reg_nr%d);\n' % (reg_nr, reg_nr))
file.write(' if (s->sim_state.trap_taken())\n')
file.write(' return trap_pc;\n')
file.write(' }\n')
elif reg == 'd':
file.write(' if (s->ras_drs%d)\n' % (reg_nr))
file.write(' {\n')
file.write(' SS_Vaddr trap_pc = (*s->ras_drs%d)(pc, npc, s, i, reg_nr%d);\n' % (reg_nr, reg_nr))
file.write(' if (s->sim_state.trap_taken())\n')
file.write(' return trap_pc;\n')
file.write(' }\n')
elif reg == 'b':
file.write(' if (s->ras_drs%d)\n' % (reg_nr))
file.write(' {\n')
file.write(' for (int ndx = 0; ndx < 8; ++ndx)\n')
file.write(' {\n')
file.write(' SS_Vaddr trap_pc = (*s->ras_drs%d)(pc, npc, s, i, reg_nr%d + 2*ndx);\n' % (reg_nr, reg_nr))
file.write(' if (s->sim_state.trap_taken())\n')
file.write(' return trap_pc;\n')
file.write(' }\n')
file.write(' }\n')
elif reg == '0':
pass
else:
raise RuntimeError, 'Bad register type: '+reg+'\n'
def gen_ras_dest_reg_c(self,file):
if self.regs[0].isupper():
reg = '0'
else:
reg = self.regs[0]
if reg == 'r' or reg == 'p':
file.write(' if (s->ras_rd && !s->sim_state.trap_taken())\n')
file.write(' {\n')
file.write(' SS_Vaddr trap_pc = (*s->ras_rd)(pc, npc, s, i, SS_Strand::reg_off2idx(i->rd));\n')
file.write(' if (s->sim_state.trap_taken())\n')
file.write(' return trap_pc;\n')
file.write(' }\n')
if reg == 'p':
file.write(' if (s->ras_rd && !s->sim_state.trap_taken())\n')
file.write(' {\n')
file.write(' SS_Vaddr trap_pc = (*s->ras_rd)(pc, npc, s, i, SS_Strand::reg_off2idx(i->rd)+1);\n')
file.write(' if (s->sim_state.trap_taken())\n')
file.write(' return trap_pc;\n')
file.write(' }\n')
elif reg == 'f':
file.write(' if (s->ras_frd && !s->sim_state.trap_taken())\n')
file.write(' {\n')
file.write(' SS_Vaddr trap_pc = (*s->ras_frd)(pc, npc, s, i, SS_Strand::freg_off2idx(i->rd));\n')
file.write(' if (s->sim_state.trap_taken())\n')
file.write(' return trap_pc;\n')
file.write(' }\n')
elif reg == 'd':
file.write(' if (s->ras_drd && !s->sim_state.trap_taken())\n')
file.write(' {\n')
file.write(' SS_Vaddr trap_pc = (*s->ras_drd)(pc, npc, s, i, SS_Strand::freg_off2idx(i->rd));\n')
file.write(' if (s->sim_state.trap_taken())\n')
file.write(' return trap_pc;\n')
file.write(' }\n')
elif reg == 'b':
file.write(' if (s->ras_drd && !s->sim_state.trap_taken())\n')
file.write(' {\n')
file.write(' int reg_nr = SS_Strand::freg_off2idx(i->rd);\n')
file.write(' for (int ndx = 0; ndx < 8; ++ndx)\n')
file.write(' {\n')
file.write(' SS_Vaddr trap_pc = (*s->ras_drd)(pc, npc, s, i, reg_nr + 2*ndx);\n')
file.write(' if (s->sim_state.trap_taken())\n')
file.write(' return trap_pc;\n')
file.write(' }\n')
file.write(' }\n')
elif reg == '0':
pass
else:
raise RuntimeError, 'Bad register type: '+reg+'\n'
ras_reg_fmts = [
'rrr',
'rr0',
'prr',
'pr0',
'r0r',
'rf0',
'rd0',
'00r',
'0r0',
'r00',
'r0f',
'r0d',
'0rr',
'Rrr',
'Rr0',
'Prr',
'Pr0',
'f0f',
'd0d',
'frf',
'drd',
'd0f',
'df0',
'f0d',
'0ff',
'0dd',
'fff',
'ddd',
'dfd',
'dff',
'fdd',
'rdd',
'frr',
'Frr',
'drr',
'Drr',
'd00',
'f0r',
'd0r',
'f00',
'ff0',
'dd0',
'fr0',
'Fr0',
'dr0',
'Dr0',
'Ddd',
'br0',
'brr',
'Br0',
'Brr',
'ffff',
'dddd'
];
if sys.argv[1] == 'h':
h_base_name = sys.argv[2].split('/')[-1]
h_file=open(sys.argv[2]+'.h','w')
h_file.write('#ifndef __'+h_base_name+'_h__\n')
h_file.write('#define __'+h_base_name+'_h__\n')
h_file.write('\n')
h_file.write('#include "SS_Types.h"\n')
h_file.write('\n')
for fmt in ras_reg_fmts:
SS_TrcExe(fmt).run_exe_h(h_file)
h_file.write('#endif\n')
h_file.close()
elif sys.argv[1] == 'cc':
cc_base_name = sys.argv[2].split('/')[-1]
cc_file=open(sys.argv[2]+'.cc','w')
cc_file.write('#include "SS_Strand.h"\n')
cc_file.write('#include "SS_Instr.h"\n')
cc_file.write('#include "SS_TrcExe.h"\n')
cc_file.write("\n")
for fmt in ras_reg_fmts:
SS_TrcExe(fmt).run_exe_c(cc_file)
cc_file.close()
else:
sys.stderr.write('bad file specifier: '+sys.argv[1]+'\n')