USI fr30_inte (SIM_CPU *current_cpu, PCADDR pc, int num) { /* The new pc is the trap #9 vector entry. We assume there's a branch there to some handler. */ USI new_pc; setup_int (current_cpu, pc); fr30bf_h_ilm_set (current_cpu, 4); new_pc = GETMEMSI (current_cpu, pc, fr30bf_h_dr_get (current_cpu, H_DR_TBR) + 1024 - ((9 + 1) * 4)); return new_pc; }
/* Set FSR0, FQ0-FQ9, depending on the interrupt. */ static void set_fp_exception_registers ( SIM_CPU *current_cpu, struct frv_interrupt_queue_element *item ) { int fq_index; SI fq; SI insn; SI fsr0; IADDR pc; struct frv_fp_exception_info *fp_info; SIM_DESC sd = CPU_STATE (current_cpu); /* No FQ registers on fr550 */ if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550) { /* Update the fsr. */ fp_info = & item->u.fp_info; fsr0 = GET_FSR (0); SET_FSR_FTT (fsr0, fp_info->ftt); SET_FSR (0, fsr0); return; } /* Select an FQ and update it with the exception information. */ fq_index = fq_for_exception (current_cpu, item); if (fq_index == -1) return; fp_info = & item->u.fp_info; fq = GET_FQ (fq_index); SET_FQ_MIV (fq, MIV_FLOAT); SET_FQ_SIE (fq, SIE_NIL); SET_FQ_FTT (fq, fp_info->ftt); SET_FQ_CEXC (fq, fp_info->fsr_mask); SET_FQ_VALID (fq); SET_FQ (fq_index, fq); /* Write the failing insn into FQx.OPC. */ pc = item->vpc; insn = GETMEMSI (current_cpu, pc, pc); SET_FQ_OPC (fq_index, insn); /* Update the fsr. */ fsr0 = GET_FSR (0); SET_FSR_QNE (fsr0); /* FQ not empty */ SET_FSR_FTT (fsr0, fp_info->ftt); SET_FSR (0, fsr0); }
static SEM_PC SEM_FN_NAME (lm32bf,lw) (SIM_CPU *current_cpu, SEM_ARG sem_arg) { #define FLD(f) abuf->fields.sfmt_addi.f ARGBUF *abuf = SEM_ARGBUF (sem_arg); int UNUSED written = 0; IADDR UNUSED pc = abuf->addr; SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4); { SI opval = GETMEMSI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm))))); CPU (h_gr[FLD (f_r1)]) = opval; TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval); } return vpc; #undef FLD }
SI frvbf_read_mem_SI (SIM_CPU *current_cpu, IADDR pc, SI address) { FRV_CACHE *cache; USI hsr0; /* Check for access exceptions. */ address = check_data_read_address (current_cpu, address, 3); address = check_readwrite_address (current_cpu, address, 3); hsr0 = GET_HSR0 (); cache = CPU_DATA_CACHE (current_cpu); /* If we need to count cycles, then the cache operation will be initiated from the model profiling functions. See frvbf_model_.... */ if (model_insn) { CPU_LOAD_ADDRESS (current_cpu) = address; CPU_LOAD_LENGTH (current_cpu) = 4; return 0x37111319; /* any random value */ } if (GET_HSR0_DCE (hsr0)) { int cycles; /* Handle access which crosses cache line boundary */ SIM_DESC sd = CPU_STATE (current_cpu); if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550) { if (DATA_CROSSES_CACHE_LINE (cache, address, 4)) return read_mem_unaligned_SI (current_cpu, pc, address); } cycles = frv_cache_read (cache, 0, address); if (cycles != 0) return CACHE_RETURN_DATA (cache, 0, address, SI, 4); } return GETMEMSI (current_cpu, pc, address); }
USI fr30_int (SIM_CPU *current_cpu, PCADDR pc, int num) { SIM_DESC sd = CPU_STATE (current_cpu); host_callback *cb = STATE_CALLBACK (sd); #ifdef SIM_HAVE_BREAKPOINTS /* Check for breakpoints "owned" by the simulator first, regardless of --environment. */ if (num == TRAP_BREAKPOINT) { /* First try sim-break.c. If it's a breakpoint the simulator "owns" it doesn't return. Otherwise it returns and let's us try. */ sim_handle_breakpoint (sd, current_cpu, pc); /* Fall through. */ } #endif if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT) { /* The new pc is the trap vector entry. We assume there's a branch there to some handler. */ USI new_pc; setup_int (current_cpu, pc); fr30bf_h_ibit_set (current_cpu, 0); new_pc = GETMEMSI (current_cpu, pc, fr30bf_h_dr_get (current_cpu, H_DR_TBR) + 1024 - ((num + 1) * 4)); return new_pc; } switch (num) { case TRAP_SYSCALL : { /* TODO: find out what the ABI for this is */ CB_SYSCALL s; CB_SYSCALL_INIT (&s); s.func = fr30bf_h_gr_get (current_cpu, 0); s.arg1 = fr30bf_h_gr_get (current_cpu, 4); s.arg2 = fr30bf_h_gr_get (current_cpu, 5); s.arg3 = fr30bf_h_gr_get (current_cpu, 6); if (s.func == TARGET_SYS_exit) { sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, s.arg1); } s.p1 = (PTR) sd; s.p2 = (PTR) current_cpu; s.read_mem = syscall_read_mem; s.write_mem = syscall_write_mem; cb_syscall (cb, &s); fr30bf_h_gr_set (current_cpu, 2, s.errcode); /* TODO: check this one */ fr30bf_h_gr_set (current_cpu, 4, s.result); fr30bf_h_gr_set (current_cpu, 1, s.result2); /* TODO: check this one */ break; } case TRAP_BREAKPOINT: sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP); break; default : { USI new_pc; setup_int (current_cpu, pc); fr30bf_h_ibit_set (current_cpu, 0); new_pc = GETMEMSI (current_cpu, pc, fr30bf_h_dr_get (current_cpu, H_DR_TBR) + 1024 - ((num + 1) * 4)); return new_pc; } } /* Fake an "reti" insn. Since we didn't push anything to stack, all we need to do is update pc. */ return pc + 2; }