POW2/LOG2 for vexptefp/vlogefp.

This commit is contained in:
Ben Vanik 2014-01-06 18:13:16 -08:00
parent de113a4a05
commit 3dcbcce38d
7 changed files with 128 additions and 10 deletions

View File

@ -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,

View File

@ -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;

View File

@ -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;
} }

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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",