From 355b9bcbc870fb79a5d682748f2475432c5cb6a5 Mon Sep 17 00:00:00 2001 From: Tim Rogers Date: Thu, 21 Feb 2013 23:56:39 -0800 Subject: Fixing a bug exposed by the fix for bug 42. The "_" "null" register potentially generated by ptx and intentionally generated by ptxplus was being initialized without a type. This caused the parser to think it was not a register. Fix is to allow the parser to think of it as register, but ensure the arch-sim does not by adding a flag indicating that it is special. [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 15305] --- src/cuda-sim/cuda-sim.cc | 7 +++++-- src/cuda-sim/ptx_ir.cc | 17 ++++++++++++++++- src/cuda-sim/ptx_ir.h | 34 +++++++++++++++++++++++++++++++--- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index 1dbff50..cba5262 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -844,7 +844,8 @@ void ptx_instruction::pre_decode() for ( ; opr != op_iter_end(); opr++, n++ ) { //process operands const operand_info &o = *opr; if ( has_dst && n==0 ) { - if ( o.is_reg() ) { + // Do not set the null register "_" as an architectural register + if ( o.is_reg() && !o.is_non_arch_reg() ) { out[0] = o.reg_num(); arch_reg.dst[0] = o.arch_reg_num(); } else if ( o.is_vector() ) { @@ -858,7 +859,7 @@ void ptx_instruction::pre_decode() arch_reg.dst[i] = o.arch_reg_num(i); } } else { - if ( o.is_reg() ) { + if ( o.is_reg() && !o.is_non_arch_reg() ) { int reg_num = o.reg_num(); arch_reg.src[m] = o.arch_reg_num(); switch ( m ) { @@ -898,6 +899,8 @@ void ptx_instruction::pre_decode() const operand_info &o = *op; if(o.is_memory_operand()) { + // We do not support the null register as a memory operand + assert( !o.is_non_arch_reg() ); // Check PTXPlus-type operand // memory operand with addressing (ex. s[0x4] or g[$r1]) diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc index 0dffe70..678febf 100644 --- a/src/cuda-sim/ptx_ir.cc +++ b/src/cuda-sim/ptx_ir.cc @@ -191,8 +191,23 @@ bool symbol_table::add_function_decl( const char *name, int entry_point, functio } else { assert( !prior_decl ); *sym_table = new symbol_table( "", entry_point, this ); - symbol *null_reg = (*sym_table)->add_variable("_",NULL,0,"",0); + + // Initial setup code to support a register represented as "_". + // This register is used when an instruction operand is + // not read or written. However, the parser must recognize it + // as a legitimate register but we do not want to pass + // it to the micro-architectural register to the performance simulator. + // For this purpose we add a symbol to the symbol table but + // mark it as a non_arch_reg so it does not effect the performance sim. + type_info_key null_key( reg_space, 0, 0, 0, 0, 0 ); + null_key.set_is_non_arch_reg(); + // First param is null - which is bad. + // However, the first parameter is actually unread in the constructor... + // TODO - remove the symbol_table* from type_info + type_info* null_type_info = new type_info( NULL, null_key ); + symbol *null_reg = (*sym_table)->add_variable( "_", null_type_info, 0, "", 0 ); null_reg->set_regno(0, 0); + (*sym_table)->set_name(name); (*func_info)->set_symtab(*sym_table); m_function_symtab_lookup[key] = *sym_table; diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h index 9a24e47..26469d5 100644 --- a/src/cuda-sim/ptx_ir.h +++ b/src/cuda-sim/ptx_ir.h @@ -47,10 +47,12 @@ class type_info_key { public: type_info_key() { + m_is_non_arch_reg = false; m_init = false; } type_info_key( memory_space_t space_spec, int scalar_type_spec, int vector_spec, int alignment_spec, int extern_spec, int array_dim ) { + m_is_non_arch_reg = false; m_init = true; m_space_spec = space_spec; m_scalar_type_spec = scalar_type_spec; @@ -75,7 +77,9 @@ public: void set_array_dim( int array_dim ) { m_array_dim = array_dim; } int get_array_dim() const { assert(m_init); return m_array_dim; } + void set_is_non_arch_reg() { m_is_non_arch_reg = true; } + bool is_non_arch_reg() const { return m_is_non_arch_reg; } bool is_reg() const { return m_space_spec == reg_space;} bool is_param_kernel() const { return m_space_spec == param_space_kernel;} bool is_param_local() const { return m_space_spec == param_space_local; } @@ -99,6 +103,7 @@ private: int m_extern_spec; int m_array_dim; int m_is_function; + bool m_is_non_arch_reg; friend class type_info_key_compare; }; @@ -219,11 +224,20 @@ 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; + bool is_reg() const + { + if ( m_type == NULL ) { + return false; + } return m_type->get_key().is_reg(); } + bool is_non_arch_reg() const + { + if ( m_type == NULL ) { + return false; + } + return m_type->get_key().is_non_arch_reg(); + } void add_initializer( const std::list &init ); bool has_initializer() const @@ -335,6 +349,7 @@ class operand_info { public: operand_info() { + m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; m_double_operand_type = 0; @@ -346,6 +361,7 @@ public: } operand_info( const symbol *addr ) { + m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; m_double_operand_type = 0; @@ -374,6 +390,8 @@ public: } else { m_type = reg_t; } + + m_is_non_arch_reg = addr->is_non_arch_reg(); m_value.m_symbolic = addr; m_addr_offset = 0; m_vector = false; @@ -383,6 +401,7 @@ public: } operand_info( const symbol *addr1, const symbol *addr2 ) { + m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; m_double_operand_type = 0; @@ -404,6 +423,7 @@ public: } operand_info( int builtin_id, int dim_mod ) { + m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; m_double_operand_type = 0; @@ -421,6 +441,7 @@ public: } operand_info( const symbol *addr, int offset ) { + m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; m_double_operand_type = 0; @@ -438,6 +459,7 @@ public: } operand_info( unsigned x ) { + m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; m_double_operand_type = 0; @@ -455,6 +477,7 @@ public: } operand_info( int x ) { + m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; m_double_operand_type = 0; @@ -472,6 +495,7 @@ public: } operand_info( float x ) { + m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; m_double_operand_type = 0; @@ -489,6 +513,7 @@ public: } operand_info( double x ) { + m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; m_double_operand_type = 0; @@ -506,6 +531,7 @@ public: } operand_info( const symbol *s1, const symbol *s2, const symbol *s3, const symbol *s4 ) { + m_is_non_arch_reg = false; m_addr_space = undefined_space; m_operand_lohi = 0; m_double_operand_type = 0; @@ -688,6 +714,7 @@ public: bool get_operand_neg() const { return m_operand_neg; } void set_const_mem_offset(addr_t set_value) { m_const_mem_offset = set_value; } addr_t get_const_mem_offset() const { return m_const_mem_offset; } + bool is_non_arch_reg() const { return m_is_non_arch_reg; } private: unsigned m_uid; @@ -717,6 +744,7 @@ private: bool m_neg_pred; bool m_is_return_var; + bool m_is_non_arch_reg; static unsigned sm_next_uid; unsigned get_uid(); -- cgit v1.3