2 void glue(do_lsw, MEMSUFFIX) (int dst);
3 void glue(do_stsw, MEMSUFFIX) (int src);
5 /* Internal helpers for sign extension and byte-reverse */
6 static inline uint32_t glue(_ld16x, MEMSUFFIX) (void *EA, int type)
8 return s_ext16(glue(_lduw, MEMSUFFIX)(EA, type));
11 static inline uint16_t glue(_ld16r, MEMSUFFIX) (void *EA, int type)
13 uint16_t tmp = glue(_lduw, MEMSUFFIX)(EA, type);
14 return ((tmp & 0xFF00) >> 8) | ((tmp & 0x00FF) << 8);
17 static inline uint32_t glue(_ld32r, MEMSUFFIX) (void *EA, int type)
19 uint32_t tmp = glue(_ldl, MEMSUFFIX)(EA, type);
20 return ((tmp & 0xFF000000) >> 24) | ((tmp & 0x00FF0000) >> 8) |
21 ((tmp & 0x0000FF00) << 8) | ((tmp & 0x000000FF) << 24);
24 static inline void glue(_st16r, MEMSUFFIX) (void *EA, uint16_t data, int type)
26 uint16_t tmp = ((data & 0xFF00) >> 8) | ((data & 0x00FF) << 8);
27 glue(_stw, MEMSUFFIX)(EA, tmp, type);
30 static inline void glue(_st32r, MEMSUFFIX) (void *EA, uint32_t data, int type)
32 uint32_t tmp = ((data & 0xFF000000) >> 24) | ((data & 0x00FF0000) >> 8) |
33 ((data & 0x0000FF00) << 8) | ((data & 0x000000FF) << 24);
34 glue(_stl, MEMSUFFIX)(EA, tmp, type);
37 /*** Integer load ***/
38 #define PPC_LD_OP(name, op) \
39 PPC_OP(glue(glue(l, name), MEMSUFFIX)) \
41 T1 = glue(op, MEMSUFFIX)((void *)T0, ACCESS_INT); \
45 #define PPC_ST_OP(name, op) \
46 PPC_OP(glue(glue(st, name), MEMSUFFIX)) \
48 glue(op, MEMSUFFIX)((void *)T0, T1, ACCESS_INT); \
53 PPC_LD_OP(ha, _ld16x);
57 /*** Integer store ***/
62 /*** Integer load and store with byte reverse ***/
63 PPC_LD_OP(hbr, _ld16r);
64 PPC_LD_OP(wbr, _ld32r);
65 PPC_ST_OP(hbr, _st16r);
66 PPC_ST_OP(wbr, _st32r);
68 /*** Integer load and store multiple ***/
69 PPC_OP(glue(lmw, MEMSUFFIX))
73 for (; dst < 32; dst++, T0 += 4) {
74 ugpr(dst) = glue(_ldl, MEMSUFFIX)((void *)T0, ACCESS_INT);
79 PPC_OP(glue(stmw, MEMSUFFIX))
83 for (; src < 32; src++, T0 += 4) {
84 glue(_stl, MEMSUFFIX)((void *)T0, ugpr(src), ACCESS_INT);
89 /*** Integer load and store strings ***/
90 PPC_OP(glue(lswi, MEMSUFFIX))
92 glue(do_lsw, MEMSUFFIX)(PARAM(1));
96 /* PPC32 specification says we must generate an exception if
97 * rA is in the range of registers to be loaded.
98 * In an other hand, IBM says this is valid, but rA won't be loaded.
99 * For now, I'll follow the spec...
101 PPC_OP(glue(lswx, MEMSUFFIX))
104 if ((PARAM(1) < PARAM(2) && (PARAM(1) + T1) > PARAM(2)) ||
105 (PARAM(1) < PARAM(3) && (PARAM(1) + T1) > PARAM(3))) {
106 do_queue_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
107 do_process_exceptions();
109 glue(do_lsw, MEMSUFFIX)(PARAM(1));
115 PPC_OP(glue(stsw, MEMSUFFIX))
117 glue(do_stsw, MEMSUFFIX)(PARAM(1));
121 /*** Floating-point store ***/
122 #define PPC_STF_OP(name, op) \
123 PPC_OP(glue(glue(st, name), MEMSUFFIX)) \
125 glue(op, MEMSUFFIX)((void *)T0, FT1); \
129 PPC_STF_OP(fd, stfq);
130 PPC_STF_OP(fs, stfl);
132 /*** Floating-point load ***/
133 #define PPC_LDF_OP(name, op) \
134 PPC_OP(glue(glue(l, name), MEMSUFFIX)) \
136 FT1 = glue(op, MEMSUFFIX)((void *)T0); \
140 PPC_LDF_OP(fd, ldfq);
141 PPC_LDF_OP(fs, ldfl);
143 /* Store with reservation */
144 PPC_OP(glue(stwcx, MEMSUFFIX))
147 do_queue_exception(EXCP_ALIGN);
148 do_process_exceptions();
150 if (regs->reserve != T0) {
151 env->crf[0] = xer_ov;
153 glue(_stl, MEMSUFFIX)((void *)T0, T1, ACCESS_RES);
154 env->crf[0] = xer_ov | 0x02;
161 PPC_OP(glue(dcbz, MEMSUFFIX))
163 glue(_stl, MEMSUFFIX)((void *)(T0 + 0x00), 0, ACCESS_INT);
164 glue(_stl, MEMSUFFIX)((void *)(T0 + 0x04), 0, ACCESS_INT);
165 glue(_stl, MEMSUFFIX)((void *)(T0 + 0x08), 0, ACCESS_INT);
166 glue(_stl, MEMSUFFIX)((void *)(T0 + 0x0C), 0, ACCESS_INT);
167 glue(_stl, MEMSUFFIX)((void *)(T0 + 0x10), 0, ACCESS_INT);
168 glue(_stl, MEMSUFFIX)((void *)(T0 + 0x14), 0, ACCESS_INT);
169 glue(_stl, MEMSUFFIX)((void *)(T0 + 0x18), 0, ACCESS_INT);
170 glue(_stl, MEMSUFFIX)((void *)(T0 + 0x1C), 0, ACCESS_INT);
174 /* External access */
175 PPC_OP(glue(eciwx, MEMSUFFIX))
177 T1 = glue(_ldl, MEMSUFFIX)((void *)T0, ACCESS_EXT);
181 PPC_OP(glue(ecowx, MEMSUFFIX))
183 glue(_stl, MEMSUFFIX)((void *)T0, T1, ACCESS_EXT);