# ========== 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 ============================================
# 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[]
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(' 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')
def gen_ras_reg_nr(self
,file,reg
,reg_nr
):
if reg
== 'r' or reg
== 'p':
file.write(' int reg_nr%d = SS_Strand::reg_off2idx(i->rs%d);\n' \
elif reg
== 'f' or reg
== 'd':
file.write(' int reg_nr%d = SS_Strand::freg_off2idx(i->rs%d);\n' \
raise RuntimeError, 'Bad regsiter type: '+reg
def gen_ras_src_reg_c(self
,file,reg_nr
):
if reg_nr
== 1 or reg_nr
== 2:
self
.gen_ras_reg_nr(file,reg
,reg_nr
)
if self
.regs
== 'ffff' or self
.regs
== 'dddd':
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')
raise RuntimeError, 'Bad regsiter type: '+reg
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(' 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(' if (s->ras_rs%d)\n' % (reg_nr
))
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(' if (s->ras_frs%d)\n' % (reg_nr
))
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(' if (s->ras_drs%d)\n' % (reg_nr
))
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(' if (s->ras_drs%d)\n' % (reg_nr
))
file.write(' for (int ndx = 0; ndx < 8; ++ndx)\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')
raise RuntimeError, 'Bad register type: '+reg
+'\n'
def gen_ras_dest_reg_c(self
,file):
if self
.regs
[0].isupper():
if reg
== 'r' or reg
== 'p':
file.write(' if (s->ras_rd && !s->sim_state.trap_taken())\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(' if (s->ras_rd && !s->sim_state.trap_taken())\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(' if (s->ras_frd && !s->sim_state.trap_taken())\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(' if (s->ras_drd && !s->sim_state.trap_taken())\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(' if (s->ras_drd && !s->sim_state.trap_taken())\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(' 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')
raise RuntimeError, 'Bad register type: '+reg
+'\n'
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('#include "SS_Types.h"\n')
SS_TrcExe(fmt
).run_exe_h(h_file
)
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')
SS_TrcExe(fmt
).run_exe_c(cc_file
)
sys
.stderr
.write('bad file specifier: '+sys
.argv
[1]+'\n')