cpu_ppc_instr_loadstore.cc Source File
Back to the index.
src
cpus
cpu_ppc_instr_loadstore.cc
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2005-2009 Anders Gavare. All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
6
*
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
12
* 3. The name of the author may not be used to endorse or promote products
13
* derived from this software without specific prior written permission.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
* SUCH DAMAGE.
26
*
27
*
28
* POWER/PowerPC load/store instructions.
29
*
30
*
31
* Load/store instructions have the following arguments:
32
*
33
* arg[0] = pointer to the register to load to or store from
34
* arg[1] = pointer to the base register
35
*
36
* arg[2] = offset (as an int32_t)
37
* (or, for Indexed load/stores: pointer to index register)
38
*/
39
40
41
#ifndef LS_IGNOREOFS
42
void
LS_GENERIC_N
(
struct
cpu
*
cpu
,
struct
ppc_instr_call *
ic
)
43
{
44
#ifdef MODE32
45
uint32_t
addr
=
46
#else
47
uint64_t
addr
=
48
#endif
49
reg
(
ic
->arg[1]) +
50
#ifdef LS_INDEXED
51
reg
(
ic
->arg[2]);
52
#else
53
(int32_t)
ic
->arg[2];
54
#endif
55
unsigned
char
data
[
LS_SIZE
];
56
57
/* Synchronize the PC: */
58
int
low_pc = ((
size_t
)
ic
- (size_t)
cpu
->
cd
.
ppc
.cur_ic_page)
59
/
sizeof
(
struct
ppc_instr_call);
60
cpu
->
pc
&= ~((
PPC_IC_ENTRIES_PER_PAGE
-1) <<
PPC_INSTR_ALIGNMENT_SHIFT
);
61
cpu
->
pc
+= (low_pc <<
PPC_INSTR_ALIGNMENT_SHIFT
);
62
63
#ifndef LS_B
64
if
((
addr
& 0xfff) +
LS_SIZE
-1 > 0xfff) {
65
fatal
(
"PPC LOAD/STORE misalignment across page boundary: TODO"
66
" (addr=0x%08x, LS_SIZE=%i)\n"
, (
int
)
addr
,
LS_SIZE
);
67
exit(1);
68
}
69
#endif
70
71
#ifdef LS_LOAD
72
if
(!
cpu
->
memory_rw
(
cpu
,
cpu
->
mem
,
addr
,
data
,
sizeof
(
data
),
73
MEM_READ
,
CACHE_DATA
)) {
74
/* Exception. */
75
return
;
76
}
77
#ifdef LS_B
78
reg
(
ic
->arg[0]) =
79
#ifndef LS_ZERO
80
(int8_t)
81
#endif
82
data
[0];
83
#endif
84
#ifdef LS_H
85
reg
(
ic
->arg[0]) =
86
#ifdef LS_BYTEREVERSE
87
((
data
[1] << 8) +
data
[0]);
88
#else
89
#ifndef LS_ZERO
90
(int16_t)
91
#endif
92
((
data
[0] << 8) +
data
[1]);
93
#endif
/* !BYTEREVERSE */
94
#endif
95
#ifdef LS_W
96
reg
(
ic
->arg[0]) =
97
#ifdef LS_BYTEREVERSE
98
((
data
[3] << 24) + (
data
[2] << 16) +
99
(
data
[1] << 8) +
data
[0]);
100
#else
/* !LS_BYTEREVERSE */
101
#ifndef LS_ZERO
102
(int32_t)
103
#
else
104
(uint32_t)
105
#endif
106
((
data
[0] << 24) + (
data
[1] << 16) +
107
(
data
[2] << 8) +
data
[3]);
108
#endif
/* !LS_BYTEREVERSE */
109
#endif
110
#ifdef LS_D
111
(*(uint64_t *)(
ic
->arg[0])) =
112
((uint64_t)
data
[0] << 56) + ((uint64_t)
data
[1] << 48) +
113
((uint64_t)
data
[2] << 40) + ((uint64_t)
data
[3] << 32) +
114
((uint64_t)
data
[4] << 24) + (
data
[5] << 16) +
115
(
data
[6] << 8) +
data
[7];
116
#endif
117
118
#else
/* store: */
119
120
#ifdef LS_B
121
data
[0] =
reg
(
ic
->arg[0]);
122
#endif
123
#ifdef LS_H
124
#ifdef LS_BYTEREVERSE
125
data
[0] =
reg
(
ic
->arg[0]);
126
data
[1] =
reg
(
ic
->arg[0]) >> 8;
127
#else
128
data
[0] =
reg
(
ic
->arg[0]) >> 8;
129
data
[1] =
reg
(
ic
->arg[0]);
130
#endif
131
#endif
132
#ifdef LS_W
133
#ifdef LS_BYTEREVERSE
134
data
[0] =
reg
(
ic
->arg[0]);
135
data
[1] =
reg
(
ic
->arg[0]) >> 8;
136
data
[2] =
reg
(
ic
->arg[0]) >> 16;
137
data
[3] =
reg
(
ic
->arg[0]) >> 24;
138
#else
139
data
[0] =
reg
(
ic
->arg[0]) >> 24;
140
data
[1] =
reg
(
ic
->arg[0]) >> 16;
141
data
[2] =
reg
(
ic
->arg[0]) >> 8;
142
data
[3] =
reg
(
ic
->arg[0]);
143
#endif
/* !LS_BYTEREVERSE */
144
#endif
145
#ifdef LS_D
146
{ uint64_t x = *(uint64_t *)(
ic
->arg[0]);
147
data
[0] = x >> 56;
148
data
[1] = x >> 48;
149
data
[2] = x >> 40;
150
data
[3] = x >> 32;
151
data
[4] = x >> 24;
152
data
[5] = x >> 16;
153
data
[6] = x >> 8;
154
data
[7] = x; }
155
#endif
156
if
(!
cpu
->
memory_rw
(
cpu
,
cpu
->
mem
,
addr
,
data
,
sizeof
(
data
),
157
MEM_WRITE
,
CACHE_DATA
)) {
158
/* Exception. */
159
return
;
160
}
161
#endif
162
163
#ifdef LS_UPDATE
164
reg
(
ic
->arg[1]) =
addr
;
165
#endif
166
}
167
#endif
168
169
170
void
LS_N
(
struct
cpu
*
cpu
,
struct
ppc_instr_call *
ic
)
171
{
172
#ifndef MODE32
173
/************************************************************/
174
/* For now, 64-bit access is done using the slow fallback. */
175
if
(!
cpu
->
is_32bit
) {
176
LS_GENERIC_N
(
cpu
,
ic
);
177
return
;
178
}
179
#endif
180
181
182
#ifdef MODE32
183
uint32_t
addr
=
184
#else
185
uint64_t
addr
=
186
#endif
187
reg
(
ic
->arg[1])
188
#ifdef LS_INDEXED
189
+
reg
(
ic
->arg[2])
190
#else
191
#ifndef LS_IGNOREOFS
192
+ (int32_t)
ic
->arg[2]
193
#endif
194
#endif
195
;
196
197
unsigned
char
*
page
=
cpu
->
cd
.
ppc
.
198
#ifdef
LS_LOAD
199
host_load
200
#
else
201
host_store
202
#endif
203
[
addr
>> 12];
204
#ifdef
LS_UPDATE
205
uint32_t new_addr =
addr
;
206
#endif
207
208
#ifndef
LS_B
209
if
(
addr
& (
LS_SIZE
-1)) {
210
LS_GENERIC_N
(
cpu
,
ic
);
211
return
;
212
}
213
#endif
214
215
if
(
page
== NULL) {
216
LS_GENERIC_N
(
cpu
,
ic
);
217
return
;
218
}
else
{
219
addr
&= 4095;
220
#ifdef LS_LOAD
221
/* Load: */
222
#ifdef LS_B
223
reg
(
ic
->arg[0]) =
224
#ifndef LS_ZERO
225
(int8_t)
226
#endif
227
page
[
addr
];
228
#endif
/* LS_B */
229
#ifdef LS_H
230
reg
(
ic
->arg[0]) =
231
#ifdef LS_BYTEREVERSE
232
((
page
[
addr
+1] << 8) +
page
[
addr
]);
233
#else
234
#ifndef LS_ZERO
235
(int16_t)
236
#endif
237
((
page
[
addr
] << 8) +
page
[
addr
+1]);
238
#endif
/* !BYTEREVERSE */
239
#endif
/* LS_H */
240
#ifdef LS_W
241
reg
(
ic
->arg[0]) =
242
#ifdef LS_BYTEREVERSE
243
((
page
[
addr
+3] << 24) + (
page
[
addr
+2] << 16) +
244
(
page
[
addr
+1] << 8) +
page
[
addr
]);
245
#else
/* !LS_BYTEREVERSE */
246
#ifndef LS_ZERO
247
(int32_t)
248
#
else
249
(uint32_t)
250
#endif
251
((
page
[
addr
] << 24) + (
page
[
addr
+1] << 16) +
252
(
page
[
addr
+2] << 8) +
page
[
addr
+3]);
253
#endif
/* !LS_BYTEREVERSE */
254
#endif
/* LS_W */
255
#ifdef LS_D
256
(*(uint64_t *)(
ic
->arg[0])) =
257
((uint64_t)
page
[
addr
+0] << 56) +
258
((uint64_t)
page
[
addr
+1] << 48) +
259
((uint64_t)
page
[
addr
+2] << 40) +
260
((uint64_t)
page
[
addr
+3] << 32) +
261
((uint64_t)
page
[
addr
+4] << 24) + (
page
[
addr
+5] << 16) +
262
(
page
[
addr
+6] << 8) +
page
[
addr
+7];
263
#endif
/* LS_D */
264
265
#else
/* !LS_LOAD */
266
267
/* Store: */
268
#ifdef LS_B
269
page
[
addr
] =
reg
(
ic
->arg[0]);
270
#endif
271
#ifdef LS_H
272
#ifdef LS_BYTEREVERSE
273
page
[
addr
] =
reg
(
ic
->arg[0]);
274
page
[
addr
+1] =
reg
(
ic
->arg[0]) >> 8;
275
#else
276
page
[
addr
] =
reg
(
ic
->arg[0]) >> 8;
277
page
[
addr
+1] =
reg
(
ic
->arg[0]);
278
#endif
/* !BYTEREVERSE */
279
#endif
280
#ifdef LS_W
281
#ifdef LS_BYTEREVERSE
282
page
[
addr
] =
reg
(
ic
->arg[0]);
283
page
[
addr
+1] =
reg
(
ic
->arg[0]) >> 8;
284
page
[
addr
+2] =
reg
(
ic
->arg[0]) >> 16;
285
page
[
addr
+3] =
reg
(
ic
->arg[0]) >> 24;
286
#else
287
page
[
addr
] =
reg
(
ic
->arg[0]) >> 24;
288
page
[
addr
+1] =
reg
(
ic
->arg[0]) >> 16;
289
page
[
addr
+2] =
reg
(
ic
->arg[0]) >> 8;
290
page
[
addr
+3] =
reg
(
ic
->arg[0]);
291
#endif
/* !LS_BYTEREVERSE */
292
#endif
293
#ifdef LS_D
294
{ uint64_t x = *(uint64_t *)(
ic
->arg[0]);
295
page
[
addr
] = x >> 56;
296
page
[
addr
+1] = x >> 48;
297
page
[
addr
+2] = x >> 40;
298
page
[
addr
+3] = x >> 32;
299
page
[
addr
+4] = x >> 24;
300
page
[
addr
+5] = x >> 16;
301
page
[
addr
+6] = x >> 8;
302
page
[
addr
+7] = x; }
303
#endif
304
#endif
/* !LS_LOAD */
305
}
306
307
#ifdef LS_UPDATE
308
reg
(
ic
->arg[1]) = new_addr;
309
#endif
310
}
311
data
u_short data
Definition:
siireg.h:79
LS_N
void LS_N(struct cpu *cpu, struct ppc_instr_call *ic)
Definition:
cpu_ppc_instr_loadstore.cc:170
if
addr & if(addr >=0x24 &&page !=NULL)
Definition:
tmp_arm_multi.cc:56
MEM_READ
#define MEM_READ
Definition:
memory.h:116
addr
uint32_t addr
Definition:
tmp_arm_multi.cc:52
MEM_WRITE
#define MEM_WRITE
Definition:
memory.h:117
LS_GENERIC_N
void LS_GENERIC_N(struct cpu *cpu, struct ppc_instr_call *ic)
Definition:
cpu_ppc_instr_loadstore.cc:42
LS_LOAD
#define LS_LOAD
Definition:
tmp_alpha_misc.cc:1154
fatal
void fatal(const char *fmt,...)
Definition:
main.cc:152
cpu::cd
union cpu::@1 cd
page
page
Definition:
tmp_arm_multi.cc:54
ic
struct arm_instr_call * ic
Definition:
tmp_arm_multi.cc:50
LS_UPDATE
#define LS_UPDATE
Definition:
tmp_ppc_loadstore.cc:879
CACHE_DATA
#define CACHE_DATA
Definition:
memory.h:121
cpu::is_32bit
uint8_t is_32bit
Definition:
cpu.h:350
LS_B
#define LS_B
Definition:
tmp_alpha_misc.cc:1016
cpu::ppc
struct ppc_cpu ppc
Definition:
cpu.h:444
cpu::mem
struct memory * mem
Definition:
cpu.h:362
reg
#define reg(x)
Definition:
tmp_alpha_tail.cc:53
PPC_IC_ENTRIES_PER_PAGE
#define PPC_IC_ENTRIES_PER_PAGE
Definition:
cpu_ppc.h:95
LS_SIZE
#define LS_SIZE
Definition:
tmp_m88k_loadstore.cc:1754
cpu
Definition:
cpu.h:326
PPC_INSTR_ALIGNMENT_SHIFT
#define PPC_INSTR_ALIGNMENT_SHIFT
Definition:
cpu_ppc.h:93
cpu::memory_rw
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
Definition:
cpu.h:365
cpu::pc
uint64_t pc
Definition:
cpu.h:383
Generated on Tue Mar 24 2020 14:04:48 for GXemul by
1.8.17