Commit cbfb6ae9b352c47810ca887011f6a64eaad44ff9
1 parent
bcd2ee23
Add {l,st}ve{b,h,w}x instructions.
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6188 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
90 additions
and
0 deletions
target-ppc/helper.h
| ... | ... | @@ -185,6 +185,12 @@ DEF_HELPER_4(vmsumuhs, void, avr, avr, avr, avr) |
| 185 | 185 | DEF_HELPER_4(vmsumshm, void, avr, avr, avr, avr) |
| 186 | 186 | DEF_HELPER_4(vmsumshs, void, avr, avr, avr, avr) |
| 187 | 187 | DEF_HELPER_4(vmladduhm, void, avr, avr, avr, avr) |
| 188 | +DEF_HELPER_2(lvebx, void, avr, tl) | |
| 189 | +DEF_HELPER_2(lvehx, void, avr, tl) | |
| 190 | +DEF_HELPER_2(lvewx, void, avr, tl) | |
| 191 | +DEF_HELPER_2(stvebx, void, avr, tl) | |
| 192 | +DEF_HELPER_2(stvehx, void, avr, tl) | |
| 193 | +DEF_HELPER_2(stvewx, void, avr, tl) | |
| 188 | 194 | |
| 189 | 195 | DEF_HELPER_1(efscfsi, i32, i32) |
| 190 | 196 | DEF_HELPER_1(efscfui, i32, i32) | ... | ... |
target-ppc/op_helper.c
| ... | ... | @@ -1999,6 +1999,26 @@ SATCVT(sw, uh, int32_t, uint16_t, 0, UINT16_MAX, 1, 1) |
| 1999 | 1999 | SATCVT(sd, uw, int64_t, uint32_t, 0, UINT32_MAX, 1, 1) |
| 2000 | 2000 | #undef SATCVT |
| 2001 | 2001 | |
| 2002 | +#define LVE(name, access, swap, element) \ | |
| 2003 | + void helper_##name (ppc_avr_t *r, target_ulong addr) \ | |
| 2004 | + { \ | |
| 2005 | + size_t n_elems = ARRAY_SIZE(r->element); \ | |
| 2006 | + int adjust = HI_IDX*(n_elems-1); \ | |
| 2007 | + int sh = sizeof(r->element[0]) >> 1; \ | |
| 2008 | + int index = (addr & 0xf) >> sh; \ | |
| 2009 | + if(msr_le) { \ | |
| 2010 | + r->element[LO_IDX ? index : (adjust - index)] = swap(access(addr)); \ | |
| 2011 | + } else { \ | |
| 2012 | + r->element[LO_IDX ? index : (adjust - index)] = access(addr); \ | |
| 2013 | + } \ | |
| 2014 | + } | |
| 2015 | +#define I(x) (x) | |
| 2016 | +LVE(lvebx, ldub, I, u8) | |
| 2017 | +LVE(lvehx, lduw, bswap16, u16) | |
| 2018 | +LVE(lvewx, ldl, bswap32, u32) | |
| 2019 | +#undef I | |
| 2020 | +#undef LVE | |
| 2021 | + | |
| 2002 | 2022 | void helper_lvsl (ppc_avr_t *r, target_ulong sh) |
| 2003 | 2023 | { |
| 2004 | 2024 | int i, j = (sh & 0xf); |
| ... | ... | @@ -2017,6 +2037,26 @@ void helper_lvsr (ppc_avr_t *r, target_ulong sh) |
| 2017 | 2037 | } |
| 2018 | 2038 | } |
| 2019 | 2039 | |
| 2040 | +#define STVE(name, access, swap, element) \ | |
| 2041 | + void helper_##name (ppc_avr_t *r, target_ulong addr) \ | |
| 2042 | + { \ | |
| 2043 | + size_t n_elems = ARRAY_SIZE(r->element); \ | |
| 2044 | + int adjust = HI_IDX*(n_elems-1); \ | |
| 2045 | + int sh = sizeof(r->element[0]) >> 1; \ | |
| 2046 | + int index = (addr & 0xf) >> sh; \ | |
| 2047 | + if(msr_le) { \ | |
| 2048 | + access(addr, swap(r->element[LO_IDX ? index : (adjust - index)])); \ | |
| 2049 | + } else { \ | |
| 2050 | + access(addr, r->element[LO_IDX ? index : (adjust - index)]); \ | |
| 2051 | + } \ | |
| 2052 | + } | |
| 2053 | +#define I(x) (x) | |
| 2054 | +STVE(stvebx, stb, I, u8) | |
| 2055 | +STVE(stvehx, stw, bswap16, u16) | |
| 2056 | +STVE(stvewx, stl, bswap32, u32) | |
| 2057 | +#undef I | |
| 2058 | +#undef LVE | |
| 2059 | + | |
| 2020 | 2060 | void helper_vaddcuw (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) |
| 2021 | 2061 | { |
| 2022 | 2062 | int i; | ... | ... |
target-ppc/translate.c
| ... | ... | @@ -6144,14 +6144,58 @@ GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC) \ |
| 6144 | 6144 | tcg_temp_free(EA); \ |
| 6145 | 6145 | } |
| 6146 | 6146 | |
| 6147 | +#define GEN_VR_LVE(name, opc2, opc3) \ | |
| 6148 | + GEN_HANDLER(lve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC) \ | |
| 6149 | + { \ | |
| 6150 | + TCGv EA; \ | |
| 6151 | + TCGv_ptr rs; \ | |
| 6152 | + if (unlikely(!ctx->altivec_enabled)) { \ | |
| 6153 | + gen_exception(ctx, POWERPC_EXCP_VPU); \ | |
| 6154 | + return; \ | |
| 6155 | + } \ | |
| 6156 | + gen_set_access_type(ctx, ACCESS_INT); \ | |
| 6157 | + EA = tcg_temp_new(); \ | |
| 6158 | + gen_addr_reg_index(ctx, EA); \ | |
| 6159 | + rs = gen_avr_ptr(rS(ctx->opcode)); \ | |
| 6160 | + gen_helper_lve##name (rs, EA); \ | |
| 6161 | + tcg_temp_free(EA); \ | |
| 6162 | + tcg_temp_free_ptr(rs); \ | |
| 6163 | + } | |
| 6164 | + | |
| 6165 | +#define GEN_VR_STVE(name, opc2, opc3) \ | |
| 6166 | + GEN_HANDLER(stve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC) \ | |
| 6167 | + { \ | |
| 6168 | + TCGv EA; \ | |
| 6169 | + TCGv_ptr rs; \ | |
| 6170 | + if (unlikely(!ctx->altivec_enabled)) { \ | |
| 6171 | + gen_exception(ctx, POWERPC_EXCP_VPU); \ | |
| 6172 | + return; \ | |
| 6173 | + } \ | |
| 6174 | + gen_set_access_type(ctx, ACCESS_INT); \ | |
| 6175 | + EA = tcg_temp_new(); \ | |
| 6176 | + gen_addr_reg_index(ctx, EA); \ | |
| 6177 | + rs = gen_avr_ptr(rS(ctx->opcode)); \ | |
| 6178 | + gen_helper_stve##name (rs, EA); \ | |
| 6179 | + tcg_temp_free(EA); \ | |
| 6180 | + tcg_temp_free_ptr(rs); \ | |
| 6181 | + } | |
| 6182 | + | |
| 6147 | 6183 | GEN_VR_LDX(lvx, 0x07, 0x03); |
| 6148 | 6184 | /* As we don't emulate the cache, lvxl is stricly equivalent to lvx */ |
| 6149 | 6185 | GEN_VR_LDX(lvxl, 0x07, 0x0B); |
| 6150 | 6186 | |
| 6187 | +GEN_VR_LVE(bx, 0x07, 0x00); | |
| 6188 | +GEN_VR_LVE(hx, 0x07, 0x01); | |
| 6189 | +GEN_VR_LVE(wx, 0x07, 0x02); | |
| 6190 | + | |
| 6151 | 6191 | GEN_VR_STX(svx, 0x07, 0x07); |
| 6152 | 6192 | /* As we don't emulate the cache, stvxl is stricly equivalent to stvx */ |
| 6153 | 6193 | GEN_VR_STX(svxl, 0x07, 0x0F); |
| 6154 | 6194 | |
| 6195 | +GEN_VR_STVE(bx, 0x07, 0x04); | |
| 6196 | +GEN_VR_STVE(hx, 0x07, 0x05); | |
| 6197 | +GEN_VR_STVE(wx, 0x07, 0x06); | |
| 6198 | + | |
| 6155 | 6199 | GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC) |
| 6156 | 6200 | { |
| 6157 | 6201 | TCGv_ptr rd; | ... | ... |