Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / ras / src / SS_TrcExe.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: SS_TrcExe.cc
// 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 ============================================
/***********************************************************************
**
** Copyright (C) 2006, Sun Microsystems, Inc.
**
** Sun considers its source code as an unpublished, proprietary
** trade secret and it is available only under strict license provisions.
** This copyright notice is placed here only to protect Sun in the event
** the source is deemed a published work. Disassembly, decompilation,
** or other means of reducing the object code to human readable form
** is prohibited by the license agreement under which this code is
** provided to the user or company in possession of this copy.
**
*************************************************************************/
#include "SS_Types.h"
#include "SS_Strand.h"
#include "SS_TrcExe.h"
// trc_exe_passthrough() just invokes the run_exe_table[] function for
// a decoded instruction. It is used to populate the trc_exe_table[]
// for any entries that do not require tracing.
SS_Vaddr trc_exe_passthrough( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i )/*{{{*/
{
SS_Execute exe = s->run_exe_table_ref[i->exe_tbl_idx];
return (*exe)(pc, npc, s, i);
}
/*}}}*/
// trc_exe_call() handles the call instruction in tracing mode.
SS_Vaddr trc_exe_call( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i )/*{{{*/
{
s->sim_state.trap_taken(0);
SS_Execute exe = s->run_exe_table_ref[i->exe_tbl_idx];
pc = (*exe)(pc, npc, s, i);
if (s->ras_rd && !s->sim_state.trap_taken())
{
SS_Vaddr trap_pc = (*s->ras_rd)(pc, npc, s, i, 15); /* %o7 */
if (s->sim_state.trap_taken())
return trap_pc;
}
return pc;
}
/*}}}*/
// trc_exe_cas_i0() handles cas*, swap, ldstub instructions in tracing mode
// taking two registers in the EA calculation.
extern "C" SS_Vaddr trc_exe_cas_i0( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i)/*{{{*/
{
s->sim_state.trap_taken(0);
int reg_nr1 = SS_Strand::reg_off2idx(i->rs1);
if (s->ras_rs1)
{
SS_Vaddr trap_pc = (*s->ras_rs1)(pc, npc, s, i, reg_nr1);
if (s->sim_state.trap_taken())
return trap_pc;
}
int reg_nr2 = SS_Strand::reg_off2idx(i->rs2);
if (s->ras_rs2)
{
SS_Vaddr trap_pc = (*s->ras_rs2)(pc, npc, s, i, reg_nr2);
if (s->sim_state.trap_taken())
return trap_pc;
}
int reg_nr3 = SS_Strand::reg_off2idx(i->rd);
if (s->ras_rs3)
{
SS_Vaddr trap_pc = (*s->ras_rs3)(pc, npc, s, i, reg_nr3);
if (s->sim_state.trap_taken())
return trap_pc;
}
SS_Execute exe = s->run_exe_table_ref[i->exe_tbl_idx];
pc = (*exe)(pc, npc, s, i);
if (s->ras_rd && !s->sim_state.trap_taken())
{
SS_Vaddr trap_pc = (*s->ras_rd)(pc, npc, s, i, SS_Strand::reg_off2idx(i->rd));
if (s->sim_state.trap_taken())
return trap_pc;
}
return pc;
}
/*}}}*/
// trc_exe_cas_i1() handles cas*, swap, ldstub instructions in tracing mode
// taking a register + immediate in the EA calculation.
extern "C" SS_Vaddr trc_exe_cas_i1( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i)/*{{{*/
{
s->sim_state.trap_taken(0);
int reg_nr1 = SS_Strand::reg_off2idx(i->rs1);
if (s->ras_rs1)
{
SS_Vaddr trap_pc = (*s->ras_rs1)(pc, npc, s, i, reg_nr1);
if (s->sim_state.trap_taken())
return trap_pc;
}
int reg_nr3 = SS_Strand::reg_off2idx(i->rd);
if (s->ras_rs3)
{
SS_Vaddr trap_pc = (*s->ras_rs3)(pc, npc, s, i, reg_nr3);
if (s->sim_state.trap_taken())
return trap_pc;
}
SS_Execute exe = s->run_exe_table_ref[i->exe_tbl_idx];
pc = (*exe)(pc, npc, s, i);
if (s->ras_rd && !s->sim_state.trap_taken())
{
SS_Vaddr trap_pc = (*s->ras_rd)(pc, npc, s, i, SS_Strand::reg_off2idx(i->rd));
if (s->sim_state.trap_taken())
return trap_pc;
}
return pc;
}
/*}}}*/
// trc_exe_pdist() handles the pdist instruction in tracing mode.
extern "C" SS_Vaddr trc_exe_pdist( SS_Vaddr pc, SS_Vaddr npc, SS_Strand* s, SS_Instr* i)/*{{{*/
{
s->sim_state.trap_taken(0);
int reg_nr1 = SS_Strand::freg_off2idx(i->rs1);
if (s->ras_drs1)
{
SS_Vaddr trap_pc = (*s->ras_drs1)(pc, npc, s, i, reg_nr1);
if (s->sim_state.trap_taken())
return trap_pc;
}
int reg_nr2 = SS_Strand::freg_off2idx(i->rs2);
if (s->ras_drs2)
{
SS_Vaddr trap_pc = (*s->ras_drs2)(pc, npc, s, i, reg_nr2);
if (s->sim_state.trap_taken())
return trap_pc;
}
int reg_nr3 = SS_Strand::freg_off2idx(i->rd);
if (s->ras_drs3)
{
SS_Vaddr trap_pc = (*s->ras_drs3)(pc, npc, s, i, reg_nr3);
if (s->sim_state.trap_taken())
return trap_pc;
}
SS_Execute exe = s->run_exe_table_ref[i->exe_tbl_idx];
pc = (*exe)(pc, npc, s, i);
if (s->ras_drd && !s->sim_state.trap_taken())
{
SS_Vaddr trap_pc = (*s->ras_drd)(pc, npc, s, i, SS_Strand::freg_off2idx(i->rd));
if (s->sim_state.trap_taken())
return trap_pc;
}
return pc;
}
/*}}}*/