diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index dd159ad3d..018f518b7 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -186,18 +186,29 @@ XEEMITTER(lvxl128, VX128_1(4, 707), VX128_1)(PPCFunctionBuilder& f, Inst } XEEMITTER(stvebx, 0x7C00010E, X )(PPCFunctionBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + Value* ea = i.X.RA ? f.Add(f.LoadGPR(i.X.RA), f.LoadGPR(i.X.RB)) : f.LoadGPR(i.X.RB); + Value* el = f.And(ea, f.LoadConstant(0xFull)); + Value* v = f.Extract(f.LoadVR(i.X.RT), el, INT8_TYPE); + f.Store(ea, v); + return 0; } XEEMITTER(stvehx, 0x7C00014E, X )(PPCFunctionBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + Value* ea = i.X.RA ? f.Add(f.LoadGPR(i.X.RA), f.LoadGPR(i.X.RB)) : f.LoadGPR(i.X.RB); + ea = f.And(ea, f.LoadConstant(~0x1ull)); + Value* el = f.Shr(f.And(ea, f.LoadConstant(0xFull)), 1); + Value* v = f.Extract(f.LoadVR(i.X.RT), el, INT16_TYPE); + f.Store(ea, f.ByteSwap(v)); + return 0; } int InstrEmit_stvewx_(PPCFunctionBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { - XEINSTRNOTIMPLEMENTED(); - return 1; + Value* ea = ra ? f.Add(f.LoadGPR(ra), f.LoadGPR(rb)) : f.LoadGPR(rb); + ea = f.And(ea, f.LoadConstant(~0x3ull)); + Value* el = f.Shr(f.And(ea, f.LoadConstant(0xFull)), 2); + Value* v = f.Extract(f.LoadVR(vd), el, INT32_TYPE); + f.Store(ea, f.ByteSwap(v)); + return 0; } XEEMITTER(stvewx, 0x7C00018E, X )(PPCFunctionBuilder& f, InstrData& i) { return InstrEmit_stvewx_(f, i, i.X.RT, i.X.RA, i.X.RB); @@ -1608,7 +1619,7 @@ XEEMITTER(vupkd3d128, VX128_3(6, 2032), VX128_3)(PPCFunctionBuilder& f, Inst // zzzzZZZZzzzzARGB v = f.LoadVR(vb); // 0zzzZZZZzzzzARGB - v = f.Insert(v, 0, f.LoadConstant((int8_t)0)); + v = f.Insert(v, 0ull, f.LoadConstant((int8_t)0)); // 000R000G000B000A vec128_t shuf_v = { 0 }; shuf_v.b16[3] = 13; diff --git a/src/alloy/hir/function_builder.cc b/src/alloy/hir/function_builder.cc index e892fcbeb..eb3750b20 100644 --- a/src/alloy/hir/function_builder.cc +++ b/src/alloy/hir/function_builder.cc @@ -1479,30 +1479,40 @@ Value* FunctionBuilder::CountLeadingZeros(Value* value) { return i->dest; } -Value* FunctionBuilder::Insert(Value* value, uint32_t index, Value* part) { +Value* FunctionBuilder::Insert(Value* value, Value* index, Value* part) { // TODO(benvanik): could do some of this as constants. Instr* i = AppendInstr( OPCODE_INSERT_info, 0, AllocValue(value->type)); i->set_src1(value); - i->src2.offset = index; + i->set_src2(ZeroExtend(index, INT64_TYPE)); i->set_src3(part); return i->dest; } -Value* FunctionBuilder::Extract(Value* value, uint32_t index, TypeName target_type) { +Value* FunctionBuilder::Insert(Value* value, uint64_t index, Value* part) { + return Insert(value, LoadConstant(index), part); +} + +Value* FunctionBuilder::Extract(Value* value, Value* index, + TypeName target_type) { // TODO(benvanik): could do some of this as constants. Instr* i = AppendInstr( OPCODE_EXTRACT_info, 0, AllocValue(target_type)); i->set_src1(value); - i->src2.offset = index; + i->set_src2(ZeroExtend(index, INT64_TYPE)); i->src3.value = NULL; return i->dest; } +Value* FunctionBuilder::Extract(Value* value, uint64_t index, + TypeName target_type) { + return Extract(value, LoadConstant(index), target_type); +} + Value* FunctionBuilder::Splat(Value* value, TypeName target_type) { // TODO(benvanik): could do some of this as constants. diff --git a/src/alloy/hir/function_builder.h b/src/alloy/hir/function_builder.h index cae613f5b..62647542c 100644 --- a/src/alloy/hir/function_builder.h +++ b/src/alloy/hir/function_builder.h @@ -183,8 +183,10 @@ public: Value* RotateLeft(Value* value1, Value* value2); Value* ByteSwap(Value* value); Value* CountLeadingZeros(Value* value); - Value* Insert(Value* value, uint32_t index, Value* part); - Value* Extract(Value* value, uint32_t index, TypeName target_type); + Value* Insert(Value* value, Value* index, Value* part); + Value* Insert(Value* value, uint64_t index, Value* part); + Value* Extract(Value* value, Value* index, TypeName target_type); + Value* Extract(Value* value, uint64_t index, TypeName target_type); // i8->i16/i32/... (i8|i8 / i8|i8|i8|i8 / ...) // i8/i16/i32 -> vec128 Value* Splat(Value* value, TypeName target_type); diff --git a/src/alloy/hir/opcodes.inl b/src/alloy/hir/opcodes.inl index 660ec25fd..b3b8f8250 100644 --- a/src/alloy/hir/opcodes.inl +++ b/src/alloy/hir/opcodes.inl @@ -508,13 +508,13 @@ DEFINE_OPCODE( DEFINE_OPCODE( OPCODE_INSERT, "insert", - OPCODE_SIG_V_V_O_V, + OPCODE_SIG_V_V_V_V, 0); DEFINE_OPCODE( OPCODE_EXTRACT, "extract", - OPCODE_SIG_V_V_O, + OPCODE_SIG_V_V_V, 0); DEFINE_OPCODE(