summaryrefslogtreecommitdiff
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
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]
-rw-r--r--src/cuda-sim/cuda-sim.cc53
-rw-r--r--src/cuda-sim/instructions.cc244
-rw-r--r--src/cuda-sim/ptx_ir.cc62
-rw-r--r--src/cuda-sim/ptx_ir.h37
-rw-r--r--src/cuda-sim/ptx_sim.cc13
-rw-r--r--src/cuda-sim/ptx_sim.h5
-rw-r--r--src/gpgpu-sim/shader.cc9
7 files changed, 277 insertions, 146 deletions
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc
index 2f66d51..1326ccd 100644
--- a/src/cuda-sim/cuda-sim.cc
+++ b/src/cuda-sim/cuda-sim.cc
@@ -417,6 +417,9 @@ ptx_instruction::ptx_instruction( int opcode,
}
m_scalar_type = scalar_type;
m_space_spec = space_spec;
+ if( ( opcode == ST_OP || opcode == LD_OP ) && (space_spec == undefined_space) ) {
+ m_space_spec = generic_space;
+ }
m_source_file = file?file:"<unknown>";
m_source_line = line;
m_source = source;
@@ -459,7 +462,7 @@ function_info::function_info(int entry_point )
m_kernel_info.lmem = 0;
m_kernel_info.regs = 0;
m_kernel_info.smem = 0;
- m_local_mem_framesize = (unsigned)-1;
+ m_local_mem_framesize = 0;
}
void function_info::print_insn( unsigned pc, FILE * fp ) const
@@ -531,14 +534,14 @@ void function_info::ptx_assemble()
create_basic_blocks();
connect_basic_blocks();
- if ( g_debug_execution>=2 ) {
+ if ( g_debug_execution>=50 ) {
print_basic_blocks();
print_basic_block_links();
print_basic_block_dot();
}
find_postdominators();
find_ipostdominators();
- if ( g_debug_execution>=2 ) {
+ if ( g_debug_execution>=50 ) {
print_postdominators();
print_ipostdominators();
}
@@ -561,37 +564,36 @@ void gpgpu_ptx_sim_init_memory()
int load_static_globals( symbol_table *symtab, unsigned min_gaddr, unsigned max_gaddr)
{
- printf( "GPGPU-Sim PTX: loading global with explicit initializers... " );
+ printf( "GPGPU-Sim PTX: loading globals with explicit initializers... \n" );
fflush(stdout);
int ng_bytes=0;
symbol_table::iterator g=symtab->global_iterator_begin();
- bool below_image=true;
for ( ; g!=symtab->global_iterator_end(); g++) {
symbol *global = *g;
if ( global->has_initializer() ) {
+ printf( "GPGPU-Sim PTX: initializing '%s' ... ", global->name().c_str() );
+ unsigned addr=global->get_address();
+ const type_info *type = global->type();
+ type_info_key ti=type->get_key();
+ size_t size;
+ int t;
+ ti.type_decode(size,t);
+ int nbytes = size/8;
+ int offset=0;
std::list<operand_info> init_list = global->get_initializer();
for ( std::list<operand_info>::iterator i=init_list.begin(); i!=init_list.end(); i++ ) {
operand_info op = *i;
ptx_reg_t value = op.get_literal_value();
- int nbytes = 0;
- switch ( op.get_type() ) {
- case int_t: nbytes = 4; break;
- case float_op_t: nbytes = 4; break;
- case double_op_t: nbytes = 8; break;
- default:
- abort();
- }
- unsigned addr=global->get_address();
-
- assert( below_image && addr+nbytes < min_gaddr ); // min_gaddr is start of "heap" for cudaMalloc
-
- g_global_mem->write(addr,nbytes,&value);
+ assert( (addr+offset+nbytes) < min_gaddr ); // min_gaddr is start of "heap" for cudaMalloc
+ g_global_mem->write(addr+offset,nbytes,&value); // assuming little endian here
+ offset+=nbytes;
ng_bytes+=nbytes;
}
+ printf(" wrote %u bytes\n", offset );
}
}
- printf( " done.\n");
+ printf( "GPGPU-Sim PTX: finished loading globals (%u bytes total).\n", ng_bytes );
fflush(stdout);
return ng_bytes;
}
@@ -610,7 +612,7 @@ int load_constants( symbol_table *symtab, addr_t min_gaddr )
// get the constant element data size
int basic_type;
size_t num_bits;
- type_decode(constant->type()->get_key().scalar_type(),num_bits,basic_type);
+ constant->type()->get_key().type_decode(num_bits,basic_type);
std::list<operand_info> init_list = constant->get_initializer();
int nbytes_written = 0;
@@ -1378,20 +1380,23 @@ unsigned ptx_sim_init_thread( ptx_thread_info** thread_info,int sid,unsigned tid
}
std::map<unsigned,memory_space*> &local_mem_lookup = g_local_memory_lookup[sid];
+ unsigned new_tid;
for ( unsigned tz=0; tz < g_cudaBlockDim.z; tz++ ) {
for ( unsigned ty=0; ty < g_cudaBlockDim.y; ty++ ) {
for ( unsigned tx=0; tx < g_cudaBlockDim.x; tx++ ) {
+ new_tid = tx + g_cudaBlockDim.x*ty + g_cudaBlockDim.x*g_cudaBlockDim.y*tz;
+ new_tid += tid;
ptx_thread_info *thd = new ptx_thread_info();
memory_space *local_mem = NULL;
- std::map<unsigned,memory_space*>::iterator l = local_mem_lookup.find(tid);
+ std::map<unsigned,memory_space*>::iterator l = local_mem_lookup.find(new_tid);
if ( l != local_mem_lookup.end() ) {
local_mem = l->second;
} else {
char buf[512];
- snprintf(buf,512,"local_%u_%u", sid, tid);
+ snprintf(buf,512,"local_%u_%u", sid, new_tid);
local_mem = new memory_space_impl<32>(buf,32);
- local_mem_lookup[tid] = local_mem;
+ local_mem_lookup[new_tid] = local_mem;
}
thd->set_info(g_entrypoint_symbol_table,g_entrypoint_func_info);
thd->set_nctaid(g_cudaGridDim.x,g_cudaGridDim.y,g_cudaGridDim.z);
@@ -1835,7 +1840,7 @@ void gpgpu_ptx_sim_load_ptx_from_string( const char *p, unsigned source_num )
exit(40);
}
- if ( g_debug_execution >= 1 )
+ if ( g_debug_execution >= 100 )
print_ptx_file(p,source_num,g_filename);
printf("GPGPU-Sim PTX: finished parsing EMBEDDED .ptx file %s\n",g_filename);
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) {
diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc
index 2597ac5..1bf9c95 100644
--- a/src/cuda-sim/ptx_ir.cc
+++ b/src/cuda-sim/ptx_ir.cc
@@ -364,7 +364,7 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident
int regnum;
size_t num_bits;
unsigned addr, addr_pad;
- type_decode(ti.scalar_type(),num_bits,basic_type);
+ ti.type_decode(num_bits,basic_type);
bool duplicates = check_for_duplicates( identifier );
if( duplicates ) {
@@ -389,7 +389,7 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident
default:
break;
}
- g_last_symbol = g_current_symbol_table->add_variable(identifier,type,g_filename,ptx_lineno);
+ g_last_symbol = g_current_symbol_table->add_variable(identifier,type,num_bits/8,g_filename,ptx_lineno);
switch ( ti.get_memory_space() ) {
case reg_space: {
regnum = g_current_symbol_table->next_reg_num();
@@ -463,6 +463,7 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident
assert( (num_bits%8) == 0 );
g_last_symbol->set_address( g_current_symbol_table->get_local_next() );
g_current_symbol_table->alloc_local( num_bits/8 );
+ g_func_info->set_framesize( g_current_symbol_table->get_local_next() );
break;
case tex_space:
printf("GPGPU-Sim PTX: encountered texture directive %s.\n", identifier);
@@ -476,6 +477,7 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident
assert( (num_bits%8) == 0 );
g_last_symbol->set_address( g_current_symbol_table->get_local_next() );
g_current_symbol_table->alloc_local( num_bits/8 );
+ g_func_info->set_framesize( g_current_symbol_table->get_local_next() );
break;
case param_space_kernel:
break;
@@ -488,16 +490,6 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident
if ( ti.is_param_kernel() ) {
g_func_info->add_param_name_type_size(g_entry_func_param_index,identifier, ti.scalar_type(), num_bits );
g_entry_func_param_index++;
- } else if ( ti.is_param_local() ) {
- printf("GPGPU-Sim PTX: allocating stack frame region for input/output .param \"%s\" from 0x%x to 0x%lx\n",
- identifier,
- g_current_symbol_table->get_local_next(),
- g_current_symbol_table->get_local_next() + num_bits/8 );
- fflush(stdout);
- assert( (num_bits%8) == 0 );
- addr_t addr = g_current_symbol_table->get_local_next();
- g_last_symbol->set_address( addr );
- g_current_symbol_table->alloc_local( num_bits/8 );
}
}
@@ -564,7 +556,7 @@ void add_label( const char *identifier )
if ( s != NULL ) {
g_label = s;
} else {
- g_label = g_current_symbol_table->add_variable(identifier,NULL,g_filename,ptx_lineno);
+ g_label = g_current_symbol_table->add_variable(identifier,NULL,0,g_filename,ptx_lineno);
}
}
@@ -659,7 +651,7 @@ void add_scalar_operand( const char *identifier )
if ( s == NULL ) {
if ( g_opcode == BRA_OP ) {
// forward branch target...
- s = g_current_symbol_table->add_variable(identifier,NULL,g_filename,ptx_lineno);
+ s = g_current_symbol_table->add_variable(identifier,NULL,0,g_filename,ptx_lineno);
} else {
std::string msg = std::string("operand \"") + identifier + "\" has no declaration.";
parse_error( msg.c_str() );
@@ -673,7 +665,7 @@ void add_neg_pred_operand( const char *identifier )
DPRINTF("add_neg_pred_operand");
const symbol *s = g_current_symbol_table->lookup(identifier);
if ( s == NULL ) {
- s = g_current_symbol_table->add_variable(identifier,NULL,g_filename,ptx_lineno);
+ s = g_current_symbol_table->add_variable(identifier,NULL,1,g_filename,ptx_lineno);
}
operand_info op(s);
op.set_neg_pred();
@@ -777,13 +769,13 @@ symbol *symbol_table::lookup( const char *identifier )
return NULL;
}
-symbol *symbol_table::add_variable( const char *identifier, const type_info *type, const char *filename, unsigned line )
+symbol *symbol_table::add_variable( const char *identifier, const type_info *type, unsigned size, const char *filename, unsigned line )
{
char buf[1024];
std::string key(identifier);
assert( m_symbols.find(key) == m_symbols.end() );
snprintf(buf,1024,"%s:%u",filename,line);
- symbol *s = new symbol(identifier,type,buf);
+ symbol *s = new symbol(identifier,type,buf,size);
m_symbols[ key ] = s;
if ( type != NULL && type->get_key().is_global() ) {
@@ -804,7 +796,7 @@ void symbol_table::add_function( function_info *func )
char buf[1024];
snprintf(buf,1024,"%s:%u",g_filename,ptx_lineno);
type_info *type = add_type( func );
- symbol *s = new symbol(func->get_name().c_str(),type,buf);
+ symbol *s = new symbol(func->get_name().c_str(),type,buf,0);
s->set_function(func);
m_symbols[ func->get_name() ] = s;
}
@@ -828,7 +820,7 @@ bool symbol_table::add_function_decl( const char *name, int entry_point, functio
} else {
assert( !prior_decl );
*sym_table = new symbol_table( "", entry_point, g_global_symbol_table );
- symbol *null_reg = (*sym_table)->add_variable("_",NULL,"",0);
+ symbol *null_reg = (*sym_table)->add_variable("_",NULL,0,"",0);
null_reg->set_regno(0, 0);
(*sym_table)->set_name(name);
(*func_info)->set_symtab(*sym_table);
@@ -1336,3 +1328,35 @@ unsigned ptx_kernel_nregs( void *kernel_impl )
const struct gpgpu_ptx_sim_kernel_info *kernel_info = f->get_kernel_info();
return kernel_info->regs;
}
+
+unsigned type_info_key::type_decode( size_t &size, int &basic_type ) const
+{
+ int type = scalar_type();
+ return type_decode(type,size,basic_type);
+}
+
+unsigned type_info_key::type_decode( int 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;
+ }
+}
diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h
index 8f3d48e..4361cb0 100644
--- a/src/cuda-sim/ptx_ir.h
+++ b/src/cuda-sim/ptx_ir.h
@@ -113,10 +113,8 @@ public:
m_is_function = 1;
}
- void set_array_dim( int array_dim )
- {
- m_array_dim = array_dim;
- }
+ void set_array_dim( int array_dim ) { m_array_dim = array_dim; }
+ int get_array_dim() const { assert(m_init); return m_array_dim; }
bool is_reg() const { return m_space_spec == reg_space;}
bool is_param_kernel() const { return m_space_spec == param_space_kernel;}
@@ -129,6 +127,8 @@ public:
bool is_tex() const { return m_space_spec == tex_space;}
bool is_func_addr() const { return m_is_function?true:false; }
int scalar_type() const { return m_scalar_type_spec;}
+ unsigned type_decode( size_t &size, int &t ) const;
+ static unsigned type_decode( int type, size_t &size, int &t );
memory_space_t get_memory_space() const { return m_space_spec; }
private:
bool m_init;
@@ -184,12 +184,13 @@ class operand_info;
class symbol {
public:
- symbol( const char *name, const type_info *type, const char *location )
+ symbol( const char *name, const type_info *type, const char *location, unsigned size )
{
m_uid = get_uid();
m_name = name;
m_decl_location = location;
m_type = type;
+ m_size = size;
m_address_valid = false;
m_is_label = false;
m_is_shared = false;
@@ -209,6 +210,10 @@ public:
if ( type ) m_is_tex = type->get_key().is_tex();
if ( type ) m_is_func_addr = type->get_key().is_func_addr();
}
+ unsigned get_size_in_bytes() const
+ {
+ return m_size;
+ }
const std::string &name() const { return m_name;}
const std::string &decl_location() const { return m_decl_location;}
const type_info *type() const { return m_type;}
@@ -254,6 +259,11 @@ public:
bool is_param_local() const { return m_is_param_local; }
bool is_tex() const { return m_is_tex;}
bool is_func_addr() const { return m_is_func_addr; }
+ bool is_reg() const {
+ if( m_type == NULL )
+ return false;
+ return m_type->get_key().is_reg();
+ }
void add_initializer( const std::list<operand_info> &init );
bool has_initializer() const
@@ -280,6 +290,7 @@ private:
unsigned get_uid();
unsigned m_uid;
const type_info *m_type;
+ unsigned m_size; // in bytes
std::string m_name;
std::string m_decl_location;
@@ -312,7 +323,7 @@ public:
void set_ptx_version( float ver, unsigned ext );
symbol* lookup( const char *identifier );
std::string get_scope_name() const { return m_scope_name; }
- symbol *add_variable( const char *identifier, const type_info *type, const char *filename, unsigned line );
+ symbol *add_variable( const char *identifier, const type_info *type, unsigned size, const char *filename, unsigned line );
void add_function( function_info *func );
bool add_function_decl( const char *name, int entry_point, function_info **func_info, symbol_table **symbol_table );
type_info *add_type( memory_space_t space_spec, int scalar_type_spec, int vector_spec, int alignment_spec, int extern_spec );
@@ -534,6 +545,12 @@ public:
}
return m_value.m_symbolic->type()->get_key().is_reg();
}
+ bool is_param_local() const
+ {
+ if ( m_type != symbolic_t )
+ return false;
+ return m_value.m_symbolic->type()->get_key().is_param_local();
+ }
bool is_vector() const
{
@@ -891,7 +908,7 @@ public:
{
m_symtab = symtab;
}
- std::string get_name()
+ std::string get_name() const
{
return m_name;
}
@@ -1016,9 +1033,13 @@ public:
}
unsigned local_mem_framesize() const
{
- assert( m_local_mem_framesize != (unsigned) -1 );
return m_local_mem_framesize;
}
+ void set_framesize( unsigned sz )
+ {
+ m_local_mem_framesize = sz;
+ }
+ bool is_entry_point() const { return m_entry_point; }
private:
unsigned m_uid;
diff --git a/src/cuda-sim/ptx_sim.cc b/src/cuda-sim/ptx_sim.cc
index 85e6185..dffc128 100644
--- a/src/cuda-sim/ptx_sim.cc
+++ b/src/cuda-sim/ptx_sim.cc
@@ -358,6 +358,7 @@ void ptx_thread_info::callstack_push( unsigned pc, unsigned rpc, const symbol *r
m_last_was_call = true;
m_callstack.push_back( stack_entry(m_symbol_table,m_func_info,pc,rpc,return_var_src,return_var_dst,call_uid) );
m_regs.push_back( reg_map_t() );
+ m_local_mem_stack_pointer += m_func_info->local_mem_framesize();
}
#define POST_DOMINATOR 1 /* must match definition in shader.h */
@@ -368,7 +369,9 @@ extern void set_operand_value( const symbol *dst, const ptx_reg_t &data );
bool ptx_thread_info::callstack_pop()
{
assert( !m_callstack.empty() );
+ assert( m_local_mem_stack_pointer >= m_func_info->local_mem_framesize() );
m_func_info = m_callstack.back().m_func_info;
+ m_local_mem_stack_pointer -= m_func_info->local_mem_framesize();
m_symbol_table = m_callstack.back().m_symbol_table;
m_NPC = m_callstack.back().m_PC;
m_RPC_updated = true;
@@ -448,16 +451,6 @@ void ptx_thread_info::dump_modifiedregs()
}
}
-void ptx_thread_info::push_local_mem_stack()
-{
- m_local_mem_stack_pointer += m_func_info->local_mem_framesize();
-}
-
-void ptx_thread_info::pop_local_mem_stack()
-{
- m_local_mem_stack_pointer -= m_func_info->local_mem_framesize();
-}
-
void ptx_thread_info::set_npc( const function_info *f )
{
m_NPC = f->get_start_PC();
diff --git a/src/cuda-sim/ptx_sim.h b/src/cuda-sim/ptx_sim.h
index d4bdf48..db38ced 100644
--- a/src/cuda-sim/ptx_sim.h
+++ b/src/cuda-sim/ptx_sim.h
@@ -423,10 +423,7 @@ public:
function_info *get_finfo() { return m_func_info; }
void enable_debug_trace() { m_enable_debug_trace = true; }
-
unsigned get_local_mem_stack_pointer() const { return m_local_mem_stack_pointer; }
- void push_local_mem_stack();
- void pop_local_mem_stack();
public:
addr_t m_last_effective_address;
@@ -477,8 +474,6 @@ private:
reg_map_t m_debug_trace_regs_modified; // track the modified register for each executed insn
};
-unsigned type_decode( unsigned type, size_t &size, int &t );
-
addr_t generic_to_local( unsigned smid, unsigned hwtid, addr_t addr );
addr_t generic_to_shared( unsigned smid, addr_t addr );
addr_t generic_to_global( addr_t addr );
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 3f084f8..05a8b0e 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -1659,8 +1659,7 @@ inline int is_const ( memory_space_t space ) {
}
inline int is_local ( memory_space_t space ) {
- assert( space != param_space_local ); // todo: map local param memory to linear address space
- return((space) == local_space);
+ return (space == local_space) || (space == param_space_local);
}
inline int is_param ( memory_space_t space ) {
@@ -2481,12 +2480,10 @@ mem_stage_stall_type send_mem_request(shader_core_ctx_t *shader, mem_access_t &a
access_type = (access.iswrite)? GLOBAL_ACC_W: GLOBAL_ACC_R;
break;
case local_space:
+ case param_space_local:
code = DCACHE;
access_type = (access.iswrite)? LOCAL_ACC_W: LOCAL_ACC_R;
break;
- case param_space_local:
- abort(); // todo: define mapping of local param space to linear memory ?
- break;
default:
assert(0); // NOT A MEM SPACE;
break;
@@ -2837,10 +2834,10 @@ void shader_memory_queue(shader_core_ctx_t *shader, shader_queues_t *accessqs)
break;
case global_space:
case local_space:
+ case param_space_local:
path[i] = GLOBAL_MEM_PATH;
type_counts[GLOBAL_MEM_PATH]++;
break;
- case param_space_local:
case param_space_unclassified:
abort(); // todo: define access details
break;