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]);
|
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) {
|
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;
|
ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 & ics.rf[i->src2_reg].i8;
|
||||||
return IA_NEXT;
|
return IA_NEXT;
|
||||||
|
@ -3223,6 +3281,8 @@ static const TranslateFn dispatch_table[] = {
|
||||||
Translate_ABS,
|
Translate_ABS,
|
||||||
Translate_SQRT,
|
Translate_SQRT,
|
||||||
Translate_RSQRT,
|
Translate_RSQRT,
|
||||||
|
Translate_POW2,
|
||||||
|
Translate_LOG2,
|
||||||
Translate_DOT_PRODUCT_3,
|
Translate_DOT_PRODUCT_3,
|
||||||
Translate_DOT_PRODUCT_4,
|
Translate_DOT_PRODUCT_4,
|
||||||
|
|
||||||
|
|
|
@ -490,6 +490,18 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) {
|
||||||
return true;
|
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) {
|
table->AddSequence(OPCODE_DOT_PRODUCT_3, [](LIRBuilder& lb, Instr*& instr) {
|
||||||
// TODO
|
// TODO
|
||||||
instr = instr->next;
|
instr = instr->next;
|
||||||
|
|
|
@ -703,22 +703,30 @@ XEEMITTER(vctuxs, 0x1000038A, VX )(PPCHIRBuilder& f, InstrData& i) {
|
||||||
return 1;
|
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) {
|
XEEMITTER(vexptefp, 0x1000018A, VX )(PPCHIRBuilder& f, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
return InstrEmit_vexptefp_(f, i.VX.VD, i.VX.VB);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
XEEMITTER(vexptefp128, VX128_3(6, 1712), VX128_3)(PPCHIRBuilder& f, InstrData& i) {
|
XEEMITTER(vexptefp128, VX128_3(6, 1712), VX128_3)(PPCHIRBuilder& f, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
return InstrEmit_vexptefp_(f, VX128_3_VD128, VX128_3_VB128);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
XEEMITTER(vlogefp, 0x100001CA, VX )(PPCHIRBuilder& f, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
return InstrEmit_vlogefp_(f, i.VX.VD, i.VX.VB);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
XEEMITTER(vlogefp128, VX128_3(6, 1776), VX128_3)(PPCHIRBuilder& f, InstrData& i) {
|
XEEMITTER(vlogefp128, VX128_3(6, 1776), VX128_3)(PPCHIRBuilder& f, InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
return InstrEmit_vlogefp_(f, VX128_3_VD128, VX128_3_VB128);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int InstrEmit_vmaddfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t vc) {
|
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) {
|
int InstrEmit_vrefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) {
|
||||||
// (VD) <- 1/(VB)
|
// (VD) <- 1/(VB)
|
||||||
vec128_t one = { 1, 1, 1, 1 };
|
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);
|
f.StoreVR(vd, v);
|
||||||
return 0;
|
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) {
|
int InstrEmit_vrfin_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) {
|
||||||
// (VD) <- RoundToNearest(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);
|
f.StoreVR(vd, v);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1267,6 +1267,28 @@ Value* HIRBuilder::RSqrt(Value* value) {
|
||||||
return i->dest;
|
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) {
|
Value* HIRBuilder::DotProduct3(Value* value1, Value* value2) {
|
||||||
ASSERT_VECTOR_TYPE(value1);
|
ASSERT_VECTOR_TYPE(value1);
|
||||||
ASSERT_VECTOR_TYPE(value2);
|
ASSERT_VECTOR_TYPE(value2);
|
||||||
|
|
|
@ -161,6 +161,8 @@ public:
|
||||||
Value* Abs(Value* value);
|
Value* Abs(Value* value);
|
||||||
Value* Sqrt(Value* value);
|
Value* Sqrt(Value* value);
|
||||||
Value* RSqrt(Value* value);
|
Value* RSqrt(Value* value);
|
||||||
|
Value* Pow2(Value* value);
|
||||||
|
Value* Log2(Value* value);
|
||||||
Value* DotProduct3(Value* value1, Value* value2);
|
Value* DotProduct3(Value* value1, Value* value2);
|
||||||
Value* DotProduct4(Value* value1, Value* value2);
|
Value* DotProduct4(Value* value1, Value* value2);
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,8 @@ enum Opcode {
|
||||||
OPCODE_ABS,
|
OPCODE_ABS,
|
||||||
OPCODE_SQRT,
|
OPCODE_SQRT,
|
||||||
OPCODE_RSQRT,
|
OPCODE_RSQRT,
|
||||||
|
OPCODE_POW2,
|
||||||
|
OPCODE_LOG2,
|
||||||
OPCODE_DOT_PRODUCT_3,
|
OPCODE_DOT_PRODUCT_3,
|
||||||
OPCODE_DOT_PRODUCT_4,
|
OPCODE_DOT_PRODUCT_4,
|
||||||
|
|
||||||
|
|
|
@ -391,6 +391,18 @@ DEFINE_OPCODE(
|
||||||
OPCODE_SIG_V_V,
|
OPCODE_SIG_V_V,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
|
DEFINE_OPCODE(
|
||||||
|
OPCODE_POW2,
|
||||||
|
"pow2",
|
||||||
|
OPCODE_SIG_V_V,
|
||||||
|
0);
|
||||||
|
|
||||||
|
DEFINE_OPCODE(
|
||||||
|
OPCODE_LOG2,
|
||||||
|
"log2",
|
||||||
|
OPCODE_SIG_V_V,
|
||||||
|
0);
|
||||||
|
|
||||||
DEFINE_OPCODE(
|
DEFINE_OPCODE(
|
||||||
OPCODE_DOT_PRODUCT_3,
|
OPCODE_DOT_PRODUCT_3,
|
||||||
"dot_product_3",
|
"dot_product_3",
|
||||||
|
|
Loading…
Reference in New Issue