POW2/LOG2 for vexptefp/vlogefp.
This commit is contained in:
parent
de113a4a05
commit
3dcbcce38d
|
@ -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,
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -142,6 +142,8 @@ enum Opcode {
|
|||
OPCODE_ABS,
|
||||
OPCODE_SQRT,
|
||||
OPCODE_RSQRT,
|
||||
OPCODE_POW2,
|
||||
OPCODE_LOG2,
|
||||
OPCODE_DOT_PRODUCT_3,
|
||||
OPCODE_DOT_PRODUCT_4,
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue