summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/abstract_hardware_model.h2
-rw-r--r--src/cuda-sim/cuda-sim.cc24
-rw-r--r--src/cuda-sim/instructions.cc80
-rw-r--r--src/cuda-sim/ptx_ir.h10
4 files changed, 88 insertions, 28 deletions
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index 9dc58d4..e00c941 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -826,7 +826,7 @@ public:
address_type reconvergence_pc; // -1 => not a branch, -2 => use function return address
unsigned out[8];
- unsigned in[8];
+ unsigned in[24];
unsigned char is_vectorin;
unsigned char is_vectorout;
int pred; // predicate register number
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc
index 006738a..62077e6 100644
--- a/src/cuda-sim/cuda-sim.cc
+++ b/src/cuda-sim/cuda-sim.cc
@@ -852,8 +852,10 @@ void ptx_instruction::pre_decode()
{
pc = m_PC;
isize = m_inst_size;
- for( unsigned i=0; i<4; i++) {
+ for(unsigned i=0; i<8; i++) {
out[i] = 0;
+ }
+ for(unsigned i=0; i<24; i++) {
in[i] = 0;
}
is_vectorin = 0;
@@ -922,6 +924,10 @@ void ptx_instruction::pre_decode()
if( num_elem >= 2 ) out[1] = o.reg2_num();
if( num_elem >= 3 ) out[2] = o.reg3_num();
if( num_elem >= 4 ) out[3] = o.reg4_num();
+ if( num_elem >= 5 ) out[4] = o.reg5_num();
+ if( num_elem >= 6 ) out[5] = o.reg6_num();
+ if( num_elem >= 7 ) out[6] = o.reg7_num();
+ if( num_elem >= 8 ) out[7] = o.reg8_num();
for (int i = 0; i < num_elem; i++)
arch_reg.dst[i] = o.arch_reg_num(i);
}
@@ -940,13 +946,17 @@ void ptx_instruction::pre_decode()
//assert(m == 0); //only support 1 vector operand (for textures) right now
is_vectorout = 1;
unsigned num_elem = o.get_vect_nelem();
- if( num_elem >= 1 ) in[0] = o.reg1_num();
- if( num_elem >= 2 ) in[1] = o.reg2_num();
- if( num_elem >= 3 ) in[2] = o.reg3_num();
- if( num_elem >= 4 ) in[3] = o.reg4_num();
+ if( num_elem >= 1 ) in[m+0] = o.reg1_num();
+ if( num_elem >= 2 ) in[m+1] = o.reg2_num();
+ if( num_elem >= 3 ) in[m+2] = o.reg3_num();
+ if( num_elem >= 4 ) in[m+3] = o.reg4_num();
+ if( num_elem >= 5 ) in[m+4] = o.reg5_num();
+ if( num_elem >= 6 ) in[m+5] = o.reg6_num();
+ if( num_elem >= 7 ) in[m+6] = o.reg7_num();
+ if( num_elem >= 8 ) in[m+7] = o.reg8_num();
for (int i = 0; i < num_elem; i++)
- arch_reg.src[i] = o.arch_reg_num(i);
- m+=4;
+ arch_reg.src[m+i] = o.arch_reg_num(i);
+ m+=num_elem;
}
}
}
diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc
index 7407269..446cdbf 100644
--- a/src/cuda-sim/instructions.cc
+++ b/src/cuda-sim/instructions.cc
@@ -748,7 +748,7 @@ void addp_impl( const ptx_instruction *pI, ptx_thread_info *thread )
case U64_TYPE:
data.s64 = src1_data.s64 + src2_data.s64 + (src3_data.pred & 0x4);
break;
- case F16_TYPE: assert(0); break;
+ case F16_TYPE: data.f16=src1_data.f16+src2_data.f16; break;//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;
@@ -826,7 +826,7 @@ void add_impl( const ptx_instruction *pI, ptx_thread_info *thread )
case U64_TYPE:
data.u64 = src1_data.u64 + src2_data.u64;
break;
- case F16_TYPE: assert(0); break;
+ case F16_TYPE: data.f16=src1_data.f16+src2_data.f16; break;//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;
@@ -1878,7 +1878,9 @@ ptx_reg_t f2x( ptx_reg_t x, unsigned from_width, unsigned to_width, int to_sign,
}
} else {
switch ( to_width ) {
- case 16: assert(0); break;
+ case 16: //assert(0); break;
+ y.f16 = x.f32;
+ break;
case 32: assert(0); break; // handled by f2f
case 64:
y.f64 = x.f32;
@@ -2140,7 +2142,7 @@ void ptx_round(ptx_reg_t& data, int rounding_mode, int type)
case U32_TYPE:
case U64_TYPE:
printf("Trying to round an integer??\n"); assert(0); break;
- case F16_TYPE: assert(0); break;
+ case F16_TYPE: data.f16=truncf(data.f16);break;//assert(0); break;
case F32_TYPE:
data.f32 = truncf(data.f32);
break;
@@ -2163,7 +2165,13 @@ void ptx_round(ptx_reg_t& data, int rounding_mode, int type)
case U32_TYPE:
case U64_TYPE:
printf("Trying to round an integer??\n"); assert(0); break;
- case F16_TYPE: assert(0); break;
+ case F16_TYPE:// assert(0); break;
+#if CUDART_VERSION >= 3000
+ data.f16 = nearbyintf(data.f16);
+#else
+ data.f16 = cuda_math::__cuda_nearbyintf(data.f16);
+#endif
+ break;
case F32_TYPE:
#if CUDART_VERSION >= 3000
data.f32 = nearbyintf(data.f32);
@@ -2186,7 +2194,7 @@ void ptx_round(ptx_reg_t& data, int rounding_mode, int type)
case U32_TYPE:
case U64_TYPE:
printf("Trying to round an integer??\n"); assert(0); break;
- case F16_TYPE: assert(0); break;
+ case F16_TYPE: data.f16=floorf(data.f16);break;//assert(0); break;
case F32_TYPE:
data.f32 = floorf(data.f32);
break;
@@ -2205,7 +2213,7 @@ void ptx_round(ptx_reg_t& data, int rounding_mode, int type)
case U32_TYPE:
case U64_TYPE:
printf("Trying to round an integer??\n"); assert(0); break;
- case F16_TYPE: assert(0); break;
+ case F16_TYPE: data.f16 = ceilf(data.f16); break; //assert(0); break;
case F32_TYPE: data.f32 = ceilf(data.f32); break;
case F64_TYPE: case FF64_TYPE: data.f64 = ceil(data.f64); break;
default: assert(0); break;
@@ -2246,7 +2254,10 @@ void ptx_saturate(ptx_reg_t& data, int saturation_mode, int type)
case U32_TYPE:
case U64_TYPE:
printf("Trying to clamp an integer to 1??\n"); assert(0); break;
- case F16_TYPE: assert(0); break;
+ case F16_TYPE: //assert(0); break;
+ if (data.f16 > 1.0f) data.f16 = 1.0f; //negative
+ if (data.f16 < 0.0f) data.f16 = 0.0f; //positive
+ break;
case F32_TYPE:
if (data.f32 > 1.0f) data.f32 = 1.0f; //negative
if (data.f32 < 0.0f) data.f32 = 0.0f; //positive
@@ -2270,8 +2281,8 @@ void cvt_impl( const ptx_instruction *pI, ptx_thread_info *thread )
unsigned rounding_mode = pI->rounding_mode();
unsigned saturation_mode = pI->saturation_mode();
- if ( to_type == F16_TYPE || from_type == F16_TYPE )
- abort();
+// if ( to_type == F16_TYPE || from_type == F16_TYPE )
+// abort();
int to_sign, from_sign;
size_t from_width, to_width;
@@ -2406,7 +2417,7 @@ void div_impl( const ptx_instruction *pI, ptx_thread_info *thread )
data.u32 = src1_data.u32 / src2_data.u32; break;
case B64_TYPE:
data.u64 = src1_data.u64 / src2_data.u64; break;
- case F16_TYPE: assert(0); break;
+ case F16_TYPE: data.f16 = src1_data.f16 / src2_data.f16; break;//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;
@@ -2744,9 +2755,24 @@ void mad_def( const ptx_instruction *pI, ptx_thread_info *thread, bool use_carry
if ( pI->is_lo() ) d.u64 = t.u64 + c.u64 + carry_bit.pred;
else assert(0);
break;
- case F16_TYPE:
- assert(0);
- break;
+ case F16_TYPE:{
+ // assert(0);
+ // break;
+ assert( use_carry == false);
+ int orig_rm = fegetround();
+ switch ( rounding_mode ) {
+ case RN_OPTION: break;
+ case RZ_OPTION: fesetround( FE_TOWARDZERO ); break;
+ default: assert(0); break;
+ }
+ d.f16 = a.f16 * b.f16 + c.f16;
+ if ( pI->saturation_mode() ) {
+ if ( d.f16 < 0 ) d.f16 = 0;
+ else if ( d.f16 > 1.0f ) d.f16 = 1.0f;
+ }
+ fesetround( orig_rm );
+ break;
+ }
case F32_TYPE: {
assert( use_carry == false);
int orig_rm = fegetround();
@@ -3046,9 +3072,25 @@ void mul_impl( const ptx_instruction *pI, ptx_thread_info *thread )
if ( pI->is_lo() ) d.u64 = t.u64;
else assert(0);
break;
- case F16_TYPE:
- assert(0);
- break;
+ case F16_TYPE:{
+ //assert(0);
+ //break;
+ int orig_rm = fegetround();
+ switch ( rounding_mode ) {
+ case RN_OPTION: break;
+ case RZ_OPTION: fesetround( FE_TOWARDZERO ); break;
+ default: assert(0); break;
+ }
+
+ d.f16 = a.f16 * b.f16;
+
+ if ( pI->saturation_mode() ) {
+ if ( d.f16 < 0 ) d.f16 = 0;
+ else if ( d.f16 > 1.0f ) d.f16 = 1.0f;
+ }
+ fesetround( orig_rm );
+ break;
+ }
case F32_TYPE: {
int orig_rm = fegetround();
switch ( rounding_mode ) {
@@ -3111,7 +3153,7 @@ void neg_impl( const ptx_instruction *pI, ptx_thread_info *thread )
case U32_TYPE:
case U64_TYPE:
assert(0); break;
- case F16_TYPE: assert(0); break;
+ case F16_TYPE: data.f16 =0.0f - src1_data.f16; break;//assert(0); break;
case F32_TYPE: data.f32 = 0.0f - src1_data.f32; break;
case F64_TYPE: case FF64_TYPE: data.f64 = 0.0f - src1_data.f64; break;
default: assert(0); break;
@@ -4165,7 +4207,7 @@ void sub_impl( const ptx_instruction *pI, ptx_thread_info *thread )
case B64_TYPE:
case U64_TYPE:
data.u64 = src1_data.u64 - src2_data.u64; break;
- case F16_TYPE: assert(0); break;
+ case F16_TYPE: data.f16 = src1_data.f16 - src2_data.f16; break;//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;
diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h
index ff24a66..833f175 100644
--- a/src/cuda-sim/ptx_ir.h
+++ b/src/cuda-sim/ptx_ir.h
@@ -656,7 +656,11 @@ public:
if( !m_value.m_vector_symbolic[1] ) return 1;
if( !m_value.m_vector_symbolic[2] ) return 2;
if( !m_value.m_vector_symbolic[3] ) return 3;
- return 4;
+ if( !m_value.m_vector_symbolic[4] ) return 4;
+ if( !m_value.m_vector_symbolic[5] ) return 5;
+ if( !m_value.m_vector_symbolic[6] ) return 6;
+ if( !m_value.m_vector_symbolic[7] ) return 7;
+ return 8;
}
const symbol* vec_symbol(int idx) const
@@ -718,6 +722,10 @@ public:
int reg2_num() const { return m_value.m_vector_symbolic[1]->reg_num();}
int reg3_num() const { return m_value.m_vector_symbolic[2]?m_value.m_vector_symbolic[2]->reg_num():0; }
int reg4_num() const { return m_value.m_vector_symbolic[3]?m_value.m_vector_symbolic[3]->reg_num():0; }
+ int reg5_num() const { return m_value.m_vector_symbolic[4]?m_value.m_vector_symbolic[4]->reg_num():0; }
+ int reg6_num() const { return m_value.m_vector_symbolic[5]?m_value.m_vector_symbolic[5]->reg_num():0; }
+ int reg7_num() const { return m_value.m_vector_symbolic[6]?m_value.m_vector_symbolic[6]->reg_num():0; }
+ int reg8_num() const { return m_value.m_vector_symbolic[7]?m_value.m_vector_symbolic[7]->reg_num():0; }
int arch_reg_num() const { return m_value.m_symbolic->arch_reg_num(); }
int arch_reg_num(unsigned n) const { return (m_value.m_vector_symbolic[n])? m_value.m_vector_symbolic[n]->arch_reg_num() : -1; }
bool is_label() const { return m_type == label_t;}