/** * @brief Saves the correct opcode and all operands of the current instruction. * @param[in] opcode The binary target specific opcode. * @param[in,out] instruction The instruction which shall be saved. */ static void saveInstruction(uint32_t opcode, sparc_instruction* instruction) { int sim_opcode = getOpcode(opcode); int dst_reg; int src1_reg; int src2_reg; int immediate; int icc; static char errormsg[100]; /* save opcode */ instruction->opcode = sim_opcode; /* save operands */ switch (sim_opcode) { /* calls only have a displacement: */ case CALL: immediate = GET_DISP30(opcode); /* sign extension of displacement */ if (immediate & (1<<29)) { immediate |= ((1<<30)|(1<<31)); } /* save call displacement as operand */ instruction->num_operands = 1; instruction->operands = malloc(sizeof(sparc_operand)); /* memory allocation OK? */ if (!(instruction->operands)) { gen_simulator->cleanUp(); simerror("Could not allocate memory for instruction operands!"); } instruction->operands[0].type = OPERAND_TYPE_LABEL_ADDRESS; /* label address is (absolute) instruction number */ instruction->operands[0].value.labeladdress = (unsigned) ((int) instruction->instr_no + immediate); break; /* handle branch instructions */ case BRANCH: immediate = GET_IMM22(opcode); /* sign extension of displacement */ if (immediate & (1<<21)) { immediate |= 0xFFC00000; } icc = GET_CC(opcode); instruction->num_operands = 2; instruction->operands = malloc(sizeof(sparc_operand)*2); /* memory allocation OK? */ if (!(instruction->operands)) { gen_simulator->cleanUp(); simerror("Could not allocate memory for instruction operands!"); } instruction->operands[0].type = OPERAND_TYPE_LABEL_ADDRESS; /* label address is (absolute) instruction number */ instruction->operands[0].value.labeladdress = (unsigned) ((int) instruction->instr_no + immediate); /* save integer condition code */ instruction->operands[1].type = OPERAND_TYPE_ICC; instruction->operands[1].value.icc = icc; break; /* handle sethi and nop instructions */ case SETHI: immediate = GET_IMM22(opcode); dst_reg = GET_RD(opcode); /* if destination register and immediate are zero, it's a NOP instruction*/ if (!dst_reg && !immediate) { instruction->num_operands = 0; instruction->opcode = NOP; } else { instruction->num_operands = 2; instruction->operands = malloc(sizeof(sparc_operand)*2); /* memory allocation OK? */ if (!(instruction->operands)) { gen_simulator->cleanUp(); simerror("Could not allocate memory for instruction operands!"); } instruction->operands[0].type = OPERAND_TYPE_REGISTER; instruction->operands[0].value.reg = dst_reg; instruction->operands[1].type = OPERAND_TYPE_IMM22; instruction->operands[1].value.imm22 = immediate; } break; case RD: dst_reg = GET_RD(opcode); src1_reg = GET_RS1(opcode); if (src1_reg != Y_REGISTER_NO) { gen_simulator->cleanUp(); simerror("Unknown source register for rd instruction!"); } instruction->num_operands = 2; instruction->operands = malloc(sizeof(sparc_operand)*2); /* memory allocation OK? */ if (!(instruction->operands)) { gen_simulator->cleanUp(); simerror("Could not allocate memory for instruction operands!"); } instruction->operands[0].type = OPERAND_TYPE_REGISTER; instruction->operands[0].value.reg = dst_reg; instruction->operands[1].type = OPERAND_TYPE_REGISTER; instruction->operands[1].value.reg = src1_reg; break; /* nothing to do for sim-cylce instruction */ case CYCLE_PRINT: case CYCLE_CLEAR: instruction->num_operands = 0; break; /* terminate on unkown instruction */ case UNKNOWN: gen_simulator->cleanUp(); snprintf(errormsg, 100, "Encountered unknown opcode at instruction no %d!", instruction->instr_no); simerror(errormsg); break; /* all other instructions have exactly three operands */ default: dst_reg = GET_RD(opcode); src1_reg = GET_RS1(opcode); instruction->num_operands = 3; instruction->operands = malloc(sizeof(sparc_operand)*3); /* memory allocation OK? */ if (!(instruction->operands)) { gen_simulator->cleanUp(); simerror("Could not allocate memory for instruction operands!"); } instruction->operands[0].type = OPERAND_TYPE_REGISTER; instruction->operands[0].value.reg = dst_reg; instruction->operands[1].type = OPERAND_TYPE_REGISTER; instruction->operands[1].value.reg = src1_reg; /* is third operand an immediate? */ if (GET_I(opcode)) { immediate = GET_SIMM13(opcode); /* sign extension of immediate */ if (immediate & (1<<12)) { immediate |= 0xFFFFE000; } instruction->operands[2].type = OPERAND_TYPE_SIMM13; instruction->operands[2].value.simm13 = immediate; } else { src2_reg = GET_RS2(opcode); instruction->operands[2].type = OPERAND_TYPE_REGISTER; instruction->operands[2].value.reg = src2_reg; } break; } }
static void episodic_store_full( noble_being * local, n_byte event, n_int affect, noble_simulation * local_sim, n_byte2 name1, n_byte2 family1, n_byte2 name2, n_byte2 family2, n_byte2 arg, n_byte food) { episodic_memory * local_episodic = GET_EPI(local_sim, local); n_int replace; n_byte old_event; n_byte2 old_time; n_byte2 new_time; if (local_episodic == 0L) { return; } if (being_awake_local(local_sim, local)==FULLY_ASLEEP) return; replace = episodic_memory_replace_index(event,affect,name1,family1,name2,family2,local,local_sim); if (replace == -1) return; old_event = local_episodic[replace].event; old_time = local_episodic[replace].time; /** insert the current event into the episodic memory */ local_episodic[replace].event = event; local_episodic[replace].affect = (n_byte2)(affect+EPISODIC_AFFECT_ZERO); local_episodic[replace].location[0] = GET_X(local); local_episodic[replace].location[1] = GET_Y(local); local_episodic[replace].time = new_time =local_sim->land->time; local_episodic[replace].date[0] = local_sim->land->date[0]; local_episodic[replace].date[1] = local_sim->land->date[1]; local_episodic[replace].first_name[BEING_MEETER]=name1; local_episodic[replace].family_name[BEING_MEETER]=family1; local_episodic[replace].first_name[BEING_MET]=name2; local_episodic[replace].family_name[BEING_MET]=family2; local_episodic[replace].food=food; local_episodic[replace].arg=arg; if ((event == 0) || (event>=EVENTS)) { (void)SHOW_ERROR("Event outside scope"); } if (local_logging) { if ((old_event != event) || ((old_time+10) < (new_time))) /* this may need to be changed */ { n_string_block description; n_string_block str; n_string_block time; n_string_block combination = {0}; n_int social_event; being_name((FIND_SEX(GET_I(local)) == SEX_FEMALE), GET_NAME(local_sim, local), GET_FAMILY_FIRST_NAME(local_sim, local), GET_FAMILY_SECOND_NAME(local_sim, local), str); social_event = episode_description(local_sim, local, replace, description); if ((local_social == 1) && (social_event == 0)) { return; } io_time_to_string(time, local_sim->land->time, local_sim->land->date[0], local_sim->land->date[1]); io_three_string_combination(combination, time, str, description, 35); (*local_logging)(combination); } } }