diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cuda-sim/instructions.cc | 71 | ||||
| -rw-r--r-- | src/cuda-sim/opcodes.def | 1 | ||||
| -rw-r--r-- | src/cuda-sim/ptx.l | 1 |
3 files changed, 73 insertions, 0 deletions
diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 4537bd0..fd9a9ac 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -674,6 +674,77 @@ void abs_impl( const ptx_instruction *pI, ptx_thread_info *thread ) thread->set_operand_value(dst,d, i_type, thread, pI); } +void addp_impl( const ptx_instruction *pI, ptx_thread_info *thread ) +{ + //PTXPlus add instruction with carry (carry is kept in a predicate) register + ptx_reg_t src1_data, src2_data, src3_data, data; + int overflow = 0; + int carry = 0; + + const operand_info &dst = pI->dst(); //get operand info of sources and destination + const operand_info &src1 = pI->src1(); //use them to determine that they are of type 'register' + const operand_info &src2 = pI->src2(); + const operand_info &src3 = pI->src3(); + + unsigned i_type = pI->get_type(); + src1_data = thread->get_operand_value(src1, dst, i_type, thread, 1); + src2_data = thread->get_operand_value(src2, dst, i_type, thread, 1); + src3_data = thread->get_operand_value(src3, dst, i_type, thread, 1); + + unsigned rounding_mode = pI->rounding_mode(); + int orig_rm = fegetround(); + switch ( rounding_mode ) { + case RN_OPTION: break; + case RZ_OPTION: fesetround( FE_TOWARDZERO ); break; + default: assert(0); break; + } + + //performs addition. Sets carry and overflow if needed. + //src3_data.pred&0x4 is the carry flag + switch ( i_type ) { + case S8_TYPE: + data.s64 = (src1_data.s64 & 0x0000000FF) + (src2_data.s64 & 0x0000000FF) + (src3_data.pred & 0x4); + if(((src1_data.s64 & 0x80)-(src2_data.s64 & 0x80)) == 0) {overflow=((src1_data.s64 & 0x80)-(data.s64 & 0x80))==0?0:1; } + carry = (data.u64 & 0x000000100)>>8; + break; + case S16_TYPE: + data.s64 = (src1_data.s64 & 0x00000FFFF) + (src2_data.s64 & 0x00000FFFF) + (src3_data.pred & 0x4); + if(((src1_data.s64 & 0x8000)-(src2_data.s64 & 0x8000)) == 0) {overflow=((src1_data.s64 & 0x8000)-(data.s64 & 0x8000))==0?0:1; } + carry = (data.u64 & 0x000010000)>>16; + break; + case S32_TYPE: + data.s64 = (src1_data.s64 & 0x0FFFFFFFF) + (src2_data.s64 & 0x0FFFFFFFF) + (src3_data.pred & 0x4); + if(((src1_data.s64 & 0x80000000)-(src2_data.s64 & 0x80000000)) == 0) {overflow=((src1_data.s64 & 0x80000000)-(data.s64 & 0x80000000))==0?0:1; } + carry = (data.u64 & 0x100000000)>>32; + break; + case S64_TYPE: + data.s64 = src1_data.s64 + src2_data.s64 + (src3_data.pred & 0x4); + break; + case U8_TYPE: + data.u64 = (src1_data.u64 & 0xFF) + (src2_data.u64 & 0xFF) + (src3_data.pred & 0x4); + carry = (data.u64 & 0x100)>>8; + break; + case U16_TYPE: + data.u64 = (src1_data.u64 & 0xFFFF) + (src2_data.u64 & 0xFFFF) + (src3_data.pred & 0x4); + carry = (data.u64 & 0x10000)>>16; + break; + case U32_TYPE: + data.u64 = (src1_data.u64 & 0xFFFFFFFF) + (src2_data.u64 & 0xFFFFFFFF) + (src3_data.pred & 0x4); + carry = (data.u64 & 0x100000000)>>32; + break; + case U64_TYPE: + data.s64 = src1_data.s64 + src2_data.s64 + (src3_data.pred & 0x4); + break; + case F16_TYPE: assert(0); break; + case F32_TYPE: data.f32 = src1_data.f32 + src2_data.f32; break; + case F64_TYPE: case FF64_TYPE: data.f64 = src1_data.f64 + src2_data.f64; break; + default: assert(0); break; + } + fesetround( orig_rm ); + + thread->set_operand_value(dst, data, i_type, thread, pI, overflow, carry ); +} + void add_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { ptx_reg_t src1_data, src2_data, data; diff --git a/src/cuda-sim/opcodes.def b/src/cuda-sim/opcodes.def index 0963fa6..adeea86 100644 --- a/src/cuda-sim/opcodes.def +++ b/src/cuda-sim/opcodes.def @@ -39,6 +39,7 @@ Other 10 */ OP_DEF(ABS_OP,abs_impl,"abs",1,1) OP_DEF(ADD_OP,add_impl,"add",1,1) +OP_DEF(ADDP_OP,addp_impl,"addp",1,1) OP_DEF(ADDC_OP,addc_impl,"addc",1,1) OP_DEF(AND_OP,and_impl,"and",1,1) OP_DEF(ANDN_OP,andn_impl,"andn",1,1) diff --git a/src/cuda-sim/ptx.l b/src/cuda-sim/ptx.l index 8c330fc..1d50a8d 100644 --- a/src/cuda-sim/ptx.l +++ b/src/cuda-sim/ptx.l @@ -53,6 +53,7 @@ int ptx_error( const char *s ); abs TC; ptx_lval.int_value = ABS_OP; return OPCODE; add TC; ptx_lval.int_value = ADD_OP; return OPCODE; +addp TC; ptx_lval.int_value = ADDP_OP; return OPCODE; addc TC; ptx_lval.int_value = ADDC_OP; return OPCODE; and TC; ptx_lval.int_value = AND_OP; return OPCODE; andn TC; ptx_lval.int_value = ANDN_OP; return OPCODE; |
