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; | ... | ... |