summaryrefslogtreecommitdiff
path: root/src/cuda-sim/instructions.cc
diff options
context:
space:
mode:
authorgpgpu-sim <[email protected]>2016-07-04 14:49:07 -0700
committerGitHub <[email protected]>2016-07-04 14:49:07 -0700
commitd90b6ad29a7cb24841841f7c54fcb4c2b1e929eb (patch)
treeaab816c03efb97100868528d4381472e5d82168c /src/cuda-sim/instructions.cc
parentaf4eee53ad30bb58c3ee53da71845ac95aa517e0 (diff)
parentf7c57e76c086ce417626f37ffc91097c839c687d (diff)
Merge pull request #26 from sspenst/dev
Additional support for CUDA 7.5
Diffstat (limited to 'src/cuda-sim/instructions.cc')
-rw-r--r--src/cuda-sim/instructions.cc79
1 files changed, 77 insertions, 2 deletions
diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc
index cf7f04a..02ce01c 100644
--- a/src/cuda-sim/instructions.cc
+++ b/src/cuda-sim/instructions.cc
@@ -1336,7 +1336,82 @@ void bar_impl( const ptx_instruction *pIin, ptx_thread_info *thread )
thread->m_last_dram_callback.instruction = pIin;
}
-void bfe_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); }
+void bfe_impl( const ptx_instruction *pI, ptx_thread_info *thread )
+{
+ unsigned i_type = pI->get_type();
+ unsigned msb = (i_type == U32_TYPE || i_type == S32_TYPE) ? 31 : 63;
+ const operand_info &dst = pI->dst();
+ const operand_info &src1 = pI->src1();
+ const operand_info &src2 = pI->src2();
+ const operand_info &src3 = pI->src3();
+ ptx_reg_t a = thread->get_operand_value(src1, dst, i_type, thread, 1);
+ ptx_reg_t b = thread->get_operand_value(src2, dst, i_type, thread, 1);
+ ptx_reg_t c = thread->get_operand_value(src3, dst, i_type, thread, 1);
+ unsigned pos = b.u32 & 0xFF;
+ unsigned len = c.u32 & 0xFF;
+ unsigned d = 0;
+ switch (i_type)
+ {
+ case U32_TYPE:
+ {
+ unsigned mask;
+ d = a.u32 >> pos;
+ mask = 0xFFFFFFFF >> (32 - len);
+ d &= mask;
+ break;
+ }
+ case U64_TYPE:
+ {
+ unsigned long mask;
+ d = a.u64 >> pos;
+ mask = 0xFFFFFFFFFFFFFFFF >> (64 - len);
+ d &= mask;
+ break;
+ }
+ case S32_TYPE:
+ {
+ unsigned mask;
+ unsigned min = MY_MIN_I(pos + len - 1, msb);
+ unsigned sbit = len == 0 ? 0 : (a.s32 >> min) & 0x1;
+ d = a.s32 >> pos;
+ if (sbit > 0)
+ {
+ mask = 0xFFFFFFFF << len;
+ d |= mask;
+ }
+ else
+ {
+ mask = 0xFFFFFFFF >> (32 - len);
+ d &= mask;
+ }
+ break;
+ }
+ case S64_TYPE:
+ {
+ unsigned long mask;
+ unsigned min = MY_MIN_I(pos + len - 1, msb);
+ unsigned sbit = len == 0 ? 0 : (a.s64 >> min) & 0x1;
+ d = a.s64 >> pos;
+ if (sbit > 0)
+ {
+ mask = 0xFFFFFFFFFFFFFFFF << len;
+ d |= mask;
+ }
+ else
+ {
+ mask = 0xFFFFFFFFFFFFFFFF >> (64 - len);
+ d &= mask;
+ }
+ break;
+ }
+ default:
+ printf("Operand type not supported for BFE instruction.\n");
+ abort();
+ return;
+ }
+ thread->set_operand_value(dst,d, i_type, thread, pI);
+}
+
void bfi_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); }
void bfind_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); }
@@ -2421,7 +2496,7 @@ void mad_impl( const ptx_instruction *pI, ptx_thread_info *thread )
mad_def(pI, thread, false);
}
-void madp_impl( const ptx_instruction *pI, ptx_thread_info *thread )
+void madc_impl( const ptx_instruction *pI, ptx_thread_info *thread )
{
mad_def(pI, thread, true);
}