/* 128 -> 64/64 unsigned division */ uint64_t HELPER(divu64)(CPUS390XState *env, uint64_t ah, uint64_t al, uint64_t b) { uint64_t ret; /* Signal divide by zero. */ if (b == 0) { runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC()); } if (ah == 0) { /* 64 -> 64/64 case */ env->retxl = al % b; ret = al / b; } else { /* ??? Move i386 idivq helper to host-utils. */ #if HOST_LONG_BITS == 64 && defined(__GNUC__) /* assuming 64-bit hosts have __uint128_t */ __uint128_t a = ((__uint128_t)ah << 64) | al; __uint128_t q = a / b; env->retxl = a % b; ret = q; if (ret != q) { runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC()); } #else /* 32-bit hosts would need special wrapper functionality - just abort if we encounter such a case; it's very unlikely anyways. */ cpu_abort(env, "128 -> 64/64 division not implemented\n"); #endif } return ret; }
void helper_monitor(CPUX86State *env, target_ulong ptr) { if ((uint32_t)env->regs[R_ECX] != 0) { raise_exception_ra(env, EXCP0D_GPF, GETPC()); } /* XXX: store address? */ cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0, GETPC()); }
void helper_rdpmc(CPUX86State *env) { if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) { raise_exception_ra(env, EXCP0D_GPF, GETPC()); } cpu_svm_check_intercept_param(env, SVM_EXIT_RDPMC, 0, GETPC()); /* currently unimplemented */ qemu_log_mask(LOG_UNIMP, "x86: unimplemented rdpmc\n"); raise_exception_err(env, EXCP06_ILLOP, 0); }
uint64_t helper_rdpkru(CPUX86State *env, uint32_t ecx) { if ((env->cr[4] & CR4_PKE_MASK) == 0) { raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); } if (ecx != 0) { raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); } return env->pkru; }
void helper_boundl(CPUX86State *env, target_ulong a0, int v) { int low, high; low = cpu_ldl_data_ra(env, a0, GETPC()); high = cpu_ldl_data_ra(env, a0 + 4, GETPC()); if (v < low || v > high) { if (env->hflags & HF_MPX_EN_MASK) { env->bndcs_regs.sts = 0; } raise_exception_ra(env, EXCP05_BOUND, GETPC()); } }
void helper_wrpkru(CPUX86State *env, uint32_t ecx, uint64_t val) { CPUState *cs = CPU(x86_env_get_cpu(env)); if ((env->cr[4] & CR4_PKE_MASK) == 0) { raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); } if (ecx != 0 || (val & 0xFFFFFFFF00000000ull)) { raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); } env->pkru = val; tlb_flush(cs); }
static target_ulong helper_udiv_common(CPUSPARCState *env, target_ulong a, target_ulong b, int cc) { int overflow = 0; uint64_t x0; uint32_t x1; x0 = (a & 0xffffffff) | ((int64_t) (env->y) << 32); x1 = (b & 0xffffffff); if (x1 == 0) { cpu_restore_state2(env, GETPC()); helper_raise_exception(env, TT_DIV_ZERO); } x0 = x0 / x1; if (x0 > 0xffffffff) { x0 = 0xffffffff; overflow = 1; } if (cc) { env->cc_dst = x0; env->cc_src2 = overflow; env->cc_op = CC_OP_DIV; } return x0; }
target_ulong helper_tsubcctv(CPUSPARCState *env, target_ulong src1, target_ulong src2) { target_ulong dst; /* Tag overflow occurs if either input has bits 0 or 1 set. */ if ((src1 | src2) & 3) { goto tag_overflow; } dst = src1 - src2; /* Tag overflow occurs if the subtraction overflows. */ if ((src1 ^ src2) & (src1 ^ dst) & (1u << 31)) { goto tag_overflow; } /* Only modify the CC after any exceptions have been generated. */ env->cc_op = CC_OP_TSUBTV; env->cc_src = src1; env->cc_src2 = src2; env->cc_dst = dst; return dst; tag_overflow: cpu_restore_state2(env, GETPC()); helper_raise_exception(env, TT_TOVF); }
//------------------------------------------------------------------------ int notmain ( void ) { unsigned int ra; unsigned int rb; leds_off(); uart_init(); hexstring(0x12345678); hexstring(GETPC()); hexstring(GETCPSR()); hexstring(GETSCTLR()); hexstring(GETMPIDR()); hexstring(GET32(0x1000)); hexstring(GET32(0x1004)); hexstring(GET32(0x1008)); if(1) { for(ra=0x000; ra<0x1000; ra+=4) { rb=GET32(ra); if(rb) { hexstrings(ra); hexstring(rb); } } } return(0); }
float32 helper_fsub_FT(float32 t0, float32 t1) { set_float_exception_flags(0, &env->fp_status); t0 = float32_sub(t0, t1, &env->fp_status); update_fpscr(GETPC()); return t0; }
float64 helper_fsqrt_DT(float64 t0) { set_float_exception_flags(0, &env->fp_status); t0 = float64_sqrt(t0, &env->fp_status); update_fpscr(GETPC()); return t0; }
float64 helper_fmul_DT(float64 t0, float64 t1) { set_float_exception_flags(0, &env->fp_status); t0 = float64_mul(t0, t1, &env->fp_status); update_fpscr(GETPC()); return t0; }
float32 helper_fmul_FT(CPUSH4State *env, float32 t0, float32 t1) { set_float_exception_flags(0, &env->fp_status); t0 = float32_mul(t0, t1, &env->fp_status); update_fpscr(env, GETPC()); return t0; }
float32 helper_fsqrt_FT(CPUSH4State *env, float32 t0) { set_float_exception_flags(0, &env->fp_status); t0 = float32_sqrt(t0, &env->fp_status); update_fpscr(env, GETPC()); return t0; }
void helper_cmpxchg8b_unlocked(CPUX86State *env, target_ulong a0) { uintptr_t ra = GETPC(); uint64_t oldv, cmpv, newv; int eflags; eflags = cpu_cc_compute_all(env, CC_OP); cmpv = deposit64(env->regs[R_EAX], 32, 32, env->regs[R_EDX]); newv = deposit64(env->regs[R_EBX], 32, 32, env->regs[R_ECX]); oldv = cpu_ldq_data_ra(env, a0, ra); newv = (cmpv == oldv ? newv : oldv); /* always do the store */ cpu_stq_data_ra(env, a0, newv, ra); if (oldv == cmpv) { eflags |= CC_Z; } else { env->regs[R_EAX] = (uint32_t)oldv; env->regs[R_EDX] = (uint32_t)(oldv >> 32); eflags &= ~CC_Z; } CC_SRC = eflags; }
void helper_sti_vm(CPUX86State *env) { env->eflags |= VIF_MASK; if (env->eflags & VIP_MASK) { raise_exception_ra(env, EXCP0D_GPF, GETPC()); } }
void notmain ( void ) { uart_init(); hexstring(0x12345678); hexstring(GETPC()); timer_init(); /* * 132 byte packet. All fields are 1 byte except for the 128 byte data * payload. * +-----+------+----------+--....----+-----+ * | SOH | blk# | 255-blk# | ..data.. | cksum | * +-----+------+----------+--....----+-----+ * Protocol: * - first block# = 1. * - CRC is over the whole packet * - after all packets sent, sender transmits a single EOT (must ACK). */ unsigned char block = 1; unsigned addr = ARMBASE; while (1) { unsigned char b; // We received an EOT, send an ACK, jump to beginning of code if((b = getbyte()) == EOT) { uart_send(ACK); BRANCHTO(ARMBASE); return; // NOTREACHED } /* * if first byte is not SOH, or second byte is not the * expected block number or the third byte is not its * negation, send a nak for a resend of this block. */ if(b != SOH || getbyte() != block || getbyte() != (0xFF - block)) { uart_send(NAK); continue; } // get the data bytes int i; unsigned char cksum; for(cksum = i = 0; i < PAYLOAD_SIZE; i++) { cksum += (b = getbyte()); PUT8(addr+i, b); } // Checksum failed: NAK the block if(getbyte() != cksum) uart_send(NAK); // Commit our addr pointer and go to next block. else { uart_send(ACK); addr += PAYLOAD_SIZE; block++; } } }
void helper_cmpxchg16b(CPUX86State *env, target_ulong a0) { uintptr_t ra = GETPC(); if ((a0 & 0xf) != 0) { raise_exception_ra(env, EXCP0D_GPF, ra); } else { #ifndef CONFIG_ATOMIC128 cpu_loop_exit_atomic(ENV_GET_CPU(env), ra); #else int eflags = cpu_cc_compute_all(env, CC_OP); Int128 cmpv = int128_make128(env->regs[R_EAX], env->regs[R_EDX]); Int128 newv = int128_make128(env->regs[R_EBX], env->regs[R_ECX]); int mem_idx = cpu_mmu_index(env, false); TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx); Int128 oldv = helper_atomic_cmpxchgo_le_mmu(env, a0, cmpv, newv, oi, ra); if (int128_eq(oldv, cmpv)) { eflags |= CC_Z; } else { env->regs[R_EAX] = int128_getlo(oldv); env->regs[R_EDX] = int128_gethi(oldv); eflags &= ~CC_Z; } CC_SRC = eflags; #endif } }
void helper_invlpg(CPUX86State *env, target_ulong addr) { X86CPU *cpu = x86_env_get_cpu(env); cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPG, 0, GETPC()); tlb_flush_page(CPU(cpu), addr); }
void helper_bndck(CPUX86State *env, uint32_t fail) { if (unlikely(fail)) { env->bndcs_regs.sts = 1; raise_exception_ra(env, EXCP05_BOUND, GETPC()); } }
void helper_ftrv(CPUSH4State *env, uint32_t n) { int bank_matrix, bank_vector; int i, j; float32 r[4]; float32 p; bank_matrix = (env->sr & FPSCR_FR) ? 0 : 16; bank_vector = (env->sr & FPSCR_FR) ? 16 : 0; set_float_exception_flags(0, &env->fp_status); for (i = 0 ; i < 4 ; i++) { r[i] = float32_zero; for (j = 0 ; j < 4 ; j++) { p = float32_mul(env->fregs[bank_matrix + 4 * j + i], env->fregs[bank_vector + j], &env->fp_status); r[i] = float32_add(r[i], p, &env->fp_status); } } update_fpscr(env, GETPC()); for (i = 0 ; i < 4 ; i++) { env->fregs[bank_vector + i] = r[i]; } }
float64 helper_fsub_DT(CPUSH4State *env, float64 t0, float64 t1) { set_float_exception_flags(0, &env->fp_status); t0 = float64_sub(t0, t1, &env->fp_status); update_fpscr(env, GETPC()); return t0; }
float32 helper_fmac_FT(float32 t0, float32 t1, float32 t2) { set_float_exception_flags(0, &env->fp_status); t0 = float32_mul(t0, t1, &env->fp_status); t0 = float32_add(t0, t2, &env->fp_status); update_fpscr(GETPC()); return t0; }
uint32_t helper_ftrc_FT(float32 t0) { uint32_t ret; set_float_exception_flags(0, &env->fp_status); ret = float32_to_int32_round_to_zero(t0, &env->fp_status); update_fpscr(GETPC()); return ret; }
/* Raise exceptions for ieee fp insns with software completion. */ void helper_fp_exc_raise_s(CPUAlphaState *env, uint32_t exc, uint32_t regno) { if (exc) { env->fpcr_exc_status |= exc; exc &= ~env->fpcr_exc_mask; inline_fp_exc_raise(env, GETPC(), exc, regno); } }
uint64_t helper_udivx(CPUSPARCState *env, uint64_t a, uint64_t b) { if (b == 0) { /* Raise divide by zero trap. */ cpu_raise_exception_ra(env, TT_DIV_ZERO, GETPC()); } return a / b; }
float32 helper_fcnvds_DT_FT(CPUSH4State *env, float64 t0) { float32 ret; set_float_exception_flags(0, &env->fp_status); ret = float64_to_float32(t0, &env->fp_status); update_fpscr(env, GETPC()); return ret; }
float64 helper_float_DT(CPUSH4State *env, uint32_t t0) { float64 ret; set_float_exception_flags(0, &env->fp_status); ret = int32_to_float64(t0, &env->fp_status); update_fpscr(env, GETPC()); return ret; }
uint32_t helper_ftrc_DT(CPUSH4State *env, float64 t0) { uint32_t ret; set_float_exception_flags(0, &env->fp_status); ret = float64_to_int32_round_to_zero(t0, &env->fp_status); update_fpscr(env, GETPC()); return ret; }
float32 helper_float_FT(uint32_t t0) { float32 ret; set_float_exception_flags(0, &env->fp_status); ret = int32_to_float32(t0, &env->fp_status); update_fpscr(GETPC()); return ret; }