diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index f19a444b0..277819185 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -2539,6 +2539,64 @@ int Translate_RSQRT(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->src1.value->type]); } +uint32_t IntCode_POW2_F32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].f32 = (float)pow(2, ics.rf[i->src1_reg].f32); + return IA_NEXT; +} +uint32_t IntCode_POW2_F64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].f64 = pow(2, ics.rf[i->src1_reg].f64); + return IA_NEXT; +} +uint32_t IntCode_POW2_V128(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 (size_t i = 0; i < 4; i++) { + dest.f4[i] = (float)pow(2, src1.f4[i]); + } + return IA_NEXT; +} +int Translate_POW2(TranslationContext& ctx, Instr* i) { + static IntCodeFn fns[] = { + IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, + IntCode_POW2_F32, + IntCode_POW2_F64, + IntCode_POW2_V128, + }; + return DispatchToC(ctx, i, fns[i->dest->type]); +} + +uint32_t IntCode_LOG2_F32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].f32 = log2(ics.rf[i->src1_reg].f32); + return IA_NEXT; +} +uint32_t IntCode_LOG2_F64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].f64 = log2(ics.rf[i->src1_reg].f64); + return IA_NEXT; +} +uint32_t IntCode_LOG2_V128(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 (size_t i = 0; i < 4; i++) { + dest.f4[i] = log2(src1.f4[i]); + } + return IA_NEXT; +} +int Translate_LOG2(TranslationContext& ctx, Instr* i) { + static IntCodeFn fns[] = { + IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, + IntCode_LOG2_F32, + IntCode_LOG2_F64, + IntCode_LOG2_V128, + }; + return DispatchToC(ctx, i, fns[i->dest->type]); +} + uint32_t IntCode_AND_I8_I8(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 & ics.rf[i->src2_reg].i8; return IA_NEXT; @@ -3223,6 +3281,8 @@ static const TranslateFn dispatch_table[] = { Translate_ABS, Translate_SQRT, Translate_RSQRT, + Translate_POW2, + Translate_LOG2, Translate_DOT_PRODUCT_3, Translate_DOT_PRODUCT_4, diff --git a/src/alloy/backend/x64/lowering/lowering_sequences.cc b/src/alloy/backend/x64/lowering/lowering_sequences.cc index 8f7038f5d..ec215f84e 100644 --- a/src/alloy/backend/x64/lowering/lowering_sequences.cc +++ b/src/alloy/backend/x64/lowering/lowering_sequences.cc @@ -490,6 +490,18 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) { return true; }); + table->AddSequence(OPCODE_POW2, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_LOG2, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + table->AddSequence(OPCODE_DOT_PRODUCT_3, [](LIRBuilder& lb, Instr*& instr) { // TODO instr = instr->next; diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index 07c2b8f28..63ba77e3c 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -703,22 +703,30 @@ XEEMITTER(vctuxs, 0x1000038A, VX )(PPCHIRBuilder& f, InstrData& i) { return 1; } +int InstrEmit_vexptefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { + // (VD) <- pow2(VB) + Value* v = f.Pow2(f.LoadVR(vb)); + f.StoreVR(vd, v); + return 0; +} XEEMITTER(vexptefp, 0x1000018A, VX )(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + return InstrEmit_vexptefp_(f, i.VX.VD, i.VX.VB); } XEEMITTER(vexptefp128, VX128_3(6, 1712), VX128_3)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + return InstrEmit_vexptefp_(f, VX128_3_VD128, VX128_3_VB128); } +int InstrEmit_vlogefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { + // (VD) <- log2(VB) + Value* v = f.Log2(f.LoadVR(vb)); + f.StoreVR(vd, v); + return 0; +} XEEMITTER(vlogefp, 0x100001CA, VX )(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + return InstrEmit_vlogefp_(f, i.VX.VD, i.VX.VB); } XEEMITTER(vlogefp128, VX128_3(6, 1776), VX128_3)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + return InstrEmit_vlogefp_(f, VX128_3_VD128, VX128_3_VB128); } int InstrEmit_vmaddfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t vc) { @@ -1158,7 +1166,7 @@ XEEMITTER(vpkd3d128, VX128_4(6, 1552), VX128_4)(PPCHIRBuilder& f, InstrData int InstrEmit_vrefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { // (VD) <- 1/(VB) vec128_t one = { 1, 1, 1, 1 }; - Value* v = f.Div(f.LoadConstant(one), f.LoadVR(vd)); + Value* v = f.Div(f.LoadConstant(one), f.LoadVR(vb)); f.StoreVR(vd, v); return 0; } @@ -1180,7 +1188,7 @@ XEEMITTER(vrfim128, VX128_3(6, 816), VX128_3)(PPCHIRBuilder& f, InstrData int InstrEmit_vrfin_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { // (VD) <- RoundToNearest(VB) - Value* v = f.Round(f.LoadVR(vd), ROUND_TO_NEAREST); + Value* v = f.Round(f.LoadVR(vb), ROUND_TO_NEAREST); f.StoreVR(vd, v); return 0; } diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index 43fa9e116..b31907438 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -1267,6 +1267,28 @@ Value* HIRBuilder::RSqrt(Value* value) { return i->dest; } +Value* HIRBuilder::Pow2(Value* value) { + ASSERT_FLOAT_TYPE(value); + + Instr* i = AppendInstr( + OPCODE_POW2_info, 0, + AllocValue(value->type)); + i->set_src1(value); + i->src2.value = i->src3.value = NULL; + return i->dest; +} + +Value* HIRBuilder::Log2(Value* value) { + ASSERT_FLOAT_TYPE(value); + + Instr* i = AppendInstr( + OPCODE_LOG2_info, 0, + AllocValue(value->type)); + i->set_src1(value); + i->src2.value = i->src3.value = NULL; + return i->dest; +} + Value* HIRBuilder::DotProduct3(Value* value1, Value* value2) { ASSERT_VECTOR_TYPE(value1); ASSERT_VECTOR_TYPE(value2); diff --git a/src/alloy/hir/hir_builder.h b/src/alloy/hir/hir_builder.h index c2097cc6d..117ff79f3 100644 --- a/src/alloy/hir/hir_builder.h +++ b/src/alloy/hir/hir_builder.h @@ -161,6 +161,8 @@ public: Value* Abs(Value* value); Value* Sqrt(Value* value); Value* RSqrt(Value* value); + Value* Pow2(Value* value); + Value* Log2(Value* value); Value* DotProduct3(Value* value1, Value* value2); Value* DotProduct4(Value* value1, Value* value2); diff --git a/src/alloy/hir/opcodes.h b/src/alloy/hir/opcodes.h index eca180ff7..e6b0e3b54 100644 --- a/src/alloy/hir/opcodes.h +++ b/src/alloy/hir/opcodes.h @@ -142,6 +142,8 @@ enum Opcode { OPCODE_ABS, OPCODE_SQRT, OPCODE_RSQRT, + OPCODE_POW2, + OPCODE_LOG2, OPCODE_DOT_PRODUCT_3, OPCODE_DOT_PRODUCT_4, diff --git a/src/alloy/hir/opcodes.inl b/src/alloy/hir/opcodes.inl index 120b52c1a..a1b56775e 100644 --- a/src/alloy/hir/opcodes.inl +++ b/src/alloy/hir/opcodes.inl @@ -391,6 +391,18 @@ DEFINE_OPCODE( OPCODE_SIG_V_V, 0); +DEFINE_OPCODE( + OPCODE_POW2, + "pow2", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_LOG2, + "log2", + OPCODE_SIG_V_V, + 0); + DEFINE_OPCODE( OPCODE_DOT_PRODUCT_3, "dot_product_3",