summaryrefslogtreecommitdiff
path: root/src/cuda-sim/instructions.cc
diff options
context:
space:
mode:
authorTor Aamodt <[email protected]>2010-07-18 02:20:50 -0800
committerTor Aamodt <[email protected]>2010-07-18 02:20:50 -0800
commitcc404275f9226185e436e1da483ee58ee85c38ca (patch)
treee133be6f3a1bb897593328e438196a04dc88b47d /src/cuda-sim/instructions.cc
parent7e755bb656b68cfb628fcc0424b1325c32cb5d61 (diff)
- simple device printf support added (supports %u, %d, %f)
- add support to call_impl for passing values in through local param space (need to add support for return) - track local framesize during ptx parsing / update local stack-pointer during call/return - detect appropriate param space for ld.param (and st.param) depending upon address symbol's scope - putting back the crazy math for local mem allocation (seems to be required) - bug fix for global byte array initialization - force ld and st w/o space specifier to be generic_space - make type_decode method of type_info_key - adjust debug printing so listing of code and CFG information requires higher numbers (100 and 50) - local param ld/st accesses treated like local ld/st for timing model [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 6878]
Diffstat (limited to 'src/cuda-sim/instructions.cc')
-rw-r--r--src/cuda-sim/instructions.cc244
1 files changed, 170 insertions, 74 deletions
diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc
index 7606686..75dc072 100644
--- a/src/cuda-sim/instructions.cc
+++ b/src/cuda-sim/instructions.cc
@@ -74,6 +74,7 @@
#include "cuda-math.h"
#include "../abstract_hardware_model.h"
+#include <stdarg.h>
unsigned g_num_ptx_inst_uid=0;
unsigned cudasim_n_tex_insn=0;
@@ -390,7 +391,7 @@ void atom_callback( void* ptx_inst, void* thd )
unsigned to_type = pI->get_type();
size_t size;
int t;
- type_decode(to_type, size, t);
+ type_info_key::type_decode(to_type, size, t);
// Set up operand variables
ptx_reg_t data, // d
@@ -684,6 +685,45 @@ void brkpt_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not
extern int gpgpu_simd_model;
#define POST_DOMINATOR 1 /* must match enum value in shader.h */
void get_pdom_stack_top_info( unsigned sid, unsigned tid, unsigned *npc, unsigned *rpc );
+void decode_space( memory_space_t &space, ptx_thread_info *thread, const operand_info &op, memory_space *&mem, addr_t &addr);
+
+void my_cuda_printf(const char *fmtstr,const char *arg_list)
+{
+ FILE *fp = stdout;
+ unsigned i=0,j=0;
+ unsigned arg_offset=0;
+ char buf[64];
+ bool in_fmt=false;
+ while( fmtstr[i] ) {
+ char c = fmtstr[i++];
+ if( !in_fmt ) {
+ if( c != '%' ) {
+ fprintf(fp,"%c",c);
+ } else {
+ in_fmt=true;
+ buf[0] = c;
+ j=1;
+ }
+ } else {
+ if(!( c == 'u' || c == 'f' || c == 'd' )) {
+ printf("GPGPU-Sim PTX: ERROR ** printf parsing support is limited to %%u, %%f, %%d at present");
+ abort();
+ }
+ buf[j] = c;
+ buf[j+1] = 0;
+ unsigned long long value = ((unsigned long long*)arg_list)[arg_offset];
+ if( c == 'u' || c == 'd' ) {
+ fprintf(fp,buf,value);
+ } else if( c == 'f' ) {
+ double tmp = *(double*)(void*)&value;
+ fprintf(fp,buf,tmp);
+ }
+ arg_offset++;
+ in_fmt=false;
+ }
+ }
+}
+
void call_impl( const ptx_instruction *pI, ptx_thread_info *thread )
{
@@ -709,51 +749,114 @@ void call_impl( const ptx_instruction *pI, ptx_thread_info *thread )
" call instruction and function declaration\n");
abort();
}
-
// read source arguements into register specified in declaration of function
std::list< std::pair<const symbol*, ptx_reg_t> > arg_values;
for( unsigned arg=0; arg < n_args; arg ++ ) {
- const operand_info &op_info = pI->operand_lookup(n_return+1+arg);
- if( !op_info.is_reg() ) {
- printf("GPGPU-Sim PTX: Execution error - no support for non-register opernands for call/return\n");
- abort();
- }
- const symbol *dst_reg = target_func->get_arg(arg);
-
- ptx_reg_t src_value = thread->get_operand_value(op_info);
- arg_values.push_back( std::make_pair(dst_reg,src_value) );
- }
-
- // note register for corresponding return instruction to place result into
- const symbol *return_var_src = NULL;
- const symbol *return_var_dst = NULL;
- if( target_func->has_return() ) {
- if( !pI->dst().is_reg() ) {
- printf("GPGPU-Sim PTX: Execution error - no support for non-register dst reg for call\n");
- abort();
- }
- return_var_dst = pI->dst().get_symbol();
- return_var_src = target_func->get_return_var();
- }
-
- unsigned sid = thread->get_hw_sid();
- unsigned tid = thread->get_hw_tid();
- unsigned callee_pc=0, callee_rpc=0;
- if( gpgpu_simd_model == POST_DOMINATOR ) {
- get_pdom_stack_top_info(sid,tid,&callee_pc,&callee_rpc);
- assert( callee_pc == thread->get_pc() );
+ const operand_info &actual_param_op = pI->operand_lookup(n_return+1+arg);
+ const symbol *formal_param = target_func->get_arg(arg);
+ unsigned size=formal_param->get_size_in_bytes();
+ if( formal_param->is_reg() ) {
+ ptx_reg_t value;
+ if( actual_param_op.is_reg() )
+ value = thread->get_operand_value(actual_param_op);
+ else {
+ assert( actual_param_op.is_param_local() );
+ const symbol *actual_param = actual_param_op.get_symbol();
+ addr_t from_addr = thread->get_local_mem_stack_pointer() + actual_param->get_address();
+ assert(size<=sizeof(value.u64));
+ thread->m_local_mem->read(from_addr,size,&value.u64);
+ }
+ arg_values.push_back( std::make_pair(formal_param,value) );
+ } else {
+ assert( formal_param->is_param_local() );
+ // copy values to location in callee frame
+ addr_t to_addr = thread->get_local_mem_stack_pointer() +
+ thread->func_info()->local_mem_framesize() +
+ formal_param->get_address();
+ if( actual_param_op.is_reg() ) {
+ ptx_reg_t value = thread->get_operand_value(actual_param_op);
+ thread->m_local_mem->write(to_addr,size,&value.u64);
+ } else {
+ addr_t from_addr = actual_param_op.get_symbol()->get_address();
+ char buffer[1024];
+ assert(size<1024);
+ thread->m_local_mem->read(from_addr,size,buffer);
+ thread->m_local_mem->write(to_addr,size,buffer);
+ }
+ }
}
- thread->callstack_push(callee_pc+1,callee_rpc,return_var_src,return_var_dst,call_uid_next++);
-
std::list< std::pair<const symbol*, ptx_reg_t> >::iterator a;
- for( a=arg_values.begin(); a != arg_values.end(); a++ ) {
- const symbol *dst_reg = a->first;
- ptx_reg_t value = a->second;
- thread->set_operand_value(dst_reg,value);
+ std::string fname = target_func->get_name();
+ if( fname == "vprintf" ) {
+ char *fmtstr = NULL;
+ char *arg_list = NULL;
+ assert( n_args == 2 );
+ for( unsigned arg=0; arg < n_args; arg ++ ) {
+ const operand_info &actual_param_op = pI->operand_lookup(n_return+1+arg);
+ const symbol *formal_param = target_func->get_arg(arg);
+ unsigned size=formal_param->get_size_in_bytes();
+ assert( formal_param->is_param_local() );
+ assert( actual_param_op.is_param_local() );
+ addr_t from_addr = actual_param_op.get_symbol()->get_address();
+ char buffer[1024];
+ assert(size<1024);
+ thread->m_local_mem->read(from_addr,size,buffer);
+ addr_t addr = (addr_t)*(unsigned long long*)((void*)buffer); // should be pointer to generic memory location
+ memory_space *mem=NULL;
+ memory_space_t space = generic_space;
+ decode_space(space,thread,actual_param_op,mem,addr); // figure out which space
+ if( arg == 0 ) {
+ unsigned len = 0;
+ char b = 0;
+ do { // figure out length
+ mem->read(addr+len,1,&b);
+ len++;
+ } while(b);
+ fmtstr = (char*)malloc(len+64);
+ for( int i=0; i < len; i++ )
+ mem->read(addr+i,1,fmtstr+i);
+ //mem->read(addr,len,fmtstr);
+ } else {
+ unsigned len = thread->get_finfo()->local_mem_framesize();
+ arg_list = (char*)malloc(len+64);
+ for( int i=0; i < len; i++ )
+ mem->read(addr+i,1,arg_list+i);
+ //mem->read(addr,len,arg_list);
+ }
+ }
+ my_cuda_printf(fmtstr,arg_list);
+ free(fmtstr);
+ free(arg_list);
+ } else {
+ // note register for corresponding return instruction to place result into
+ const symbol *return_var_src = NULL;
+ const symbol *return_var_dst = NULL;
+ if( target_func->has_return() ) {
+ if( pI->dst().is_reg() ) {
+ return_var_dst = pI->dst().get_symbol();
+ return_var_src = target_func->get_return_var();
+ }
+ }
+
+ unsigned sid = thread->get_hw_sid();
+ unsigned tid = thread->get_hw_tid();
+ unsigned callee_pc=0, callee_rpc=0;
+ if( gpgpu_simd_model == POST_DOMINATOR ) {
+ get_pdom_stack_top_info(sid,tid,&callee_pc,&callee_rpc);
+ assert( callee_pc == thread->get_pc() );
+ }
+
+ thread->callstack_push(callee_pc+1,callee_rpc,return_var_src,return_var_dst,call_uid_next++);
+
+ for( a=arg_values.begin(); a != arg_values.end(); a++ ) {
+ const symbol *dst_reg = a->first;
+ ptx_reg_t value = a->second;
+ thread->set_operand_value(dst_reg,value);
+ }
+
+ thread->set_npc(target_func);
}
-
- thread->set_npc(target_func);
}
void clz_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); }
@@ -1133,32 +1236,6 @@ ptx_reg_t (*g_cvt_fn[11][11])( ptx_reg_t x, unsigned from_width, unsigned to_wid
{ d2x , d2x , d2x , d2x , d2x , d2x , d2x , d2x , d2x, d2x, d2d}
};
-unsigned type_decode( unsigned type, size_t &size, int &basic_type )
-{
- switch ( type ) {
- case S8_TYPE: size=8; basic_type=1; return 0;
- case S16_TYPE: size=16; basic_type=1; return 1;
- case S32_TYPE: size=32; basic_type=1; return 2;
- case S64_TYPE: size=64; basic_type=1; return 3;
- case U8_TYPE: size=8; basic_type=0; return 4;
- case U16_TYPE: size=16; basic_type=0; return 5;
- case U32_TYPE: size=32; basic_type=0; return 6;
- case U64_TYPE: size=64; basic_type=0; return 7;
- case F16_TYPE: size=16; basic_type=-1; return 8;
- case F32_TYPE: size=32; basic_type=-1; return 9;
- case F64_TYPE: size=64; basic_type=-1; return 10;
- case PRED_TYPE: size=1; basic_type=2; return 11;
- case B8_TYPE: size=8; basic_type=0; return 12;
- case B16_TYPE: size=16; basic_type=0; return 13;
- case B32_TYPE: size=32; basic_type=0; return 14;
- case B64_TYPE: size=64; basic_type=0; return 15;
- default:
- printf("ERROR ** type_decode() does not know about \"%s\"\n", g_ptx_token_decode[type].c_str() );
- assert(0);
- return 0xDEADBEEF;
- }
-}
-
void ptx_round(ptx_reg_t& data, int rounding_mode, int type)
{
if (rounding_mode == RN_OPTION) {
@@ -1309,8 +1386,8 @@ void cvt_impl( const ptx_instruction *pI, ptx_thread_info *thread )
int to_sign, from_sign;
size_t from_width, to_width;
- unsigned src_fmt = type_decode(from_type, from_width, from_sign);
- unsigned dst_fmt = type_decode(to_type, to_width, to_sign);
+ unsigned src_fmt = type_info_key::type_decode(from_type, from_width, from_sign);
+ unsigned dst_fmt = type_info_key::type_decode(to_type, to_width, to_sign);
ptx_reg_t data = thread->get_operand_value(src1);
if ( g_cvt_fn[src_fmt][dst_fmt] != NULL ) {
@@ -1458,10 +1535,25 @@ void isspacep_impl( const ptx_instruction *pI, ptx_thread_info *thread )
thread->set_operand_value(dst,p);
}
-void decode_space( memory_space_t &space, ptx_thread_info *thread, memory_space *&mem, addr_t &addr)
+void decode_space( memory_space_t &space, ptx_thread_info *thread, const operand_info &op, memory_space *&mem, addr_t &addr)
{
unsigned smid = thread->get_hw_sid();
unsigned hwtid = thread->get_hw_tid();
+
+ if( space == param_space_unclassified ) {
+ // need to op to determine whether it refers to a kernel param or local param
+ const symbol *s = op.get_symbol();
+ const type_info *t = s->type();
+ type_info_key ti = t->get_key();
+ if( ti.is_param_kernel() )
+ space = param_space_kernel;
+ else if( ti.is_param_local() ) {
+ space = param_space_local;
+ } else {
+ printf("GPGPU-Sim PTX: ERROR ** cannot resolve .param space for '%s'\n", s->name().c_str() );
+ abort();
+ }
+ }
switch ( space ) {
case global_space: mem = g_global_mem; break;
case param_space_local:
@@ -1474,7 +1566,7 @@ void decode_space( memory_space_t &space, ptx_thread_info *thread, memory_space
case param_space_kernel: mem = g_param_mem; break;
case shared_space: mem = thread->m_shared_mem; break;
case const_space: mem = g_global_mem; break;
- default:
+ case generic_space:
if( thread->get_ptx_version().ver() >= 2.0 ) {
// convert generic address to memory space address
space = whichspace(addr);
@@ -1488,6 +1580,10 @@ void decode_space( memory_space_t &space, ptx_thread_info *thread, memory_space
abort();
}
break;
+ case param_space_unclassified:
+ case undefined_space:
+ default:
+ abort();
}
}
@@ -1503,12 +1599,12 @@ void ld_impl( const ptx_instruction *pI, ptx_thread_info *thread )
memory_space *mem = NULL;
addr_t addr = src1_data.u32;
- decode_space(space,thread,mem,addr);
+ decode_space(space,thread,src1,mem,addr);
size_t size;
int t;
data.u64=0;
- type_decode(type,size,t);
+ type_info_key::type_decode(type,size,t);
if (!vector_spec) {
mem->read(addr,size/8,&data.s64);
if( type == S16_TYPE || type == S32_TYPE )
@@ -2640,11 +2736,11 @@ void st_impl( const ptx_instruction *pI, ptx_thread_info *thread )
memory_space *mem = NULL;
addr_t addr = addr_reg.u32;
- decode_space(space,thread,mem,addr);
+ decode_space(space,thread,dst,mem,addr);
size_t size;
int t;
- type_decode(type,size,t);
+ type_info_key::type_decode(type,size,t);
if (!vector_spec) {
data = thread->get_operand_value(src1);
@@ -2815,7 +2911,7 @@ void tex_impl( const ptx_instruction *pI, ptx_thread_info *thread )
unsigned tex_array_index;
float alpha=0, beta=0;
- type_decode(to_type,size,t);
+ type_info_key::type_decode(to_type,size,t);
tex_array_base = cuArray->devPtr32;
switch (dimension) {