uint8_t execute_interpreter_cycle(cpu_registers* registers, bool nmi_flag) { static bool previous_nmi_flag = false; uint8_t cpu_cycles_executed = 0; uint8_t extra_cycles= 0; if(DMA_is_executing()) cpu_cycles_executed = execute_DMA(); else { uint8_t opcode = fetch_opcode(registers); increment_PC(registers); if(nmi_flag && !previous_nmi_flag) cpu_cycles_executed = execute_NMI(registers); else { #ifdef DEBUG print_debug_info(registers, opcode); #endif extra_cycles = execute_instruction(registers, opcode); cpu_cycles_executed = instruction_cycle_length[opcode] + extra_cycles; // Do not increment PC if we jump because it will skip the first instruction at least if(!is_JSR_or_JMP(opcode) && !is_RTI(opcode)) increment_PC_instruction_length(registers, opcode); } } previous_nmi_flag = nmi_flag; odd_cpu_cycle = cpu_cycles_executed & 0x1; return cpu_cycles_executed; }
//Executes all commmands stored in 'command_arr'. void execute_set_of_instructions(COMMAND* commands_arr, int* registers_arr, byte* mem, int* current_time, CONFIG* config, L1_CACHE* L1_cache, L2_CACHE* L2_cache ){ int instruction_counter = 1; int pc = 0; unsigned tag_L1; unsigned index_L1; unsigned offset_L1; unsigned tag_L2; unsigned index_L2; unsigned offset_L2; int way; int mem_to_L2_end_time_last_trans; while (strcmp(commands_arr[pc].cmd_type, "H") != 0){ parse_address(&offset_L1, &index_L1, &tag_L1, commands_arr[pc].inst_address, config->l1_block_size, config->l1_cache_size); parse_address(&offset_L2, &index_L2, &tag_L2, commands_arr[pc].inst_address, config->l2_block_size, config->l2_cache_size); if (!is_in_L1(index_L1, tag_L1,offset_L1,L1_cache, current_time, config)){ if (is_in_L2(index_L2, tag_L2,offset_L2,L2_cache,current_time,config)){ L2_to_L1_trans(L1_cache, offset_L1,index_L1,tag_L1,L2_cache,offset_L2,index_L2,tag_L2,*current_time,config,way,true); }else{ MEM_to_L2_trans(mem, L2_cache, offset_L2, index_L2, tag_L2,*current_time,config,NULL,way,true); way = !L2_cache->block_arr[index_L2].LRU; mem_to_L2_end_time_last_trans = L2_cache->block_arr[index_L2].block_trans_end_time[way]; L2_to_L1_trans(L1_cache, offset_L1,index_L1,tag_L1,L2_cache,offset_L2,index_L2,tag_L2,mem_to_L2_end_time_last_trans,config,way,true); } } execute_instruction(commands_arr[pc], commands_arr, registers_arr, mem, &pc); instruction_counter++; } }
void execute(Processor *processor,int prompt,int print) { Instruction instruction; /* fetch an instruction */ instruction.bits = load(memory,processor->PC,LENGTH_WORD); /* interactive-mode prompt */ if(prompt) { if(prompt==1) { printf("simulator paused,enter to continue..."); while(getchar()!='\n'); } printf("%08x: ",processor->PC); decode_instruction(instruction); } execute_instruction(instruction,processor,memory); // enforce $0 being hard-wired to 0 processor->R[0] = 0; // print trace if(print) { int i,j; for(i=0;i<8;i++) { for(j=0;j<4;j++) { printf("r%2d=%08x ",i*4+j,processor->R[i*4+j]); } puts(""); } } }
/* Simulate the code and output results to standard out */ void simulate(Instruction* code) { Change* list_of_effects = NULL; Change* last_effect = NULL; Change* new_effects; int instruction_count = 0; int operation_count = 0; int vect_operation_count = 0; /* Number of operations that can be vectorized. Uli 04/13/2011 */ int cycle_count = 0; while(code) { if (!((memory_stall(code,list_of_effects) && stall_on_memory) || (register_stall(code,list_of_effects) && stall_on_registers) || (branch_stall(list_of_effects) && stall_on_branches))) { if (!check_machine_constraints(code)) { fprintf(stderr,"Error: Machine constraints violated.\n"); exit(1); } new_effects = execute_instruction(code,&operation_count,&vect_operation_count); instruction_count++; if (!list_of_effects) { list_of_effects = new_effects; last_effect = new_effects; } else last_effect->next = new_effects; /* Move last effect to end */ if (last_effect) while(last_effect->next) last_effect = last_effect->next; /* Go to next instruction */ code = code->next; } list_of_effects = execute_changes(list_of_effects,&last_effect,&code); cycle_count++; } while(list_of_effects) { list_of_effects = execute_changes(list_of_effects,&last_effect,&code); cycle_count++; } fprintf(stdout,"Executed %d instructions and %d operations in %d cycles.\n", instruction_count,operation_count,cycle_count); fprintf(stdout,"Executed %d vectorizable operations (%d percent of overall executed operations).\n", vect_operation_count, (int) floor(((double) vect_operation_count / (double) operation_count) * 100)); }
void process_instruction(){ // update stage write_back(); if( if_register.stall == 0 ) { instruction_fetch(); } else { if_register.stall += -1; } instruction_decode(); execute_instruction(); memory_access(); btb_move_right(); int index = (CURRENT_STATE.PC - MEM_TEXT_START - 4)/4 ; // printf(" index %d, NUM_INST %d \n",index,NUM_INST); if( index == NUM_INST ) { CURRENT_STATE.PC += -4; // printf("Run bit unset pc: %x\n",CURRENT_STATE.PC); } }
/* * Creates memeory for the program to run and gets the instruction code along * with the registers. */ void build_and_execute_um(FILE* program){ memorySegments = newMem(); instantiateMem(memorySegments, INITIAL_SET_SIZE); initializeRegisters(registers, numRegisters); mapProgram(program); programCounter = 0; numInstructions = instructionLength(); //programPointer = getInstructions(memorySegments); while(programCounter < numInstructions){ UM_Word instruction = getInstruction(programCounter); Instruction instr = parseInstruction(instruction); execute_instruction(instr); if(instr.op == HALT) break; } freeMem(memorySegments); }
inline void cosmac_device::run() { output_state_code(); switch (m_state) { case COSMAC_STATE_0_FETCH: fetch_instruction(); break; case COSMAC_STATE_1_RESET: reset(); debug(); break; case COSMAC_STATE_1_INIT: initialize(); debug(); break; case COSMAC_STATE_1_EXECUTE: sample_ef_lines(); execute_instruction(); debug(); break; case COSMAC_STATE_2_DMA_IN: dma_input(); break; case COSMAC_STATE_2_DMA_OUT: dma_output(); break; case COSMAC_STATE_3_INT: interrupt(); debug(); break; } }
void ick_iffi_interpreter_one_iteration(void) { funge_cell opcode; opcode = fungespace_get(&iffiIP->position); if (setting_trace_level > 8) { fprintf(stderr, "x=%" FUNGECELLPRI " y=%" FUNGECELLPRI ": %c (%" FUNGECELLPRI ")\n", iffiIP->position.x, iffiIP->position.y, (char)opcode, opcode); stack_print_top(iffiIP->stack); } else if (setting_trace_level > 3) { fprintf(stderr, "x=%" FUNGECELLPRI " y=%" FUNGECELLPRI ": %c (%" FUNGECELLPRI ")\n", iffiIP->position.x, iffiIP->position.y, (char)opcode, opcode); } else if (setting_trace_level > 2) fprintf(stderr, "%c", (char)opcode); execute_instruction(opcode, iffiIP); if (iffiIP->needMove) ip_forward(iffiIP); else iffiIP->needMove = true; }
int process_block(struct self_s *self, struct process_state_s *process_state, uint64_t inst_log_prev, uint64_t eip_offset_limit) { uint64_t offset = 0; int result; int n, m, l; int err; int found; struct inst_log_entry_s *inst_exe_prev; struct inst_log_entry_s *inst_exe; struct inst_log_entry_s *inst_log_entry = self->inst_log_entry; struct instruction_s *instruction = NULL; int instruction_offset = 0; int octets = 0; //struct memory_s *memory_text; //struct memory_s *memory_stack; struct memory_s *memory_reg; //struct memory_s *memory_data; struct dis_instructions_s dis_instructions; int *memory_used; struct entry_point_s *entry = self->entry_point; uint64_t list_length = self->entry_point_list_length; void *handle_void = self->handle_void; //memory_text = process_state->memory_text; //memory_stack = process_state->memory_stack; memory_reg = process_state->memory_reg; //memory_data = process_state->memory_data; memory_used = process_state->memory_used; debug_print(DEBUG_EXE, 1, "process_block entry\n"); debug_print(DEBUG_EXE, 1, "inst_log=%"PRId64"\n", inst_log); debug_print(DEBUG_EXE, 1, "dis:Data at %p, size=0x%"PRIx64"\n", inst, inst_size); for (offset = 0; ;) { //for (offset = 0; offset < inst_size; //offset += dis_instructions.bytes_used) { /* Update EIP */ offset = memory_reg[2].offset_value; if (offset >= eip_offset_limit) { debug_print(DEBUG_EXE, 1, "Over ran offset=0x%"PRIx64" >= eip_offset_limit=0x%"PRIx64" \n", offset, eip_offset_limit); return 1; } dis_instructions.instruction_number = 0; dis_instructions.bytes_used = 0; debug_print(DEBUG_EXE, 1, "eip=0x%"PRIx64", offset=0x%"PRIx64"\n", memory_reg[2].offset_value, offset); /* the calling program must define this function. This is a callback. */ result = disassemble(self, &dis_instructions, inst, inst_size, offset); debug_print(DEBUG_EXE, 1, "bytes used = %d\n", dis_instructions.bytes_used); debug_print(DEBUG_EXE, 1, "eip=0x%"PRIx64", offset=0x%"PRIx64"\n", memory_reg[2].offset_value, offset); /* Memory not used yet */ if (0 == memory_used[offset]) { debug_print(DEBUG_EXE, 1, "Memory not used yet\n"); for (n = 0; n < dis_instructions.bytes_used; n++) { memory_used[offset + n] = -n; debug_print(DEBUG_EXE, 1, " 0x%02x\n", inst[offset + n]); } debug_print(DEBUG_EXE, 1, "\n"); memory_used[offset] = inst_log; } else { int inst_this = memory_used[offset]; if (inst_this < 0) { /* FIXME: What to do in this case? */ /* problem caused by rep movs instruction */ debug_print(DEBUG_EXE, 1, "process_block:line110:FIXME:Not a valid instuction %d at eip offset 0x%"PRIx64"\n", inst_this, offset); } /* If value == maxint, then it is the destination of a jump */ /* But I need to separate the instruction flows */ /* A jump/branch inst should create a new instruction tree */ debug_print(DEBUG_EXE, 1, "Memory already used\n"); inst_exe_prev = &inst_log_entry[inst_log_prev]; inst_exe = &inst_log_entry[inst_this]; debug_print(DEBUG_EXE, 1, "inst_exe_prev=%p, inst_exe=%p\n", inst_exe_prev, inst_exe); inst_exe->prev_size++; if (inst_exe->prev_size == 1) { inst_exe->prev = malloc(sizeof(inst_exe->prev)); } else { inst_exe->prev = realloc(inst_exe->prev, sizeof(inst_exe->prev) * inst_exe->prev_size); } inst_exe->prev[inst_exe->prev_size - 1] = inst_log_prev; if (inst_exe_prev->next_size > 0) { debug_print(DEBUG_EXE, 1, "JCD8a: next_size = 0x%x\n", inst_exe_prev->next_size); } if (inst_exe_prev->next_size == 0) { inst_exe_prev->next_size++; inst_exe_prev->next = malloc(sizeof(inst_exe_prev->next)); inst_exe_prev->next[inst_exe_prev->next_size - 1] = inst_this; } else { found = 0; for (l = 0; l < inst_exe_prev->next_size; l++) { if (inst_exe_prev->next[inst_exe_prev->next_size - 1] == inst_this) { found = 1; break; } } if (!found) { inst_exe_prev->next_size++; if (inst_exe_prev->next_size > 2) { debug_print(DEBUG_EXE, 1, "process_block: next_size = %d, inst = 0x%x\n", inst_exe_prev->next_size, inst_this); } inst_exe_prev->next = realloc(inst_exe_prev->next, sizeof(inst_exe_prev->next) * inst_exe_prev->next_size); inst_exe_prev->next[inst_exe_prev->next_size - 1] = inst_this; } } break; } //debug_print(DEBUG_EXE, 1, "disassemble_fn\n"); //disassemble_fn = disassembler (handle->bfd); //debug_print(DEBUG_EXE, 1, "disassemble_fn done\n"); debug_print(DEBUG_EXE, 1, "disassemble att : "); bf_disassemble_set_options(handle_void, "att"); bf_disassemble_callback_start(handle_void); octets = bf_disassemble(handle_void, offset); bf_disassemble_callback_end(handle_void); debug_print(DEBUG_EXE, 1, " octets=%d\n", octets); debug_print(DEBUG_EXE, 1, "disassemble intel: "); bf_disassemble_set_options(handle_void, "intel"); bf_disassemble_callback_start(handle_void); octets = bf_disassemble(handle_void, offset); bf_disassemble_callback_end(handle_void); debug_print(DEBUG_EXE, 1, " octets=%d\n", octets); if (dis_instructions.bytes_used != octets) { debug_print(DEBUG_EXE, 1, "Unhandled instruction. Length mismatch. Got %d, expected %d, Exiting\n", dis_instructions.bytes_used, octets); return 1; } /* Update EIP */ memory_reg[2].offset_value += octets; debug_print(DEBUG_EXE, 1, "Number of RTL dis_instructions=%d\n", dis_instructions.instruction_number); if (result != 0) { debug_print(DEBUG_EXE, 1, "Unhandled instruction. Exiting\n"); return 1; } if (dis_instructions.instruction_number == 0) { debug_print(DEBUG_EXE, 1, "NOP instruction. Get next inst\n"); continue; } for (n = 0; n < dis_instructions.instruction_number; n++) { instruction = &dis_instructions.instruction[n]; debug_print(DEBUG_EXE, 1, "Printing inst1111:0x%x, 0x%x, 0x%"PRIx64"\n",instruction_offset, n, inst_log); err = print_inst(self, instruction, instruction_offset + n + 1, NULL); if (err) { debug_print(DEBUG_EXE, 1, "print_inst failed\n"); return err; } inst_exe_prev = &inst_log_entry[inst_log_prev]; inst_exe = &inst_log_entry[inst_log]; memcpy(&(inst_exe->instruction), instruction, sizeof(struct instruction_s)); err = execute_instruction(self, process_state, inst_exe); if (err) { debug_print(DEBUG_EXE, 1, "execute_intruction failed err=%d\n", err); return err; } inst_exe->prev_size++; if (inst_exe->prev_size == 1) { inst_exe->prev = malloc(sizeof(inst_exe->prev)); } else { inst_exe->prev = realloc(inst_exe->prev, sizeof(inst_exe->prev) * inst_exe->prev_size); } inst_exe->prev[inst_exe->prev_size - 1] = inst_log_prev; inst_exe_prev->next_size++; if (inst_exe_prev->next_size > 2) { debug_print(DEBUG_EXE, 1, "process_block:line203: next_size = %d, inst = 0x%"PRIx64"\n", inst_exe_prev->next_size, inst_log); } if (inst_exe_prev->next_size > 1) { debug_print(DEBUG_EXE, 1, "JCD8b: next_size = 0x%x\n", inst_exe_prev->next_size); } if (inst_exe_prev->next_size == 1) { inst_exe_prev->next = malloc(sizeof(inst_exe_prev->next)); inst_exe_prev->next[inst_exe_prev->next_size - 1] = inst_log; } else { inst_exe_prev->next = realloc(inst_exe_prev->next, sizeof(inst_exe_prev->next) * inst_exe_prev->next_size); inst_exe_prev->next[inst_exe_prev->next_size - 1] = inst_log; } inst_exe_prev->next[inst_exe_prev->next_size - 1] = inst_log; if (IF == instruction->opcode) { debug_print(DEBUG_EXE, 1, "IF FOUND\n"); //debug_print(DEBUG_EXE, 1, "Breaking at IF\n"); debug_print(DEBUG_EXE, 1, "IF: this EIP = 0x%"PRIx64"\n", memory_reg[2].offset_value); debug_print(DEBUG_EXE, 1, "IF: jump dst abs EIP = 0x%"PRIx64"\n", inst_exe->value3.offset_value); debug_print(DEBUG_EXE, 1, "IF: inst_log = %"PRId64"\n", inst_log); for (m = 0; m < list_length; m++ ) { if (0 == entry[m].used) { entry[m].esp_init_value = memory_reg[0].init_value; entry[m].esp_offset_value = memory_reg[0].offset_value; entry[m].ebp_init_value = memory_reg[1].init_value; entry[m].ebp_offset_value = memory_reg[1].offset_value; entry[m].eip_init_value = memory_reg[2].init_value; entry[m].eip_offset_value = memory_reg[2].offset_value; entry[m].previous_instuction = inst_log; entry[m].used = 1; debug_print(DEBUG_EXE, 1, "JCD:8 used 1\n"); break; } } /* FIXME: Would starting a "m" be better here? */ for (m = 0; m < list_length; m++ ) { if (0 == entry[m].used) { entry[m].esp_init_value = memory_reg[0].init_value; entry[m].esp_offset_value = memory_reg[0].offset_value; entry[m].ebp_init_value = memory_reg[1].init_value; entry[m].ebp_offset_value = memory_reg[1].offset_value; entry[m].eip_init_value = inst_exe->value3.init_value; entry[m].eip_offset_value = inst_exe->value3.offset_value; entry[m].previous_instuction = inst_log; entry[m].used = 1; debug_print(DEBUG_EXE, 1, "JCD:8 used 2\n"); break; } } } if (JMPT == instruction->opcode) { /* FIXME: add the jump table detection here */ uint64_t inst_base; int tmp; struct inst_log_entry_s *inst_exe_base; struct instruction_s *instruction = NULL; int relocation_area; uint64_t relocation_index; tmp = search_for_jump_table_base(self, inst_log, &inst_base); if (tmp) { debug_print(DEBUG_EXE, 1, "FIXME: JMPT reached..exiting %d 0x%"PRIx64"\n", tmp, inst_base); exit(1); } inst_exe_base = &inst_log_entry[inst_base]; instruction = &(inst_exe_base->instruction); debug_print(DEBUG_EXE, 1, "Relocated = 0x%x\n", instruction->srcB.relocated); debug_print(DEBUG_EXE, 1, "Relocated_area = 0x%x\n", instruction->srcB.relocated_area); debug_print(DEBUG_EXE, 1, "Relocated_index = 0x%x\n", instruction->srcB.relocated_index); if (2 == instruction->srcB.relocated_area) { uint64_t index = instruction->srcB.relocated_index; tmp = 0; do { tmp = bf_find_relocation_rodata(handle_void, index, &relocation_area, &relocation_index); if (!tmp) { if (1 != relocation_area) { debug_print(DEBUG_EXE, 1, "JMPT Relocation area not to code\n"); exit(1); } for (m = 0; m < list_length; m++ ) { if (0 == entry[m].used) { entry[m].esp_init_value = memory_reg[0].init_value; entry[m].esp_offset_value = memory_reg[0].offset_value; entry[m].ebp_init_value = memory_reg[1].init_value; entry[m].ebp_offset_value = memory_reg[1].offset_value; entry[m].eip_init_value = 0; entry[m].eip_offset_value = relocation_index; entry[m].previous_instuction = inst_log; entry[m].used = 1; debug_print(DEBUG_EXE, 1, "JMPT new entry \n"); break; } } } else { debug_print(DEBUG_EXE, 1, "JMPT index, 0x%"PRIx64", not found in rodata relocation table\n", index); } index += 8; } while (!tmp); } } inst_log_prev = inst_log; inst_log++; if (0 == memory_reg[2].offset_value) { debug_print(DEBUG_EXE, 1, "Function exited\n"); if (inst_exe_prev->instruction.opcode == NOP) { inst_exe_prev->instruction.opcode = RET; } break; } if (JMPT == instruction->opcode) { debug_print(DEBUG_EXE, 1, "Function exited. Temporary action for JMPT\n"); break; } } instruction_offset += dis_instructions.instruction_number; if (0 == memory_reg[2].offset_value) { debug_print(DEBUG_EXE, 1, "Breaking\n"); break; } if (instruction && (JMPT == instruction->opcode)) { debug_print(DEBUG_EXE, 1, "Function exited. Temporary action for JMPT\n"); break; } #if 0 if (IF == instruction->opcode) { debug_print(DEBUG_EXE, 1, "Breaking at IF\n"); debug_print(DEBUG_EXE, 1, "IF: this EIP = 0x%"PRIx64"\n", memory_reg[2].offset_value); debug_print(DEBUG_EXE, 1, "IF: jump dst abs EIP = 0x%"PRIx64"\n", inst_exe->value3.offset_value); debug_print(DEBUG_EXE, 1, "IF: inst_log = %"PRId64"\n", inst_log); for (n = 0; n < list_length; n++ ) { if (0 == entry[n].used) { entry[n].esp_init_value = memory_reg[0].init_value; entry[n].esp_offset_value = memory_reg[0].offset_value; entry[n].ebp_init_value = memory_reg[1].init_value; entry[n].ebp_offset_value = memory_reg[1].offset_value; entry[n].eip_init_value = memory_reg[2].init_value; entry[n].eip_offset_value = memory_reg[2].offset_value; entry[n].previous_instuction = inst_log - 1; entry[n].used = 1; break; } } /* FIXME: Would starting a "n" be better here? */ for (n = 0; n < list_length; n++ ) { if (0 == entry[n].used) { entry[n].esp_init_value = memory_reg[0].init_value; entry[n].esp_offset_value = memory_reg[0].offset_value; entry[n].ebp_init_value = memory_reg[1].init_value; entry[n].ebp_offset_value = memory_reg[1].offset_value; entry[n].eip_init_value = inst_exe->value3.init_value; entry[n].eip_offset_value = inst_exe->value3.offset_value; entry[n].previous_instuction = inst_log - 1; entry[n].used = 1; break; } } break; } #endif } return 0; }