OPCODE_RECIP

This commit is contained in:
Dr. Chat 2016-06-26 13:03:42 -05:00
parent 212cd6ee3d
commit f2ad6b8cb8
9 changed files with 68 additions and 3 deletions

View File

@ -4863,6 +4863,28 @@ struct RSQRT_V128 : Sequence<RSQRT_V128, I<OPCODE_RSQRT, V128Op, V128Op>> {
}; };
EMITTER_OPCODE_TABLE(OPCODE_RSQRT, RSQRT_F32, RSQRT_F64, RSQRT_V128); EMITTER_OPCODE_TABLE(OPCODE_RSQRT, RSQRT_F32, RSQRT_F64, RSQRT_V128);
// ============================================================================
// OPCODE_RECIP
// ============================================================================
struct RECIP_F32 : Sequence<RECIP_F32, I<OPCODE_RECIP, F32Op, F32Op>> {
static void Emit(X64Emitter& e, const EmitArgType& i) {
e.vrcpss(i.dest, i.src1);
}
};
struct RECIP_F64 : Sequence<RECIP_F64, I<OPCODE_RECIP, F64Op, F64Op>> {
static void Emit(X64Emitter& e, const EmitArgType& i) {
e.vcvtsd2ss(i.dest, i.src1);
e.vrcpss(i.dest, i.dest);
e.vcvtss2sd(i.dest, i.dest);
}
};
struct RECIP_V128 : Sequence<RECIP_V128, I<OPCODE_RECIP, V128Op, V128Op>> {
static void Emit(X64Emitter& e, const EmitArgType& i) {
e.vrcpps(i.dest, i.src1);
}
};
EMITTER_OPCODE_TABLE(OPCODE_RECIP, RECIP_F32, RECIP_F64, RECIP_V128);
// ============================================================================ // ============================================================================
// OPCODE_POW2 // OPCODE_POW2
// ============================================================================ // ============================================================================
@ -7582,6 +7604,7 @@ void RegisterSequences() {
Register_OPCODE_ABS(); Register_OPCODE_ABS();
Register_OPCODE_SQRT(); Register_OPCODE_SQRT();
Register_OPCODE_RSQRT(); Register_OPCODE_RSQRT();
Register_OPCODE_RECIP();
Register_OPCODE_POW2(); Register_OPCODE_POW2();
Register_OPCODE_LOG2(); Register_OPCODE_LOG2();
Register_OPCODE_DOT_PRODUCT_3(); Register_OPCODE_DOT_PRODUCT_3();

View File

@ -487,7 +487,13 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) {
i->Remove(); i->Remove();
} }
break; break;
case OPCODE_RECIP:
if (i->src1.value->IsConstant()) {
v->set_from(i->src1.value);
v->Recip();
i->Remove();
}
break;
case OPCODE_AND: case OPCODE_AND:
if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) {
v->set_from(i->src1.value); v->set_from(i->src1.value);

View File

@ -1659,6 +1659,15 @@ Value* HIRBuilder::RSqrt(Value* value) {
return i->dest; return i->dest;
} }
Value* HIRBuilder::Recip(Value* value) {
ASSERT_FLOAT_OR_VECTOR_TYPE(value);
Instr* i = AppendInstr(OPCODE_RECIP_info, 0, AllocValue(value->type));
i->set_src1(value);
i->src2.value = i->src3.value = NULL;
return i->dest;
}
Value* HIRBuilder::Pow2(Value* value) { Value* HIRBuilder::Pow2(Value* value) {
ASSERT_FLOAT_OR_VECTOR_TYPE(value); ASSERT_FLOAT_OR_VECTOR_TYPE(value);

View File

@ -196,6 +196,7 @@ class HIRBuilder {
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* Recip(Value* value);
Value* Pow2(Value* value); Value* Pow2(Value* value);
Value* Log2(Value* value); Value* Log2(Value* value);
Value* DotProduct3(Value* value1, Value* value2); Value* DotProduct3(Value* value1, Value* value2);

View File

@ -194,6 +194,7 @@ enum Opcode {
OPCODE_ABS, OPCODE_ABS,
OPCODE_SQRT, OPCODE_SQRT,
OPCODE_RSQRT, OPCODE_RSQRT,
OPCODE_RECIP,
OPCODE_POW2, OPCODE_POW2,
OPCODE_LOG2, OPCODE_LOG2,
OPCODE_DOT_PRODUCT_3, OPCODE_DOT_PRODUCT_3,

View File

@ -470,6 +470,12 @@ DEFINE_OPCODE(
OPCODE_SIG_V_V, OPCODE_SIG_V_V,
0) 0)
DEFINE_OPCODE(
OPCODE_RECIP,
"recip",
OPCODE_SIG_V_V,
0)
DEFINE_OPCODE( DEFINE_OPCODE(
OPCODE_POW2, OPCODE_POW2,
"pow2", "pow2",

View File

@ -629,6 +629,25 @@ void Value::RSqrt() {
} }
} }
void Value::Recip() {
switch (type) {
case FLOAT32_TYPE:
constant.f32 = 1.0f / constant.f32;
break;
case FLOAT64_TYPE:
constant.f64 = 1.0f / constant.f64;
break;
case VEC128_TYPE:
for (int i = 0; i < 4; i++) {
constant.v128.f32[i] = 1.0f / constant.v128.f32[i];
}
break;
default:
assert_unhandled_case(type);
break;
}
}
void Value::And(Value* other) { void Value::And(Value* other) {
assert_true(type == other->type); assert_true(type == other->type);
switch (type) { switch (type) {

View File

@ -487,6 +487,7 @@ class Value {
void Abs(); void Abs();
void Sqrt(); void Sqrt();
void RSqrt(); void RSqrt();
void Recip();
void And(Value* other); void And(Value* other);
void Or(Value* other); void Or(Value* other);
void Xor(Value* other); void Xor(Value* other);

View File

@ -1210,8 +1210,7 @@ int InstrEmit_vpermwi128(PPCHIRBuilder& f, const InstrData& i) {
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 = vec128f(1.0f); Value* v = f.Recip(f.LoadVR(vb));
Value* v = f.Div(f.LoadConstantVec128(one), f.LoadVR(vb));
f.StoreVR(vd, v); f.StoreVR(vd, v);
return 0; return 0;
} }