diff options
| -rw-r--r-- | src/abstract_hardware_model.h | 14 | ||||
| -rw-r--r-- | src/cuda-sim/cuda-sim.cc | 15 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 12 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 6 |
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; |
