root / target-ppc / op_mem.h @ 9a64fbe4
History | View | Annotate | Download (5.9 kB)
1 | 9a64fbe4 | bellard | /* External helpers */
|
---|---|---|---|
2 | 9a64fbe4 | bellard | void glue(do_lsw, MEMSUFFIX) (int dst); |
3 | 9a64fbe4 | bellard | void glue(do_stsw, MEMSUFFIX) (int src); |
4 | 9a64fbe4 | bellard | |
5 | 9a64fbe4 | bellard | /* Internal helpers for sign extension and byte-reverse */
|
6 | 9a64fbe4 | bellard | static inline uint32_t glue(_ld16x, MEMSUFFIX) (void *EA, int type) |
7 | 9a64fbe4 | bellard | { |
8 | 9a64fbe4 | bellard | return s_ext16(glue(_lduw, MEMSUFFIX)(EA, type));
|
9 | 9a64fbe4 | bellard | } |
10 | 9a64fbe4 | bellard | |
11 | 9a64fbe4 | bellard | static inline uint16_t glue(_ld16r, MEMSUFFIX) (void *EA, int type) |
12 | 9a64fbe4 | bellard | { |
13 | 9a64fbe4 | bellard | uint16_t tmp = glue(_lduw, MEMSUFFIX)(EA, type); |
14 | 9a64fbe4 | bellard | return ((tmp & 0xFF00) >> 8) | ((tmp & 0x00FF) << 8); |
15 | 9a64fbe4 | bellard | } |
16 | 9a64fbe4 | bellard | |
17 | 9a64fbe4 | bellard | static inline uint32_t glue(_ld32r, MEMSUFFIX) (void *EA, int type) |
18 | 9a64fbe4 | bellard | { |
19 | 9a64fbe4 | bellard | uint32_t tmp = glue(_ldl, MEMSUFFIX)(EA, type); |
20 | 9a64fbe4 | bellard | return ((tmp & 0xFF000000) >> 24) | ((tmp & 0x00FF0000) >> 8) | |
21 | 9a64fbe4 | bellard | ((tmp & 0x0000FF00) << 8) | ((tmp & 0x000000FF) << 24); |
22 | 9a64fbe4 | bellard | } |
23 | 9a64fbe4 | bellard | |
24 | 9a64fbe4 | bellard | static inline void glue(_st16r, MEMSUFFIX) (void *EA, uint16_t data, int type) |
25 | 9a64fbe4 | bellard | { |
26 | 9a64fbe4 | bellard | uint16_t tmp = ((data & 0xFF00) >> 8) | ((data & 0x00FF) << 8); |
27 | 9a64fbe4 | bellard | glue(_stw, MEMSUFFIX)(EA, tmp, type); |
28 | 9a64fbe4 | bellard | } |
29 | 9a64fbe4 | bellard | |
30 | 9a64fbe4 | bellard | static inline void glue(_st32r, MEMSUFFIX) (void *EA, uint32_t data, int type) |
31 | 9a64fbe4 | bellard | { |
32 | 9a64fbe4 | bellard | uint32_t tmp = ((data & 0xFF000000) >> 24) | ((data & 0x00FF0000) >> 8) | |
33 | 9a64fbe4 | bellard | ((data & 0x0000FF00) << 8) | ((data & 0x000000FF) << 24); |
34 | 9a64fbe4 | bellard | glue(_stl, MEMSUFFIX)(EA, tmp, type); |
35 | 9a64fbe4 | bellard | } |
36 | 9a64fbe4 | bellard | |
37 | 9a64fbe4 | bellard | /*** Integer load ***/
|
38 | 9a64fbe4 | bellard | #define PPC_LD_OP(name, op) \
|
39 | 9a64fbe4 | bellard | PPC_OP(glue(glue(l, name), MEMSUFFIX)) \ |
40 | 9a64fbe4 | bellard | { \ |
41 | 9a64fbe4 | bellard | T1 = glue(op, MEMSUFFIX)((void *)T0, ACCESS_INT); \
|
42 | 9a64fbe4 | bellard | RETURN(); \ |
43 | 9a64fbe4 | bellard | } |
44 | 9a64fbe4 | bellard | |
45 | 9a64fbe4 | bellard | #define PPC_ST_OP(name, op) \
|
46 | 9a64fbe4 | bellard | PPC_OP(glue(glue(st, name), MEMSUFFIX)) \ |
47 | 9a64fbe4 | bellard | { \ |
48 | 9a64fbe4 | bellard | glue(op, MEMSUFFIX)((void *)T0, T1, ACCESS_INT); \
|
49 | 9a64fbe4 | bellard | RETURN(); \ |
50 | 9a64fbe4 | bellard | } |
51 | 9a64fbe4 | bellard | |
52 | 9a64fbe4 | bellard | PPC_LD_OP(bz, _ldub); |
53 | 9a64fbe4 | bellard | PPC_LD_OP(ha, _ld16x); |
54 | 9a64fbe4 | bellard | PPC_LD_OP(hz, _lduw); |
55 | 9a64fbe4 | bellard | PPC_LD_OP(wz, _ldl); |
56 | 9a64fbe4 | bellard | |
57 | 9a64fbe4 | bellard | /*** Integer store ***/
|
58 | 9a64fbe4 | bellard | PPC_ST_OP(b, _stb); |
59 | 9a64fbe4 | bellard | PPC_ST_OP(h, _stw); |
60 | 9a64fbe4 | bellard | PPC_ST_OP(w, _stl); |
61 | 9a64fbe4 | bellard | |
62 | 9a64fbe4 | bellard | /*** Integer load and store with byte reverse ***/
|
63 | 9a64fbe4 | bellard | PPC_LD_OP(hbr, _ld16r); |
64 | 9a64fbe4 | bellard | PPC_LD_OP(wbr, _ld32r); |
65 | 9a64fbe4 | bellard | PPC_ST_OP(hbr, _st16r); |
66 | 9a64fbe4 | bellard | PPC_ST_OP(wbr, _st32r); |
67 | 9a64fbe4 | bellard | |
68 | 9a64fbe4 | bellard | /*** Integer load and store multiple ***/
|
69 | 9a64fbe4 | bellard | PPC_OP(glue(lmw, MEMSUFFIX)) |
70 | 9a64fbe4 | bellard | { |
71 | 9a64fbe4 | bellard | int dst = PARAM(1); |
72 | 9a64fbe4 | bellard | |
73 | 9a64fbe4 | bellard | for (; dst < 32; dst++, T0 += 4) { |
74 | 9a64fbe4 | bellard | ugpr(dst) = glue(_ldl, MEMSUFFIX)((void *)T0, ACCESS_INT);
|
75 | 9a64fbe4 | bellard | } |
76 | 9a64fbe4 | bellard | RETURN(); |
77 | 9a64fbe4 | bellard | } |
78 | 9a64fbe4 | bellard | |
79 | 9a64fbe4 | bellard | PPC_OP(glue(stmw, MEMSUFFIX)) |
80 | 9a64fbe4 | bellard | { |
81 | 9a64fbe4 | bellard | int src = PARAM(1); |
82 | 9a64fbe4 | bellard | |
83 | 9a64fbe4 | bellard | for (; src < 32; src++, T0 += 4) { |
84 | 9a64fbe4 | bellard | glue(_stl, MEMSUFFIX)((void *)T0, ugpr(src), ACCESS_INT);
|
85 | 9a64fbe4 | bellard | } |
86 | 9a64fbe4 | bellard | RETURN(); |
87 | 9a64fbe4 | bellard | } |
88 | 9a64fbe4 | bellard | |
89 | 9a64fbe4 | bellard | /*** Integer load and store strings ***/
|
90 | 9a64fbe4 | bellard | PPC_OP(glue(lswi, MEMSUFFIX)) |
91 | 9a64fbe4 | bellard | { |
92 | 9a64fbe4 | bellard | glue(do_lsw, MEMSUFFIX)(PARAM(1));
|
93 | 9a64fbe4 | bellard | RETURN(); |
94 | 9a64fbe4 | bellard | } |
95 | 9a64fbe4 | bellard | |
96 | 9a64fbe4 | bellard | /* PPC32 specification says we must generate an exception if
|
97 | 9a64fbe4 | bellard | * rA is in the range of registers to be loaded.
|
98 | 9a64fbe4 | bellard | * In an other hand, IBM says this is valid, but rA won't be loaded.
|
99 | 9a64fbe4 | bellard | * For now, I'll follow the spec...
|
100 | 9a64fbe4 | bellard | */
|
101 | 9a64fbe4 | bellard | PPC_OP(glue(lswx, MEMSUFFIX)) |
102 | 9a64fbe4 | bellard | { |
103 | 9a64fbe4 | bellard | if (T1 > 0) { |
104 | 9a64fbe4 | bellard | if ((PARAM(1) < PARAM(2) && (PARAM(1) + T1) > PARAM(2)) || |
105 | 9a64fbe4 | bellard | (PARAM(1) < PARAM(3) && (PARAM(1) + T1) > PARAM(3))) { |
106 | 9a64fbe4 | bellard | do_queue_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX); |
107 | 9a64fbe4 | bellard | do_process_exceptions(); |
108 | 9a64fbe4 | bellard | } else {
|
109 | 9a64fbe4 | bellard | glue(do_lsw, MEMSUFFIX)(PARAM(1));
|
110 | 9a64fbe4 | bellard | } |
111 | 9a64fbe4 | bellard | } |
112 | 9a64fbe4 | bellard | RETURN(); |
113 | 9a64fbe4 | bellard | } |
114 | 9a64fbe4 | bellard | |
115 | 9a64fbe4 | bellard | PPC_OP(glue(stsw, MEMSUFFIX)) |
116 | 9a64fbe4 | bellard | { |
117 | 9a64fbe4 | bellard | glue(do_stsw, MEMSUFFIX)(PARAM(1));
|
118 | 9a64fbe4 | bellard | RETURN(); |
119 | 9a64fbe4 | bellard | } |
120 | 9a64fbe4 | bellard | |
121 | 9a64fbe4 | bellard | /*** Floating-point store ***/
|
122 | 9a64fbe4 | bellard | #define PPC_STF_OP(name, op) \
|
123 | 9a64fbe4 | bellard | PPC_OP(glue(glue(st, name), MEMSUFFIX)) \ |
124 | 9a64fbe4 | bellard | { \ |
125 | 9a64fbe4 | bellard | glue(op, MEMSUFFIX)((void *)T0, FT1); \
|
126 | 9a64fbe4 | bellard | RETURN(); \ |
127 | 9a64fbe4 | bellard | } |
128 | 9a64fbe4 | bellard | |
129 | 9a64fbe4 | bellard | PPC_STF_OP(fd, stfq); |
130 | 9a64fbe4 | bellard | PPC_STF_OP(fs, stfl); |
131 | 9a64fbe4 | bellard | |
132 | 9a64fbe4 | bellard | /*** Floating-point load ***/
|
133 | 9a64fbe4 | bellard | #define PPC_LDF_OP(name, op) \
|
134 | 9a64fbe4 | bellard | PPC_OP(glue(glue(l, name), MEMSUFFIX)) \ |
135 | 9a64fbe4 | bellard | { \ |
136 | 9a64fbe4 | bellard | FT1 = glue(op, MEMSUFFIX)((void *)T0); \
|
137 | 9a64fbe4 | bellard | RETURN(); \ |
138 | 9a64fbe4 | bellard | } |
139 | 9a64fbe4 | bellard | |
140 | 9a64fbe4 | bellard | PPC_LDF_OP(fd, ldfq); |
141 | 9a64fbe4 | bellard | PPC_LDF_OP(fs, ldfl); |
142 | 9a64fbe4 | bellard | |
143 | 9a64fbe4 | bellard | /* Store with reservation */
|
144 | 9a64fbe4 | bellard | PPC_OP(glue(stwcx, MEMSUFFIX)) |
145 | 9a64fbe4 | bellard | { |
146 | 9a64fbe4 | bellard | if (T0 & 0x03) { |
147 | 9a64fbe4 | bellard | do_queue_exception(EXCP_ALIGN); |
148 | 9a64fbe4 | bellard | do_process_exceptions(); |
149 | 9a64fbe4 | bellard | } else {
|
150 | 9a64fbe4 | bellard | if (regs->reserve != T0) {
|
151 | 9a64fbe4 | bellard | env->crf[0] = xer_ov;
|
152 | 9a64fbe4 | bellard | } else {
|
153 | 9a64fbe4 | bellard | glue(_stl, MEMSUFFIX)((void *)T0, T1, ACCESS_RES);
|
154 | 9a64fbe4 | bellard | env->crf[0] = xer_ov | 0x02; |
155 | 9a64fbe4 | bellard | } |
156 | 9a64fbe4 | bellard | } |
157 | 9a64fbe4 | bellard | regs->reserve = 0;
|
158 | 9a64fbe4 | bellard | RETURN(); |
159 | 9a64fbe4 | bellard | } |
160 | 9a64fbe4 | bellard | |
161 | 9a64fbe4 | bellard | PPC_OP(glue(dcbz, MEMSUFFIX)) |
162 | 9a64fbe4 | bellard | { |
163 | 9a64fbe4 | bellard | glue(_stl, MEMSUFFIX)((void *)(T0 + 0x00), 0, ACCESS_INT); |
164 | 9a64fbe4 | bellard | glue(_stl, MEMSUFFIX)((void *)(T0 + 0x04), 0, ACCESS_INT); |
165 | 9a64fbe4 | bellard | glue(_stl, MEMSUFFIX)((void *)(T0 + 0x08), 0, ACCESS_INT); |
166 | 9a64fbe4 | bellard | glue(_stl, MEMSUFFIX)((void *)(T0 + 0x0C), 0, ACCESS_INT); |
167 | 9a64fbe4 | bellard | glue(_stl, MEMSUFFIX)((void *)(T0 + 0x10), 0, ACCESS_INT); |
168 | 9a64fbe4 | bellard | glue(_stl, MEMSUFFIX)((void *)(T0 + 0x14), 0, ACCESS_INT); |
169 | 9a64fbe4 | bellard | glue(_stl, MEMSUFFIX)((void *)(T0 + 0x18), 0, ACCESS_INT); |
170 | 9a64fbe4 | bellard | glue(_stl, MEMSUFFIX)((void *)(T0 + 0x1C), 0, ACCESS_INT); |
171 | 9a64fbe4 | bellard | RETURN(); |
172 | 9a64fbe4 | bellard | } |
173 | 9a64fbe4 | bellard | |
174 | 9a64fbe4 | bellard | /* External access */
|
175 | 9a64fbe4 | bellard | PPC_OP(glue(eciwx, MEMSUFFIX)) |
176 | 9a64fbe4 | bellard | { |
177 | 9a64fbe4 | bellard | T1 = glue(_ldl, MEMSUFFIX)((void *)T0, ACCESS_EXT);
|
178 | 9a64fbe4 | bellard | RETURN(); |
179 | 9a64fbe4 | bellard | } |
180 | 9a64fbe4 | bellard | |
181 | 9a64fbe4 | bellard | PPC_OP(glue(ecowx, MEMSUFFIX)) |
182 | 9a64fbe4 | bellard | { |
183 | 9a64fbe4 | bellard | glue(_stl, MEMSUFFIX)((void *)T0, T1, ACCESS_EXT);
|
184 | 9a64fbe4 | bellard | RETURN(); |
185 | 9a64fbe4 | bellard | } |
186 | 9a64fbe4 | bellard | |
187 | 9a64fbe4 | bellard | #undef MEMSUFFIX |