Statistics
| Branch: | Revision:

root / target-i386 / mem_helper.c @ feature-archipelago

History | View | Annotate | Download (3.8 kB)

1 10774999 Blue Swirl
/*
2 10774999 Blue Swirl
 *  x86 memory access helpers
3 10774999 Blue Swirl
 *
4 10774999 Blue Swirl
 *  Copyright (c) 2003 Fabrice Bellard
5 10774999 Blue Swirl
 *
6 10774999 Blue Swirl
 * This library is free software; you can redistribute it and/or
7 10774999 Blue Swirl
 * modify it under the terms of the GNU Lesser General Public
8 10774999 Blue Swirl
 * License as published by the Free Software Foundation; either
9 10774999 Blue Swirl
 * version 2 of the License, or (at your option) any later version.
10 10774999 Blue Swirl
 *
11 10774999 Blue Swirl
 * This library is distributed in the hope that it will be useful,
12 10774999 Blue Swirl
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 10774999 Blue Swirl
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 10774999 Blue Swirl
 * Lesser General Public License for more details.
15 10774999 Blue Swirl
 *
16 10774999 Blue Swirl
 * You should have received a copy of the GNU Lesser General Public
17 10774999 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 10774999 Blue Swirl
 */
19 10774999 Blue Swirl
20 10774999 Blue Swirl
#include "cpu.h"
21 10774999 Blue Swirl
#include "helper.h"
22 10774999 Blue Swirl
23 10774999 Blue Swirl
#if !defined(CONFIG_USER_ONLY)
24 022c62cb Paolo Bonzini
#include "exec/softmmu_exec.h"
25 10774999 Blue Swirl
#endif /* !defined(CONFIG_USER_ONLY) */
26 10774999 Blue Swirl
27 10774999 Blue Swirl
/* broken thread support */
28 10774999 Blue Swirl
29 10774999 Blue Swirl
static spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
30 10774999 Blue Swirl
31 10774999 Blue Swirl
void helper_lock(void)
32 10774999 Blue Swirl
{
33 10774999 Blue Swirl
    spin_lock(&global_cpu_lock);
34 10774999 Blue Swirl
}
35 10774999 Blue Swirl
36 10774999 Blue Swirl
void helper_unlock(void)
37 10774999 Blue Swirl
{
38 10774999 Blue Swirl
    spin_unlock(&global_cpu_lock);
39 10774999 Blue Swirl
}
40 10774999 Blue Swirl
41 92fc4b58 Blue Swirl
void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
42 10774999 Blue Swirl
{
43 10774999 Blue Swirl
    uint64_t d;
44 10774999 Blue Swirl
    int eflags;
45 10774999 Blue Swirl
46 f0967a1a Blue Swirl
    eflags = cpu_cc_compute_all(env, CC_OP);
47 92fc4b58 Blue Swirl
    d = cpu_ldq_data(env, a0);
48 00f5e6f2 liguang
    if (d == (((uint64_t)env->regs[R_EDX] << 32) | (uint32_t)env->regs[R_EAX])) {
49 a4165610 liguang
        cpu_stq_data(env, a0, ((uint64_t)env->regs[R_ECX] << 32) | (uint32_t)env->regs[R_EBX]);
50 10774999 Blue Swirl
        eflags |= CC_Z;
51 10774999 Blue Swirl
    } else {
52 10774999 Blue Swirl
        /* always do the store */
53 92fc4b58 Blue Swirl
        cpu_stq_data(env, a0, d);
54 00f5e6f2 liguang
        env->regs[R_EDX] = (uint32_t)(d >> 32);
55 4b34e3ad liguang
        env->regs[R_EAX] = (uint32_t)d;
56 10774999 Blue Swirl
        eflags &= ~CC_Z;
57 10774999 Blue Swirl
    }
58 10774999 Blue Swirl
    CC_SRC = eflags;
59 10774999 Blue Swirl
}
60 10774999 Blue Swirl
61 10774999 Blue Swirl
#ifdef TARGET_X86_64
62 92fc4b58 Blue Swirl
void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
63 10774999 Blue Swirl
{
64 10774999 Blue Swirl
    uint64_t d0, d1;
65 10774999 Blue Swirl
    int eflags;
66 10774999 Blue Swirl
67 10774999 Blue Swirl
    if ((a0 & 0xf) != 0) {
68 10774999 Blue Swirl
        raise_exception(env, EXCP0D_GPF);
69 10774999 Blue Swirl
    }
70 f0967a1a Blue Swirl
    eflags = cpu_cc_compute_all(env, CC_OP);
71 92fc4b58 Blue Swirl
    d0 = cpu_ldq_data(env, a0);
72 92fc4b58 Blue Swirl
    d1 = cpu_ldq_data(env, a0 + 8);
73 00f5e6f2 liguang
    if (d0 == env->regs[R_EAX] && d1 == env->regs[R_EDX]) {
74 70b51365 liguang
        cpu_stq_data(env, a0, env->regs[R_EBX]);
75 a4165610 liguang
        cpu_stq_data(env, a0 + 8, env->regs[R_ECX]);
76 10774999 Blue Swirl
        eflags |= CC_Z;
77 10774999 Blue Swirl
    } else {
78 10774999 Blue Swirl
        /* always do the store */
79 92fc4b58 Blue Swirl
        cpu_stq_data(env, a0, d0);
80 92fc4b58 Blue Swirl
        cpu_stq_data(env, a0 + 8, d1);
81 00f5e6f2 liguang
        env->regs[R_EDX] = d1;
82 4b34e3ad liguang
        env->regs[R_EAX] = d0;
83 10774999 Blue Swirl
        eflags &= ~CC_Z;
84 10774999 Blue Swirl
    }
85 10774999 Blue Swirl
    CC_SRC = eflags;
86 10774999 Blue Swirl
}
87 10774999 Blue Swirl
#endif
88 10774999 Blue Swirl
89 92fc4b58 Blue Swirl
void helper_boundw(CPUX86State *env, target_ulong a0, int v)
90 10774999 Blue Swirl
{
91 10774999 Blue Swirl
    int low, high;
92 10774999 Blue Swirl
93 92fc4b58 Blue Swirl
    low = cpu_ldsw_data(env, a0);
94 92fc4b58 Blue Swirl
    high = cpu_ldsw_data(env, a0 + 2);
95 10774999 Blue Swirl
    v = (int16_t)v;
96 10774999 Blue Swirl
    if (v < low || v > high) {
97 10774999 Blue Swirl
        raise_exception(env, EXCP05_BOUND);
98 10774999 Blue Swirl
    }
99 10774999 Blue Swirl
}
100 10774999 Blue Swirl
101 92fc4b58 Blue Swirl
void helper_boundl(CPUX86State *env, target_ulong a0, int v)
102 10774999 Blue Swirl
{
103 10774999 Blue Swirl
    int low, high;
104 10774999 Blue Swirl
105 92fc4b58 Blue Swirl
    low = cpu_ldl_data(env, a0);
106 92fc4b58 Blue Swirl
    high = cpu_ldl_data(env, a0 + 4);
107 10774999 Blue Swirl
    if (v < low || v > high) {
108 10774999 Blue Swirl
        raise_exception(env, EXCP05_BOUND);
109 10774999 Blue Swirl
    }
110 10774999 Blue Swirl
}
111 10774999 Blue Swirl
112 10774999 Blue Swirl
#if !defined(CONFIG_USER_ONLY)
113 10774999 Blue Swirl
114 10774999 Blue Swirl
#define MMUSUFFIX _mmu
115 10774999 Blue Swirl
116 10774999 Blue Swirl
#define SHIFT 0
117 022c62cb Paolo Bonzini
#include "exec/softmmu_template.h"
118 10774999 Blue Swirl
119 10774999 Blue Swirl
#define SHIFT 1
120 022c62cb Paolo Bonzini
#include "exec/softmmu_template.h"
121 10774999 Blue Swirl
122 10774999 Blue Swirl
#define SHIFT 2
123 022c62cb Paolo Bonzini
#include "exec/softmmu_template.h"
124 10774999 Blue Swirl
125 10774999 Blue Swirl
#define SHIFT 3
126 022c62cb Paolo Bonzini
#include "exec/softmmu_template.h"
127 10774999 Blue Swirl
128 10774999 Blue Swirl
#endif
129 10774999 Blue Swirl
130 10774999 Blue Swirl
#if !defined(CONFIG_USER_ONLY)
131 10774999 Blue Swirl
/* try to fill the TLB and return an exception if error. If retaddr is
132 10774999 Blue Swirl
   NULL, it means that the function was called in C code (i.e. not
133 10774999 Blue Swirl
   from generated code or from helper.c) */
134 10774999 Blue Swirl
/* XXX: fix it to restore all registers */
135 92fc4b58 Blue Swirl
void tlb_fill(CPUX86State *env, target_ulong addr, int is_write, int mmu_idx,
136 10774999 Blue Swirl
              uintptr_t retaddr)
137 10774999 Blue Swirl
{
138 10774999 Blue Swirl
    int ret;
139 10774999 Blue Swirl
140 10774999 Blue Swirl
    ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx);
141 10774999 Blue Swirl
    if (ret) {
142 10774999 Blue Swirl
        if (retaddr) {
143 10774999 Blue Swirl
            /* now we have a real cpu fault */
144 a8a826a3 Blue Swirl
            cpu_restore_state(env, retaddr);
145 10774999 Blue Swirl
        }
146 10774999 Blue Swirl
        raise_exception_err(env, env->exception_index, env->error_code);
147 10774999 Blue Swirl
    }
148 10774999 Blue Swirl
}
149 10774999 Blue Swirl
#endif