summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorInderpreet Singh <[email protected]>2012-03-02 03:39:08 -0800
committerAndrew Boktor <[email protected]>2014-08-14 13:19:04 -0700
commitf103f929522f964501de1a7f6935fc3b294d5790 (patch)
tree9a8336dee733ea52f6ef29f64d6dd828a08c7dd9 /src
parent4658b0a943887513cbe6232fff09fafeeb77baaf (diff)
Changed arch_rech type to store 16 registers, 8 input and 8 output. 8 inputs because one can have 4 input operands and 4 register operands in a surface store instruction.
Fixed arch_regs for memory instructions being ignored in the pre-decode statge. [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 11576]
Diffstat (limited to 'src')
-rw-r--r--src/abstract_hardware_model.h14
-rw-r--r--src/cuda-sim/cuda-sim.cc15
-rw-r--r--src/gpgpu-sim/shader.cc12
-rw-r--r--src/gpgpu-sim/shader.h6
4 files changed, 30 insertions, 17 deletions
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index 2fdebfc..69faa5c 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -586,6 +586,7 @@ public:
virtual mem_fetch *alloc( const class warp_inst_t &inst, const mem_access_t &access ) const = 0;
};
+// the maximum number of destination, source, or address uarch operands in a instruction
#define MAX_REG_OPERANDS 8
struct dram_callback_t {
@@ -611,8 +612,10 @@ public:
cache_op = CACHE_UNDEFINED;
latency = 1;
initiation_interval = 1;
- for( unsigned i=0; i < MAX_REG_OPERANDS; i++ )
- arch_reg[i]=-1;
+ for( unsigned i=0; i < MAX_REG_OPERANDS; i++ ) {
+ arch_reg.src[i] = -1;
+ arch_reg.dst[i] = -1;
+ }
isize=0;
}
bool valid() const { return m_decoded; }
@@ -636,7 +639,12 @@ public:
unsigned char is_vectorout;
int pred; // predicate register number
int ar1, ar2;
- int arch_reg[MAX_REG_OPERANDS]; // register number for bank conflict evaluation
+ // register number for bank conflict evaluation
+ struct {
+ int dst[MAX_REG_OPERANDS];
+ int src[MAX_REG_OPERANDS];
+ } arch_reg;
+ //int arch_reg[MAX_REG_OPERANDS]; // register number for bank conflict evaluation
unsigned latency; // operation latency
unsigned initiation_interval;
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc
index e8611fb..f5203ef 100644
--- a/src/cuda-sim/cuda-sim.cc
+++ b/src/cuda-sim/cuda-sim.cc
@@ -533,7 +533,8 @@ void ptx_instruction::pre_decode()
}
is_vectorin = 0;
is_vectorout = 0;
- std::fill_n(arch_reg, MAX_REG_OPERANDS, -1);
+ std::fill_n(arch_reg.src, MAX_REG_OPERANDS, -1);
+ std::fill_n(arch_reg.dst, MAX_REG_OPERANDS, -1);
pred = 0;
ar1 = 0;
ar2 = 0;
@@ -585,7 +586,7 @@ void ptx_instruction::pre_decode()
if ( has_dst && n==0 ) {
if ( o.is_reg() ) {
out[0] = o.reg_num();
- arch_reg[0] = o.arch_reg_num();
+ arch_reg.dst[0] = o.arch_reg_num();
} else if ( o.is_vector() ) {
is_vectorin = 1;
unsigned num_elem = o.get_vect_nelem();
@@ -594,12 +595,12 @@ void ptx_instruction::pre_decode()
if( num_elem >= 3 ) out[2] = o.reg3_num();
if( num_elem >= 4 ) out[3] = o.reg4_num();
for (int i = 0; i < num_elem; i++)
- arch_reg[i] = o.arch_reg_num(i);
+ arch_reg.dst[i] = o.arch_reg_num(i);
}
} else {
if ( o.is_reg() ) {
int reg_num = o.reg_num();
- arch_reg[m + 4] = o.arch_reg_num();
+ arch_reg.src[m] = o.arch_reg_num();
switch ( m ) {
case 0: in[0] = reg_num; break;
case 1: in[1] = reg_num; break;
@@ -616,7 +617,7 @@ void ptx_instruction::pre_decode()
if( num_elem >= 3 ) in[2] = o.reg3_num();
if( num_elem >= 4 ) in[3] = o.reg4_num();
for (int i = 0; i < num_elem; i++)
- arch_reg[i + 4] = o.arch_reg_num(i);
+ arch_reg.src[i] = o.arch_reg_num(i);
m+=4;
}
}
@@ -645,18 +646,22 @@ void ptx_instruction::pre_decode()
// memory operand with one address register (ex. g[$r1+0x4] or s[$r2+=0x4])
if(o.get_double_operand_type() == 0 || o.get_double_operand_type() == 3){
ar1 = o.reg_num();
+ arch_reg.src[4] = o.arch_reg_num();
// TODO: address register in $r2+=0x4 should be an output register as well
}
// memory operand with two address register (ex. s[$r1+$r1] or g[$r1+=$r2])
else if(o.get_double_operand_type() == 1 || o.get_double_operand_type() == 2) {
ar1 = o.reg1_num();
+ arch_reg.src[4] = o.arch_reg_num();
ar2 = o.reg2_num();
+ arch_reg.src[5] = o.arch_reg_num();
// TODO: first address register in $r1+=$r2 should be an output register as well
}
}
// Regular PTX operand
else if (o.get_symbol()->type()->get_key().is_reg()) { // Memory operand contains a register
ar1 = o.reg_num();
+ arch_reg.src[4] = o.arch_reg_num();
}
}
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 060dd07..82be8ed 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -54,8 +54,8 @@
std::list<unsigned> shader_core_ctx::get_regs_written( const inst_t &fvt ) const
{
std::list<unsigned> result;
- for( unsigned op=0; op < 4; op++ ) {
- int reg_num = fvt.arch_reg[op]; // this math needs to match that used in function_info::ptx_decode_inst
+ for( unsigned op=0; op < MAX_REG_OPERANDS; op++ ) {
+ int reg_num = fvt.arch_reg.dst[op]; // this math needs to match that used in function_info::ptx_decode_inst
if( reg_num >= 0 ) // valid register
result.push_back(reg_num);
}
@@ -1976,7 +1976,7 @@ void opndcoll_rfu_t::collector_unit_t::dump(FILE *fp, const shader_core_ctx *sha
fprintf(fp," <free>\n");
} else {
m_warp->print(fp);
- for( unsigned i=0; i < MAX_REG_OPERANDS; i++ ) {
+ for( unsigned i=0; i < MAX_REG_OPERANDS*2; i++ ) {
if( m_not_ready.test(i) ) {
std::string r = m_src_op[i].get_reg_string();
fprintf(fp," '%s' not ready\n", r.c_str() );
@@ -2007,8 +2007,8 @@ void opndcoll_rfu_t::collector_unit_t::allocate( warp_inst_t** pipeline_reg, war
m_output_register = output_reg;
if( !(*pipeline_reg)->empty() ) {
m_warp_id = (*pipeline_reg)->warp_id();
- for( unsigned op=0; op < 4; op++ ) {
- int reg_num = (*pipeline_reg)->arch_reg[4+op]; // this math needs to match that used in function_info::ptx_decode_inst
+ for( unsigned op=0; op < MAX_REG_OPERANDS; op++ ) {
+ int reg_num = (*pipeline_reg)->arch_reg.src[op]; // this math needs to match that used in function_info::ptx_decode_inst
if( reg_num >= 0 ) { // valid register
m_src_op[op] = op_t( this, op, reg_num, m_num_banks, m_bank_warp_shift );
m_not_ready.set(op);
@@ -2025,7 +2025,7 @@ void opndcoll_rfu_t::collector_unit_t::dispatch()
move_warp(*m_output_register,m_warp);
m_free=true;
m_output_register = NULL;
- for( unsigned i=0; i<MAX_REG_OPERANDS;i++)
+ for( unsigned i=0; i<MAX_REG_OPERANDS*2;i++)
m_src_op[i].reset();
}
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index f8b0e58..b0a9c3a 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -490,7 +490,7 @@ private:
void add_read_requests( collector_unit_t *cu )
{
const op_t *src = cu->get_operands();
- for( unsigned i=0; i<MAX_REG_OPERANDS; i++) {
+ for( unsigned i=0; i<MAX_REG_OPERANDS*2; i++) {
const op_t &op = src[i];
if( op.valid() ) {
unsigned bank = op.get_bank();
@@ -554,7 +554,7 @@ private:
m_free = true;
m_warp = NULL;
m_output_register = NULL;
- m_src_op = new op_t[MAX_REG_OPERANDS];
+ m_src_op = new op_t[MAX_REG_OPERANDS*2];
m_not_ready.reset();
m_warp_id = -1;
m_num_banks = 0;
@@ -591,7 +591,7 @@ private:
warp_inst_t *m_warp;
warp_inst_t** m_output_register; // pipeline register to issue to when ready
op_t *m_src_op;
- std::bitset<MAX_REG_OPERANDS> m_not_ready;
+ std::bitset<MAX_REG_OPERANDS*2> m_not_ready;
unsigned m_num_banks;
unsigned m_bank_warp_shift;
opndcoll_rfu_t *m_rfu;