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

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

unix.superglobalmegacorp.com

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