OPCODE_RECIP
This commit is contained in:
parent
212cd6ee3d
commit
f2ad6b8cb8
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue