summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/shader.cc
diff options
context:
space:
mode:
authorInderpreet Singh <[email protected]>2011-12-26 00:07:19 -0800
committerAndrew Boktor <[email protected]>2014-08-14 13:19:01 -0700
commit20b3ca2e081e9ee076483ca06e382002709b54dd (patch)
tree0a23508d0d20a17457479f44b969e88a0e0a8474 /src/gpgpu-sim/shader.cc
parentb916cd600d109938a1621345bfc3c46da4bff4c6 (diff)
Fix for Bug 124 - ld.local.s8 instructions are not supported
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 11231]
Diffstat (limited to 'src/gpgpu-sim/shader.cc')
-rw-r--r--src/gpgpu-sim/shader.cc34
1 files changed, 25 insertions, 9 deletions
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 7ef5140..b513edb 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -795,16 +795,32 @@ unsigned shader_core_ctx::translate_local_memaddr( address_type localaddr, unsig
}
assert( thread_base < 4/*word size*/*max_concurrent_threads );
- assert(datasize%4 == 0);
- assert(datasize >= 4);
- assert(datasize/4 <= MAX_ACCESSES_PER_INSN_PER_THREAD); // max 32B
- assert(localaddr%4 == 0); // Required if accessing 4B per request, otherwise access will overflow into next thread's space
- for(unsigned i=0; i<datasize/4; i++) {
- address_type local_word = localaddr/4 + i;
- address_type linear_address = local_word*max_concurrent_threads*4 + thread_base + LOCAL_GENERIC_START;
- translated_addrs[i] = linear_address;
+ // If requested datasize > 4B, split into multiple 4B accesses
+ // otherwise do one sub-4 byte memory access
+ unsigned num_accesses = 0;
+
+ if(datasize >= 4) {
+ // >4B access, split into 4B chunks
+ assert(datasize%4 == 0); // Must be a multiple of 4B
+ num_accesses = datasize/4;
+ assert(num_accesses <= MAX_ACCESSES_PER_INSN_PER_THREAD); // max 32B
+ assert(localaddr%4 == 0); // Address must be 4B aligned - required if accessing 4B per request, otherwise access will overflow into next thread's space
+ for(unsigned i=0; i<num_accesses; i++) {
+ address_type local_word = localaddr/4 + i;
+ address_type linear_address = local_word*max_concurrent_threads*4 + thread_base + LOCAL_GENERIC_START;
+ translated_addrs[i] = linear_address;
+ }
+ } else {
+ // Sub-4B access, do only one access
+ assert(datasize > 0);
+ num_accesses = 1;
+ address_type local_word = localaddr/4;
+ address_type local_word_offset = localaddr%4;
+ assert( (localaddr+datasize-1)/4 == local_word ); // Make sure access doesn't overflow into next 4B chunk
+ address_type linear_address = local_word*max_concurrent_threads*4 + local_word_offset + thread_base + LOCAL_GENERIC_START;
+ translated_addrs[0] = linear_address;
}
- return datasize/4;
+ return num_accesses;
}
/////////////////////////////////////////////////////////////////////////////////////////