From f6866098c5b69a96a2de487ed6fee13c58e46855 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 12 Jan 2014 15:41:18 -0800 Subject: [PATCH] Probably correct vupkh|lsb. --- src/alloy/backend/ivm/ivm_intcode.cc | 20 ++++++++ src/alloy/frontend/ppc/ppc_emit_altivec.cc | 57 +++++++++++++--------- src/alloy/hir/opcodes.h | 2 + 3 files changed, 56 insertions(+), 23 deletions(-) diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 5a5c98a5e..4aed60d15 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -3790,6 +3790,8 @@ int Translate_PACK(TranslationContext& ctx, Instr* i) { IntCode_PACK_FLOAT16_2, IntCode_PACK_FLOAT16_4, IntCode_PACK_SHORT_2, + IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->flags]); } @@ -3844,12 +3846,30 @@ uint32_t IntCode_UNPACK_SHORT_2(IntCodeState& ics, const IntCode* i) { dest.f4[3] = 1.0f; // 3? return IA_NEXT; } +uint32_t IntCode_UNPACK_S8_IN_16_LO(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 8; n++) { + dest.s8[n] = (int16_t)(int8_t)src1.b16[8 + n]; + } + return IA_NEXT; +} +uint32_t IntCode_UNPACK_S8_IN_16_HI(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 8; n++) { + dest.s8[n] = (int16_t)(int8_t)src1.b16[n]; + } + return IA_NEXT; +} int Translate_UNPACK(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { IntCode_UNPACK_D3DCOLOR, IntCode_UNPACK_FLOAT16_2, IntCode_UNPACK_FLOAT16_4, IntCode_UNPACK_SHORT_2, + IntCode_UNPACK_S8_IN_16_LO, + IntCode_UNPACK_S8_IN_16_HI, }; return DispatchToC(ctx, i, fns[i->flags]); } diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index 416005aef..9c6c9efa8 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -1691,44 +1691,55 @@ XEEMITTER(vpkuwus128, VX128(5, 960), VX128 )(PPCHIRBuilder& f, InstrData return 1; } - XEEMITTER(vupkhpx, 0x1000034E, VX )(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vupkhsb, 0x1000020E, VX )(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; -} -XEEMITTER(vupkhsb128, VX128(6, 896), VX128 )(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; -} - -XEEMITTER(vupkhsh, 0x1000024E, VX )(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; -} - XEEMITTER(vupklpx, 0x100003CE, VX )(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vupklsb, 0x1000028E, VX )(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; +int InstrEmit_vupkhsb_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { + // bytes 0-7 expanded to halfwords 0-8 and sign extended + Value* v = f.Unpack(f.LoadVR(vb), PACK_TYPE_S8_IN_16_HI); + f.StoreVR(vd, v); + return 0; } -XEEMITTER(vupklsb128, VX128(6, 960), VX128 )(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; +XEEMITTER(vupkhsb, 0x1000020E, VX )(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vupkhsb_(f, i.VX.VD, i.VX.VB); +} +XEEMITTER(vupkhsb128, VX128(6, 896), VX128 )(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vupkhsb_(f, VX128_VD128, VX128_VB128); } -XEEMITTER(vupklsh, 0x100002CE, VX )(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); +int InstrEmit_vupkhsh_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { return 1; } +XEEMITTER(vupkhsh, 0x1000024E, VX )(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vupkhsh_(f, i.VX.VD, i.VX.VA, i.VX.VB); +} + +int InstrEmit_vupklsb_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { + // bytes 8-15 expanded to halfwords 0-8 and sign extended + Value* v = f.Unpack(f.LoadVR(vb), PACK_TYPE_S8_IN_16_LO); + f.StoreVR(vd, v); + return 0; +} +XEEMITTER(vupklsb, 0x1000028E, VX )(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vupklsb_(f, i.VX.VD, i.VX.VB); +} +XEEMITTER(vupklsb128, VX128(6, 960), VX128 )(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vupklsb_(f, VX128_VD128, VX128_VB128); +} + +int InstrEmit_vupklsh_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { + return 1; +} +XEEMITTER(vupklsh, 0x100002CE, VX )(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vupklsh_(f, i.VX.VD, i.VX.VA, i.VX.VB); +} XEEMITTER(vpkd3d128, VX128_4(6, 1552), VX128_4)(PPCHIRBuilder& f, InstrData& i) { const uint32_t vd = i.VX128_4.VD128l | (i.VX128_4.VD128h << 5); diff --git a/src/alloy/hir/opcodes.h b/src/alloy/hir/opcodes.h index 282a9600a..af3c36b72 100644 --- a/src/alloy/hir/opcodes.h +++ b/src/alloy/hir/opcodes.h @@ -71,6 +71,8 @@ enum PackType { PACK_TYPE_FLOAT16_2 = 1, PACK_TYPE_FLOAT16_4 = 2, PACK_TYPE_SHORT_2 = 3, + PACK_TYPE_S8_IN_16_LO = 4, + PACK_TYPE_S8_IN_16_HI = 5, };