root / target-ppc / op_helper_mem.h @ 76a66253
History | View | Annotate | Download (5.7 kB)
1 | 76a66253 | j_mayer | /*
|
---|---|---|---|
2 | 76a66253 | j_mayer | * PowerPC emulation micro-operations helpers for qemu.
|
3 | 76a66253 | j_mayer | *
|
4 | 76a66253 | j_mayer | * Copyright (c) 2003-2007 Jocelyn Mayer
|
5 | 76a66253 | j_mayer | *
|
6 | 76a66253 | j_mayer | * This library is free software; you can redistribute it and/or
|
7 | 76a66253 | j_mayer | * modify it under the terms of the GNU Lesser General Public
|
8 | 76a66253 | j_mayer | * License as published by the Free Software Foundation; either
|
9 | 76a66253 | j_mayer | * version 2 of the License, or (at your option) any later version.
|
10 | 76a66253 | j_mayer | *
|
11 | 76a66253 | j_mayer | * This library is distributed in the hope that it will be useful,
|
12 | 76a66253 | j_mayer | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 76a66253 | j_mayer | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | 76a66253 | j_mayer | * Lesser General Public License for more details.
|
15 | 76a66253 | j_mayer | *
|
16 | 76a66253 | j_mayer | * You should have received a copy of the GNU Lesser General Public
|
17 | 76a66253 | j_mayer | * License along with this library; if not, write to the Free Software
|
18 | 76a66253 | j_mayer | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19 | 76a66253 | j_mayer | */
|
20 | 76a66253 | j_mayer | |
21 | 76a66253 | j_mayer | /* Multiple word / string load and store */
|
22 | 76a66253 | j_mayer | static inline target_ulong glue(ld32r, MEMSUFFIX) (target_ulong EA) |
23 | 76a66253 | j_mayer | { |
24 | 76a66253 | j_mayer | uint32_t tmp = glue(ldl, MEMSUFFIX)(EA); |
25 | 76a66253 | j_mayer | return ((tmp & 0xFF000000UL) >> 24) | ((tmp & 0x00FF0000UL) >> 8) | |
26 | 76a66253 | j_mayer | ((tmp & 0x0000FF00UL) << 8) | ((tmp & 0x000000FFUL) << 24); |
27 | 76a66253 | j_mayer | } |
28 | 76a66253 | j_mayer | |
29 | 76a66253 | j_mayer | static inline void glue(st32r, MEMSUFFIX) (target_ulong EA, target_ulong data) |
30 | 76a66253 | j_mayer | { |
31 | 76a66253 | j_mayer | uint32_t tmp = |
32 | 76a66253 | j_mayer | ((data & 0xFF000000UL) >> 24) | ((data & 0x00FF0000UL) >> 8) | |
33 | 76a66253 | j_mayer | ((data & 0x0000FF00UL) << 8) | ((data & 0x000000FFUL) << 24); |
34 | 76a66253 | j_mayer | glue(stl, MEMSUFFIX)(EA, tmp); |
35 | 76a66253 | j_mayer | } |
36 | 76a66253 | j_mayer | |
37 | 76a66253 | j_mayer | void glue(do_lmw, MEMSUFFIX) (int dst) |
38 | 76a66253 | j_mayer | { |
39 | 76a66253 | j_mayer | for (; dst < 32; dst++, T0 += 4) { |
40 | 76a66253 | j_mayer | ugpr(dst) = glue(ldl, MEMSUFFIX)(T0); |
41 | 76a66253 | j_mayer | } |
42 | 76a66253 | j_mayer | } |
43 | 76a66253 | j_mayer | |
44 | 76a66253 | j_mayer | void glue(do_stmw, MEMSUFFIX) (int src) |
45 | 76a66253 | j_mayer | { |
46 | 76a66253 | j_mayer | for (; src < 32; src++, T0 += 4) { |
47 | 76a66253 | j_mayer | glue(stl, MEMSUFFIX)(T0, ugpr(src)); |
48 | 76a66253 | j_mayer | } |
49 | 76a66253 | j_mayer | } |
50 | 76a66253 | j_mayer | |
51 | 76a66253 | j_mayer | void glue(do_lmw_le, MEMSUFFIX) (int dst) |
52 | 76a66253 | j_mayer | { |
53 | 76a66253 | j_mayer | for (; dst < 32; dst++, T0 += 4) { |
54 | 76a66253 | j_mayer | ugpr(dst) = glue(ld32r, MEMSUFFIX)(T0); |
55 | 76a66253 | j_mayer | } |
56 | 76a66253 | j_mayer | } |
57 | 76a66253 | j_mayer | |
58 | 76a66253 | j_mayer | void glue(do_stmw_le, MEMSUFFIX) (int src) |
59 | 76a66253 | j_mayer | { |
60 | 76a66253 | j_mayer | for (; src < 32; src++, T0 += 4) { |
61 | 76a66253 | j_mayer | glue(st32r, MEMSUFFIX)(T0, ugpr(src)); |
62 | 76a66253 | j_mayer | } |
63 | 76a66253 | j_mayer | } |
64 | 76a66253 | j_mayer | |
65 | 9a64fbe4 | bellard | void glue(do_lsw, MEMSUFFIX) (int dst) |
66 | 9a64fbe4 | bellard | { |
67 | 9a64fbe4 | bellard | uint32_t tmp; |
68 | 9a64fbe4 | bellard | int sh;
|
69 | 9a64fbe4 | bellard | |
70 | 9a64fbe4 | bellard | for (; T1 > 3; T1 -= 4, T0 += 4) { |
71 | 0fa85d43 | bellard | ugpr(dst++) = glue(ldl, MEMSUFFIX)(T0); |
72 | 76a66253 | j_mayer | if (unlikely(dst == 32)) |
73 | 9a64fbe4 | bellard | dst = 0;
|
74 | 9a64fbe4 | bellard | } |
75 | 76a66253 | j_mayer | if (unlikely(T1 != 0)) { |
76 | 9a64fbe4 | bellard | tmp = 0;
|
77 | 9a64fbe4 | bellard | for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) { |
78 | 0fa85d43 | bellard | tmp |= glue(ldub, MEMSUFFIX)(T0) << sh; |
79 | 9a64fbe4 | bellard | } |
80 | 9a64fbe4 | bellard | ugpr(dst) = tmp; |
81 | 9a64fbe4 | bellard | } |
82 | 9a64fbe4 | bellard | } |
83 | 9a64fbe4 | bellard | |
84 | 9a64fbe4 | bellard | void glue(do_stsw, MEMSUFFIX) (int src) |
85 | 9a64fbe4 | bellard | { |
86 | 9a64fbe4 | bellard | int sh;
|
87 | 9a64fbe4 | bellard | |
88 | 9a64fbe4 | bellard | for (; T1 > 3; T1 -= 4, T0 += 4) { |
89 | 0fa85d43 | bellard | glue(stl, MEMSUFFIX)(T0, ugpr(src++)); |
90 | 76a66253 | j_mayer | if (unlikely(src == 32)) |
91 | 9a64fbe4 | bellard | src = 0;
|
92 | 9a64fbe4 | bellard | } |
93 | 76a66253 | j_mayer | if (unlikely(T1 != 0)) { |
94 | 9a64fbe4 | bellard | for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) |
95 | 0fa85d43 | bellard | glue(stb, MEMSUFFIX)(T0, (ugpr(src) >> sh) & 0xFF);
|
96 | 9a64fbe4 | bellard | } |
97 | 9a64fbe4 | bellard | } |
98 | 9a64fbe4 | bellard | |
99 | 111bfab3 | bellard | void glue(do_lsw_le, MEMSUFFIX) (int dst) |
100 | 111bfab3 | bellard | { |
101 | 111bfab3 | bellard | uint32_t tmp; |
102 | 111bfab3 | bellard | int sh;
|
103 | 111bfab3 | bellard | |
104 | 111bfab3 | bellard | for (; T1 > 3; T1 -= 4, T0 += 4) { |
105 | 76a66253 | j_mayer | ugpr(dst++) = glue(ld32r, MEMSUFFIX)(T0); |
106 | 76a66253 | j_mayer | if (unlikely(dst == 32)) |
107 | 111bfab3 | bellard | dst = 0;
|
108 | 111bfab3 | bellard | } |
109 | 76a66253 | j_mayer | if (unlikely(T1 != 0)) { |
110 | 111bfab3 | bellard | tmp = 0;
|
111 | 111bfab3 | bellard | for (sh = 0; T1 > 0; T1--, T0++, sh += 8) { |
112 | 111bfab3 | bellard | tmp |= glue(ldub, MEMSUFFIX)(T0) << sh; |
113 | 111bfab3 | bellard | } |
114 | 111bfab3 | bellard | ugpr(dst) = tmp; |
115 | 111bfab3 | bellard | } |
116 | 111bfab3 | bellard | } |
117 | 111bfab3 | bellard | |
118 | 111bfab3 | bellard | void glue(do_stsw_le, MEMSUFFIX) (int src) |
119 | 111bfab3 | bellard | { |
120 | 111bfab3 | bellard | int sh;
|
121 | 111bfab3 | bellard | |
122 | 111bfab3 | bellard | for (; T1 > 3; T1 -= 4, T0 += 4) { |
123 | 76a66253 | j_mayer | glue(st32r, MEMSUFFIX)(T0, ugpr(src++)); |
124 | 76a66253 | j_mayer | if (unlikely(src == 32)) |
125 | 111bfab3 | bellard | src = 0;
|
126 | 111bfab3 | bellard | } |
127 | 76a66253 | j_mayer | if (unlikely(T1 != 0)) { |
128 | 111bfab3 | bellard | for (sh = 0; T1 > 0; T1--, T0++, sh += 8) |
129 | 111bfab3 | bellard | glue(stb, MEMSUFFIX)(T0, (ugpr(src) >> sh) & 0xFF);
|
130 | 111bfab3 | bellard | } |
131 | 111bfab3 | bellard | } |
132 | 111bfab3 | bellard | |
133 | 76a66253 | j_mayer | /* PPC 601 specific instructions (POWER bridge) */
|
134 | 76a66253 | j_mayer | // XXX: to be tested
|
135 | 76a66253 | j_mayer | void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb) |
136 | 76a66253 | j_mayer | { |
137 | 76a66253 | j_mayer | int i, c, d, reg;
|
138 | 76a66253 | j_mayer | |
139 | 76a66253 | j_mayer | d = 24;
|
140 | 76a66253 | j_mayer | reg = dest; |
141 | 76a66253 | j_mayer | for (i = 0; i < T1; i++) { |
142 | 76a66253 | j_mayer | c = glue(ldub, MEMSUFFIX)(T0++); |
143 | 76a66253 | j_mayer | /* ra (if not 0) and rb are never modified */
|
144 | 76a66253 | j_mayer | if (likely(reg != rb && (ra == 0 || reg != ra))) { |
145 | 76a66253 | j_mayer | ugpr(reg) = (ugpr(reg) & ~(0xFF << d)) | (c << d);
|
146 | 76a66253 | j_mayer | } |
147 | 76a66253 | j_mayer | if (unlikely(c == T2))
|
148 | 76a66253 | j_mayer | break;
|
149 | 76a66253 | j_mayer | if (likely(d != 0)) { |
150 | 76a66253 | j_mayer | d -= 8;
|
151 | 76a66253 | j_mayer | } else {
|
152 | 76a66253 | j_mayer | d = 24;
|
153 | 76a66253 | j_mayer | reg++; |
154 | 76a66253 | j_mayer | reg = reg & 0x1F;
|
155 | 76a66253 | j_mayer | } |
156 | 76a66253 | j_mayer | } |
157 | 76a66253 | j_mayer | T0 = i; |
158 | 76a66253 | j_mayer | } |
159 | 76a66253 | j_mayer | |
160 | 76a66253 | j_mayer | /* XXX: TAGs are not managed */
|
161 | 76a66253 | j_mayer | void glue(do_POWER2_lfq, MEMSUFFIX) (void) |
162 | 76a66253 | j_mayer | { |
163 | 76a66253 | j_mayer | FT0 = glue(ldfq, MEMSUFFIX)(T0); |
164 | 76a66253 | j_mayer | FT1 = glue(ldfq, MEMSUFFIX)(T0 + 4);
|
165 | 76a66253 | j_mayer | } |
166 | 76a66253 | j_mayer | |
167 | 76a66253 | j_mayer | static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA) |
168 | 76a66253 | j_mayer | { |
169 | 76a66253 | j_mayer | union {
|
170 | 76a66253 | j_mayer | double d;
|
171 | 76a66253 | j_mayer | uint64_t u; |
172 | 76a66253 | j_mayer | } u; |
173 | 76a66253 | j_mayer | |
174 | 76a66253 | j_mayer | u.d = glue(ldfq, MEMSUFFIX)(EA); |
175 | 76a66253 | j_mayer | u.u = ((u.u & 0xFF00000000000000ULL) >> 56) | |
176 | 76a66253 | j_mayer | ((u.u & 0x00FF000000000000ULL) >> 40) | |
177 | 76a66253 | j_mayer | ((u.u & 0x0000FF0000000000ULL) >> 24) | |
178 | 76a66253 | j_mayer | ((u.u & 0x000000FF00000000ULL) >> 8) | |
179 | 76a66253 | j_mayer | ((u.u & 0x00000000FF000000ULL) << 8) | |
180 | 76a66253 | j_mayer | ((u.u & 0x0000000000FF0000ULL) << 24) | |
181 | 76a66253 | j_mayer | ((u.u & 0x000000000000FF00ULL) << 40) | |
182 | 76a66253 | j_mayer | ((u.u & 0x00000000000000FFULL) << 56); |
183 | 76a66253 | j_mayer | |
184 | 76a66253 | j_mayer | return u.d;
|
185 | 76a66253 | j_mayer | } |
186 | 76a66253 | j_mayer | |
187 | 76a66253 | j_mayer | void glue(do_POWER2_lfq_le, MEMSUFFIX) (void) |
188 | 76a66253 | j_mayer | { |
189 | 76a66253 | j_mayer | FT0 = glue(ldfqr, MEMSUFFIX)(T0 + 4);
|
190 | 76a66253 | j_mayer | FT1 = glue(ldfqr, MEMSUFFIX)(T0); |
191 | 76a66253 | j_mayer | } |
192 | 76a66253 | j_mayer | |
193 | 76a66253 | j_mayer | void glue(do_POWER2_stfq, MEMSUFFIX) (void) |
194 | 76a66253 | j_mayer | { |
195 | 76a66253 | j_mayer | glue(stfq, MEMSUFFIX)(T0, FT0); |
196 | 76a66253 | j_mayer | glue(stfq, MEMSUFFIX)(T0 + 4, FT1);
|
197 | 76a66253 | j_mayer | } |
198 | 76a66253 | j_mayer | |
199 | 76a66253 | j_mayer | static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d) |
200 | 76a66253 | j_mayer | { |
201 | 76a66253 | j_mayer | union {
|
202 | 76a66253 | j_mayer | double d;
|
203 | 76a66253 | j_mayer | uint64_t u; |
204 | 76a66253 | j_mayer | } u; |
205 | 76a66253 | j_mayer | |
206 | 76a66253 | j_mayer | u.d = d; |
207 | 76a66253 | j_mayer | u.u = ((u.u & 0xFF00000000000000ULL) >> 56) | |
208 | 76a66253 | j_mayer | ((u.u & 0x00FF000000000000ULL) >> 40) | |
209 | 76a66253 | j_mayer | ((u.u & 0x0000FF0000000000ULL) >> 24) | |
210 | 76a66253 | j_mayer | ((u.u & 0x000000FF00000000ULL) >> 8) | |
211 | 76a66253 | j_mayer | ((u.u & 0x00000000FF000000ULL) << 8) | |
212 | 76a66253 | j_mayer | ((u.u & 0x0000000000FF0000ULL) << 24) | |
213 | 76a66253 | j_mayer | ((u.u & 0x000000000000FF00ULL) << 40) | |
214 | 76a66253 | j_mayer | ((u.u & 0x00000000000000FFULL) << 56); |
215 | 76a66253 | j_mayer | glue(stfq, MEMSUFFIX)(EA, u.d); |
216 | 76a66253 | j_mayer | } |
217 | 76a66253 | j_mayer | |
218 | 76a66253 | j_mayer | void glue(do_POWER2_stfq_le, MEMSUFFIX) (void) |
219 | 76a66253 | j_mayer | { |
220 | 76a66253 | j_mayer | glue(stfqr, MEMSUFFIX)(T0 + 4, FT0);
|
221 | 76a66253 | j_mayer | glue(stfqr, MEMSUFFIX)(T0, FT1); |
222 | 76a66253 | j_mayer | } |
223 | 76a66253 | j_mayer | |
224 | 9a64fbe4 | bellard | #undef MEMSUFFIX |