Annotation of qemu/target-microblaze/op_helper.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  Microblaze helper routines.
                      3:  *
                      4:  *  Copyright (c) 2009 Edgar E. Iglesias <[email protected]>.
                      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, see <http://www.gnu.org/licenses/>.
                     18:  */
                     19: 
                     20: #include <assert.h>
                     21: #include "exec.h"
                     22: #include "helper.h"
                     23: #include "host-utils.h"
                     24: 
                     25: #define D(x)
                     26: 
                     27: #if !defined(CONFIG_USER_ONLY)
                     28: #define MMUSUFFIX _mmu
                     29: #define SHIFT 0
                     30: #include "softmmu_template.h"
                     31: #define SHIFT 1
                     32: #include "softmmu_template.h"
                     33: #define SHIFT 2
                     34: #include "softmmu_template.h"
                     35: #define SHIFT 3
                     36: #include "softmmu_template.h"
                     37: 
                     38: /* Try to fill the TLB and return an exception if error. If retaddr is
                     39:    NULL, it means that the function was called in C code (i.e. not
                     40:    from generated code or from helper.c) */
                     41: /* XXX: fix it to restore all registers */
                     42: void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
                     43: {
                     44:     TranslationBlock *tb;
                     45:     CPUState *saved_env;
                     46:     unsigned long pc;
                     47:     int ret;
                     48: 
                     49:     /* XXX: hack to restore env in all cases, even if not called from
                     50:        generated code */
                     51:     saved_env = env;
                     52:     env = cpu_single_env;
                     53: 
                     54:     ret = cpu_mb_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
                     55:     if (unlikely(ret)) {
                     56:         if (retaddr) {
                     57:             /* now we have a real cpu fault */
                     58:             pc = (unsigned long)retaddr;
                     59:             tb = tb_find_pc(pc);
                     60:             if (tb) {
                     61:                 /* the PC is inside the translated code. It means that we have
                     62:                    a virtual CPU fault */
                     63:                 cpu_restore_state(tb, env, pc, NULL);
                     64:             }
                     65:         }
                     66:         cpu_loop_exit();
                     67:     }
                     68:     env = saved_env;
                     69: }
                     70: #endif
                     71: 
                     72: void helper_raise_exception(uint32_t index)
                     73: {
                     74:     env->exception_index = index;
                     75:     cpu_loop_exit();
                     76: }
                     77: 
                     78: void helper_debug(void)
                     79: {
                     80:     int i;
                     81: 
                     82:     qemu_log("PC=%8.8x\n", env->sregs[SR_PC]);
                     83:     for (i = 0; i < 32; i++) {
                     84:         qemu_log("r%2.2d=%8.8x ", i, env->regs[i]);
                     85:         if ((i + 1) % 4 == 0)
                     86:             qemu_log("\n");
                     87:     }
                     88:     qemu_log("\n\n");
                     89: }
                     90: 
                     91: static inline uint32_t compute_carry(uint32_t a, uint32_t b, uint32_t cin)
                     92: {
                     93:     uint32_t cout = 0;
                     94: 
                     95:     if ((b == ~0) && cin)
                     96:         cout = 1;
                     97:     else if ((~0 - a) < (b + cin))
                     98:         cout = 1;
                     99:     return cout;
                    100: }
                    101: 
                    102: uint32_t helper_cmp(uint32_t a, uint32_t b)
                    103: {
                    104:     uint32_t t;
                    105: 
                    106:     t = b + ~a + 1;
                    107:     if ((b & 0x80000000) ^ (a & 0x80000000))
                    108:         t = (t & 0x7fffffff) | (b & 0x80000000);
                    109:     return t;
                    110: }
                    111: 
                    112: uint32_t helper_cmpu(uint32_t a, uint32_t b)
                    113: {
                    114:     uint32_t t;
                    115: 
                    116:     t = b + ~a + 1;
                    117:     if ((b & 0x80000000) ^ (a & 0x80000000))
                    118:         t = (t & 0x7fffffff) | (a & 0x80000000);
                    119:     return t;
                    120: }
                    121: 
                    122: uint32_t helper_addkc(uint32_t a, uint32_t b, uint32_t k, uint32_t c)
                    123: {
                    124:     uint32_t d, cf = 0, ncf;
                    125: 
                    126:     if (c)
                    127:         cf = env->sregs[SR_MSR] >> 31;
                    128:     assert(cf == 0 || cf == 1);
                    129:     d = a + b + cf;
                    130: 
                    131:     if (!k) {
                    132:         ncf = compute_carry(a, b, cf);
                    133:         assert(ncf == 0 || ncf == 1);
                    134:         if (ncf)
                    135:             env->sregs[SR_MSR] |= MSR_C | MSR_CC;
                    136:         else
                    137:             env->sregs[SR_MSR] &= ~(MSR_C | MSR_CC);
                    138:     }
                    139:     D(qemu_log("%x = %x + %x cf=%d ncf=%d k=%d c=%d\n",
                    140:                d, a, b, cf, ncf, k, c));
                    141:     return d;
                    142: }
                    143: 
                    144: uint32_t helper_subkc(uint32_t a, uint32_t b, uint32_t k, uint32_t c)
                    145: {
                    146:     uint32_t d, cf = 1, ncf;
                    147: 
                    148:     if (c)
                    149:         cf = env->sregs[SR_MSR] >> 31; 
                    150:     assert(cf == 0 || cf == 1);
                    151:     d = b + ~a + cf;
                    152: 
                    153:     if (!k) {
                    154:         ncf = compute_carry(b, ~a, cf);
                    155:         assert(ncf == 0 || ncf == 1);
                    156:         if (ncf)
                    157:             env->sregs[SR_MSR] |= MSR_C | MSR_CC;
                    158:         else
                    159:             env->sregs[SR_MSR] &= ~(MSR_C | MSR_CC);
                    160:     }
                    161:     D(qemu_log("%x = %x + %x cf=%d ncf=%d k=%d c=%d\n",
                    162:                d, a, b, cf, ncf, k, c));
                    163:     return d;
                    164: }
                    165: 
                    166: static inline int div_prepare(uint32_t a, uint32_t b)
                    167: {
                    168:     if (b == 0) {
                    169:         env->sregs[SR_MSR] |= MSR_DZ;
                    170:         /* FIXME: Raise the div by zero exception.  */
                    171:         return 0;
                    172:     }
                    173:     env->sregs[SR_MSR] &= ~MSR_DZ;
                    174:     return 1;
                    175: }
                    176: 
                    177: uint32_t helper_divs(uint32_t a, uint32_t b)
                    178: {
                    179:     if (!div_prepare(a, b))
                    180:         return 0;
                    181:     return (int32_t)a / (int32_t)b;
                    182: }
                    183: 
                    184: uint32_t helper_divu(uint32_t a, uint32_t b)
                    185: {
                    186:     if (!div_prepare(a, b))
                    187:         return 0;
                    188:     return a / b;
                    189: }
                    190: 
                    191: uint32_t helper_pcmpbf(uint32_t a, uint32_t b)
                    192: {
                    193:     unsigned int i;
                    194:     uint32_t mask = 0xff000000;
                    195: 
                    196:     for (i = 0; i < 4; i++) {
                    197:         if ((a & mask) == (b & mask))
                    198:             return i + 1;
                    199:         mask >>= 8;
                    200:     }
                    201:     return 0;
                    202: }
                    203: 
                    204: #if !defined(CONFIG_USER_ONLY)
                    205: /* Writes/reads to the MMU's special regs end up here.  */
                    206: uint32_t helper_mmu_read(uint32_t rn)
                    207: {
                    208:     return mmu_read(env, rn);
                    209: }
                    210: 
                    211: void helper_mmu_write(uint32_t rn, uint32_t v)
                    212: {
                    213:     mmu_write(env, rn, v);
                    214: }
                    215: #endif

unix.superglobalmegacorp.com

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