summaryrefslogtreecommitdiff
path: root/src/cuda-sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/cuda-sim')
-rw-r--r--src/cuda-sim/cuda-sim.cc25
-rw-r--r--src/cuda-sim/instructions.cc97
-rw-r--r--src/cuda-sim/ptx.l6
-rw-r--r--src/cuda-sim/ptx.y8
-rw-r--r--src/cuda-sim/ptx_ir.cc18
-rw-r--r--src/cuda-sim/ptx_ir.h9
-rw-r--r--src/cuda-sim/ptx_sim.cc5
-rw-r--r--src/cuda-sim/ptx_sim.h26
8 files changed, 147 insertions, 47 deletions
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc
index f8a8db0..705a80a 100644
--- a/src/cuda-sim/cuda-sim.cc
+++ b/src/cuda-sim/cuda-sim.cc
@@ -294,6 +294,7 @@ ptx_instruction::ptx_instruction( int opcode,
m_lo = false;
m_uni = false;
m_to_option = false;
+ m_cache_option = 0;
m_rounding_mode = RN_OPTION;
m_compare_op = -1;
m_saturation_mode = 0;
@@ -405,6 +406,9 @@ ptx_instruction::ptx_instruction( int opcode,
case TO_OPTION:
m_to_option = true;
break;
+ case CA_OPTION: case CG_OPTION: case CS_OPTION: case LU_OPTION: case CV_OPTION:
+ m_cache_option = last_ptx_inst_option;
+ break;
default:
assert(0);
@@ -655,6 +659,11 @@ addr_t shared_to_generic( unsigned smid, addr_t addr )
return SHARED_GENERIC_START + smid*SHARED_MEM_SIZE_MAX + addr;
}
+addr_t global_to_generic( addr_t addr )
+{
+ return addr;
+}
+
bool isspace_shared( unsigned smid, addr_t addr )
{
addr_t start = SHARED_GENERIC_START + smid*SHARED_MEM_SIZE_MAX;
@@ -669,6 +678,17 @@ bool isspace_global( addr_t addr )
return (addr > GLOBAL_HEAP_START) || (addr < STATIC_ALLOC_LIMIT);
}
+unsigned whichspace( addr_t addr )
+{
+ if( (addr > GLOBAL_HEAP_START) || (addr < STATIC_ALLOC_LIMIT) ) {
+ return GLOBAL_DIRECTIVE;
+ } else if( addr > SHARED_GENERIC_START ) {
+ return SHARED_DIRECTIVE;
+ } else {
+ return LOCAL_DIRECTIVE;
+ }
+}
+
addr_t generic_to_shared( unsigned smid, addr_t addr )
{
assert(isspace_shared(smid,addr));
@@ -696,6 +716,11 @@ addr_t generic_to_local( unsigned smid, unsigned hwtid, addr_t addr )
return addr - (LOCAL_GENERIC_START + (TOTAL_LOCAL_MEM_PER_SM * smid) + (LOCAL_MEM_SIZE_MAX * hwtid));
}
+addr_t generic_to_global( addr_t addr )
+{
+ return addr;
+}
+
unsigned long long g_dev_malloc=GLOBAL_HEAP_START;
diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc
index ffbcd8f..60ff83d 100644
--- a/src/cuda-sim/instructions.cc
+++ b/src/cuda-sim/instructions.cc
@@ -1345,14 +1345,14 @@ void cvta_impl( const ptx_instruction *pI, ptx_thread_info *thread )
switch( space ) {
case SHARED_DIRECTIVE: to_addr_hw = generic_to_shared( smid, from_addr_hw ); break;
case LOCAL_DIRECTIVE: to_addr_hw = generic_to_local( smid, hwtid, from_addr_hw ); break;
- case GLOBAL_DIRECTIVE: to_addr_hw = from_addr_hw; break;
+ case GLOBAL_DIRECTIVE: to_addr_hw = generic_to_global(from_addr_hw ); break;
default: abort();
}
} else {
switch( space ) {
case SHARED_DIRECTIVE: to_addr_hw = shared_to_generic( smid, from_addr_hw ); break;
- case LOCAL_DIRECTIVE: to_addr_hw = local_to_generic( smid, hwtid, from_addr_hw ); break;
- case GLOBAL_DIRECTIVE: to_addr_hw = from_addr_hw; break;
+ case LOCAL_DIRECTIVE: to_addr_hw = local_to_generic( smid, hwtid, from_addr_hw ); break;
+ case GLOBAL_DIRECTIVE: to_addr_hw = global_to_generic( from_addr_hw ); break;
default: abort();
}
}
@@ -1463,6 +1463,34 @@ void isspacep_impl( const ptx_instruction *pI, ptx_thread_info *thread )
thread->set_operand_value(dst,p);
}
+void decode_space( unsigned &space, ptx_thread_info *thread, memory_space *&mem, addr_t &addr)
+{
+ unsigned smid = thread->get_hw_sid();
+ unsigned hwtid = thread->get_hw_tid();
+ switch ( space ) {
+ case GLOBAL_DIRECTIVE: mem = g_global_mem; break;
+ case LOCAL_DIRECTIVE: mem = thread->m_local_mem; break;
+ case TEX_DIRECTIVE: mem = g_tex_mem; break;
+ case SURF_DIRECTIVE: mem = g_surf_mem; break;
+ case PARAM_DIRECTIVE: mem = g_param_mem; break;
+ case SHARED_DIRECTIVE: mem = thread->m_shared_mem; break;
+ case CONST_DIRECTIVE: mem = g_global_mem; break;
+ default:
+ if( thread->get_ptx_version().ver() >= 2.0 ) {
+ // convert generic address to memory space address
+ space = whichspace(addr);
+ switch ( space ) {
+ case GLOBAL_DIRECTIVE: mem = g_global_mem; addr = generic_to_global(addr); break;
+ case LOCAL_DIRECTIVE: mem = thread->m_local_mem; addr = generic_to_local(smid,hwtid,addr); break;
+ case SHARED_DIRECTIVE: mem = thread->m_shared_mem; addr = generic_to_shared(smid,addr); break;
+ default: abort();
+ }
+ } else {
+ abort();
+ }
+ break;
+ }
+}
void ld_impl( const ptx_instruction *pI, ptx_thread_info *thread )
{
@@ -1474,44 +1502,34 @@ void ld_impl( const ptx_instruction *pI, ptx_thread_info *thread )
unsigned vector_spec = pI->get_vector();
unsigned type = pI->get_type();
memory_space *mem = NULL;
+ addr_t addr = src1_data.u32;
- switch ( space ) {
- case GLOBAL_DIRECTIVE: mem = g_global_mem; break;
- case LOCAL_DIRECTIVE: mem = thread->m_local_mem; break;
- case TEX_DIRECTIVE: mem = g_tex_mem; break;
- case SURF_DIRECTIVE: mem = g_surf_mem; break;
- case PARAM_DIRECTIVE: mem = g_param_mem; break;
- case SHARED_DIRECTIVE: mem = thread->m_shared_mem; break;
- case CONST_DIRECTIVE: mem = g_global_mem; break;
- default:
- assert(0);
- break;
- }
+ decode_space(space,thread,mem,addr);
size_t size;
int t;
data.u64=0;
type_decode(type,size,t);
if (!vector_spec) {
- mem->read(src1_data.u32,size/8,&data.s64);
+ mem->read(addr,size/8,&data.s64);
if( type == S16_TYPE || type == S32_TYPE )
sign_extend(data,size,dst);
thread->set_operand_value(dst,data);
} else {
ptx_reg_t data1, data2, data3, data4;
- mem->read(src1_data.u32,size/8,&data1.s64);
- mem->read(src1_data.u32+size/8,size/8,&data2.s64);
+ mem->read(addr,size/8,&data1.s64);
+ mem->read(addr+size/8,size/8,&data2.s64);
if (vector_spec != V2_TYPE) { //either V3 or V4
- mem->read(src1_data.u32+2*size/8,size/8,&data3.s64);
+ mem->read(addr+2*size/8,size/8,&data3.s64);
if (vector_spec != V3_TYPE) { //v4
- mem->read(src1_data.u32+3*size/8,size/8,&data4.s64);
+ mem->read(addr+3*size/8,size/8,&data4.s64);
thread->set_vector_operand_values(dst,data1,data2,data3,data4, 4);
} else //v3
thread->set_vector_operand_values(dst,data1,data2,data3,data3,3);
} else //v2
thread->set_vector_operand_values(dst,data1,data2,data2,data2,2);
}
- thread->m_last_effective_address = src1_data.u32;
+ thread->m_last_effective_address = addr;
thread->m_last_memory_space = space;
}
@@ -2615,24 +2633,15 @@ void st_impl( const ptx_instruction *pI, ptx_thread_info *thread )
{
const operand_info &dst = pI->dst();
const operand_info &src1 = pI->src1(); //may be scalar or vector of regs
- ptx_reg_t addr = thread->get_operand_value(dst);
+ ptx_reg_t addr_reg = thread->get_operand_value(dst);
ptx_reg_t data;
unsigned space = pI->get_space();
unsigned vector_spec = pI->get_vector();
unsigned type = pI->get_type();
memory_space *mem = NULL;
+ addr_t addr = addr_reg.u32;
- switch ( space ) {
- case GLOBAL_DIRECTIVE: mem = g_global_mem; break;
- case LOCAL_DIRECTIVE: mem = thread->m_local_mem; break;
- case TEX_DIRECTIVE: mem = g_tex_mem; break;
- case SURF_DIRECTIVE: mem = g_surf_mem; break;
- case PARAM_DIRECTIVE: mem = g_param_mem; break;
- case SHARED_DIRECTIVE: mem = thread->m_shared_mem; break;
- default:
- assert(0);
- break;
- }
+ decode_space(space,thread,mem,addr);
size_t size;
int t;
@@ -2640,34 +2649,34 @@ void st_impl( const ptx_instruction *pI, ptx_thread_info *thread )
if (!vector_spec) {
data = thread->get_operand_value(src1);
- mem->write(addr.u32,size/8,&data.s64);
+ mem->write(addr,size/8,&data.s64);
} else {
if (vector_spec == V2_TYPE) {
ptx_reg_t* ptx_regs = new ptx_reg_t[2];
thread->get_vector_operand_values(src1, ptx_regs, 2);
- mem->write(addr.u32,size/8,&ptx_regs[0].s64);
- mem->write(addr.u32+size/8,size/8,&ptx_regs[1].s64);
+ mem->write(addr,size/8,&ptx_regs[0].s64);
+ mem->write(addr+size/8,size/8,&ptx_regs[1].s64);
free(ptx_regs);
}
if (vector_spec == V3_TYPE) {
ptx_reg_t* ptx_regs = new ptx_reg_t[3];
thread->get_vector_operand_values(src1, ptx_regs, 3);
- mem->write(addr.u32,size/8,&ptx_regs[0].s64);
- mem->write(addr.u32+size/8,size/8,&ptx_regs[1].s64);
- mem->write(addr.u32+2*size/8,size/8,&ptx_regs[2].s64);
+ mem->write(addr,size/8,&ptx_regs[0].s64);
+ mem->write(addr+size/8,size/8,&ptx_regs[1].s64);
+ mem->write(addr+2*size/8,size/8,&ptx_regs[2].s64);
free(ptx_regs);
}
if (vector_spec == V4_TYPE) {
ptx_reg_t* ptx_regs = new ptx_reg_t[4];
thread->get_vector_operand_values(src1, ptx_regs, 4);
- mem->write(addr.u32,size/8,&ptx_regs[0].s64);
- mem->write(addr.u32+size/8,size/8,&ptx_regs[1].s64);
- mem->write(addr.u32+2*size/8,size/8,&ptx_regs[2].s64);
- mem->write(addr.u32+3*size/8,size/8,&ptx_regs[3].s64);
+ mem->write(addr,size/8,&ptx_regs[0].s64);
+ mem->write(addr+size/8,size/8,&ptx_regs[1].s64);
+ mem->write(addr+2*size/8,size/8,&ptx_regs[2].s64);
+ mem->write(addr+3*size/8,size/8,&ptx_regs[3].s64);
free(ptx_regs);
}
}
- thread->m_last_effective_address = addr.u32;
+ thread->m_last_effective_address = addr;
thread->m_last_memory_space = space;
}
diff --git a/src/cuda-sim/ptx.l b/src/cuda-sim/ptx.l
index 4711470..21f8b08 100644
--- a/src/cuda-sim/ptx.l
+++ b/src/cuda-sim/ptx.l
@@ -307,6 +307,12 @@ xor TC; ptx_lval.int_value = XOR_OP; return OPCODE;
\.to TC; return TO_OPTION;
+\.ca TC; return CA_OPTION;
+\.cg TC; return CG_OPTION;
+\.cs TC; return CS_OPTION;
+\.lu TC; return LU_OPTION;
+\.cv TC; return CV_OPTION;
+
\.and TC; return ATOMIC_AND;
\.or TC; return ATOMIC_OR;
\.xor TC; return ATOMIC_XOR;
diff --git a/src/cuda-sim/ptx.y b/src/cuda-sim/ptx.y
index 7b4c17a..5711b94 100644
--- a/src/cuda-sim/ptx.y
+++ b/src/cuda-sim/ptx.y
@@ -196,6 +196,12 @@
%token GLOBAL_OPTION
%token CTA_OPTION
%token TO_OPTION
+%token CA_OPTION;
+%token CG_OPTION;
+%token CS_OPTION;
+%token LU_OPTION;
+%token CV_OPTION;
+
%type <int_value> function_decl_header
%type <ptr_value> function_decl
@@ -252,7 +258,7 @@ statement_list: directive_statement { add_directive(); }
;
directive_statement: variable_declaration SEMI_COLON
- | VERSION_DIRECTIVE DOUBLE_OPERAND
+ | VERSION_DIRECTIVE DOUBLE_OPERAND { add_version_info($2); }
| TARGET_DIRECTIVE IDENTIFIER COMMA IDENTIFIER
| TARGET_DIRECTIVE IDENTIFIER
| FILE_DIRECTIVE INT_OPERAND STRING { add_file($2,$3); }
diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc
index 79dc2b0..d5e8df2 100644
--- a/src/cuda-sim/ptx_ir.cc
+++ b/src/cuda-sim/ptx_ir.cc
@@ -731,6 +731,18 @@ void symbol_table::set_name( const char *name )
m_scope_name = std::string(name);
}
+const ptx_version &symbol_table::get_ptx_version() const
+{
+ if( m_parent == NULL ) return m_ptx_version;
+ else return m_parent->get_ptx_version();
+}
+
+void symbol_table::set_ptx_version( float ver, unsigned ext )
+{
+ m_ptx_version = ptx_version(ver,ext);
+ assert( m_ptx_version.ver() < 3 );
+}
+
symbol *symbol_table::lookup( const char *identifier )
{
std::string key(identifier);
@@ -1241,6 +1253,12 @@ void function_info::print_basic_block_dot()
printf("}\n");
}
+extern "C" void add_version_info( float ver )
+{
+ g_global_symbol_table->set_ptx_version(ver,0);
+}
+
+
extern "C" void add_file( unsigned num, const char *filename )
{
if( g_filename == NULL ) {
diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h
index 3f2080b..bdcd1a4 100644
--- a/src/cuda-sim/ptx_ir.h
+++ b/src/cuda-sim/ptx_ir.h
@@ -313,12 +313,13 @@ private:
static unsigned sm_next_uid;
};
-
class symbol_table {
public:
symbol_table();
symbol_table( const char *scope_name, unsigned entry_point, symbol_table *parent );
void set_name( const char *name );
+ const ptx_version &get_ptx_version() const;
+ 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 );
@@ -359,6 +360,7 @@ private:
unsigned m_tex_next;
symbol_table *m_parent;
+ ptx_version m_ptx_version;
std::string m_scope_name;
std::map<std::string, symbol *> m_symbols; //map from name of register to pointers to the registers
std::map<type_info_key,type_info*,type_info_key_compare> m_types;
@@ -682,7 +684,6 @@ public:
const char *file,
unsigned line,
const char *source );
-
void print_insn() const;
void print_insn( FILE *fp ) const;
unsigned uid() const { return m_uid;}
@@ -808,6 +809,7 @@ public:
bool is_wide() const { return m_wide;}
bool is_uni() const { return m_uni;}
bool is_to() const { return m_to_option; }
+ unsigned cache_option() const { return m_cache_option; }
unsigned rounding_mode() const { return m_rounding_mode;}
unsigned saturation_mode() const { return m_saturation_mode;}
unsigned dimension() const { return m_geom_spec;}
@@ -838,6 +840,7 @@ private:
bool m_lo;
bool m_uni; //if branch instruction, this evaluates to true for uniform branches (ie jumps)
bool m_to_option;
+ unsigned m_cache_option;
unsigned m_rounding_mode;
unsigned m_compare_op;
unsigned m_saturation_mode;
@@ -882,6 +885,7 @@ private:
class function_info {
public:
function_info(int entry_point );
+ const ptx_version &get_ptx_version() const { return m_symtab->get_ptx_version(); }
bool is_extern() const { return m_extern; }
void set_name(const char *name)
{
@@ -1204,6 +1208,7 @@ extern "C" {
void add_alignment_spec( int spec );
void add_array_initializer();
void add_file( unsigned num, const char *filename );
+ void add_version_info( float ver );
void *reset_symtab();
void set_symtab(void*);
void add_pragma( const char *str );
diff --git a/src/cuda-sim/ptx_sim.cc b/src/cuda-sim/ptx_sim.cc
index 6a62783..d551c43 100644
--- a/src/cuda-sim/ptx_sim.cc
+++ b/src/cuda-sim/ptx_sim.cc
@@ -243,6 +243,11 @@ ptx_thread_info::ptx_thread_info()
m_last_was_call = false;
}
+const ptx_version &ptx_thread_info::get_ptx_version() const
+{
+ return m_func_info->get_ptx_version();
+}
+
extern unsigned long long gpu_sim_cycle;
void ptx_thread_info::set_done()
diff --git a/src/cuda-sim/ptx_sim.h b/src/cuda-sim/ptx_sim.h
index b4a78c8..976ce70 100644
--- a/src/cuda-sim/ptx_sim.h
+++ b/src/cuda-sim/ptx_sim.h
@@ -231,11 +231,34 @@ struct stack_entry {
unsigned m_call_uid;
};
+class ptx_version {
+public:
+ ptx_version()
+ {
+ m_valid = false;
+ m_ptx_version = 0;
+ m_ptx_extensions = 0;
+ }
+ ptx_version(float ver, unsigned extensions)
+ {
+ m_valid = true;
+ m_ptx_version = ver;
+ m_ptx_extensions = extensions;
+ }
+ float ver() const { assert(m_valid); return m_ptx_version; }
+ float extensions() const { assert(m_valid); return m_ptx_extensions; }
+private:
+ bool m_valid;
+ float m_ptx_version;
+ unsigned m_ptx_extensions;
+};
+
class ptx_thread_info {
public:
~ptx_thread_info();
ptx_thread_info();
+ const ptx_version &get_ptx_version() const;
ptx_reg_t get_operand_value( const symbol *reg );
ptx_reg_t get_operand_value( const operand_info &op );
void set_operand_value( const operand_info &dst, const ptx_reg_t &data );
@@ -450,11 +473,14 @@ 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 );
addr_t local_to_generic( unsigned smid, unsigned hwtid, addr_t addr );
addr_t shared_to_generic( unsigned smid, addr_t addr );
+addr_t global_to_generic( addr_t addr );
bool isspace_local( unsigned smid, unsigned hwtid, addr_t addr );
bool isspace_shared( unsigned smid, addr_t addr );
bool isspace_global( addr_t addr );
+unsigned whichspace( addr_t addr );
#endif