Annotation of qemu/target-sh4/op_helper.c, revision 1.1.1.3

1.1       root        1: /*
                      2:  *  SH4 emulation
1.1.1.3 ! root        3:  *
1.1       root        4:  *  Copyright (c) 2005 Samuel Tardieu
                      5:  *
                      6:  * This library is free software; you can redistribute it and/or
                      7:  * modify it under the terms of the GNU Lesser General Public
                      8:  * License as published by the Free Software Foundation; either
                      9:  * version 2 of the License, or (at your option) any later version.
                     10:  *
                     11:  * This library is distributed in the hope that it will be useful,
                     12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * Lesser General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU Lesser General Public
                     17:  * License along with this library; if not, write to the Free Software
                     18:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     19:  */
                     20: #include <assert.h>
                     21: #include "exec.h"
                     22: 
                     23: void do_raise_exception(void)
                     24: {
                     25:     cpu_loop_exit();
                     26: }
                     27: 
                     28: #ifndef CONFIG_USER_ONLY
                     29: 
                     30: #define MMUSUFFIX _mmu
1.1.1.3 ! root       31: #ifdef __s390__
        !            32: # define GETPC() ((void*)((unsigned long)__builtin_return_address(0) & 0x7fffffffUL))
        !            33: #else
        !            34: # define GETPC() (__builtin_return_address(0))
        !            35: #endif
1.1       root       36: 
                     37: #define SHIFT 0
                     38: #include "softmmu_template.h"
                     39: 
                     40: #define SHIFT 1
                     41: #include "softmmu_template.h"
                     42: 
                     43: #define SHIFT 2
                     44: #include "softmmu_template.h"
                     45: 
                     46: #define SHIFT 3
                     47: #include "softmmu_template.h"
                     48: 
1.1.1.3 ! root       49: void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
1.1       root       50: {
                     51:     TranslationBlock *tb;
                     52:     CPUState *saved_env;
                     53:     unsigned long pc;
                     54:     int ret;
                     55: 
                     56:     /* XXX: hack to restore env in all cases, even if not called from
                     57:        generated code */
                     58:     saved_env = env;
                     59:     env = cpu_single_env;
1.1.1.3 ! root       60:     ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
1.1       root       61:     if (ret) {
                     62:        if (retaddr) {
                     63:            /* now we have a real cpu fault */
                     64:            pc = (unsigned long) retaddr;
                     65:            tb = tb_find_pc(pc);
                     66:            if (tb) {
                     67:                /* the PC is inside the translated code. It means that we have
                     68:                   a virtual CPU fault */
                     69:                cpu_restore_state(tb, env, pc, NULL);
                     70:            }
                     71:        }
                     72:        do_raise_exception();
                     73:     }
                     74:     env = saved_env;
                     75: }
                     76: 
                     77: #endif
                     78: 
                     79: void helper_addc_T0_T1(void)
                     80: {
                     81:     uint32_t tmp0, tmp1;
                     82: 
                     83:     tmp1 = T0 + T1;
                     84:     tmp0 = T1;
                     85:     T1 = tmp1 + (env->sr & 1);
                     86:     if (tmp0 > tmp1)
                     87:        env->sr |= SR_T;
                     88:     else
                     89:        env->sr &= ~SR_T;
                     90:     if (tmp1 > T1)
                     91:        env->sr |= SR_T;
                     92: }
                     93: 
                     94: void helper_addv_T0_T1(void)
                     95: {
                     96:     uint32_t dest, src, ans;
                     97: 
                     98:     if ((int32_t) T1 >= 0)
                     99:        dest = 0;
                    100:     else
                    101:        dest = 1;
                    102:     if ((int32_t) T0 >= 0)
                    103:        src = 0;
                    104:     else
                    105:        src = 1;
                    106:     src += dest;
                    107:     T1 += T0;
                    108:     if ((int32_t) T1 >= 0)
                    109:        ans = 0;
                    110:     else
                    111:        ans = 1;
                    112:     ans += dest;
                    113:     if (src == 0 || src == 2) {
                    114:        if (ans == 1)
                    115:            env->sr |= SR_T;
                    116:        else
                    117:            env->sr &= ~SR_T;
                    118:     } else
                    119:        env->sr &= ~SR_T;
                    120: }
                    121: 
                    122: #define T (env->sr & SR_T)
                    123: #define Q (env->sr & SR_Q ? 1 : 0)
                    124: #define M (env->sr & SR_M ? 1 : 0)
                    125: #define SETT env->sr |= SR_T
                    126: #define CLRT env->sr &= ~SR_T
                    127: #define SETQ env->sr |= SR_Q
                    128: #define CLRQ env->sr &= ~SR_Q
                    129: #define SETM env->sr |= SR_M
                    130: #define CLRM env->sr &= ~SR_M
                    131: 
                    132: void helper_div1_T0_T1(void)
                    133: {
                    134:     uint32_t tmp0, tmp2;
                    135:     uint8_t old_q, tmp1 = 0xff;
                    136: 
1.1.1.2   root      137:     //printf("div1 T0=0x%08x T1=0x%08x M=%d Q=%d T=%d\n", T0, T1, M, Q, T);
1.1       root      138:     old_q = Q;
                    139:     if ((0x80000000 & T1) != 0)
                    140:        SETQ;
                    141:     else
                    142:        CLRQ;
                    143:     tmp2 = T0;
                    144:     T1 <<= 1;
                    145:     T1 |= T;
                    146:     switch (old_q) {
                    147:     case 0:
                    148:        switch (M) {
                    149:        case 0:
                    150:            tmp0 = T1;
                    151:            T1 -= tmp2;
                    152:            tmp1 = T1 > tmp0;
                    153:            switch (Q) {
                    154:            case 0:
                    155:                if (tmp1)
                    156:                    SETQ;
                    157:                else
                    158:                    CLRQ;
                    159:                break;
                    160:            case 1:
                    161:                if (tmp1 == 0)
                    162:                    SETQ;
                    163:                else
                    164:                    CLRQ;
                    165:                break;
                    166:            }
                    167:            break;
                    168:        case 1:
                    169:            tmp0 = T1;
                    170:            T1 += tmp2;
                    171:            tmp1 = T1 < tmp0;
                    172:            switch (Q) {
                    173:            case 0:
                    174:                if (tmp1 == 0)
                    175:                    SETQ;
                    176:                else
                    177:                    CLRQ;
                    178:                break;
                    179:            case 1:
                    180:                if (tmp1)
                    181:                    SETQ;
                    182:                else
                    183:                    CLRQ;
                    184:                break;
                    185:            }
                    186:            break;
                    187:        }
                    188:        break;
                    189:     case 1:
                    190:        switch (M) {
                    191:        case 0:
                    192:            tmp0 = T1;
                    193:            T1 += tmp2;
                    194:            tmp1 = T1 < tmp0;
                    195:            switch (Q) {
                    196:            case 0:
                    197:                if (tmp1)
                    198:                    SETQ;
                    199:                else
                    200:                    CLRQ;
                    201:                break;
                    202:            case 1:
                    203:                if (tmp1 == 0)
                    204:                    SETQ;
                    205:                else
                    206:                    CLRQ;
                    207:                break;
                    208:            }
                    209:            break;
                    210:        case 1:
                    211:            tmp0 = T1;
                    212:            T1 -= tmp2;
                    213:            tmp1 = T1 > tmp0;
                    214:            switch (Q) {
                    215:            case 0:
                    216:                if (tmp1 == 0)
                    217:                    SETQ;
                    218:                else
                    219:                    CLRQ;
                    220:                break;
                    221:            case 1:
                    222:                if (tmp1)
                    223:                    SETQ;
                    224:                else
                    225:                    CLRQ;
                    226:                break;
                    227:            }
                    228:            break;
                    229:        }
                    230:        break;
                    231:     }
                    232:     if (Q == M)
                    233:        SETT;
                    234:     else
                    235:        CLRT;
1.1.1.2   root      236:     //printf("Output: T1=0x%08x M=%d Q=%d T=%d\n", T1, M, Q, T);
1.1       root      237: }
                    238: 
                    239: void helper_dmulsl_T0_T1()
                    240: {
                    241:     int64_t res;
                    242: 
                    243:     res = (int64_t) (int32_t) T0 *(int64_t) (int32_t) T1;
                    244:     env->mach = (res >> 32) & 0xffffffff;
                    245:     env->macl = res & 0xffffffff;
                    246: }
                    247: 
                    248: void helper_dmulul_T0_T1()
                    249: {
                    250:     uint64_t res;
                    251: 
                    252:     res = (uint64_t) (uint32_t) T0 *(uint64_t) (uint32_t) T1;
                    253:     env->mach = (res >> 32) & 0xffffffff;
                    254:     env->macl = res & 0xffffffff;
                    255: }
                    256: 
                    257: void helper_macl_T0_T1()
                    258: {
                    259:     int64_t res;
                    260: 
                    261:     res = ((uint64_t) env->mach << 32) | env->macl;
                    262:     res += (int64_t) (int32_t) T0 *(int64_t) (int32_t) T1;
                    263:     env->mach = (res >> 32) & 0xffffffff;
                    264:     env->macl = res & 0xffffffff;
                    265:     if (env->sr & SR_S) {
                    266:        if (res < 0)
                    267:            env->mach |= 0xffff0000;
                    268:        else
                    269:            env->mach &= 0x00007fff;
                    270:     }
                    271: }
                    272: 
                    273: void helper_macw_T0_T1()
                    274: {
                    275:     int64_t res;
                    276: 
                    277:     res = ((uint64_t) env->mach << 32) | env->macl;
                    278:     res += (int64_t) (int16_t) T0 *(int64_t) (int16_t) T1;
                    279:     env->mach = (res >> 32) & 0xffffffff;
                    280:     env->macl = res & 0xffffffff;
                    281:     if (env->sr & SR_S) {
                    282:        if (res < -0x80000000) {
                    283:            env->mach = 1;
                    284:            env->macl = 0x80000000;
                    285:        } else if (res > 0x000000007fffffff) {
                    286:            env->mach = 1;
                    287:            env->macl = 0x7fffffff;
                    288:        }
                    289:     }
                    290: }
                    291: 
                    292: void helper_negc_T0()
                    293: {
                    294:     uint32_t temp;
                    295: 
                    296:     temp = -T0;
                    297:     T0 = temp - (env->sr & SR_T);
                    298:     if (0 < temp)
                    299:        env->sr |= SR_T;
                    300:     else
                    301:        env->sr &= ~SR_T;
                    302:     if (temp < T0)
                    303:        env->sr |= SR_T;
                    304: }
                    305: 
                    306: void helper_subc_T0_T1()
                    307: {
                    308:     uint32_t tmp0, tmp1;
                    309: 
                    310:     tmp1 = T1 - T0;
                    311:     tmp0 = T1;
                    312:     T1 = tmp1 - (env->sr & SR_T);
                    313:     if (tmp0 < tmp1)
                    314:        env->sr |= SR_T;
                    315:     else
                    316:        env->sr &= ~SR_T;
                    317:     if (tmp1 < T1)
                    318:        env->sr |= SR_T;
                    319: }
                    320: 
                    321: void helper_subv_T0_T1()
                    322: {
                    323:     int32_t dest, src, ans;
                    324: 
                    325:     if ((int32_t) T1 >= 0)
                    326:        dest = 0;
                    327:     else
                    328:        dest = 1;
                    329:     if ((int32_t) T0 >= 0)
                    330:        src = 0;
                    331:     else
                    332:        src = 1;
                    333:     src += dest;
                    334:     T1 -= T0;
                    335:     if ((int32_t) T1 >= 0)
                    336:        ans = 0;
                    337:     else
                    338:        ans = 1;
                    339:     ans += dest;
                    340:     if (src == 1) {
                    341:        if (ans == 1)
                    342:            env->sr |= SR_T;
                    343:        else
                    344:            env->sr &= ~SR_T;
                    345:     } else
                    346:        env->sr &= ~SR_T;
                    347: }
                    348: 
                    349: void helper_rotcl(uint32_t * addr)
                    350: {
                    351:     uint32_t new;
                    352: 
                    353:     new = (*addr << 1) | (env->sr & SR_T);
                    354:     if (*addr & 0x80000000)
                    355:        env->sr |= SR_T;
                    356:     else
                    357:        env->sr &= ~SR_T;
                    358:     *addr = new;
                    359: }
                    360: 
                    361: void helper_rotcr(uint32_t * addr)
                    362: {
                    363:     uint32_t new;
                    364: 
                    365:     new = (*addr >> 1) | ((env->sr & SR_T) ? 0x80000000 : 0);
                    366:     if (*addr & 1)
                    367:        env->sr |= SR_T;
                    368:     else
                    369:        env->sr &= ~SR_T;
                    370:     *addr = new;
                    371: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.