From 9b43d5685c269331ea6d15fe3ed0dade063a798a Mon Sep 17 00:00:00 2001 From: Tor Aamodt Date: Sat, 17 Jul 2010 10:19:14 -0800 Subject: - add support for ld/st with generic addresses - add support for parsing cache operators (still need to pass to timing model) [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 6868] --- src/cuda-sim/cuda-sim.cc | 25 ++++++++++++ src/cuda-sim/instructions.cc | 97 ++++++++++++++++++++++++-------------------- src/cuda-sim/ptx.l | 6 +++ src/cuda-sim/ptx.y | 8 +++- src/cuda-sim/ptx_ir.cc | 18 ++++++++ src/cuda-sim/ptx_ir.h | 9 +++- src/cuda-sim/ptx_sim.cc | 5 +++ src/cuda-sim/ptx_sim.h | 26 ++++++++++++ 8 files changed, 147 insertions(+), 47 deletions(-) (limited to 'src/cuda-sim') 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 function_decl_header %type 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 m_symbols; //map from name of register to pointers to the registers std::map 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 -- cgit v1.3