summaryrefslogtreecommitdiff
path: root/src/cuda-sim/instructions.cc
diff options
context:
space:
mode:
authorLucy Liu <[email protected]>2020-07-03 13:09:18 -0700
committerLucy Liu <[email protected]>2020-07-03 13:09:18 -0700
commit52bee41cfea17f13e93cc1fb812c125fd44bac7b (patch)
tree5c1657b9bdae72a3958330e03bb0ea8683a7bea5 /src/cuda-sim/instructions.cc
parent708a249f854cedb08b0b5e494f45f2371f0525a6 (diff)
add activemask, bfind, vmin, and vmax implementations from Francois
Diffstat (limited to 'src/cuda-sim/instructions.cc')
-rw-r--r--src/cuda-sim/instructions.cc137
1 files changed, 131 insertions, 6 deletions
diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc
index bf9a040..886c6c0 100644
--- a/src/cuda-sim/instructions.cc
+++ b/src/cuda-sim/instructions.cc
@@ -166,6 +166,7 @@ void inst_not_implemented(const ptx_instruction *pI);
ptx_reg_t srcOperandModifiers(ptx_reg_t opData, operand_info opInfo,
operand_info dstInfo, unsigned type,
ptx_thread_info *thread);
+void video_mem_instruction(const ptx_instruction *pI, ptx_thread_info *thread, int op_code);
void sign_extend(ptx_reg_t &data, unsigned src_size, const operand_info &dst);
@@ -1709,8 +1710,40 @@ void bfi_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
}
thread->set_operand_value(dst, data, i_type, thread, pI);
}
-void bfind_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
- inst_not_implemented(pI);
+void bfind_impl(const ptx_instruction *pI, ptx_thread_info *thread)
+{
+ const operand_info &dst = pI->dst();
+ const operand_info &src1 = pI->src1();
+ const unsigned i_type = pI->get_type();
+
+ const ptx_reg_t src1_data = thread->get_operand_value(src1, dst, i_type, thread, 1);
+ const int msb = ( i_type == U32_TYPE || i_type == S32_TYPE) ? 31 : 63;
+
+ unsigned long a = 0;
+ switch (i_type)
+ {
+ case S32_TYPE: a = src1_data.s32; break;
+ case U32_TYPE: a = src1_data.u32; break;
+ case S64_TYPE: a = src1_data.s64; break;
+ case U64_TYPE: a = src1_data.u64; break;
+ default: assert(false); abort();
+ }
+
+ // negate negative signed inputs
+ if ( ( i_type == S32_TYPE || i_type == S64_TYPE ) && ( a & ( 1 << msb ) ) ) {
+ a = ~a;
+ }
+ uint32_t d_data = 0xffffffff;
+ for (uint32_t i = msb; i >= 0; i--) {
+ if (a & (1<<i)) { d_data = i; break; }
+ }
+
+ // if (.shiftamt && d != 0xffffffff) { d = msb - d; }
+
+ // store d
+ thread->set_operand_value(dst, d_data, U32_TYPE, thread, pI);
+
+
}
void bra_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
@@ -6301,11 +6334,17 @@ void vadd_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
void vmad_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
inst_not_implemented(pI);
}
-void vmax_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
- inst_not_implemented(pI);
+
+#define VMAX 0
+#define VMIN 1
+
+void vmax_impl(const ptx_instruction *pI, ptx_thread_info *thread)
+{
+ video_mem_instruction(pI, thread, VMAX);
}
-void vmin_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
- inst_not_implemented(pI);
+void vmin_impl(const ptx_instruction *pI, ptx_thread_info *thread)
+{
+ video_mem_instruction(pI, thread, VMIN);
}
void vset_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
inst_not_implemented(pI);
@@ -6400,6 +6439,15 @@ void vote_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
}
}
+void activemask_impl( const ptx_instruction *pI, ptx_thread_info *thread )
+{
+ active_mask_t l_activemask_bitset = pI->get_warp_active_mask();
+ uint32_t l_activemask_uint = static_cast<uint32_t>(l_activemask_bitset.to_ulong());
+
+ const operand_info &dst = pI->dst();
+ thread->set_operand_value(dst, l_activemask_uint, U32_TYPE, thread, pI);
+}
+
void xor_impl(const ptx_instruction *pI, ptx_thread_info *thread) {
ptx_reg_t src1_data, src2_data, data;
@@ -6477,3 +6525,80 @@ ptx_reg_t srcOperandModifiers(ptx_reg_t opData, operand_info opInfo,
return result;
}
+
+void video_mem_instruction(const ptx_instruction *pI, ptx_thread_info *thread, int op_code)
+{
+ const operand_info &dst = pI->dst(); // d
+ const operand_info &src1 = pI->src1(); // a
+ const operand_info &src2 = pI->src2(); // b
+ const operand_info &src3 = pI->src3(); // c
+
+ const unsigned i_type = pI->get_type();
+
+ std::list<int> scalar_type;
+ std::list<int> options;
+
+ ptx_reg_t a, b, ta, tb, c, data;
+
+ a = thread->get_operand_value(src1, dst, i_type, thread, 1);
+ b = thread->get_operand_value(src2, dst, i_type, thread, 1);
+ c = thread->get_operand_value(src3, dst, i_type, thread, 1);
+
+ // TODO: implement this
+ // ta = partSelectSignExtend( a, atype );
+ // tb = partSelectSignExtend( b, btype );
+ ta = a;
+ tb = b;
+
+ options = pI->get_options();
+ assert(options.size() == 1);
+
+ auto option = options.begin();
+ assert(*option == ATOMIC_MAX || *option == ATOMIC_MIN);
+
+ switch ( i_type ) {
+ case S32_TYPE: {
+ // assert all operands are S32_TYPE:
+ scalar_type = pI->get_scalar_type();
+ for (auto scalar : scalar_type)
+ {
+ assert(scalar == S32_TYPE);
+ }
+ assert(scalar_type.size() == 3);
+ scalar_type.clear();
+
+ switch (op_code)
+ {
+ case VMAX:
+ data.s32 = MY_MAX_I(ta.s32, tb.s32);
+ break;
+ case VMIN:
+ data.s32 = MY_MIN_I(ta.s32, tb.s32);
+ break;
+ default:
+ assert(0);
+ }
+
+ switch (*option)
+ {
+ case ATOMIC_MAX:
+ data.s32 = MY_MAX_I(data.s32, c.s32);
+ break;
+ case ATOMIC_MIN:
+ data.s32 = MY_MIN_I(data.s32, c.s32);
+ break;
+ default:
+ assert(0); // not yet implemented
+ }
+ break;
+
+ }
+ default:
+ assert(0); // not yet implemented
+ }
+
+ thread->set_operand_value(dst, data, i_type, thread, pI);
+
+ return;
+}
+