⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 op_helper.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
/* *  PowerPC emulation helpers for qemu. * *  Copyright (c) 2003-2007 Jocelyn Mayer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "exec.h"#include "host-utils.h"#include "helper_regs.h"#include "op_helper.h"#define MEMSUFFIX _raw#include "op_helper.h"#include "op_helper_mem.h"#if !defined(CONFIG_USER_ONLY)#define MEMSUFFIX _user#include "op_helper.h"#include "op_helper_mem.h"#define MEMSUFFIX _kernel#include "op_helper.h"#include "op_helper_mem.h"#define MEMSUFFIX _hypv#include "op_helper.h"#include "op_helper_mem.h"#endif//#define DEBUG_OP//#define DEBUG_EXCEPTIONS//#define DEBUG_SOFTWARE_TLB/*****************************************************************************//* Exceptions processing helpers */void do_raise_exception_err (uint32_t exception, int error_code){#if 0    printf("Raise exception %3x code : %d\n", exception, error_code);#endif    env->exception_index = exception;    env->error_code = error_code;	    cpu_loop_exit();}void do_raise_exception (uint32_t exception){    do_raise_exception_err(exception, 0);}void cpu_dump_EA (target_ulong EA);void do_print_mem_EA (target_ulong EA){    cpu_dump_EA(EA);    }/*****************************************************************************//* Registers load and stores */void do_load_cr (void){    T0 = (env->crf[0] << 28) |        (env->crf[1] << 24) |        (env->crf[2] << 20) |        (env->crf[3] << 16) |        (env->crf[4] << 12) |        (env->crf[5] << 8) |        (env->crf[6] << 4) |        (env->crf[7] << 0);}void do_store_cr (uint32_t mask){    int i, sh;    for (i = 0, sh = 7; i < 8; i++, sh--) {        if (mask & (1 << sh))            env->crf[i] = (T0 >> (sh * 4)) & 0xFUL;    }}#if defined(TARGET_PPC64)void do_store_pri (int prio){    env->spr[SPR_PPR] &= ~0x001C000000000000ULL;    env->spr[SPR_PPR] |= ((uint64_t)prio & 0x7) << 50;}#endiftarget_ulong ppc_load_dump_spr (int sprn){    if (loglevel != 0) {        fprintf(logfile, "Read SPR %d %03x => " ADDRX "\n",                sprn, sprn, env->spr[sprn]);    }    return env->spr[sprn];}void ppc_store_dump_spr (int sprn, target_ulong val){    if (loglevel != 0) {        fprintf(logfile, "Write SPR %d %03x => " ADDRX " <= " ADDRX "\n",                sprn, sprn, env->spr[sprn], val);    }    env->spr[sprn] = val;}/*****************************************************************************//* Fixed point operations helpers */void do_adde (void){    T2 = T0;    T0 += T1 + xer_ca;    if (likely(!((uint32_t)T0 < (uint32_t)T2 ||                 (xer_ca == 1 && (uint32_t)T0 == (uint32_t)T2)))) {        xer_ca = 0;    } else {        xer_ca = 1;    }}#if defined(TARGET_PPC64)void do_adde_64 (void){    T2 = T0;    T0 += T1 + xer_ca;    if (likely(!((uint64_t)T0 < (uint64_t)T2 ||                 (xer_ca == 1 && (uint64_t)T0 == (uint64_t)T2)))) {        xer_ca = 0;    } else {        xer_ca = 1;    }}#endifvoid do_addmeo (void){    T1 = T0;    T0 += xer_ca + (-1);    xer_ov = ((uint32_t)T1 & ((uint32_t)T1 ^ (uint32_t)T0)) >> 31;    xer_so |= xer_ov;    if (likely(T1 != 0))        xer_ca = 1;    else        xer_ca = 0;}#if defined(TARGET_PPC64)void do_addmeo_64 (void){    T1 = T0;    T0 += xer_ca + (-1);    xer_ov = ((uint64_t)T1 & ((uint64_t)T1 ^ (uint64_t)T0)) >> 63;    xer_so |= xer_ov;    if (likely(T1 != 0))        xer_ca = 1;    else        xer_ca = 0;}#endifvoid do_divwo (void){    if (likely(!(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) ||                 (int32_t)T1 == 0))) {        xer_ov = 0;        T0 = (int32_t)T0 / (int32_t)T1;    } else {        xer_ov = 1;        T0 = UINT32_MAX * ((uint32_t)T0 >> 31);    }    xer_so |= xer_ov;}#if defined(TARGET_PPC64)void do_divdo (void){    if (likely(!(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) ||                 (int64_t)T1 == 0))) {        xer_ov = 0;        T0 = (int64_t)T0 / (int64_t)T1;    } else {        xer_ov = 1;        T0 = UINT64_MAX * ((uint64_t)T0 >> 63);    }    xer_so |= xer_ov;}#endifvoid do_divwuo (void){    if (likely((uint32_t)T1 != 0)) {        xer_ov = 0;        T0 = (uint32_t)T0 / (uint32_t)T1;    } else {        xer_ov = 1;        xer_so = 1;        T0 = 0;    }}#if defined(TARGET_PPC64)void do_divduo (void){    if (likely((uint64_t)T1 != 0)) {        xer_ov = 0;        T0 = (uint64_t)T0 / (uint64_t)T1;    } else {        xer_ov = 1;        xer_so = 1;        T0 = 0;    }}#endifvoid do_mullwo (void){    int64_t res = (int64_t)T0 * (int64_t)T1;    if (likely((int32_t)res == res)) {        xer_ov = 0;    } else {        xer_ov = 1;        xer_so = 1;    }    T0 = (int32_t)res;}#if defined(TARGET_PPC64)void do_mulldo (void){    int64_t th;    uint64_t tl;    muls64(&tl, &th, T0, T1);    T0 = (int64_t)tl;    /* If th != 0 && th != -1, then we had an overflow */    if (likely((uint64_t)(th + 1) <= 1)) {        xer_ov = 0;    } else {        xer_ov = 1;    }    xer_so |= xer_ov;}#endifvoid do_nego (void){    if (likely((int32_t)T0 != INT32_MIN)) {        xer_ov = 0;        T0 = -(int32_t)T0;    } else {        xer_ov = 1;        xer_so = 1;    }}#if defined(TARGET_PPC64)void do_nego_64 (void){    if (likely((int64_t)T0 != INT64_MIN)) {        xer_ov = 0;        T0 = -(int64_t)T0;    } else {        xer_ov = 1;        xer_so = 1;    }}#endifvoid do_subfe (void){    T0 = T1 + ~T0 + xer_ca;    if (likely((uint32_t)T0 >= (uint32_t)T1 &&               (xer_ca == 0 || (uint32_t)T0 != (uint32_t)T1))) {        xer_ca = 0;    } else {        xer_ca = 1;    }}#if defined(TARGET_PPC64)void do_subfe_64 (void){    T0 = T1 + ~T0 + xer_ca;    if (likely((uint64_t)T0 >= (uint64_t)T1 &&               (xer_ca == 0 || (uint64_t)T0 != (uint64_t)T1))) {        xer_ca = 0;    } else {        xer_ca = 1;    }}#endifvoid do_subfmeo (void){    T1 = T0;    T0 = ~T0 + xer_ca - 1;    xer_ov = ((uint32_t)~T1 & ((uint32_t)~T1 ^ (uint32_t)T0)) >> 31;    xer_so |= xer_ov;    if (likely((uint32_t)T1 != UINT32_MAX))        xer_ca = 1;    else        xer_ca = 0;}#if defined(TARGET_PPC64)void do_subfmeo_64 (void){    T1 = T0;    T0 = ~T0 + xer_ca - 1;    xer_ov = ((uint64_t)~T1 & ((uint64_t)~T1 ^ (uint64_t)T0)) >> 63;    xer_so |= xer_ov;    if (likely((uint64_t)T1 != UINT64_MAX))        xer_ca = 1;    else        xer_ca = 0;}#endifvoid do_subfzeo (void){    T1 = T0;    T0 = ~T0 + xer_ca;    xer_ov = (((uint32_t)~T1 ^ UINT32_MAX) &              ((uint32_t)(~T1) ^ (uint32_t)T0)) >> 31;    xer_so |= xer_ov;    if (likely((uint32_t)T0 >= (uint32_t)~T1)) {        xer_ca = 0;    } else {        xer_ca = 1;    }}#if defined(TARGET_PPC64)void do_subfzeo_64 (void){    T1 = T0;    T0 = ~T0 + xer_ca;    xer_ov = (((uint64_t)~T1 ^  UINT64_MAX) &              ((uint64_t)(~T1) ^ (uint64_t)T0)) >> 63;    xer_so |= xer_ov;    if (likely((uint64_t)T0 >= (uint64_t)~T1)) {        xer_ca = 0;    } else {        xer_ca = 1;    }}#endifvoid do_cntlzw (void){    T0 = clz32(T0);}#if defined(TARGET_PPC64)void do_cntlzd (void){    T0 = clz64(T0);}#endif/* shift right arithmetic helper */void do_sraw (void){    int32_t ret;    if (likely(!(T1 & 0x20UL))) {        if (likely((uint32_t)T1 != 0)) {            ret = (int32_t)T0 >> (T1 & 0x1fUL);            if (likely(ret >= 0 || ((int32_t)T0 & ((1 << T1) - 1)) == 0)) {                xer_ca = 0;            } else {                xer_ca = 1;            }        } else {            ret = T0;            xer_ca = 0;        }    } else {        ret = UINT32_MAX * ((uint32_t)T0 >> 31);        if (likely(ret >= 0 || ((uint32_t)T0 & ~0x80000000UL) == 0)) {            xer_ca = 0;        } else {            xer_ca = 1;        }    }    T0 = ret;}#if defined(TARGET_PPC64)void do_srad (void){    int64_t ret;    if (likely(!(T1 & 0x40UL))) {        if (likely((uint64_t)T1 != 0)) {            ret = (int64_t)T0 >> (T1 & 0x3FUL);            if (likely(ret >= 0 || ((int64_t)T0 & ((1 << T1) - 1)) == 0)) {                xer_ca = 0;            } else {                xer_ca = 1;            }        } else {            ret = T0;            xer_ca = 0;        }    } else {        ret = UINT64_MAX * ((uint64_t)T0 >> 63);        if (likely(ret >= 0 || ((uint64_t)T0 & ~0x8000000000000000ULL) == 0)) {            xer_ca = 0;        } else {            xer_ca = 1;        }    }    T0 = ret;}#endifvoid do_popcntb (void){    uint32_t ret;    int i;    ret = 0;    for (i = 0; i < 32; i += 8)        ret |= ctpop8((T0 >> i) & 0xFF) << i;    T0 = ret;}#if defined(TARGET_PPC64)void do_popcntb_64 (void){    uint64_t ret;    int i;    ret = 0;    for (i = 0; i < 64; i += 8)        ret |= ctpop8((T0 >> i) & 0xFF) << i;    T0 = ret;}#endif/*****************************************************************************//* Floating point operations helpers */static always_inline int fpisneg (float64 f){    union {        float64 f;        uint64_t u;    } u;    u.f = f;    return u.u >> 63 != 0;}static always_inline int isden (float f){    union {        float64 f;        uint64_t u;    } u;    u.f = f;    return ((u.u >> 52) & 0x7FF) == 0;}static always_inline int iszero (float64 f){    union {        float64 f;        uint64_t u;    } u;    u.f = f;    return (u.u & ~0x8000000000000000ULL) == 0;}static always_inline int isinfinity (float64 f){    union {        float64 f;        uint64_t u;    } u;    u.f = f;    return ((u.u >> 52) & 0x7FF) == 0x7FF &&        (u.u & 0x000FFFFFFFFFFFFFULL) == 0;}void do_compute_fprf (int set_fprf){    int isneg;    isneg = fpisneg(FT0);    if (unlikely(float64_is_nan(FT0))) {        if (float64_is_signaling_nan(FT0)) {            /* Signaling NaN: flags are undefined */            T0 = 0x00;        } else {            /* Quiet NaN */            T0 = 0x11;        }    } else if (unlikely(isinfinity(FT0))) {        /* +/- infinity */        if (isneg)            T0 = 0x09;        else            T0 = 0x05;    } else {        if (iszero(FT0)) {            /* +/- zero */            if (isneg)                T0 = 0x12;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -