summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Rogers <[email protected]>2013-02-21 23:56:39 -0800
committerAndrew Boktor <[email protected]>2014-08-14 13:50:05 -0700
commit355b9bcbc870fb79a5d682748f2475432c5cb6a5 (patch)
treeb2b4e671874102de77a8d3ab44555aab90413df3
parentb346aa92a4d8a432eb5b6f5aa5d4cc22aef41833 (diff)
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]
-rw-r--r--src/cuda-sim/cuda-sim.cc7
-rw-r--r--src/cuda-sim/ptx_ir.cc17
-rw-r--r--src/cuda-sim/ptx_ir.h34
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<operand_info> &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();