summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cuobjdump_to_ptxplus/cuobjdumpInst.cc16
-rw-r--r--cuobjdump_to_ptxplus/sass.l2
-rw-r--r--cuobjdump_to_ptxplus/sass.y9
-rw-r--r--src/cuda-sim/instructions.cc71
-rw-r--r--src/cuda-sim/opcodes.def1
-rw-r--r--src/cuda-sim/ptx.l1
6 files changed, 94 insertions, 6 deletions
diff --git a/cuobjdump_to_ptxplus/cuobjdumpInst.cc b/cuobjdump_to_ptxplus/cuobjdumpInst.cc
index b014888..e4bf0b0 100644
--- a/cuobjdump_to_ptxplus/cuobjdumpInst.cc
+++ b/cuobjdump_to_ptxplus/cuobjdumpInst.cc
@@ -938,6 +938,22 @@ void cuobjdumpInst::printCuobjdumpPtxPlus(std::list<std::string> labelList, std:
printCuobjdumpOperands();
output(";");
}
+ else if(strstr(m_base, "IADD.CARRY")){
+ std::string pred = "C0";
+ pred[1] = m_base[10];
+ this->addOperand(pred.c_str());
+ printCuobjdumpPredicate();
+ output("addp");
+ printCuobjdumpBaseModifiers();
+
+ if(m_typeModifiers->getSize() == 0)
+ output(int_default_mod()); //TODO: setting default type modifier but I'm not sure if this is right.
+ else
+ printCuobjdumpTypeModifiers();
+
+ printCuobjdumpOperands();
+ output(";");
+ }
else if(strcmp(m_base, "IADD")==0)
{
printCuobjdumpPredicate();
diff --git a/cuobjdump_to_ptxplus/sass.l b/cuobjdump_to_ptxplus/sass.l
index ea1e052..88187f5 100644
--- a/cuobjdump_to_ptxplus/sass.l
+++ b/cuobjdump_to_ptxplus/sass.l
@@ -78,6 +78,7 @@ STS yylval.string_value = strdup(yytext); return STS;
LD yylval.string_value = strdup(yytext); return SASS_LD;
ST yylval.string_value = strdup(yytext); return SASS_ST;
IADD yylval.string_value = strdup(yytext); return IADD;
+IADD\.CARRY{numeric} yylval.string_value = strdup(yytext); return IADDCARRY;
IADD32 yylval.string_value = strdup(yytext); return IADD32;
IADD32I yylval.string_value = strdup(yytext); return IADD32I;
IMAD yylval.string_value = strdup(yytext); return IMAD;
@@ -160,7 +161,6 @@ NEU yylval.string_value = strdup(yytext); return NEU;
\.IR yylval.string_value = strdup(yytext); /*return DOTIR;*/
\.UN yylval.string_value = strdup(yytext); return DOTUN;
\.NODEP yylval.string_value = strdup(yytext); return DOTNODEP;
-\.CARRY0 yylval.string_value = strdup(yytext); return DOTCARRY0;
\.SAT yylval.string_value = strdup(yytext);
diff --git a/cuobjdump_to_ptxplus/sass.y b/cuobjdump_to_ptxplus/sass.y
index 634757b..33785a0 100644
--- a/cuobjdump_to_ptxplus/sass.y
+++ b/cuobjdump_to_ptxplus/sass.y
@@ -22,7 +22,7 @@ cuobjdumpInst *instEntry;
%token <string_value> BAR
%token <string_value> ADA AND ANDS BRA CAL COS DADD DFMA DMUL EX2 F2F F2I FADD
%token <string_value> FADD32 FADD32I FMAD FMAD32I FMUL FMUL32 FMUL32I FSET G2R
-%token <string_value> GLD GST I2F I2I IADD IADD32 IADD32I IMAD IMAD24 IMAD32I IMAD32
+%token <string_value> GLD GST I2F I2I IADD IADD32 IADD32I IMAD IMAD24 IMAD32I IMAD32 IADDCARRY
%token <string_value> IMUL IMUL24 IMULS24 IMUL32 IMUL32S24 IMUL32U24 IMUL32I IMUL32I24 IMUL32IS24
%token <string_value> ISET LG2 LLD LST MOV MOV32 MVC MVI NOP NOT NOTS OR ORS
%token <string_value> R2A R2G R2GU16U8 RCP RCP32 RET RRO RSQ SIN SHL SHR SSY XOR XORS
@@ -31,7 +31,7 @@ cuobjdumpInst *instEntry;
%token <string_value> EQ EQU GE GEU GT GTU LE LEU LT LTU NE NEU
%token <string_value> DOTBEXT DOTS DOTSFU
-%token <string_value> DOTTRUNC DOTIR DOTUN DOTNODEP DOTCARRY0 DOTSAT
+%token <string_value> DOTTRUNC DOTIR DOTUN DOTNODEP DOTSAT
%token <string_value> DOTF16 DOTF32 DOTF64 DOTS8 DOTS16 DOTS32 DOTS64 DOTS128 DOTU8 DOTU16 DOTU32 DOTU24 DOTU64
%token <string_value> DOTHI DOTNOINC
%token <string_value> DOTEQ DOTEQU DOTGE DOTGEU DOTGT DOTGTU DOTLE DOTLEU DOTLT DOTLTU DOTNE DOTNEU DOTNSF DOTSF DOTCARRY
@@ -147,7 +147,7 @@ simpleInstructions : ADA | AND | ANDS | COS | DADD | DFMA | DMUL | EX2 | F2F
| NOT | NOTS | OR | ORS | R2A | R2G | R2GU16U8 | RCP | RCP32 | RET | RRO
| RSQ | SHL | SHR | SIN | SSY | XOR | XORS | S2R | SASS_LD | STS
| LDS | SASS_ST | EXIT | BAR | IMIN | IMAX | A2R | FMAX | FMIN
- | TEX | TEX32 | C2R | BRK | R2C
+ | TEX | TEX32 | C2R | BRK | R2C | IADDCARRY
;
pbkInstruction : PBK {
@@ -264,8 +264,7 @@ modifier : opTypes { printf($1); g_instList->getListEnd().addTypeModifier($1);}
| DOTPOPC { g_instList->getListEnd().addBaseModifier(".popc"); }
| DOTIR { g_instList->getListEnd().addBaseModifier(".ir"); }
| DOTUN { /*g_instList->getListEnd().addBaseModifier(".un"); */}
- | DOTNODEP { /*g_instList->getListEnd().addBaseModifier(".nodep"); */}
- | DOTCARRY0 { /*g_instList->getListEnd().addBaseModifier(".carry0"); */}
+ | DOTNODEP { /*g_instList->getListEnd().addBaseModifier(".nodep"); */}
;
opTypes : DOTF16 //{ printf($1); g_instList->getListEnd().addTypeModifier($1);}
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;