summaryrefslogtreecommitdiff
path: root/src/cuda-sim/cuda-sim.cc
diff options
context:
space:
mode:
authorTor Aamodt <[email protected]>2010-08-30 11:05:15 -0800
committerTor Aamodt <[email protected]>2010-08-30 11:05:15 -0800
commitbb820c116764d7a1b8e071137d32b74e7f34dd2f (patch)
tree313d6794087adc13490963b1f847bcc88ccdc0dd /src/cuda-sim/cuda-sim.cc
parent80e1b49ff823190d0316623d414a343575c93eae (diff)
integrating CL 7421-7434 from fermi-test
this integrates the ptxplus functional model changes, but has only been verified with CUDA 3.1 PTX regressions (which pass) still need to verify ptxplus itself is working in this branch [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 7435]
Diffstat (limited to 'src/cuda-sim/cuda-sim.cc')
-rw-r--r--src/cuda-sim/cuda-sim.cc140
1 files changed, 128 insertions, 12 deletions
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc
index 2c317b2..0a6ccd6 100644
--- a/src/cuda-sim/cuda-sim.cc
+++ b/src/cuda-sim/cuda-sim.cc
@@ -82,6 +82,7 @@
#include "../gpgpu-sim/gpu-sim.h"
#include "ptx_sim.h"
#include "../gpgpusim_entrypoint.h"
+#include "decuda_pred_table/decuda_pred_table.h"
int gpgpu_ptx_instruction_classification;
void ** g_inst_classification_stat = NULL;
@@ -90,6 +91,9 @@ int g_ptx_kernel_count = -1; // used for classification stat collection purposes
int g_debug_execution = 0;
int g_debug_thread_uid = 0;
addr_t g_debug_pc = 0xBEEF1518;
+// Output debug information to file options
+FILE* ptx_inst_debug_file;
+
unsigned g_ptx_sim_num_insn = 0;
std::map<const struct textureReference*,const struct cudaArray*> TextureToArrayMap; // texture bindings
std::map<const struct textureReference*, const struct textureInfo*> TextureToInfoMap;
@@ -245,7 +249,7 @@ void function_info::ptx_assemble()
g_assemble_code_next_pc=PC;
for ( unsigned ii=0; ii < n; ii++ ) { // handle branch instructions
ptx_instruction *pI = m_instr_mem[ii];
- if ( pI->get_opcode() == BRA_OP ) {
+ if ( pI->get_opcode() == BRA_OP || pI->get_opcode() == BREAKADDR_OP ) {
operand_info &target = pI->dst(); //get operand, e.g. target name
if ( labels.find(target.name()) == labels.end() ) {
printf("GPGPU-Sim PTX: Loader error (%s:%u): Branch label \"%s\" does not appear in assembly code.",
@@ -263,17 +267,28 @@ void function_info::ptx_assemble()
create_basic_blocks();
connect_basic_blocks();
+ bool modified = false;
+ do {
+ find_dominators();
+ find_idominators();
+ modified = connect_break_targets();
+ } while (modified == true);
+
if ( g_debug_execution>=50 ) {
print_basic_blocks();
print_basic_block_links();
print_basic_block_dot();
}
+ if ( g_debug_execution>=2 ) {
+ print_dominators();
+ }
find_postdominators();
find_ipostdominators();
if ( g_debug_execution>=50 ) {
print_postdominators();
print_ipostdominators();
}
+
m_assembled = true;
}
@@ -534,6 +549,8 @@ static void get_opcode_info( const ptx_instruction *pI, unsigned opcode, unsigne
*op_type = STORE_OP;
} else if ( opcode == BRA_OP ) {
*op_type = BRANCH_OP;
+ } else if ( opcode == BREAKADDR_OP ) {
+ *op_type = BRANCH_OP;
} else if ( opcode == TEX_OP ) {
*op_type = LOAD_OP;
} else if ( opcode == ATOM_OP ) {
@@ -596,6 +613,17 @@ void function_info::ptx_decode_inst( ptx_thread_info *thread,
unsigned cycles;
get_opcode_info(pI,opcode,&cycles,op_type);
+ // Quick fix for memory operands in ALU instructions
+ if( pI->has_memory_read() )
+ *op_type = LOAD_OP;
+ else if( pI->has_memory_write() )
+ *op_type = STORE_OP;
+
+ if( pI->has_memory_read() && pI->has_memory_write() ) {
+ printf("Instruction has both a memory read and memory write - not supported by timing simulator.");
+ assert(0);
+ }
+
// Get register operands
int n=0,m=0;
ptx_instruction::const_iterator op=pI->op_iter_begin();
@@ -659,6 +687,35 @@ void function_info::ptx_decode_inst( ptx_thread_info *thread,
if(o.is_memory_operand2()) {
// memory operand with one address register (ex. g[$r1] or s[$r2+0x4])
if(o.get_double_operand_type() == 0 && o.is_memory_operand()){
+ *ar1 = o.reg_num();
+ }
+ // memory operand with two address register (ex. s[$r1+$r1] or g[$r1+=$r2])
+ else if(o.get_double_operand_type() == 1 || o.get_double_operand_type() == 2) {
+ *ar1 = o.reg1_num();
+ *ar2 = o.reg2_num();
+ }
+ }
+ }
+ }
+
+ // Get predicate
+ if(pI->has_pred()) {
+ const operand_info &p = pI->get_pred();
+ *pred = p.reg_num();
+ }
+
+ // Get address registers inside memory operands.
+ // Assuming only one memory operand per instruction,
+ // and maximum of two address registers for one memory operand.
+ if( pI->has_memory_read() || pI->has_memory_write() ) {
+ ptx_instruction::const_iterator op=pI->op_iter_begin();
+ for ( ; op != pI->op_iter_end(); op++, n++ ) { //process operands
+ const operand_info &o = *op;
+
+ // memory operand with addressing (ex. s[0x4] or g[$r1])
+ if(o.is_memory_operand2()) {
+ // memory operand with one address register (ex. g[$r1] or s[$r2+0x4])
+ if(o.get_double_operand_type() == 0 && o.is_memory_operand()){
const symbol *base_addr = o.get_symbol();
if( base_addr->is_reg() )
*ar1 = base_addr->reg_num();
@@ -700,6 +757,7 @@ void function_info::add_param_data( unsigned argn, struct gpgpu_ptx_sim_arg *arg
tmp.offset = args->m_offset;
tmp.type = 0;
i->second.add_data(tmp);
+ i->second.add_offset((unsigned) args->m_offset);
} else {
// This should only happen for OpenCL:
//
@@ -778,6 +836,30 @@ void function_info::finalize( memory_space *param_mem )
}
}
+void function_info::param_to_shared( memory_space *shared_mem, symbol_table *symtab )
+{
+/*copies parameters into simulated shared memory*/
+ for( std::map<unsigned,param_info>::iterator i=m_ptx_kernel_param_info.begin(); i!=m_ptx_kernel_param_info.end(); i++ ) {
+ param_info &p = i->second;
+ std::string name = p.get_name();
+ int type = p.get_type();
+ param_t value = p.get_value();
+ value.type = type;
+ symbol *param = symtab->lookup(name.c_str());
+ unsigned xtype = param->type()->get_key().scalar_type();
+ assert(xtype==(unsigned)type);
+
+ int tmp;
+ size_t size;
+ unsigned offset = p.get_offset();
+ type_info_key::type_decode(xtype,size,tmp);
+
+ // Write to shared memory - offset + 0x10
+ shared_mem->write(offset+0x10,size/8,&value,NULL,NULL);
+ }
+}
+
+
void function_info::list_param( FILE *fout ) const
{
for( std::map<unsigned,param_info>::const_iterator i=m_ptx_kernel_param_info.begin(); i!=m_ptx_kernel_param_info.end(); i++ ) {
@@ -827,17 +909,19 @@ unsigned datatype2size( unsigned data_type )
case F32_TYPE:
data_size = 4; break;
case B64_TYPE:
+ case BB64_TYPE:
case S64_TYPE:
case U64_TYPE:
case F64_TYPE:
data_size = 8; break;
+ case BB128_TYPE:
+ data_size = 16; break;
default: assert(0); break;
}
return data_size;
}
unsigned g_warp_active_mask;
-FILE *ptx_inst_debug_file;
void function_info::ptx_exec_inst( ptx_thread_info *thread,
addr_t *addr,
@@ -858,6 +942,11 @@ void function_info::ptx_exec_inst( ptx_thread_info *thread,
thread->clearRPC();
thread->m_last_set_operand_value.u64 = 0;
+ if(thread->is_done())
+ {
+ printf("attempted to execute instruction on a thread that is already done.\n");
+ assert(0);
+ }
if ( g_debug_execution >= 6 ) {
if ( (g_debug_thread_uid==0) || (thread->get_uid() == (unsigned)g_debug_thread_uid) ) {
thread->clear_modifiedregs();
@@ -866,8 +955,12 @@ void function_info::ptx_exec_inst( ptx_thread_info *thread,
}
if( pI->has_pred() ) {
const operand_info &pred = pI->get_pred();
- ptx_reg_t pred_value = thread->get_operand_value(pred);
- skip = !pred_value.pred ^ pI->get_pred_neg();
+ ptx_reg_t pred_value = thread->get_operand_value(pred, pred, PRED_TYPE, thread, 0);
+ if(pI->get_pred_mod() == -1) {
+ skip = (pred_value.pred & 0x0001) ^ pI->get_pred_neg(); //ptxplus inverts the zero flag
+ } else {
+ skip = !pred_lookup(pI->get_pred_mod(), pred_value.pred & 0x000F);
+ }
}
g_warp_active_mask = warp_active_mask;
if( !skip ) {
@@ -875,10 +968,28 @@ void function_info::ptx_exec_inst( ptx_thread_info *thread,
#define OP_DEF(OP,FUNC,STR,DST,CLASSIFICATION) case OP: FUNC(pI,thread); op_classification = CLASSIFICATION; break;
#include "opcodes.def"
#undef OP_DEF
- default:
- printf( "Execution error: Invalid opcode (0x%x)\n", pI->get_opcode() );
- break;
+
+ default:
+ printf( "Execution error: Invalid opcode (0x%x)\n", pI->get_opcode() );
+ break;
}
+
+ // Run exit instruction if exit option included
+ if(pI->is_exit())
+ exit_impl(pI,thread);
+ }
+
+ // Output instruction information to file and stdout
+ if( g_ptx_inst_debug_to_file != 0 &&
+ (g_ptx_inst_debug_thread_uid == 0 || g_ptx_inst_debug_thread_uid == thread->get_uid()) ) {
+ dim3 ctaid = thread->get_ctaid();
+ dim3 tid = thread->get_tid();
+ fprintf(ptx_inst_debug_file,
+ "[thd=%u] : (%s:%u - %s)\n",
+ thread->get_uid(),
+ pI->source_file(), pI->source_line(), pI->get_source() );
+ //fprintf(ptx_inst_debug_file, "has memory read=%d, has memory write=%d\n", pI->has_memory_read(), pI->has_memory_write());
+ fflush(ptx_inst_debug_file);
}
if ( ptx_debug_exec_dump_cond<5>(thread->get_uid(), pc) ) {
@@ -958,15 +1069,15 @@ void function_info::ptx_exec_inst( ptx_thread_info *thread,
if( g_ptx_inst_debug_to_file != 0 &&
(g_ptx_inst_debug_thread_uid == 0 || g_ptx_inst_debug_thread_uid == thread->get_uid()) ) {
thread->dump_modifiedregs(ptx_inst_debug_file);
- thread->dump_regs(ptx_inst_debug_file);
}
if ( g_debug_execution >= 6 ) {
if ( ptx_debug_exec_dump_cond<6>(thread->get_uid(), pc) )
- thread->dump_modifiedregs();
- } else if ( g_debug_execution >= 10 ) {
+ thread->dump_modifiedregs(stdout);
+ }
+ if ( g_debug_execution >= 10 ) {
if ( ptx_debug_exec_dump_cond<10>(thread->get_uid(), pc) )
- thread->dump_regs();
+ thread->dump_regs(stdout);
}
thread->update_pc();
g_ptx_sim_num_insn++;
@@ -1168,6 +1279,8 @@ unsigned ptx_sim_init_thread( ptx_thread_info** thread_info,int sid,unsigned tid
thd->set_ntid(g_cudaBlockDim.x,g_cudaBlockDim.y,g_cudaBlockDim.z);
thd->set_ctaid(g_gx,g_gy,g_gz);
thd->set_tid(tx,ty,tz);
+ if( g_entrypoint_func_info->get_ptx_version().extensions() )
+ thd->cpy_tid_to_reg(tx,ty,tz);
thd->set_hw_tid((unsigned)-1);
thd->set_hw_wid((unsigned)-1);
thd->set_hw_ctaid((unsigned)-1);
@@ -1175,6 +1288,9 @@ unsigned ptx_sim_init_thread( ptx_thread_info** thread_info,int sid,unsigned tid
thd->set_hw_sid((unsigned)-1);
thd->set_valid();
thd->m_shared_mem = shared_mem;
+ function_info *finfo = thd->func_info();
+ symbol_table *st = finfo->get_symtab();
+ thd->func_info()->param_to_shared(thd->m_shared_mem,st);
thd->m_cta_info = cta_info;
cta_info->add_thread(thd);
thd->m_local_mem = local_mem;
@@ -1691,7 +1807,7 @@ void ptx_dump_regs( void *thd )
if ( thd == NULL )
return;
ptx_thread_info *t = (ptx_thread_info *) thd;
- t->dump_regs();
+ t->dump_regs(stdout);
}
unsigned ptx_set_tex_cache_linesize(unsigned linesize)