summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cuobjdump_to_ptxplus/ptx_parser.h1
-rw-r--r--src/abstract_hardware_model.cc4
-rw-r--r--src/abstract_hardware_model.h4
-rw-r--r--src/cuda-sim/cuda-sim.cc42
-rw-r--r--src/cuda-sim/instructions.cc238
-rw-r--r--src/cuda-sim/opcodes.def2
-rw-r--r--src/cuda-sim/ptx.l11
-rw-r--r--src/cuda-sim/ptx.y2
-rw-r--r--src/cuda-sim/ptx_ir.h6
-rw-r--r--src/cuda-sim/ptx_parser.cc14
-rw-r--r--src/cuda-sim/ptx_sim.cc17
-rw-r--r--src/cuda-sim/ptx_sim.h7
-rw-r--r--src/gpgpu-sim/gpu-sim.cc3
-rw-r--r--src/gpgpu-sim/shader.cc1
-rw-r--r--src/gpgpu-sim/shader.h1
15 files changed, 334 insertions, 19 deletions
diff --git a/cuobjdump_to_ptxplus/ptx_parser.h b/cuobjdump_to_ptxplus/ptx_parser.h
index 418a733..7cfb5c5 100644
--- a/cuobjdump_to_ptxplus/ptx_parser.h
+++ b/cuobjdump_to_ptxplus/ptx_parser.h
@@ -58,6 +58,7 @@ enum _memory_space_t {
reg_space,
local_space,
shared_space,
+ sstarr_space,
param_space_unclassified,
param_space_kernel, /* global to all threads in a kernel : read-only */
param_space_local, /* local to a thread : read-writable */
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc
index fe6f8ab..d668de7 100644
--- a/src/abstract_hardware_model.cc
+++ b/src/abstract_hardware_model.cc
@@ -213,6 +213,7 @@ void warp_inst_t::generate_mem_accesses()
access_type = is_write? LOCAL_ACC_W: LOCAL_ACC_R;
break;
case shared_space: break;
+ case sstarr_space: break;
default: assert(0); break;
}
@@ -220,7 +221,8 @@ void warp_inst_t::generate_mem_accesses()
new_addr_type cache_block_size = 0; // in bytes
switch( space.get_type() ) {
- case shared_space: {
+ case shared_space:
+ case sstarr_space: {
unsigned subwarp_size = m_config->warp_size / m_config->mem_warp_parts;
unsigned total_accesses=0;
for( unsigned subwarp=0; subwarp < m_config->mem_warp_parts; subwarp++ ) {
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index aaa4b00..607eda7 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -41,6 +41,7 @@ enum _memory_space_t {
reg_space,
local_space,
shared_space,
+ sstarr_space,
param_space_unclassified,
param_space_kernel, /* global to all threads in a kernel : read-only */
param_space_local, /* local to a thread : read-writable */
@@ -602,6 +603,7 @@ public:
return false;
}
enum _memory_space_t get_type() const { return m_type; }
+ void set_type( enum _memory_space_t t ) { m_type = t; }
unsigned get_bank() const { return m_bank; }
void set_bank( unsigned b ) { m_bank = b; }
bool is_const() const { return (m_type == const_space) || (m_type == param_space_kernel); }
@@ -835,7 +837,7 @@ public:
int src[MAX_REG_OPERANDS];
} arch_reg;
//int arch_reg[MAX_REG_OPERANDS]; // register number for bank conflict evaluation
- unsigned latency; // operation latency
+ unsigned latency; // operation latency
unsigned initiation_interval;
unsigned data_size; // what is the size of the word being operated on?
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc
index d4ace76..b5b79e7 100644
--- a/src/cuda-sim/cuda-sim.cc
+++ b/src/cuda-sim/cuda-sim.cc
@@ -69,9 +69,9 @@ unsigned cdp_latency[5];
void ptx_opcocde_latency_options (option_parser_t opp) {
option_parser_register(opp, "-ptx_opcode_latency_int", OPT_CSTR, &opcode_latency_int,
- "Opcode latencies for integers <ADD,MAX,MUL,MAD,DIV>"
- "Default 1,1,19,25,145",
- "1,1,19,25,145");
+ "Opcode latencies for integers <ADD,MAX,MUL,MAD,DIV,BSMAD>"
+ "Default 1,1,19,25,145,1",
+ "1,1,19,25,145,1");
option_parser_register(opp, "-ptx_opcode_latency_fp", OPT_CSTR, &opcode_latency_fp,
"Opcode latencies for single precision floating points <ADD,MAX,MUL,MAD,DIV>"
"Default 1,1,1,1,30",
@@ -81,9 +81,9 @@ void ptx_opcocde_latency_options (option_parser_t opp) {
"Default 8,8,8,8,335",
"8,8,8,8,335");
option_parser_register(opp, "-ptx_opcode_initiation_int", OPT_CSTR, &opcode_initiation_int,
- "Opcode initiation intervals for integers <ADD,MAX,MUL,MAD,DIV>"
- "Default 1,1,4,4,32",
- "1,1,4,4,32");
+ "Opcode initiation intervals for integers <ADD,MAX,MUL,MAD,DIV,BSMAD>"
+ "Default 1,1,4,4,32,1",
+ "1,1,4,4,32,1");
option_parser_register(opp, "-ptx_opcode_initiation_fp", OPT_CSTR, &opcode_initiation_fp,
"Opcode initiation intervals for single precision floating points <ADD,MAX,MUL,MAD,DIV>"
"Default 1,1,1,1,5",
@@ -581,15 +581,18 @@ void ptx_instruction::set_bar_type()
abort();
}
}
+ else if(m_opcode==SST_OP) {
+ bar_type = SYNC;
+ }
}
void ptx_instruction::set_opcode_and_latency()
{
- unsigned int_latency[5];
+ unsigned int_latency[6];
unsigned fp_latency[5];
unsigned dp_latency[5];
- unsigned int_init[5];
+ unsigned int_init[6];
unsigned fp_init[5];
unsigned dp_init[5];
/*
@@ -598,19 +601,20 @@ void ptx_instruction::set_opcode_and_latency()
* [2] MUL
* [3] MAD
* [4] DIV
+ * [5] BSMAD
*/
- sscanf(opcode_latency_int, "%u,%u,%u,%u,%u",
+ sscanf(opcode_latency_int, "%u,%u,%u,%u,%u,%u",
&int_latency[0],&int_latency[1],&int_latency[2],
- &int_latency[3],&int_latency[4]);
+ &int_latency[3],&int_latency[4],&int_latency[5]);
sscanf(opcode_latency_fp, "%u,%u,%u,%u,%u",
&fp_latency[0],&fp_latency[1],&fp_latency[2],
&fp_latency[3],&fp_latency[4]);
sscanf(opcode_latency_dp, "%u,%u,%u,%u,%u",
&dp_latency[0],&dp_latency[1],&dp_latency[2],
&dp_latency[3],&dp_latency[4]);
- sscanf(opcode_initiation_int, "%u,%u,%u,%u,%u",
+ sscanf(opcode_initiation_int, "%u,%u,%u,%u,%u,%u",
&int_init[0],&int_init[1],&int_init[2],
- &int_init[3],&int_init[4]);
+ &int_init[3],&int_init[4],&int_init[5]);
sscanf(opcode_initiation_fp, "%u,%u,%u,%u,%u",
&fp_init[0],&fp_init[1],&fp_init[2],
&fp_init[3],&fp_init[4]);
@@ -647,6 +651,7 @@ void ptx_instruction::set_opcode_and_latency()
case TEX_OP: op = LOAD_OP; mem_op=TEX; break;
case ATOM_OP: op = LOAD_OP; break;
case BAR_OP: op = BARRIER_OP; break;
+ case SST_OP: op = BARRIER_OP; break;
case MEMBAR_OP: op = MEMORY_BARRIER_OP; break;
case CALL_OP:
{
@@ -783,6 +788,10 @@ void ptx_instruction::set_opcode_and_latency()
initiation_interval = dp_init[2];
op = SFU_OP;
break;
+ case BSMAD_OP:
+ latency = int_latency[5];
+ initiation_interval = int_init[5];
+ break;
case SHFL_OP:
latency = 32;
initiation_interval = 15;
@@ -1459,6 +1468,7 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel,
std::list<ptx_thread_info *> &active_threads = kernel.active_threads();
static std::map<unsigned,memory_space*> shared_memory_lookup;
+ static std::map<unsigned,memory_space*> sstarr_memory_lookup;
static std::map<unsigned,ptx_cta_info*> ptx_cta_lookup;
static std::map<unsigned,ptx_warp_info*> ptx_warp_lookup;
static std::map<unsigned,std::map<unsigned,memory_space*> > local_memory_lookup;
@@ -1503,6 +1513,7 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel,
//initializing new CTA
ptx_cta_info *cta_info = NULL;
memory_space *shared_mem = NULL;
+ memory_space *sstarr_mem = NULL;
unsigned cta_size = kernel.threads_per_cta();
unsigned max_cta_per_sm = num_threads/cta_size; // e.g., 256 / 48 = 5
@@ -1520,6 +1531,9 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel,
snprintf(buf,512,"shared_%u", sid);
shared_mem = new memory_space_impl<16*1024>(buf,4);
shared_memory_lookup[sm_idx] = shared_mem;
+ snprintf(buf,512,"sstarr_%u", sid);
+ sstarr_mem = new memory_space_impl<16*1024>(buf,4);
+ sstarr_memory_lookup[sm_idx] = sstarr_mem;
cta_info = new ptx_cta_info(sm_idx);
ptx_cta_lookup[sm_idx] = cta_info;
} else {
@@ -1528,6 +1542,7 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel,
sm_idx, sid, max_cta_per_sm );
}
shared_mem = shared_memory_lookup[sm_idx];
+ sstarr_mem = sstarr_memory_lookup[sm_idx];
cta_info = ptx_cta_lookup[sm_idx];
cta_info->check_cta_thread_status_and_reset();
}
@@ -1540,7 +1555,6 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel,
kernel.increment_thread_id();
new_tid += tid;
ptx_thread_info *thd = new ptx_thread_info(kernel);
-
ptx_warp_info *warp_info = NULL;
if ( ptx_warp_lookup.find(hw_warp_id) == ptx_warp_lookup.end() ) {
warp_info = new ptx_warp_info();
@@ -1569,9 +1583,11 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel,
thd->cpy_tid_to_reg(tid3d);
thd->set_valid();
thd->m_shared_mem = shared_mem;
+ thd->m_sstarr_mem = sstarr_mem;
function_info *finfo = thd->func_info();
symbol_table *st = finfo->get_symtab();
thd->func_info()->param_to_shared(thd->m_shared_mem,st);
+ thd->func_info()->param_to_shared(thd->m_sstarr_mem,st);
thd->m_cta_info = cta_info;
cta_info->add_thread(thd);
thd->m_local_mem = local_mem;
diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc
index 011c285..159fd4c 100644
--- a/src/cuda-sim/instructions.cc
+++ b/src/cuda-sim/instructions.cc
@@ -135,6 +135,8 @@ ptx_reg_t ptx_thread_info::get_operand_value( const operand_info &op, operand_in
result.u64 = sym->get_address() + op.get_addr_offset();
} else if ( op.is_shared() ) {
result.u64 = op.get_symbol()->get_address() + op.get_addr_offset();
+ } else if ( op.is_sstarr() ) {
+ result.u64 = op.get_symbol()->get_address() + op.get_addr_offset();
} else {
const char *name = op.name().c_str();
printf("GPGPU-Sim PTX: ERROR ** get_operand_value : unknown memory operand type for %s\n", name );
@@ -147,6 +149,8 @@ ptx_reg_t ptx_thread_info::get_operand_value( const operand_info &op, operand_in
result.u64 = op.get_symbol()->get_address();
} else if ( op.is_shared() ) {
result.u64 = op.get_symbol()->get_address();
+ } else if ( op.is_sstarr() ) {
+ result.u64 = op.get_symbol()->get_address();
} else if ( op.is_const() ) {
result.u64 = op.get_symbol()->get_address();
} else if ( op.is_global() ) {
@@ -1459,6 +1463,157 @@ void breakaddr_impl( const ptx_instruction *pI, ptx_thread_info *thread )
void brev_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); }
void brkpt_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); }
+unsigned trunc(unsigned num, unsigned precision) {
+ int mask = 1, latest_one = -1;
+ unsigned data = num;
+ for (unsigned j = 0; j < sizeof(unsigned)*8; j++) {
+ int bit = data & mask;
+ if (bit == 1) latest_one = j;
+ data >>= 1;
+ }
+ if (latest_one >= precision) {
+ // round_up is 1 if the most significant truncated digit is a 1, otherwise it is 0
+ //int round_up = (num & (1 << (latest_one-precision))) >> (latest_one-precision);
+ //unsigned shifted_output = num >> (latest_one-precision+1);
+ // if shifted_output is a number like 1111, don't round up
+ //if (shifted_output == (pow(2,precision)-1)) round_up = 0;
+ //num = shifted_output + round_up;
+ num >>= (latest_one-precision+1);
+ }
+ return num;
+}
+
+void bsmad_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst )
+{
+ // operands:
+ // 0 = output
+ // 1 = input precision
+ // 2 = output precision
+ // 3 = buffer0
+ // 4 = buffer1
+ // 5 = buffer2
+ // 6 = buffer3
+ // 7 = synapse value
+ // 8 = output value
+
+ const operand_info &dst = pI->dst();
+ const operand_info &src1 = pI->src1();
+ const operand_info &src2 = pI->src2();
+ unsigned type = pI->get_type();
+ int tid = inst.warp_id() * core->get_warp_size();
+ ptx_thread_info *thread = core->get_thread_info()[tid];
+ const int ip = (thread->get_operand_value(src1, dst, type, thread, 1)).u32;
+ const int op = (thread->get_operand_value(src2, dst, type, thread, 1)).u32;
+ const int THREADS = inst.active_count();
+ const int INBUFFERS = 4;
+ const int OUTBUFFERS = (((32/ip)*INBUFFERS) / (32/op)) + ((((32/ip)*INBUFFERS) % (32/op)) != 0);
+ if (OUTBUFFERS > THREADS) {
+ printf("GPGPU-Sim PTX: BSMAD ERROR - Number of output registers required (%d) is greater than the number available (%d)\n", OUTBUFFERS, THREADS);
+ abort();
+ }
+ ptx_warp_info *warp_info = thread->m_warp_info;
+ warp_info->inc_done_threads();
+
+ // threads within the warp are executed sequentially by the simulator, store output in first four registers
+ if (warp_info->get_done_threads() <= OUTBUFFERS) {
+ unsigned buffer[THREADS][INBUFFERS];
+ unsigned synapse[THREADS];
+ unsigned output;
+
+ // loop through all threads in the warp and get all data
+ for (unsigned i = 0, j = 0; i < core->get_warp_size(); i++) {
+ if (inst.active(i)) {
+ const operand_info &src3 = pI->operand_lookup(3);
+ const operand_info &src4 = pI->operand_lookup(4);
+ const operand_info &src5 = pI->operand_lookup(5);
+ const operand_info &src6 = pI->operand_lookup(6);
+ const operand_info &src7 = pI->operand_lookup(7);
+ const operand_info &src8 = pI->operand_lookup(8);
+
+ thread = core->get_thread_info()[tid+i];
+ // get buffer data and synapse data from each thread
+ buffer[j][0] = (thread->get_operand_value(src3, dst, type, thread, 1)).u32;
+ buffer[j][1] = (thread->get_operand_value(src4, dst, type, thread, 1)).u32;
+ buffer[j][2] = (thread->get_operand_value(src5, dst, type, thread, 1)).u32;
+ buffer[j][3] = (thread->get_operand_value(src6, dst, type, thread, 1)).u32;
+ synapse[j] = (thread->get_operand_value(src7, dst, type, thread, 1)).u32;
+ j++;
+ // get output data from the first 4 threads
+ if (j == warp_info->get_done_threads()) {
+ output = (thread->get_operand_value(src8, dst, type, thread, 1)).u32;
+ }
+ }
+ }
+
+ // unpack registers, compute enough outputs to fill an output register
+ unsigned *unpacked_output = (unsigned*)calloc(32/op,sizeof(unsigned));
+ unsigned buffer_data_start = (32/op)*(warp_info->get_done_threads()-1);
+ for (unsigned i = buffer_data_start; i < (32/op + buffer_data_start) && i < (32/ip)*INBUFFERS; i++) {
+ unsigned buf = i/(32/ip);
+ unsigned pos = i%(32/ip);
+ // sum values from the buffers
+ int sum = 0;
+ unsigned mask = (unsigned)(pow(2,ip)-1) << (pos*ip);
+ for (int j = 0; j < THREADS; j++) {
+ //sum += ((mask & buffer[j][buf]) >> (pos*ip)) * synapse[j];
+ sum += trunc(((mask & buffer[j][buf]) >> (pos*ip)) * synapse[j], op);
+ }
+ // get the previous output
+ mask = (unsigned)(pow(2,op)-1) << (op*(i-buffer_data_start));
+ int past_output = (mask & output) >> (op*(i-buffer_data_start));
+ unpacked_output[i-buffer_data_start] = trunc(trunc(sum,op) + past_output,op);
+ // truncate sum, truncate (truncated sum + past_output)
+ }
+
+ // truncate output
+ /*for (unsigned i = 0; i < 32/op; i++) {
+ int mask = 1, latest_one = -1;
+ unsigned data = unpacked_output[i];
+ for (unsigned j = 0; j < sizeof(unsigned)*8; j++) {
+ int bit = data & mask;
+ if (bit == 1) latest_one = j;
+ data >>= 1;
+ }
+ if (latest_one >= op) {
+ // round_up is 1 if the most significant truncated digit is a 1, otherwise it is 0
+ int round_up = (unpacked_output[i] & (1 << (latest_one-op))) >> (latest_one-op);
+ unsigned shifted_output = unpacked_output[i] >> (latest_one-op+1);
+ // if shifted_output is a number like 1111, don't round up
+ if (shifted_output == (pow(2,op)-1)) round_up = 0;
+ unpacked_output[i] = shifted_output + round_up;
+ }
+ }*/
+
+ // pack the outputs into one register
+ unsigned mask = pow(2,op)-1;
+ unsigned output_data = 0;
+ for (int i = 0; i < 32/op; i++) {
+ output_data |= (unpacked_output[i] & mask) << (op*i);
+ }
+
+ // store the result in the correct thread's output register
+ for (unsigned i = 0, j = 0; i < core->get_warp_size(); i++) {
+ if (inst.active(i)) j++;
+ if (j == warp_info->get_done_threads()) {
+ thread = core->get_thread_info()[tid+i];
+ ptx_reg_t data;
+ data.u32 = output_data;
+ thread->set_operand_value(dst, data, type, thread, pI);
+ break;
+ }
+ }
+ }
+
+ // once the warp has finished, set the number of completed threads back to 0 for the next warp
+ if (warp_info->get_done_threads() == THREADS) {
+ warp_info->reset_done_threads();
+ }
+
+ // set the latency assuming 4 bits of each input get processed every cycle
+ // mutable latency variable???
+ //pI->latency = (ip+3)/4;
+}
+
void call_impl( const ptx_instruction *pI, ptx_thread_info *thread )
{
static unsigned call_uid_next = 1;
@@ -2370,6 +2525,7 @@ void decode_space( memory_space_t &space, ptx_thread_info *thread, const operand
case surf_space: mem = thread->get_surf_memory(); break;
case param_space_kernel: mem = thread->get_param_memory(); break;
case shared_space: mem = thread->m_shared_mem; break;
+ case sstarr_space: mem = thread->m_sstarr_mem; break;
case const_space: mem = thread->get_global_memory(); break;
case generic_space:
if( thread->get_ptx_version().ver() >= 2.0 ) {
@@ -3832,6 +3988,88 @@ void sqrt_impl( const ptx_instruction *pI, ptx_thread_info *thread )
thread->set_operand_value(dst,d, i_type, thread, pI);
}
+void sst_impl( const ptx_instruction *pI, ptx_thread_info *thread )
+{
+ ptx_instruction * cpI = const_cast<ptx_instruction *>(pI); // constant
+ const operand_info &dst = cpI->dst();
+ const operand_info &src1 = pI->src1();
+ const operand_info &src2 = pI->src2();
+ const operand_info &src3 = pI->src3();
+ unsigned type = pI->get_type();
+ ptx_reg_t dst_data = thread->get_operand_value(dst, dst, type, thread, 1);
+ ptx_reg_t src1_data = thread->get_operand_value(src1, src1, type, thread, 1);
+ ptx_reg_t src2_data = thread->get_operand_value(src2, src1, type, thread, 1);
+ ptx_reg_t src3_data = thread->get_operand_value(src3, src1, type, thread, 1);
+ memory_space_t space = pI->get_space();
+ memory_space *mem = NULL;
+ addr_t addr = src2_data.u32 * 4; // this assumes sstarr memory starts at address 0
+ ptx_cta_info *cta_info = thread->m_cta_info;
+
+ decode_space(space,thread,src1,mem,addr);
+
+ size_t size;
+ int t;
+ type_info_key::type_decode(type,size,t);
+
+ // store data in sstarr memory
+ mem->write(addr,size/8,&src3_data.s64,thread,pI);
+
+ // sync threads
+ cpI->set_bar_id(16); // use 16 for sst because bar uses an int from 0-15
+
+ thread->m_last_effective_address = addr;
+ thread->m_last_memory_space = space;
+ thread->m_last_dram_callback.function = bar_callback;
+ thread->m_last_dram_callback.instruction = cpI;
+
+ // the last thread that executes loads all of the data back from sstarr memory
+ int NUM_THREADS = cta_info->num_threads();
+ cta_info->inc_bar_threads();
+ if (NUM_THREADS == cta_info->get_bar_threads()) {
+ unsigned offset = 0;
+ addr = 0;
+ ptx_reg_t data;
+ float sstarr_fdata[NUM_THREADS];
+ signed long long sstarr_ldata[NUM_THREADS];
+ // loop through all of the threads
+ for (int tid = 0; tid < NUM_THREADS; tid++) {
+ data.u64=0;
+ mem->read(addr+(tid*4),size/8,&data.s64);
+ sstarr_fdata[tid] = data.f32;
+ sstarr_ldata[tid] = data.s64;
+ }
+
+ // squeeze the zeros out of the array and store data back into original array
+ mem = NULL;
+ addr = src1_data.u32;
+ space.set_type(global_space);
+ decode_space(space,thread,src1,mem,addr);
+ // store nonzero entries and indices
+ for (int tid = 0; tid < NUM_THREADS; tid++) {
+ if (sstarr_fdata[tid] != 0) {
+ float ftid = (float)tid;
+ mem->write(addr+(offset*4),size/8,&sstarr_ldata[tid],thread,pI);
+ mem->write(addr+((NUM_THREADS+offset)*4),size/8,&ftid,thread,pI);
+ offset++;
+ }
+ }
+ // store the number of nonzero elements in the array
+ data = thread->get_operand_value(src1, dst, type, thread, 1);
+ data.s64 += 4*(offset-1);
+ thread->set_operand_value(dst, data, type, thread, pI);
+
+ // fill the rest of the array with zeros (dst should always have a 0 in it)
+ while (offset < NUM_THREADS) {
+ mem->write(addr+(offset*4),size/8,&dst_data.s64,thread,pI);
+ offset++;
+ }
+
+ cta_info->reset_bar_threads();
+ thread->m_last_effective_address = addr+(NUM_THREADS-1)*4;
+ thread->m_last_memory_space = space;
+ }
+}
+
void ssy_impl( const ptx_instruction *pI, ptx_thread_info *thread )
{
//printf("Execution Warning: unimplemented ssy instruction is treated as a nop\n");
diff --git a/src/cuda-sim/opcodes.def b/src/cuda-sim/opcodes.def
index e1b1422..41f2f22 100644
--- a/src/cuda-sim/opcodes.def
+++ b/src/cuda-sim/opcodes.def
@@ -52,6 +52,7 @@ OP_DEF(BRA_OP,bra_impl,"bra",0,3)
OP_DEF(BRX_OP,brx_impl,"brx",0,3)
OP_DEF(BREV_OP,brev_impl,"brev",1,1)
OP_DEF(BRKPT_OP,brkpt_impl,"brkpt",1,9)
+OP_W_DEF(BSMAD_OP,bsmad_impl,"bsmad",1,1)
OP_DEF(CALL_OP,call_impl,"call",1,3)
OP_DEF(CALLP_OP,callp_impl,"callp",1,3)
OP_DEF(CLZ_OP,clz_impl,"clz",1,1)
@@ -104,6 +105,7 @@ OP_DEF(SHR_OP,shr_impl,"shr",1,1)
OP_DEF(SIN_OP,sin_impl,"sin",1,4)
OP_DEF(SLCT_OP,slct_impl,"slct",1,1)
OP_DEF(SQRT_OP,sqrt_impl,"sqrt",1,4)
+OP_DEF(SST_OP,sst_impl,"sst",1,5)
OP_DEF(SSY_OP,ssy_impl,"ssy",0,3)
OP_DEF(ST_OP,st_impl,"st",0,5)
OP_DEF(SUB_OP,sub_impl,"sub",1,1)
diff --git a/src/cuda-sim/ptx.l b/src/cuda-sim/ptx.l
index 5471d6f..7620134 100644
--- a/src/cuda-sim/ptx.l
+++ b/src/cuda-sim/ptx.l
@@ -68,6 +68,7 @@ bra TC; ptx_lval.int_value = BRA_OP; return OPCODE;
brx TC; ptx_lval.int_value = BRX_OP; return OPCODE;
brev TC; ptx_lval.int_value = BREV_OP; return OPCODE;
brkpt TC; ptx_lval.int_value = BRKPT_OP; return OPCODE;
+bsmad TC; ptx_lval.int_value = BSMAD_OP; return OPCODE;
call TC; BEGIN(NOT_OPCODE); ptx_lval.int_value = CALL_OP; return OPCODE; // blocking opcode token in case the callee has the same name as an opcode
callp TC; BEGIN(NOT_OPCODE); ptx_lval.int_value = CALLP_OP; return OPCODE;
clz TC; ptx_lval.int_value = CLZ_OP; return OPCODE;
@@ -121,6 +122,7 @@ shr TC; ptx_lval.int_value = SHR_OP; return OPCODE;
sin TC; ptx_lval.int_value = SIN_OP; return OPCODE;
slct TC; ptx_lval.int_value = SLCT_OP; return OPCODE;
sqrt TC; ptx_lval.int_value = SQRT_OP; return OPCODE;
+sst TC; ptx_lval.int_value = SST_OP; return OPCODE;
ssy TC; ptx_lval.int_value = SSY_OP; return OPCODE;
st TC; ptx_lval.int_value = ST_OP; return OPCODE;
st.volatile TC; ptx_lval.int_value = ST_OP; return OPCODE;
@@ -148,6 +150,8 @@ nop TC; ptx_lval.int_value = NOP_OP; return OPCODE;
break TC; ptx_lval.int_value = BREAK_OP; return OPCODE;
breakaddr TC; ptx_lval.int_value = BREAKADDR_OP; return OPCODE;
+"CPTX_END" printf("ENDING CUSTOM PTX.\n"); BEGIN(IN_COMMENT);
+
<INITIAL,NOT_OPCODE,IN_INST,IN_FUNC_DECL>{
\.align TC; return ALIGN_DIRECTIVE;
@@ -175,6 +179,7 @@ breakaddr TC; ptx_lval.int_value = BREAKADDR_OP; return OPCODE;
\.section TC; return SECTION_DIRECTIVE;
\.shared TC; return SHARED_DIRECTIVE;
\.sreg TC; return SREG_DIRECTIVE;
+\.sstarr TC; return SSTARR_DIRECTIVE;
\.struct TC; return STRUCT_DIRECTIVE;
\.surf TC; return SURF_DIRECTIVE; /* not in PTX 2.1 */
\.target TC; return TARGET_DIRECTIVE;
@@ -399,9 +404,9 @@ breakaddr TC; ptx_lval.int_value = BREAKADDR_OP; return OPCODE;
<IN_COMMENT>{
"*/" BEGIN(INITIAL);
"CPTX_BEGIN" printf("BEGINNING CUSTOM PTX.\n"); BEGIN(INITIAL);
-[^C*\n]+ // eat comment in chunks
-"C"
-"*" // eat the lone star
+[^C*\n]+ // eat comment in chunks
+"C" // eat the lone C
+"*" // eat the lone star
\n TC;
}
diff --git a/src/cuda-sim/ptx.y b/src/cuda-sim/ptx.y
index e00aa4b..3360c55 100644
--- a/src/cuda-sim/ptx.y
+++ b/src/cuda-sim/ptx.y
@@ -64,6 +64,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%token SECTION_DIRECTIVE
%token SHARED_DIRECTIVE
%token SREG_DIRECTIVE
+%token SSTARR_DIRECTIVE
%token STRUCT_DIRECTIVE
%token SURF_DIRECTIVE
%token TARGET_DIRECTIVE
@@ -347,6 +348,7 @@ addressable_spec: CONST_DIRECTIVE { add_space_spec(const_space,$1); }
| LOCAL_DIRECTIVE { add_space_spec(local_space,0); }
| PARAM_DIRECTIVE { add_space_spec(param_space_unclassified,0); }
| SHARED_DIRECTIVE { add_space_spec(shared_space,0); }
+ | SSTARR_DIRECTIVE { add_space_spec(sstarr_space,0); }
| SURF_DIRECTIVE { add_space_spec(surf_space,0); }
| TEX_DIRECTIVE { add_space_spec(tex_space,0); }
;
diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h
index 9ad1571..4c10373 100644
--- a/src/cuda-sim/ptx_ir.h
+++ b/src/cuda-sim/ptx_ir.h
@@ -222,6 +222,7 @@ public:
bool is_label() const { return m_is_label;}
bool is_shared() const { return m_is_shared;}
+ bool is_sstarr() const { return m_is_sstarr;}
bool is_const() const { return m_is_const;}
bool is_global() const { return m_is_global;}
bool is_local() const { return m_is_local;}
@@ -279,6 +280,7 @@ private:
bool m_address_valid;
bool m_is_label;
bool m_is_shared;
+ bool m_is_sstarr;
bool m_is_const;
bool m_is_global;
bool m_is_local;
@@ -314,10 +316,12 @@ public:
void set_label_address( const symbol *label, unsigned addr );
unsigned next_reg_num() { return ++m_reg_allocator;}
addr_t get_shared_next() { return m_shared_next;}
+ addr_t get_sstarr_next() { return m_sstarr_next;}
addr_t get_global_next() { return m_global_next;}
addr_t get_local_next() { return m_local_next;}
addr_t get_tex_next() { return m_tex_next;}
void alloc_shared( unsigned num_bytes ) { m_shared_next += num_bytes;}
+ void alloc_sstarr( unsigned num_bytes ) { m_sstarr_next += num_bytes;}
void alloc_global( unsigned num_bytes ) { m_global_next += num_bytes;}
void alloc_local( unsigned num_bytes ) { m_local_next += num_bytes;}
void alloc_tex( unsigned num_bytes ) { m_tex_next += num_bytes;}
@@ -339,6 +343,7 @@ public:
private:
unsigned m_reg_allocator;
unsigned m_shared_next;
+ unsigned m_sstarr_next;
unsigned m_const_next;
unsigned m_global_next;
unsigned m_local_next;
@@ -713,6 +718,7 @@ public:
}
return m_value.m_symbolic->is_shared();
}
+ bool is_sstarr() const { return m_value.m_symbolic->is_sstarr();}
bool is_const() const { return m_value.m_symbolic->is_const();}
bool is_global() const { return m_value.m_symbolic->is_global();}
bool is_local() const { return m_value.m_symbolic->is_local();}
diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc
index baa3bcd..7fc54e9 100644
--- a/src/cuda-sim/ptx_parser.cc
+++ b/src/cuda-sim/ptx_parser.cc
@@ -440,6 +440,20 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident
g_last_symbol->set_address( addr+addr_pad );
g_current_symbol_table->alloc_shared( num_bits/8 + addr_pad );
break;
+ case sstarr_space:
+ printf("GPGPU-Sim PTX: allocating sstarr region for \"%s\" ",
+ identifier);
+ fflush(stdout);
+ assert( (num_bits%8) == 0 );
+ addr = g_current_symbol_table->get_sstarr_next();
+ addr_pad = pad_address(addr, num_bits/8, 128);
+ printf("from 0x%x to 0x%lx (sstarr memory space)\n",
+ addr+addr_pad,
+ addr+addr_pad + num_bits/8);
+ fflush(stdout);
+ g_last_symbol->set_address( addr+addr_pad );
+ g_current_symbol_table->alloc_sstarr( num_bits/8 + addr_pad );
+ break;
case const_space:
if( array_ident == ARRAY_IDENTIFIER_NO_DIM ) {
printf("GPGPU-Sim PTX: deferring allocation of constant region for \"%s\" (need size information)\n", identifier );
diff --git a/src/cuda-sim/ptx_sim.cc b/src/cuda-sim/ptx_sim.cc
index a3e43aa..820287d 100644
--- a/src/cuda-sim/ptx_sim.cc
+++ b/src/cuda-sim/ptx_sim.cc
@@ -44,6 +44,7 @@ ptx_cta_info::ptx_cta_info( unsigned sm_idx )
m_sm_idx = sm_idx;
m_uid = g_ptx_cta_info_uid++;
+ m_bar_threads = 0;
}
void ptx_cta_info::add_thread( ptx_thread_info *thd )
@@ -128,6 +129,21 @@ unsigned ptx_cta_info::get_sm_idx() const
return m_sm_idx;
}
+unsigned ptx_cta_info::get_bar_threads() const
+{
+ return m_bar_threads;
+}
+
+void ptx_cta_info::inc_bar_threads()
+{
+ m_bar_threads++;
+}
+
+void ptx_cta_info::reset_bar_threads()
+{
+ m_bar_threads = 0;
+}
+
ptx_warp_info::ptx_warp_info()
{
reset_done_threads();
@@ -173,6 +189,7 @@ ptx_thread_info::ptx_thread_info( kernel_info_t &kernel )
m_last_memory_space = undefined_space;
m_branch_taken = 0;
m_shared_mem = NULL;
+ m_sstarr_mem = NULL;
m_warp_info = NULL;
m_cta_info = NULL;
m_local_mem = NULL;
diff --git a/src/cuda-sim/ptx_sim.h b/src/cuda-sim/ptx_sim.h
index e6eb02e..05acf20 100644
--- a/src/cuda-sim/ptx_sim.h
+++ b/src/cuda-sim/ptx_sim.h
@@ -158,8 +158,12 @@ public:
void register_thread_exit( ptx_thread_info *thd );
void register_deleted_thread( ptx_thread_info *thd );
unsigned get_sm_idx() const;
+ unsigned get_bar_threads() const;
+ void inc_bar_threads();
+ void reset_bar_threads();
private:
+ unsigned m_bar_threads;
unsigned long long m_uid;
unsigned m_sm_idx;
std::set<ptx_thread_info*> m_threads_in_cta;
@@ -169,7 +173,7 @@ private:
class ptx_warp_info {
public:
- ptx_warp_info();
+ ptx_warp_info(); // add get_core or something, or threads?
unsigned get_done_threads() const;
void inc_done_threads();
void reset_done_threads();
@@ -438,6 +442,7 @@ public:
memory_space_t m_last_memory_space;
dram_callback_t m_last_dram_callback;
memory_space *m_shared_mem;
+ memory_space *m_sstarr_mem;
memory_space *m_local_mem;
ptx_warp_info *m_warp_info;
ptx_cta_info *m_cta_info;
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index 58a5d16..3bd1892 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -1081,6 +1081,9 @@ void shader_core_ctx::mem_instruction_stats(const warp_inst_t &inst)
case shared_space:
m_stats->gpgpu_n_shmem_insn += active_count;
break;
+ case sstarr_space:
+ m_stats->gpgpu_n_sstarr_insn += active_count;
+ break;
case const_space:
m_stats->gpgpu_n_const_insn += active_count;
break;
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index d17e51d..92cdb5b 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -403,6 +403,7 @@ void shader_core_stats::print( FILE* fout ) const
fprintf(fout, "gpgpu_n_load_insn = %d\n", gpgpu_n_load_insn);
fprintf(fout, "gpgpu_n_store_insn = %d\n", gpgpu_n_store_insn);
fprintf(fout, "gpgpu_n_shmem_insn = %d\n", gpgpu_n_shmem_insn);
+ fprintf(fout, "gpgpu_n_shmem_insn = %d\n", gpgpu_n_sstarr_insn);
fprintf(fout, "gpgpu_n_tex_insn = %d\n", gpgpu_n_tex_insn);
fprintf(fout, "gpgpu_n_const_mem_insn = %d\n", gpgpu_n_const_insn);
fprintf(fout, "gpgpu_n_param_mem_insn = %d\n", gpgpu_n_param_insn);
diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h
index bdd8dbe..db2af01 100644
--- a/src/gpgpu-sim/shader.h
+++ b/src/gpgpu-sim/shader.h
@@ -1388,6 +1388,7 @@ struct shader_core_stats_pod {
unsigned gpgpu_n_load_insn;
unsigned gpgpu_n_store_insn;
unsigned gpgpu_n_shmem_insn;
+ unsigned gpgpu_n_sstarr_insn;
unsigned gpgpu_n_tex_insn;
unsigned gpgpu_n_const_insn;
unsigned gpgpu_n_param_insn;