diff options
| author | Lucy Liu <[email protected]> | 2020-07-03 13:09:18 -0700 |
|---|---|---|
| committer | Lucy Liu <[email protected]> | 2020-07-03 13:09:18 -0700 |
| commit | 52bee41cfea17f13e93cc1fb812c125fd44bac7b (patch) | |
| tree | 5c1657b9bdae72a3958330e03bb0ea8683a7bea5 | |
| parent | 708a249f854cedb08b0b5e494f45f2371f0525a6 (diff) | |
add activemask, bfind, vmin, and vmax implementations from Francois
| -rw-r--r-- | cuobjdump_to_ptxplus/cuobjdumpInst.cc | 41 | ||||
| -rw-r--r-- | src/abstract_hardware_model.h | 1 | ||||
| -rw-r--r-- | src/cuda-sim/cuda-sim.cc | 6 | ||||
| -rw-r--r-- | src/cuda-sim/instructions.cc | 137 | ||||
| -rw-r--r-- | src/cuda-sim/opcodes.def | 11 | ||||
| -rw-r--r-- | src/cuda-sim/ptx.l | 9 | ||||
| -rw-r--r-- | src/cuda-sim/ptx.y | 36 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_ir.cc | 3 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_ir.h | 3 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_parser.cc | 5 |
10 files changed, 195 insertions, 57 deletions
diff --git a/cuobjdump_to_ptxplus/cuobjdumpInst.cc b/cuobjdump_to_ptxplus/cuobjdumpInst.cc index 392f829..969313c 100644 --- a/cuobjdump_to_ptxplus/cuobjdumpInst.cc +++ b/cuobjdump_to_ptxplus/cuobjdumpInst.cc @@ -742,18 +742,18 @@ void cuobjdumpInst::printCuobjdumpOutputModifiers(const char* defaultMod) { std::list<std::string>::iterator typemod = m_typeModifiers->begin(); if (*typemod == ".U16" or *typemod == ".S16") { - std::list<std::string>::iterator dest_op = m_operands->begin(); - std::string& destination = *dest_op; + std::list<std::string>::iterator dest_op = m_operands->begin(); + std::string& destination = *dest_op; if (destination[destination.length()-1] == 'l') { - output(".lo"); // write to the lower 16-bits + output(".lo"); // write to the lower 16-bits } else if (destination[destination.length()-1] == 'h') { - output(".hi"); // write to the upper 16-bits + output(".hi"); // write to the upper 16-bits } else { - output(".wide"); // write to the whole 32-bits + output(".wide"); // write to the whole 32-bits } - return; + return; } - output(defaultMod); // default output modifier for mul + output(defaultMod); // default output modifier for mul } std::string int_default_mod () { return ".u32" ;} @@ -1357,9 +1357,9 @@ void cuobjdumpInst::printCuobjdumpPtxPlus(std::list<std::string> labelList, std: /*if(type1Size==16 && type2Size==16) output(".lo");*/ if(tempString[1] >= 'A' && tempString[1] <= 'Z') - tempString[1] += 32; + tempString[1] += 32; output(tempString); - } + } else { printCuobjdumpTypeModifiers(); @@ -1393,9 +1393,9 @@ void cuobjdumpInst::printCuobjdumpPtxPlus(std::list<std::string> labelList, std: type = (type1Size > type2Size) ? type1 : type2; strcpy(tempString, type.c_str()); if(tempString[1] >= 'A' && tempString[1] <= 'Z') - tempString[1] += 32; + tempString[1] += 32; output(tempString); - } + } else { printCuobjdumpTypeModifiers(); @@ -1407,7 +1407,7 @@ void cuobjdumpInst::printCuobjdumpPtxPlus(std::list<std::string> labelList, std: { printCuobjdumpPredicate(); output("mul"); - printCuobjdumpOutputModifiers(".lo"); + printCuobjdumpOutputModifiers(".lo"); printCuobjdumpBaseModifiers(); if(m_typeModifiers->size() == 0) @@ -1434,9 +1434,9 @@ void cuobjdumpInst::printCuobjdumpPtxPlus(std::list<std::string> labelList, std: /*if(type1Size==16 && type2Size==16) output(".lo");*/ if(tempString[1] >= 'A' && tempString[1] <= 'Z') - tempString[1] += 32; + tempString[1] += 32; output(tempString); - } + } else { printCuobjdumpTypeModifiers(); @@ -1468,10 +1468,10 @@ void cuobjdumpInst::printCuobjdumpPtxPlus(std::list<std::string> labelList, std: /*if(type1Size==16 && type2Size==16) output(".lo");*/ if(tempString[1] >= 'A' && tempString[1] <= 'Z') - tempString[1] += 32; + tempString[1] += 32; output(tempString); - } + } else printCuobjdumpTypeModifiers(); @@ -1506,10 +1506,10 @@ void cuobjdumpInst::printCuobjdumpPtxPlus(std::list<std::string> labelList, std: /*if(type1Size==16 && type2Size==16) output(".lo");*/ if(tempString[1] >= 'A' && tempString[1] <= 'Z') - tempString[1] += 32; + tempString[1] += 32; output(tempString); - } + } else printCuobjdumpTypeModifiers(); @@ -2071,6 +2071,11 @@ void cuobjdumpInst::printCuobjdumpPtxPlus(std::list<std::string> labelList, std: printCuobjdumpTypeModifiers(); printCuobjdumpOperands(); output(";"); + } else if(m_base == "ACTIVEMASK") { + printCuobjdumpPredicate(); + output("activemask.b32"); + printCuobjdumpOperands(); + output(";"); } else if(m_base == "DFMA") { diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 46534ab..c6e3b43 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -1132,6 +1132,7 @@ class warp_inst_t : public inst_t { void print(FILE *fout) const; unsigned get_uid() const { return m_uid; } unsigned get_schd_id() const { return m_scheduler_id; } + active_mask_t get_warp_active_mask() const { return m_warp_active_mask; } protected: unsigned m_uid; diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index 75dd3c8..451feb5 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -346,11 +346,11 @@ void function_info::ptx_assemble() { printf("GPGPU-Sim PTX: finding reconvergence points for \'%s\'...\n", m_name.c_str() ); create_basic_blocks(); connect_basic_blocks(); - bool modified = false; + bool modified = false; do { find_dominators(); find_idominators(); - modified = connect_break_targets(); + modified = connect_break_targets(); } while (modified == true); if ( g_debug_execution>=50 ) { @@ -1741,7 +1741,7 @@ void ptx_thread_info::ptx_exec_inst(warp_inst_t &inst, unsigned lane_id) { } else { const ptx_instruction *pI_saved = pI; ptx_instruction *pJ = NULL; - if (pI->get_opcode() == VOTE_OP) { + if( pI->get_opcode() == VOTE_OP || pI->get_opcode() == ACTIVEMASK_OP ) { pJ = new ptx_instruction(*pI); *((warp_inst_t *)pJ) = inst; // copy active mask information pI = pJ; 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; +} + diff --git a/src/cuda-sim/opcodes.def b/src/cuda-sim/opcodes.def index c4d6a83..aa85512 100644 --- a/src/cuda-sim/opcodes.def +++ b/src/cuda-sim/opcodes.def @@ -1,10 +1,10 @@ -// Copyright (c) 2009-2011, Tor M. Aamodt, Ali Bakhoda +// Copyright (c) 2009-2011, Tor M. Aamodt, Ali Bakhoda // The University of British Columbia // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: -// +// // Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // Redistributions in binary form must reproduce the above copyright notice, this @@ -13,7 +13,7 @@ // Neither the name of The University of British Columbia nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -27,7 +27,7 @@ /*6th operand of each OP_DEF reflects its classification */ -/*Type +/*Type ALU 1 MAD 2 Control 3 @@ -129,6 +129,7 @@ OP_DEF(VSHL_OP,vshl_impl,"vshl",0,11) OP_DEF(VSHR_OP,vshr_impl,"vshr",0,11) OP_DEF(VSUB_OP,vsub_impl,"vsub",0,11) OP_DEF(VOTE_OP,vote_impl,"vote",0,3) +OP_DEF(ACTIVEMASK_OP,activemask_impl,"activemask",1,3) OP_DEF(XOR_OP,xor_impl,"xor",1,1) OP_DEF(NOP_OP,nop_impl,"nop",0,7) OP_DEF(BREAK_OP,break_impl,"break",0,3) diff --git a/src/cuda-sim/ptx.l b/src/cuda-sim/ptx.l index 2dadda4..3592501 100644 --- a/src/cuda-sim/ptx.l +++ b/src/cuda-sim/ptx.l @@ -158,6 +158,7 @@ vshl TC; yylval->int_value = VSHL_OP; return OPCODE; vshr TC; yylval->int_value = VSHR_OP; return OPCODE; vsub TC; yylval->int_value = VSUB_OP; return OPCODE; vote TC; yylval->int_value = VOTE_OP; return OPCODE; +activemask TC; yylval->int_value = ACTIVEMASK_OP; return OPCODE; xor TC; yylval->int_value = XOR_OP; return OPCODE; nop TC; yylval->int_value = NOP_OP; return OPCODE; break TC; yylval->int_value = BREAK_OP; return OPCODE; @@ -252,7 +253,7 @@ breakaddr TC; yylval->int_value = BREAKADDR_OP; return OPCODE; [$%][a-zA-Z0-9_$]+ TC; yylval->string_value = strdup(yytext); return IDENTIFIER; [0-9]+\.[0-9]+ TC; sscanf(yytext,"%lf", &yylval->double_value); return DOUBLE_OPERAND; - + 0[xX][0-9a-fA-F]+U? TC; CHECK_UNSIGNED; sscanf(yytext,"%x", &yylval->int_value); return INT_OPERAND; 0[0-7]+U? TC; printf("GPGPU-Sim: ERROR ** parsing octal not (yet) implemented\n"); abort(); return INT_OPERAND; 0[bB][01]+U? TC; printf("GPGPU-Sim: ERROR ** parsing binary not (yet) implemented\n"); abort(); return INT_OPERAND; @@ -438,9 +439,9 @@ breakaddr TC; yylval->int_value = BREAKADDR_OP; return OPCODE; "*/" BEGIN(INITIAL); "CPTX_BEGIN" printf("BEGINNING CUSTOM PTX.\n"); BEGIN(INITIAL); [^C*\n]+ // eat comment in chunks -"C" // eat the lone C +"C" // eat the lone C "*" // eat the lone star -\n TC; +\n TC; } <INITIAL>{ @@ -470,7 +471,7 @@ int ptx_error( yyscan_t yyscanner, ptx_recognizer* recognizer, const char *s ) if( recognizer->linebuf[i] == '\t' ) printf("\t"); else printf(" "); } - + printf("^\n\n"); fflush(stdout); //exit(1); diff --git a/src/cuda-sim/ptx.y b/src/cuda-sim/ptx.y index b38f783..90accc9 100644 --- a/src/cuda-sim/ptx.y +++ b/src/cuda-sim/ptx.y @@ -50,8 +50,8 @@ class ptx_recognizer; %token <string_value> STRING %token <int_value> OPCODE %token <int_value> WMMA_DIRECTIVE -%token <int_value> LAYOUT -%token <int_value> CONFIGURATION +%token <int_value> LAYOUT +%token <int_value> CONFIGURATION %token ALIGN_DIRECTIVE %token BRANCHTARGETS_DIRECTIVE %token BYTE_DIRECTIVE @@ -295,7 +295,7 @@ ptr_space_spec: GLOBAL_DIRECTIVE { recognizer->add_ptr_spec(global_space); } ptr_align_spec: ALIGN_DIRECTIVE INT_OPERAND -statement_block: LEFT_BRACE statement_list RIGHT_BRACE +statement_block: LEFT_BRACE statement_list RIGHT_BRACE statement_list: directive_statement { recognizer->add_directive(); } | statement_list prototype_block {printf("Prototype statement detected. WARNING: this is not supported yet on GPGPU-SIM\n"); } @@ -315,7 +315,7 @@ directive_statement: variable_declaration SEMI_COLON | TARGET_DIRECTIVE IDENTIFIER { recognizer->target_header($2); } | FILE_DIRECTIVE INT_OPERAND STRING { recognizer->add_file($2,$3); } | FILE_DIRECTIVE INT_OPERAND STRING COMMA INT_OPERAND COMMA INT_OPERAND { recognizer->add_file($2,$3); } - | LOC_DIRECTIVE INT_OPERAND INT_OPERAND INT_OPERAND + | LOC_DIRECTIVE INT_OPERAND INT_OPERAND INT_OPERAND | PRAGMA_DIRECTIVE STRING SEMI_COLON { recognizer->add_pragma($2); } | function_decl SEMI_COLON {/*Do nothing*/} ; @@ -336,7 +336,7 @@ identifier_spec: IDENTIFIER { recognizer->add_identifier($1,0,NON_ARRAY_IDENTIFI int i,lbase,l; char *id = NULL; lbase = strlen($1); - for( i=0; i < $3; i++ ) { + for( i=0; i < $3; i++ ) { l = lbase + (int)log10(i+1)+10; id = (char*) malloc(l); snprintf(id,l,"%s%u",$1,i); @@ -348,10 +348,10 @@ identifier_spec: IDENTIFIER { recognizer->add_identifier($1,0,NON_ARRAY_IDENTIFI | IDENTIFIER LEFT_SQUARE_BRACKET INT_OPERAND RIGHT_SQUARE_BRACKET { recognizer->add_identifier($1,$3,ARRAY_IDENTIFIER); recognizer->func_header_info($1); recognizer->func_header_info_int("[",$3); recognizer->func_header_info("]");} ; -var_spec_list: var_spec +var_spec_list: var_spec | var_spec_list var_spec; -var_spec: space_spec +var_spec: space_spec | type_spec | align_spec | VISIBLE_DIRECTIVE @@ -376,8 +376,8 @@ addressable_spec: CONST_DIRECTIVE { recognizer->add_space_spec(const_space,$1); | TEX_DIRECTIVE { recognizer->add_space_spec(tex_space,0); } ; -type_spec: scalar_type - | vector_spec scalar_type +type_spec: scalar_type + | vector_spec scalar_type ; vector_spec: V2_TYPE { recognizer->add_option(V2_TYPE); recognizer->func_header_info(".v2");} @@ -417,14 +417,14 @@ literal_list: literal_operand // TODO: This is currently hardcoded to handle and ignore one specific case // that all prototype statements follow in the PTX from Pytorch. As a -// workaround, this parses and ignores both the prototype declaration -// and calling of the prototype (which conveniently comes right after the -// declaration for all cases.) This should be changed to handle both +// workaround, this parses and ignores both the prototype declaration +// and calling of the prototype (which conveniently comes right after the +// declaration for all cases.) This should be changed to handle both // declaring the prototype, and actually calling it. prototype_block: prototype_decl prototype_call -prototype_decl: IDENTIFIER COLON CALLPROTOTYPE_DIRECTIVE LEFT_PAREN prototype_param RIGHT_PAREN IDENTIFIER LEFT_PAREN prototype_param RIGHT_PAREN SEMI_COLON - +prototype_decl: IDENTIFIER COLON CALLPROTOTYPE_DIRECTIVE LEFT_PAREN prototype_param RIGHT_PAREN IDENTIFIER LEFT_PAREN prototype_param RIGHT_PAREN SEMI_COLON + prototype_call: OPCODE LEFT_PAREN IDENTIFIER RIGHT_PAREN COMMA operand COMMA LEFT_PAREN IDENTIFIER RIGHT_PAREN COMMA IDENTIFIER SEMI_COLON | OPCODE IDENTIFIER COMMA LEFT_PAREN IDENTIFIER RIGHT_PAREN COMMA IDENTIFIER SEMI_COLON @@ -439,7 +439,7 @@ instruction_statement: instruction SEMI_COLON instruction: opcode_spec LEFT_PAREN operand RIGHT_PAREN { recognizer->set_return(); } COMMA operand COMMA LEFT_PAREN operand_list RIGHT_PAREN | opcode_spec operand COMMA LEFT_PAREN operand_list RIGHT_PAREN | opcode_spec operand COMMA LEFT_PAREN RIGHT_PAREN - | opcode_spec operand_list + | opcode_spec operand_list | opcode_spec ; @@ -468,8 +468,8 @@ option: type_spec | compare_spec | addressable_spec | rounding_mode - | wmma_spec - | prmt_spec + | wmma_spec + | prmt_spec | SYNC_OPTION { recognizer->add_option(SYNC_OPTION); } | ARRIVE_OPTION { recognizer->add_option(ARRIVE_OPTION); } | RED_OPTION { recognizer->add_option(RED_OPTION); } @@ -609,7 +609,7 @@ vector_operand: LEFT_BRACE IDENTIFIER COMMA IDENTIFIER RIGHT_BRACE { recognizer- ; tex_operand: LEFT_SQUARE_BRACKET IDENTIFIER COMMA { recognizer->add_scalar_operand($2); } - vector_operand + vector_operand RIGHT_SQUARE_BRACKET ; diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc index aa1c25a..e5b5fb7 100644 --- a/src/cuda-sim/ptx_ir.cc +++ b/src/cuda-sim/ptx_ir.cc @@ -1147,7 +1147,8 @@ static std::list<operand_info> check_operands( const std::list<operand_info> &operands, gpgpu_context *ctx) { static int g_warn_literal_operands_two_type_inst; if ((opcode == CVT_OP) || (opcode == SET_OP) || (opcode == SLCT_OP) || - (opcode == TEX_OP) || (opcode == MMA_OP) || (opcode == DP4A_OP)) { + (opcode == TEX_OP) || (opcode == MMA_OP) || (opcode == DP4A_OP) || + (opcode == VMIN_OP) || (opcode == VMAX_OP) ) { // just make sure these do not have have const operands... if (!g_warn_literal_operands_two_type_inst) { std::list<operand_info>::const_iterator o; diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h index 6627847..26283a6 100644 --- a/src/cuda-sim/ptx_ir.h +++ b/src/cuda-sim/ptx_ir.h @@ -965,6 +965,9 @@ class ptx_instruction : public warp_inst_t { bool get_pred_neg() const { return m_neg_pred; } int get_pred_mod() const { return m_pred_mod; } const char *get_source() const { return m_source.c_str(); } + + const std::list<int> get_scalar_type() const {return m_scalar_type;} + const std::list<int> get_options() const {return m_options;} typedef std::vector<operand_info>::const_iterator const_iterator; diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc index 3ae8de3..549c08c 100644 --- a/src/cuda-sim/ptx_parser.cc +++ b/src/cuda-sim/ptx_parser.cc @@ -624,8 +624,9 @@ void ptx_recognizer::add_scalar_type_spec(int type_spec) { parse_assert((g_opcode == -1) || (g_opcode == CVT_OP) || (g_opcode == SET_OP) || (g_opcode == SLCT_OP) || (g_opcode == TEX_OP) || (g_opcode == MMA_OP) || - (g_opcode == DP4A_OP), - "only cvt, set, slct, tex and dp4a can have more than one " + (g_opcode == DP4A_OP) || (g_opcode == VMIN_OP) || + (g_opcode == VMAX_OP), + "only cvt, set, slct, tex, vmin, vmax and dp4a can have more than one " "type specifier."); } g_scalar_type_spec = type_spec; |
