diff options
Diffstat (limited to 'src/cuda-sim/ptx_parser.cc')
| -rw-r--r-- | src/cuda-sim/ptx_parser.cc | 147 |
1 files changed, 145 insertions, 2 deletions
diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc index 05ce397..d4a892f 100644 --- a/src/cuda-sim/ptx_parser.cc +++ b/src/cuda-sim/ptx_parser.cc @@ -94,6 +94,7 @@ type_info *g_var_type = NULL; // instruction definition stuff: const symbol *g_pred; int g_neg_pred; +int g_pred_mod; symbol *g_label; int g_opcode = -1; std::list<operand_info> g_operands; @@ -165,6 +166,7 @@ void init_instruction_state() DPRINTF("init_instruction_state"); g_pred = NULL; g_neg_pred = 0; + g_pred_mod = -1; g_label = NULL; g_opcode = -1; g_options.clear(); @@ -291,7 +293,8 @@ void add_instruction() DPRINTF("add_instruction: %s", ((g_opcode>0)?g_opcode_string[g_opcode]:"<label>") ); ptx_instruction *i = new ptx_instruction( g_opcode, g_pred, - g_neg_pred, + g_neg_pred, + g_pred_mod, g_label, g_operands, g_return_var, @@ -495,6 +498,21 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident } } +void add_constptr(const char* identifier1, const char* identifier2, int offset) +{ + symbol *s1 = g_current_symbol_table->lookup(identifier1); + const symbol *s2 = g_current_symbol_table->lookup(identifier2); + parse_assert( s1 != NULL, "'from' constant identifier does not exist."); + parse_assert( s1 != NULL, "'to' constant identifier does not exist."); + + unsigned addr = s2->get_address(); + + printf("GPGPU-Sim PTX: moving \"%s\" from 0x%x to 0x%x (%s+%x)\n", + identifier1, s1->get_address(), addr+offset, identifier2, offset); + + s1->set_address( addr + offset ); +} + void add_function_arg() { if( g_func_info ) { @@ -570,7 +588,7 @@ void add_opcode( int opcode ) g_opcode = opcode; } -void add_pred( const char *identifier, int neg ) +void add_pred( const char *identifier, int neg, int predModifier ) { DPRINTF("add_pred"); const symbol *s = g_current_symbol_table->lookup(identifier); @@ -580,6 +598,7 @@ void add_pred( const char *identifier, int neg ) } g_pred = s; g_neg_pred = neg; + g_pred_mod = predModifier; } void add_option( int option ) @@ -588,6 +607,19 @@ void add_option( int option ) g_options.push_back( option ); } +void add_double_operand( const char *d1, const char *d2 ) +{ + //operands that access two variables. + //eg. s[$ofs1+$r0], g[$ofs1+=$r0] + //TODO: Not sure if I'm going to use this for storing to two destinations or not. + + DPRINTF("add_double_operand"); + const symbol *s1 = g_current_symbol_table->lookup(d1); + const symbol *s2 = g_current_symbol_table->lookup(d2); + parse_assert( s1 != NULL && s2 != NULL, "component(s) missing declarations."); + g_operands.push_back( operand_info(s1,s2) ); +} + void add_2vector_operand( const char *d1, const char *d2 ) { DPRINTF("add_2vector_operand"); @@ -631,6 +663,109 @@ void add_memory_operand() g_operands.back().make_memory_operand(); } +/*TODO: add other memory locations*/ +void change_memory_addr_space(const char *identifier) +{ + /*0 = N/A, not reading from memory + *1 = global memory + *2 = shared memory + *3 = const memory segment + *4 = local memory segment + */ + + bool recognizedType = false; + + DPRINTF("change_memory_addr_space"); + assert( !g_operands.empty() ); + if(!strcmp(identifier, "g")) + { + g_operands.back().set_addr_space(1); + recognizedType = true; + } + if(!strcmp(identifier, "s")) + { + g_operands.back().set_addr_space(2); + recognizedType = true; + } + // For constants, check if the first character is 'c' + char c[2]; + strncpy(c, identifier, 1); c[1] = '\0'; + if(!strcmp(c, "c")) + { + g_operands.back().set_addr_space(3); + parse_assert(g_current_symbol_table->lookup(identifier) != NULL, "Constant was not defined."); + g_operands.back().set_const_mem_offset(g_current_symbol_table->lookup(identifier)->get_address()); + recognizedType = true; + } + // For local memory, check if the first character is 'l' + char l[2]; + strncpy(l, identifier, 1); l[1] = '\0'; + if(!strcmp(l, "l")) + { + g_operands.back().set_addr_space(4); + parse_assert(g_current_symbol_table->lookup(identifier) != NULL, "Local memory segment was not defined."); + g_operands.back().set_const_mem_offset(g_current_symbol_table->lookup(identifier)->get_address()); + recognizedType = true; + } + + parse_assert(recognizedType, "Error: unrecognized memory type."); +} + +void change_operand_lohi( int lohi ) +{ + /*0 = N/A, read entire operand + *1 = lo, reading from lowest bits + *2 = hi, reading from highest bits + */ + + DPRINTF("change_operand_lohi"); + assert( !g_operands.empty() ); + + g_operands.back().set_operand_lohi(lohi); + +} + +void change_double_operand_type( int operand_type ) +{ + /* + *-3 = reg / reg (set instruction, but both get same value) + *-2 = reg | reg (cvt instruction) + *-1 = reg | reg (set instruction) + *0 = N/A, default + *1 = reg + reg + *2 = reg += reg + *3 = reg += immediate + */ + + DPRINTF("change_double_operand_type"); + assert( !g_operands.empty() ); + + // For double destination operands, ensure valid instruction + if( operand_type == -1 || operand_type == -2 ) { + if((g_opcode == SET_OP)||(g_opcode == SETP_OP)) + g_operands.back().set_double_operand_type(-1); + else + g_operands.back().set_double_operand_type(-2); + } else if( operand_type == -3 ) { + if(g_opcode == SET_OP) + g_operands.back().set_double_operand_type(operand_type); + else + parse_assert(0, "Error: Unsupported use of double destination operand."); + } else { + g_operands.back().set_double_operand_type(operand_type); + } + +} + +void change_operand_neg( ) +{ + DPRINTF("change_operand_neg"); + assert( !g_operands.empty() ); + + g_operands.back().set_operand_neg(); + +} + void add_literal_int( int value ) { DPRINTF("add_literal_int"); @@ -741,3 +876,11 @@ void add_pragma( const char *str ) { printf("GPGPU-Sim PTX: Warning -- ignoring pragma '%s'\n", str ); } + +void version_header(double a) {} //intentional dummy function +void target_header(char* a) {} //intentional dummy function +void target_header2(char* a, char* b) {} //intentional dummy function + +void func_header(char* a) {} //intentional dummy function +void func_header_info(char* a) {} //intentional dummy function +void func_header_info_int(char* a, int b) {} //intentional dummy function |
