Statistics
| Branch: | Revision:

root / target-arm / op.c @ 4373f3ce

History | View | Annotate | Download (6.8 kB)

1 2c0262af bellard
/*
2 2c0262af bellard
 *  ARM micro operations
3 5fafdf24 ths
 *
4 2c0262af bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 9ee6e8bb pbrook
 *  Copyright (c) 2005-2007 CodeSourcery, LLC
6 2c0262af bellard
 *
7 2c0262af bellard
 * This library is free software; you can redistribute it and/or
8 2c0262af bellard
 * modify it under the terms of the GNU Lesser General Public
9 2c0262af bellard
 * License as published by the Free Software Foundation; either
10 2c0262af bellard
 * version 2 of the License, or (at your option) any later version.
11 2c0262af bellard
 *
12 2c0262af bellard
 * This library is distributed in the hope that it will be useful,
13 2c0262af bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 2c0262af bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 2c0262af bellard
 * Lesser General Public License for more details.
16 2c0262af bellard
 *
17 2c0262af bellard
 * You should have received a copy of the GNU Lesser General Public
18 2c0262af bellard
 * License along with this library; if not, write to the Free Software
19 2c0262af bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 2c0262af bellard
 */
21 2c0262af bellard
#include "exec.h"
22 2c0262af bellard
23 2c0262af bellard
void OPPROTO op_addl_T0_T1_cc(void)
24 2c0262af bellard
{
25 2c0262af bellard
    unsigned int src1;
26 2c0262af bellard
    src1 = T0;
27 2c0262af bellard
    T0 += T1;
28 2c0262af bellard
    env->NZF = T0;
29 2c0262af bellard
    env->CF = T0 < src1;
30 2c0262af bellard
    env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
31 2c0262af bellard
}
32 2c0262af bellard
33 2c0262af bellard
void OPPROTO op_adcl_T0_T1_cc(void)
34 2c0262af bellard
{
35 2c0262af bellard
    unsigned int src1;
36 2c0262af bellard
    src1 = T0;
37 2c0262af bellard
    if (!env->CF) {
38 2c0262af bellard
        T0 += T1;
39 2c0262af bellard
        env->CF = T0 < src1;
40 2c0262af bellard
    } else {
41 2c0262af bellard
        T0 += T1 + 1;
42 2c0262af bellard
        env->CF = T0 <= src1;
43 2c0262af bellard
    }
44 2c0262af bellard
    env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
45 2c0262af bellard
    env->NZF = T0;
46 2c0262af bellard
    FORCE_RET();
47 2c0262af bellard
}
48 2c0262af bellard
49 2c0262af bellard
#define OPSUB(sub, sbc, res, T0, T1)            \
50 2c0262af bellard
                                                \
51 2c0262af bellard
void OPPROTO op_ ## sub ## l_T0_T1_cc(void)     \
52 2c0262af bellard
{                                               \
53 2c0262af bellard
    unsigned int src1;                          \
54 2c0262af bellard
    src1 = T0;                                  \
55 2c0262af bellard
    T0 -= T1;                                   \
56 2c0262af bellard
    env->NZF = T0;                              \
57 2c0262af bellard
    env->CF = src1 >= T1;                       \
58 2c0262af bellard
    env->VF = (src1 ^ T1) & (src1 ^ T0);        \
59 2c0262af bellard
    res = T0;                                   \
60 2c0262af bellard
}                                               \
61 2c0262af bellard
                                                \
62 2c0262af bellard
void OPPROTO op_ ## sbc ## l_T0_T1_cc(void)     \
63 2c0262af bellard
{                                               \
64 2c0262af bellard
    unsigned int src1;                          \
65 2c0262af bellard
    src1 = T0;                                  \
66 2c0262af bellard
    if (!env->CF) {                             \
67 2c0262af bellard
        T0 = T0 - T1 - 1;                       \
68 78573df6 bellard
        env->CF = src1 > T1;                    \
69 2c0262af bellard
    } else {                                    \
70 2c0262af bellard
        T0 = T0 - T1;                           \
71 78573df6 bellard
        env->CF = src1 >= T1;                   \
72 2c0262af bellard
    }                                           \
73 2c0262af bellard
    env->VF = (src1 ^ T1) & (src1 ^ T0);        \
74 2c0262af bellard
    env->NZF = T0;                              \
75 2c0262af bellard
    res = T0;                                   \
76 2c0262af bellard
    FORCE_RET();                                \
77 2c0262af bellard
}
78 2c0262af bellard
79 2c0262af bellard
OPSUB(sub, sbc, T0, T0, T1)
80 2c0262af bellard
81 2c0262af bellard
OPSUB(rsb, rsc, T0, T1, T0)
82 2c0262af bellard
83 2c0262af bellard
void OPPROTO op_addq_T0_T1(void)
84 2c0262af bellard
{
85 2c0262af bellard
    uint64_t res;
86 2c0262af bellard
    res = ((uint64_t)T1 << 32) | T0;
87 2c0262af bellard
    res += ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
88 2c0262af bellard
    T1 = res >> 32;
89 2c0262af bellard
    T0 = res;
90 2c0262af bellard
}
91 2c0262af bellard
92 99c475ab bellard
void OPPROTO op_addq_lo_T0_T1(void)
93 99c475ab bellard
{
94 99c475ab bellard
    uint64_t res;
95 99c475ab bellard
    res = ((uint64_t)T1 << 32) | T0;
96 99c475ab bellard
    res += (uint64_t)(env->regs[PARAM1]);
97 99c475ab bellard
    T1 = res >> 32;
98 99c475ab bellard
    T0 = res;
99 99c475ab bellard
}
100 99c475ab bellard
101 9ee6e8bb pbrook
/* Dual 16-bit accumulate.  */
102 9ee6e8bb pbrook
void OPPROTO op_addq_T0_T1_dual(void)
103 9ee6e8bb pbrook
{
104 9ee6e8bb pbrook
  uint64_t res;
105 9ee6e8bb pbrook
  res = ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
106 9ee6e8bb pbrook
  res += (int32_t)T0;
107 9ee6e8bb pbrook
  res += (int32_t)T1;
108 9ee6e8bb pbrook
  env->regs[PARAM1] = (uint32_t)res;
109 9ee6e8bb pbrook
  env->regs[PARAM2] = res >> 32;
110 9ee6e8bb pbrook
}
111 9ee6e8bb pbrook
112 9ee6e8bb pbrook
/* Dual 16-bit subtract accumulate.  */
113 9ee6e8bb pbrook
void OPPROTO op_subq_T0_T1_dual(void)
114 9ee6e8bb pbrook
{
115 9ee6e8bb pbrook
  uint64_t res;
116 9ee6e8bb pbrook
  res = ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
117 9ee6e8bb pbrook
  res += (int32_t)T0;
118 9ee6e8bb pbrook
  res -= (int32_t)T1;
119 9ee6e8bb pbrook
  env->regs[PARAM1] = (uint32_t)res;
120 9ee6e8bb pbrook
  env->regs[PARAM2] = res >> 32;
121 9ee6e8bb pbrook
}
122 9ee6e8bb pbrook
123 2c0262af bellard
void OPPROTO op_logicq_cc(void)
124 2c0262af bellard
{
125 2c0262af bellard
    env->NZF = (T1 & 0x80000000) | ((T0 | T1) != 0);
126 2c0262af bellard
}
127 2c0262af bellard
128 2c0262af bellard
/* memory access */
129 2c0262af bellard
130 b5ff1b31 bellard
#define MEMSUFFIX _raw
131 b5ff1b31 bellard
#include "op_mem.h"
132 2c0262af bellard
133 b5ff1b31 bellard
#if !defined(CONFIG_USER_ONLY)
134 b5ff1b31 bellard
#define MEMSUFFIX _user
135 b5ff1b31 bellard
#include "op_mem.h"
136 b5ff1b31 bellard
#define MEMSUFFIX _kernel
137 b5ff1b31 bellard
#include "op_mem.h"
138 b5ff1b31 bellard
#endif
139 2c0262af bellard
140 9ee6e8bb pbrook
void OPPROTO op_clrex(void)
141 9ee6e8bb pbrook
{
142 9ee6e8bb pbrook
    cpu_lock();
143 9ee6e8bb pbrook
    helper_clrex(env);
144 9ee6e8bb pbrook
    cpu_unlock();
145 9ee6e8bb pbrook
}
146 9ee6e8bb pbrook
147 2c0262af bellard
/* T1 based, use T0 as shift count */
148 2c0262af bellard
149 2c0262af bellard
void OPPROTO op_shll_T1_T0(void)
150 2c0262af bellard
{
151 2c0262af bellard
    int shift;
152 2c0262af bellard
    shift = T0 & 0xff;
153 2c0262af bellard
    if (shift >= 32)
154 2c0262af bellard
        T1 = 0;
155 2c0262af bellard
    else
156 2c0262af bellard
        T1 = T1 << shift;
157 2c0262af bellard
    FORCE_RET();
158 2c0262af bellard
}
159 2c0262af bellard
160 2c0262af bellard
void OPPROTO op_shrl_T1_T0(void)
161 2c0262af bellard
{
162 2c0262af bellard
    int shift;
163 2c0262af bellard
    shift = T0 & 0xff;
164 2c0262af bellard
    if (shift >= 32)
165 2c0262af bellard
        T1 = 0;
166 2c0262af bellard
    else
167 2c0262af bellard
        T1 = (uint32_t)T1 >> shift;
168 2c0262af bellard
    FORCE_RET();
169 2c0262af bellard
}
170 2c0262af bellard
171 2c0262af bellard
void OPPROTO op_sarl_T1_T0(void)
172 2c0262af bellard
{
173 2c0262af bellard
    int shift;
174 2c0262af bellard
    shift = T0 & 0xff;
175 2c0262af bellard
    if (shift >= 32)
176 2c0262af bellard
        shift = 31;
177 2c0262af bellard
    T1 = (int32_t)T1 >> shift;
178 2c0262af bellard
}
179 2c0262af bellard
180 2c0262af bellard
void OPPROTO op_rorl_T1_T0(void)
181 2c0262af bellard
{
182 2c0262af bellard
    int shift;
183 2c0262af bellard
    shift = T0 & 0x1f;
184 2c0262af bellard
    if (shift) {
185 2c0262af bellard
        T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
186 2c0262af bellard
    }
187 2c0262af bellard
    FORCE_RET();
188 2c0262af bellard
}
189 2c0262af bellard
190 2c0262af bellard
/* T1 based, use T0 as shift count and compute CF */
191 2c0262af bellard
192 2c0262af bellard
void OPPROTO op_shll_T1_T0_cc(void)
193 2c0262af bellard
{
194 2c0262af bellard
    int shift;
195 2c0262af bellard
    shift = T0 & 0xff;
196 2c0262af bellard
    if (shift >= 32) {
197 2c0262af bellard
        if (shift == 32)
198 2c0262af bellard
            env->CF = T1 & 1;
199 2c0262af bellard
        else
200 2c0262af bellard
            env->CF = 0;
201 2c0262af bellard
        T1 = 0;
202 2c0262af bellard
    } else if (shift != 0) {
203 2c0262af bellard
        env->CF = (T1 >> (32 - shift)) & 1;
204 2c0262af bellard
        T1 = T1 << shift;
205 2c0262af bellard
    }
206 2c0262af bellard
    FORCE_RET();
207 2c0262af bellard
}
208 2c0262af bellard
209 2c0262af bellard
void OPPROTO op_shrl_T1_T0_cc(void)
210 2c0262af bellard
{
211 2c0262af bellard
    int shift;
212 2c0262af bellard
    shift = T0 & 0xff;
213 2c0262af bellard
    if (shift >= 32) {
214 2c0262af bellard
        if (shift == 32)
215 2c0262af bellard
            env->CF = (T1 >> 31) & 1;
216 2c0262af bellard
        else
217 2c0262af bellard
            env->CF = 0;
218 2c0262af bellard
        T1 = 0;
219 2c0262af bellard
    } else if (shift != 0) {
220 2c0262af bellard
        env->CF = (T1 >> (shift - 1)) & 1;
221 2c0262af bellard
        T1 = (uint32_t)T1 >> shift;
222 2c0262af bellard
    }
223 2c0262af bellard
    FORCE_RET();
224 2c0262af bellard
}
225 2c0262af bellard
226 2c0262af bellard
void OPPROTO op_sarl_T1_T0_cc(void)
227 2c0262af bellard
{
228 2c0262af bellard
    int shift;
229 2c0262af bellard
    shift = T0 & 0xff;
230 2c0262af bellard
    if (shift >= 32) {
231 2c0262af bellard
        env->CF = (T1 >> 31) & 1;
232 2c0262af bellard
        T1 = (int32_t)T1 >> 31;
233 1b1afeb9 balrog
    } else if (shift != 0) {
234 2c0262af bellard
        env->CF = (T1 >> (shift - 1)) & 1;
235 2c0262af bellard
        T1 = (int32_t)T1 >> shift;
236 2c0262af bellard
    }
237 2c0262af bellard
    FORCE_RET();
238 2c0262af bellard
}
239 2c0262af bellard
240 2c0262af bellard
void OPPROTO op_rorl_T1_T0_cc(void)
241 2c0262af bellard
{
242 2c0262af bellard
    int shift1, shift;
243 2c0262af bellard
    shift1 = T0 & 0xff;
244 2c0262af bellard
    shift = shift1 & 0x1f;
245 2c0262af bellard
    if (shift == 0) {
246 2c0262af bellard
        if (shift1 != 0)
247 2c0262af bellard
            env->CF = (T1 >> 31) & 1;
248 2c0262af bellard
    } else {
249 2c0262af bellard
        env->CF = (T1 >> (shift - 1)) & 1;
250 2c0262af bellard
        T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
251 2c0262af bellard
    }
252 2c0262af bellard
    FORCE_RET();
253 2c0262af bellard
}
254 2c0262af bellard
255 c1713132 balrog
void OPPROTO op_movl_cp_T0(void)
256 c1713132 balrog
{
257 c1713132 balrog
    helper_set_cp(env, PARAM1, T0);
258 c1713132 balrog
    FORCE_RET();
259 c1713132 balrog
}
260 c1713132 balrog
261 c1713132 balrog
void OPPROTO op_movl_T0_cp(void)
262 c1713132 balrog
{
263 c1713132 balrog
    T0 = helper_get_cp(env, PARAM1);
264 c1713132 balrog
    FORCE_RET();
265 c1713132 balrog
}
266 c1713132 balrog
267 b5ff1b31 bellard
void OPPROTO op_movl_cp15_T0(void)
268 b7bcbe95 bellard
{
269 b5ff1b31 bellard
    helper_set_cp15(env, PARAM1, T0);
270 b5ff1b31 bellard
    FORCE_RET();
271 b7bcbe95 bellard
}
272 b7bcbe95 bellard
273 b5ff1b31 bellard
void OPPROTO op_movl_T0_cp15(void)
274 b7bcbe95 bellard
{
275 b5ff1b31 bellard
    T0 = helper_get_cp15(env, PARAM1);
276 b5ff1b31 bellard
    FORCE_RET();
277 b7bcbe95 bellard
}
278 b7bcbe95 bellard
279 9ee6e8bb pbrook
void OPPROTO op_v7m_mrs_T0(void)
280 9ee6e8bb pbrook
{
281 9ee6e8bb pbrook
    T0 = helper_v7m_mrs(env, PARAM1);
282 9ee6e8bb pbrook
}
283 9ee6e8bb pbrook
284 9ee6e8bb pbrook
void OPPROTO op_v7m_msr_T0(void)
285 9ee6e8bb pbrook
{
286 9ee6e8bb pbrook
    helper_v7m_msr(env, PARAM1, T0);
287 9ee6e8bb pbrook
}
288 9ee6e8bb pbrook
289 9ee6e8bb pbrook
void OPPROTO op_movl_T0_sp(void)
290 9ee6e8bb pbrook
{
291 9ee6e8bb pbrook
    if (PARAM1 == env->v7m.current_sp)
292 9ee6e8bb pbrook
        T0 = env->regs[13];
293 9ee6e8bb pbrook
    else
294 9ee6e8bb pbrook
        T0 = env->v7m.other_sp;
295 9ee6e8bb pbrook
    FORCE_RET();
296 9ee6e8bb pbrook
}
297 9ee6e8bb pbrook
298 9ee6e8bb pbrook
#include "op_neon.h"
299 9ee6e8bb pbrook
300 18c9b560 balrog
/* iwMMXt support */
301 18c9b560 balrog
#include "op_iwmmxt.c"