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

📄 translate.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
    case 4: /* Indirect predecrememnt.  */        {            int tmp;            if (addrp && val > 0) {                tmp = *addrp;            } else {                tmp = gen_lea(s, insn, opsize);                if (tmp == -1)                    return -1;                if (addrp)                    *addrp = tmp;            }            result = gen_ldst(s, opsize, tmp, val);            /* ??? This is not exception safe.  The instruction may still               fault after this point.  */            if (val > 0 || !addrp) {                reg += QREG_A0;                gen_op_mov32(reg, tmp);            }        }        return result;    case 5: /* Indirect displacement.  */    case 6: /* Indirect index + displacement.  */        return gen_ea_once(s, insn, opsize, val, addrp);    case 7: /* Other */        switch (reg) {        case 0: /* Absolute short.  */        case 1: /* Absolute long.  */        case 2: /* pc displacement  */        case 3: /* pc index+displacement.  */            return gen_ea_once(s, insn, opsize, val, addrp);        case 4: /* Immediate.  */            /* Sign extend values for consistency.  */            switch (opsize) {            case OS_BYTE:                if (val)                    offset = ldsb_code(s->pc + 1);                else                    offset = ldub_code(s->pc + 1);                s->pc += 2;                break;            case OS_WORD:                if (val)                    offset = ldsw_code(s->pc);                else                    offset = lduw_code(s->pc);                s->pc += 2;                break;            case OS_LONG:                offset = read_im32(s);                break;            default:                qemu_assert(0, "Bad immediate operand");            }            return gen_im32(offset);        default:            return -1;        }    }    /* Should never happen.  */    return -1;}static void gen_logic_cc(DisasContext *s, int val){    gen_op_logic_cc(val);    s->cc_op = CC_OP_LOGIC;}static void gen_jmpcc(DisasContext *s, int cond, int l1){    int tmp;    gen_flush_flags(s);    switch (cond) {    case 0: /* T */        gen_op_jmp(l1);        break;    case 1: /* F */        break;    case 2: /* HI (!C && !Z) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));        gen_op_jmp_z32(tmp, l1);        break;    case 3: /* LS (C || Z) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C | CCF_Z));        gen_op_jmp_nz32(tmp, l1);        break;    case 4: /* CC (!C) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));        gen_op_jmp_z32(tmp, l1);        break;    case 5: /* CS (C) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_C));        gen_op_jmp_nz32(tmp, l1);        break;    case 6: /* NE (!Z) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));        gen_op_jmp_z32(tmp, l1);        break;    case 7: /* EQ (Z) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));        gen_op_jmp_nz32(tmp, l1);        break;    case 8: /* VC (!V) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));        gen_op_jmp_z32(tmp, l1);        break;    case 9: /* VS (V) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));        gen_op_jmp_nz32(tmp, l1);        break;    case 10: /* PL (!N) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));        gen_op_jmp_z32(tmp, l1);        break;    case 11: /* MI (N) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));        gen_op_jmp_nz32(tmp, l1);        break;    case 12: /* GE (!(N ^ V)) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));        gen_op_xor32(tmp, tmp, QREG_CC_DEST);        gen_op_and32(tmp, tmp, gen_im32(CCF_V));        gen_op_jmp_z32(tmp, l1);        break;    case 13: /* LT (N ^ V) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));        gen_op_xor32(tmp, tmp, QREG_CC_DEST);        gen_op_and32(tmp, tmp, gen_im32(CCF_V));        gen_op_jmp_nz32(tmp, l1);        break;    case 14: /* GT (!(Z || (N ^ V))) */        {            int l2;            l2 = gen_new_label();            tmp = gen_new_qreg(QMODE_I32);            gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));            gen_op_jmp_nz32(tmp, l2);            tmp = gen_new_qreg(QMODE_I32);            gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));            gen_op_xor32(tmp, tmp, QREG_CC_DEST);            gen_op_and32(tmp, tmp, gen_im32(CCF_V));            gen_op_jmp_nz32(tmp, l2);            gen_op_jmp(l1);            gen_set_label(l2);        }        break;    case 15: /* LE (Z || (N ^ V)) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));        gen_op_jmp_nz32(tmp, l1);        tmp = gen_new_qreg(QMODE_I32);        gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));        gen_op_xor32(tmp, tmp, QREG_CC_DEST);        gen_op_and32(tmp, tmp, gen_im32(CCF_V));        gen_op_jmp_nz32(tmp, l1);        break;    default:        /* Should ever happen.  */        abort();    }}DISAS_INSN(scc){    int l1;    int cond;    int reg;    l1 = gen_new_label();    cond = (insn >> 8) & 0xf;    reg = DREG(insn, 0);    gen_op_and32(reg, reg, gen_im32(0xffffff00));    gen_jmpcc(s, cond ^ 1, l1);    gen_op_or32(reg, reg, gen_im32(0xff));    gen_set_label(l1);}/* Force a TB lookup after an instruction that changes the CPU state.  */static void gen_lookup_tb(DisasContext *s){    gen_flush_cc_op(s);    gen_op_mov32(QREG_PC, gen_im32(s->pc));    s->is_jmp = DISAS_UPDATE;}/* Generate a jump to to the address in qreg DEST.  */static void gen_jmp(DisasContext *s, int dest){    gen_flush_cc_op(s);    gen_op_mov32(QREG_PC, dest);    s->is_jmp = DISAS_JUMP;}static void gen_exception(DisasContext *s, uint32_t where, int nr){    gen_flush_cc_op(s);    gen_jmp(s, gen_im32(where));    gen_op_raise_exception(nr);}static inline void gen_addr_fault(DisasContext *s){    gen_exception(s, s->insn_pc, EXCP_ADDRESS);}#define SRC_EA(result, opsize, val, addrp) do { \    result = gen_ea(s, insn, opsize, val, addrp); \    if (result == -1) { \        gen_addr_fault(s); \        return; \    } \    } while (0)#define DEST_EA(insn, opsize, val, addrp) do { \    int ea_result = gen_ea(s, insn, opsize, val, addrp); \    if (ea_result == -1) { \        gen_addr_fault(s); \        return; \    } \    } while (0)/* Generate a jump to an immediate address.  */static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest){    TranslationBlock *tb;    tb = s->tb;    if (__builtin_expect (s->singlestep_enabled, 0)) {        gen_exception(s, dest, EXCP_DEBUG);    } else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||               (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {        gen_op_goto_tb(0, n, (long)tb);        gen_op_mov32(QREG_PC, gen_im32(dest));        gen_op_mov32(QREG_T0, gen_im32((long)tb + n));        gen_op_exit_tb();    } else {        gen_jmp(s, gen_im32(dest));        gen_op_mov32(QREG_T0, gen_im32(0));        gen_op_exit_tb();    }    s->is_jmp = DISAS_TB_JUMP;}DISAS_INSN(undef_mac){    gen_exception(s, s->pc - 2, EXCP_LINEA);}DISAS_INSN(undef_fpu){    gen_exception(s, s->pc - 2, EXCP_LINEF);}DISAS_INSN(undef){    gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);    cpu_abort(cpu_single_env, "Illegal instruction: %04x @ %08x",              insn, s->pc - 2);}DISAS_INSN(mulw){    int reg;    int tmp;    int src;    int sign;    sign = (insn & 0x100) != 0;    reg = DREG(insn, 9);    tmp = gen_new_qreg(QMODE_I32);    if (sign)        gen_op_ext16s32(tmp, reg);    else        gen_op_ext16u32(tmp, reg);    SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL);    gen_op_mul32(tmp, tmp, src);    gen_op_mov32(reg, tmp);    /* Unlike m68k, coldfire always clears the overflow bit.  */    gen_logic_cc(s, tmp);}DISAS_INSN(divw){    int reg;    int tmp;    int src;    int sign;    sign = (insn & 0x100) != 0;    reg = DREG(insn, 9);    if (sign) {        gen_op_ext16s32(QREG_DIV1, reg);    } else {        gen_op_ext16u32(QREG_DIV1, reg);    }    SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL);    gen_op_mov32(QREG_DIV2, src);    if (sign) {        gen_op_divs(1);    } else {        gen_op_divu(1);    }    tmp = gen_new_qreg(QMODE_I32);    src = gen_new_qreg(QMODE_I32);    gen_op_ext16u32(tmp, QREG_DIV1);    gen_op_shl32(src, QREG_DIV2, gen_im32(16));    gen_op_or32(reg, tmp, src);    gen_op_flags_set();    s->cc_op = CC_OP_FLAGS;}DISAS_INSN(divl){    int num;    int den;    int reg;    uint16_t ext;    ext = lduw_code(s->pc);    s->pc += 2;    if (ext & 0x87f8) {        gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);        return;    }    num = DREG(ext, 12);    reg = DREG(ext, 0);    gen_op_mov32(QREG_DIV1, num);    SRC_EA(den, OS_LONG, 0, NULL);    gen_op_mov32(QREG_DIV2, den);    if (ext & 0x0800) {        gen_op_divs(2);    } else {        gen_op_divu(2);    }    if (num == reg) {        /* div */        gen_op_mov32 (reg, QREG_DIV1);    } else {        /* rem */        gen_op_mov32 (reg, QREG_DIV2);    }    gen_op_flags_set();    s->cc_op = CC_OP_FLAGS;}DISAS_INSN(addsub){    int reg;    int dest;    int src;    int tmp;    int addr;    int add;    add = (insn & 0x4000) != 0;    reg = DREG(insn, 9);    dest = gen_new_qreg(QMODE_I32);    if (insn & 0x100) {        SRC_EA(tmp, OS_LONG, 0, &addr);        src = reg;    } else {        tmp = reg;        SRC_EA(src, OS_LONG, 0, NULL);    }    if (add) {        gen_op_add32(dest, tmp, src);        gen_op_update_xflag_lt(dest, src);        s->cc_op = CC_OP_ADD;    } else {        gen_op_update_xflag_lt(tmp, src);        gen_op_sub32(dest, tmp, src);        s->cc_op = CC_OP_SUB;    }    gen_op_update_cc_add(dest, src);    if (insn & 0x100) {        DEST_EA(insn, OS_LONG, dest, &addr);    } else {        gen_op_mov32(reg, dest);    }}/* Reverse the order of the bits in REG.  */DISAS_INSN(bitrev){    int val;    int tmp1;    int tmp2;    int reg;    val = gen_new_qreg(QMODE_I32);    tmp1 = gen_new_qreg(QMODE_I32);    tmp2 = gen_new_qreg(QMODE_I32);    reg = DREG(insn, 0);    gen_op_mov32(val, reg);    /* Reverse bits within each nibble.  */    gen_op_shl32(tmp1, val, gen_im32(3));    gen_op_and32(tmp1, tmp1, gen_im32(0x88888888));    gen_op_shl32(tmp2, val, gen_im32(1));    gen_op_and32(tmp2, tmp2, gen_im32(0x44444444));    gen_op_or32(tmp1, tmp1, tmp2);    gen_op_shr32(tmp2, val, gen_im32(1));    gen_op_and32(tmp2, tmp2, gen_im32(0x22222222));    gen_op_or32(tmp1, tmp1, tmp2);    gen_op_shr32(tmp2, val, gen_im32(3));    gen_op_and32(tmp2, tmp2, gen_im32(0x11111111));    gen_op_or32(tmp1, tmp1, tmp2);    /* Reverse nibbles withing bytes.  */    gen_op_shl32(val, tmp1, gen_im32(4));    gen_op_and32(val, val, gen_im32(0xf0f0f0f0));    gen_op_shr32(tmp2, tmp1, gen_im32(4));    gen_op_and32(tmp2, tmp2, gen_im32(0x0f0f0f0f));    gen_op_or32(val, val, tmp2);    /* Reverse bytes.  */    gen_op_bswap32(reg, val);    gen_op_mov32(reg, val);}DISAS_INSN(bitop_reg){    int opsize;    int op;    int src1;    int src2;    int tmp;    int addr;    int dest;    if ((insn & 0x38) != 0)        opsize = OS_BYTE;    else        opsize = OS_LONG;    op = (insn >> 6) & 3;    SRC_EA(src1, opsize, 0, op ? &addr: NULL);    src2 = DREG(insn, 9);    dest = gen_new_qreg(QMODE_I32);    gen_flush_flags(s);    tmp = gen_new_qreg(QMODE_I32);    if (opsize == OS_BYTE)        gen_op_and32(tmp, src2, gen_im32(7));    else        gen_op_and32(tmp, src2, gen_im32(31));    src2 = tmp;    tmp = gen_new_qreg(QMODE_I32);    gen_op_shl32(tmp, gen_im32(1), src2);    gen_op_btest(src1, tmp);    switch (op) {    case 1: /* bchg */        gen_op_xor32(dest, src1, tmp);        break;    case 2: /* bclr */        gen_op_not32(tmp, tmp);        gen_op_and32(dest, src1, tmp);        break;    case 3: /* bset */        gen_op_or32(dest, src1, tmp);        break;    default: /* btst */        break;    }    if (op)        DEST_EA(insn, opsize, dest, &addr);}DISAS_INSN(sats){    int reg;    int tmp;    int l1;    reg = DREG(insn, 0);    tmp = gen_new_qreg(QMODE_I32);    gen_flush_flags(s);    gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));    l1 = gen_new_label();    gen_op_jmp_z32(tmp, l1);    tmp = gen_new_qreg(QMODE_I32);    gen_op_shr32(tmp, reg, gen_im32(31));    gen_op_xor32(tmp, tmp, gen_im32(0x80000000));    gen_op_mov32(reg, tmp);    gen_set_label(l1);    gen_logic_cc(s, tmp);}static void gen_push(DisasContext *s, int val){    int tmp;    tmp = gen_new_qreg(QMODE_I32);    gen_op_sub32(tmp, QREG_SP, gen_im32(4));    gen_store(s, OS_LONG, tmp, val);    gen_op_mov32(QREG_SP, tmp);}DISAS_INSN(movem){    int addr;    int i;    uint16_t mask;    int reg;    int tmp;    int is_load;    mask = lduw_code(s->pc);    s->pc += 2;    tmp = gen_lea(s, insn, OS_LONG);    if (tmp == -1) {        gen_addr_fault(s);        return;    }    addr = gen_new_qreg(QMODE_I32);    gen_op_mov32(addr, tmp);    is_load = ((insn & 0x0400) != 0);    for (i = 0; i < 16; i++, mask >>= 1) {        if (mask & 1) {            if (i < 8)                reg = DREG(i, 0);            else                reg = AREG(i, 0);            if (is_load) {                tmp = gen_load(s, OS_LONG, addr, 0);                gen_op_mov32(reg, tmp);            } else {                gen_store(s, OS_LONG, addr, reg);            }            if (mask != 1)                gen_op_add32(addr, addr, gen_im32(4));        }    }}

⌨️ 快捷键说明

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