mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
!2656 Lower number/int/double mod/shl/shr/ashr with constant check
Merge pull request !2656 from 吴璋达/ashr
This commit is contained in:
commit
1334d2886d
@ -759,6 +759,7 @@ BytecodeInfo BytecodeCircuitBuilder::GetBytecodeInfo(const uint8_t *pc)
|
||||
case EcmaOpcode::MOD2_IMM8_V8: {
|
||||
uint16_t v0 = READ_INST_8_1();
|
||||
info.inputs.emplace_back(VirtualRegister(v0));
|
||||
info.deopt = true;
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::EQ_IMM8_V8: {
|
||||
@ -800,16 +801,19 @@ BytecodeInfo BytecodeCircuitBuilder::GetBytecodeInfo(const uint8_t *pc)
|
||||
case EcmaOpcode::SHL2_IMM8_V8: {
|
||||
uint16_t v0 = READ_INST_8_1();
|
||||
info.inputs.emplace_back(VirtualRegister(v0));
|
||||
info.deopt = true;
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::SHR2_IMM8_V8: {
|
||||
uint16_t v0 = READ_INST_8_1();
|
||||
info.inputs.emplace_back(VirtualRegister(v0));
|
||||
info.deopt = true;
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::ASHR2_IMM8_V8: {
|
||||
uint16_t v0 = READ_INST_8_1();
|
||||
info.inputs.emplace_back(VirtualRegister(v0));
|
||||
info.deopt = true;
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::AND2_IMM8_V8: {
|
||||
|
@ -1110,6 +1110,21 @@ DEF_CALL_SIGNATURE(InsertOldToNewRSet)
|
||||
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(AotFloatMod)
|
||||
{
|
||||
// 2 : 2 input parameters
|
||||
CallSignature index("AotFloatMod", 0, 2, ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = index;
|
||||
// 2 : 2 input parameters
|
||||
std::array<VariableType, 2> params = {
|
||||
VariableType::FLOAT64(),
|
||||
VariableType::FLOAT64(),
|
||||
};
|
||||
callSign->SetParameters(params.data());
|
||||
callSign->SetGCLeafFunction(false);
|
||||
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(FloatMod)
|
||||
{
|
||||
// 2 : 2 input parameters
|
||||
|
@ -369,6 +369,7 @@ private:
|
||||
V(FatalPrint) \
|
||||
V(InsertOldToNewRSet) \
|
||||
V(DoubleToInt) \
|
||||
V(AotFloatMod) \
|
||||
V(FloatMod) \
|
||||
V(FindElementWithCache) \
|
||||
V(MarkingBarrier) \
|
||||
|
@ -94,6 +94,7 @@ void TSTypeLowering::Lower(GateRef gate)
|
||||
LowerTypedDiv(gate);
|
||||
break;
|
||||
case EcmaOpcode::MOD2_IMM8_V8:
|
||||
LowerTypedMod(gate);
|
||||
break;
|
||||
case EcmaOpcode::LESS_IMM8_V8:
|
||||
LowerTypedLess(gate);
|
||||
@ -114,13 +115,13 @@ void TSTypeLowering::Lower(GateRef gate)
|
||||
LowerTypedNotEq(gate);
|
||||
break;
|
||||
case EcmaOpcode::SHL2_IMM8_V8:
|
||||
// lower JS_SHL
|
||||
LowerTypedShl(gate);
|
||||
break;
|
||||
case EcmaOpcode::SHR2_IMM8_V8:
|
||||
// lower JS_SHR
|
||||
LowerTypedShr(gate);
|
||||
break;
|
||||
case EcmaOpcode::ASHR2_IMM8_V8:
|
||||
// lower JS_ASHR
|
||||
LowerTypedAshr(gate);
|
||||
break;
|
||||
case EcmaOpcode::AND2_IMM8_V8:
|
||||
// lower JS_AND
|
||||
@ -388,6 +389,45 @@ void TSTypeLowering::LowerTypedNotEq(GateRef gate)
|
||||
}
|
||||
}
|
||||
|
||||
void TSTypeLowering::LowerTypedShl(GateRef gate)
|
||||
{
|
||||
GateRef left = acc_.GetValueIn(gate, 0);
|
||||
GateRef right = acc_.GetValueIn(gate, 1);
|
||||
GateType leftType = acc_.GetGateType(left);
|
||||
GateType rightType = acc_.GetGateType(right);
|
||||
if (leftType.IsNumberType() && rightType.IsNumberType()) {
|
||||
SpeculateNumbers<TypedBinOp::TYPED_SHL>(gate);
|
||||
} else {
|
||||
acc_.DeleteGuardAndFrameState(gate);
|
||||
}
|
||||
}
|
||||
|
||||
void TSTypeLowering::LowerTypedShr(GateRef gate)
|
||||
{
|
||||
GateRef left = acc_.GetValueIn(gate, 0);
|
||||
GateRef right = acc_.GetValueIn(gate, 1);
|
||||
GateType leftType = acc_.GetGateType(left);
|
||||
GateType rightType = acc_.GetGateType(right);
|
||||
if (leftType.IsNumberType() && rightType.IsNumberType()) {
|
||||
SpeculateNumbers<TypedBinOp::TYPED_SHR>(gate);
|
||||
} else {
|
||||
acc_.DeleteGuardAndFrameState(gate);
|
||||
}
|
||||
}
|
||||
|
||||
void TSTypeLowering::LowerTypedAshr(GateRef gate)
|
||||
{
|
||||
GateRef left = acc_.GetValueIn(gate, 0);
|
||||
GateRef right = acc_.GetValueIn(gate, 1);
|
||||
GateType leftType = acc_.GetGateType(left);
|
||||
GateType rightType = acc_.GetGateType(right);
|
||||
if (leftType.IsNumberType() && rightType.IsNumberType()) {
|
||||
SpeculateNumbers<TypedBinOp::TYPED_ASHR>(gate);
|
||||
} else {
|
||||
acc_.DeleteGuardAndFrameState(gate);
|
||||
}
|
||||
}
|
||||
|
||||
void TSTypeLowering::LowerTypedInc(GateRef gate)
|
||||
{
|
||||
GateRef value = acc_.GetValueIn(gate, 0);
|
||||
|
@ -59,6 +59,9 @@ private:
|
||||
void LowerTypedDiv(GateRef gate);
|
||||
void LowerTypedEq(GateRef gate);
|
||||
void LowerTypedNotEq(GateRef gate);
|
||||
void LowerTypedShl(GateRef gate);
|
||||
void LowerTypedShr(GateRef gate);
|
||||
void LowerTypedAshr(GateRef gate);
|
||||
void LowerTypedInc(GateRef gate);
|
||||
void LowerTypedDec(GateRef gate);
|
||||
void LowerTypeToNumeric(GateRef gate);
|
||||
|
@ -189,6 +189,18 @@ void TypeLowering::LowerTypedBinaryOp(GateRef gate)
|
||||
LowerTypedNotEq(gate);
|
||||
break;
|
||||
}
|
||||
case TypedBinOp::TYPED_SHL: {
|
||||
LowerTypedShl(gate);
|
||||
break;
|
||||
}
|
||||
case TypedBinOp::TYPED_SHR: {
|
||||
LowerTypedShr(gate);
|
||||
break;
|
||||
}
|
||||
case TypedBinOp::TYPED_ASHR: {
|
||||
LowerTypedAshr(gate);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -257,8 +269,14 @@ void TypeLowering::LowerTypedMul(GateRef gate)
|
||||
|
||||
void TypeLowering::LowerTypedMod(GateRef gate)
|
||||
{
|
||||
gate++;
|
||||
UNREACHABLE();
|
||||
auto leftType = acc_.GetLeftType(gate);
|
||||
auto rightType = acc_.GetRightType(gate);
|
||||
if (leftType.IsNumberType() && rightType.IsNumberType()) {
|
||||
LowerNumberMod(gate);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void TypeLowering::LowerTypedLess(GateRef gate)
|
||||
@ -345,6 +363,42 @@ void TypeLowering::LowerTypedNotEq(GateRef gate)
|
||||
return;
|
||||
}
|
||||
|
||||
void TypeLowering::LowerTypedShl(GateRef gate)
|
||||
{
|
||||
auto leftType = acc_.GetLeftType(gate);
|
||||
auto rightType = acc_.GetRightType(gate);
|
||||
if (leftType.IsNumberType() && rightType.IsNumberType()) {
|
||||
LowerNumberShl(gate);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void TypeLowering::LowerTypedShr(GateRef gate)
|
||||
{
|
||||
auto leftType = acc_.GetLeftType(gate);
|
||||
auto rightType = acc_.GetRightType(gate);
|
||||
if (leftType.IsNumberType() && rightType.IsNumberType()) {
|
||||
LowerNumberShr(gate);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void TypeLowering::LowerTypedAshr(GateRef gate)
|
||||
{
|
||||
auto leftType = acc_.GetLeftType(gate);
|
||||
auto rightType = acc_.GetRightType(gate);
|
||||
if (leftType.IsNumberType() && rightType.IsNumberType()) {
|
||||
LowerNumberAshr(gate);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void TypeLowering::LowerTypedInc(GateRef gate)
|
||||
{
|
||||
auto value = acc_.GetLeftType(gate);
|
||||
@ -411,6 +465,17 @@ void TypeLowering::LowerNumberMul(GateRef gate)
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberMod(GateRef gate)
|
||||
{
|
||||
GateRef left = acc_.GetValueIn(gate, 0);
|
||||
GateRef right = acc_.GetValueIn(gate, 1);
|
||||
GateType leftType = acc_.GetLeftType(gate);
|
||||
GateType rightType = acc_.GetRightType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = ModNumbers(left, right, leftType, rightType);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberLess(GateRef gate)
|
||||
{
|
||||
GateRef left = acc_.GetValueIn(gate, 0);
|
||||
@ -488,6 +553,39 @@ void TypeLowering::LowerNumberNotEq(GateRef gate)
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberShl(GateRef gate)
|
||||
{
|
||||
GateRef left = acc_.GetValueIn(gate, 0);
|
||||
GateRef right = acc_.GetValueIn(gate, 1);
|
||||
GateType leftType = acc_.GetLeftType(gate);
|
||||
GateType rightType = acc_.GetRightType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = ShiftNumber<OpCode::LSL>(left, right, leftType, rightType);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberShr(GateRef gate)
|
||||
{
|
||||
GateRef left = acc_.GetValueIn(gate, 0);
|
||||
GateRef right = acc_.GetValueIn(gate, 1);
|
||||
GateType leftType = acc_.GetLeftType(gate);
|
||||
GateType rightType = acc_.GetRightType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = ShiftNumber<OpCode::LSR>(left, right, leftType, rightType);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberAshr(GateRef gate)
|
||||
{
|
||||
GateRef left = acc_.GetValueIn(gate, 0);
|
||||
GateRef right = acc_.GetValueIn(gate, 1);
|
||||
GateType leftType = acc_.GetLeftType(gate);
|
||||
GateType rightType = acc_.GetRightType(gate);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
result = ShiftNumber<OpCode::ASR>(left, right, leftType, rightType);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypeLowering::LowerNumberInc(GateRef gate)
|
||||
{
|
||||
GateRef value = acc_.GetValueIn(gate, 0);
|
||||
@ -636,6 +734,115 @@ GateRef TypeLowering::CalculateNumbers(GateRef left, GateRef right, GateType lef
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<OpCode::Op Op>
|
||||
GateRef TypeLowering::ShiftNumber(GateRef left, GateRef right, GateType leftType, GateType rightType)
|
||||
{
|
||||
auto env = builder_.GetCurrentEnvironment();
|
||||
Label entry(&builder_);
|
||||
env->SubCfgEntry(&entry);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
DEFVAlUE(intLeft, (&builder_), VariableType::INT32(), builder_.Int32(0));
|
||||
DEFVAlUE(intRight, (&builder_), VariableType::INT32(), builder_.Int32(0));
|
||||
|
||||
Label exit(&builder_);
|
||||
Label doIntOp(&builder_);
|
||||
Label leftIsIntRightIsInt(&builder_);
|
||||
Label leftIsIntRightIsDouble(&builder_);
|
||||
Label rightIsInt(&builder_);
|
||||
Label rightIsDouble(&builder_);
|
||||
Label leftIsInt(&builder_);
|
||||
Label leftIsDouble(&builder_);
|
||||
|
||||
auto LowerIntOpInt = [&]() -> void {
|
||||
intLeft = builder_.GetInt32OfTInt(left);
|
||||
intRight = builder_.GetInt32OfTInt(right);
|
||||
builder_.Jump(&doIntOp);
|
||||
};
|
||||
auto LowerDoubleOpInt = [&]() -> void {
|
||||
intLeft = TruncDoubleToInt(builder_.GetDoubleOfTDouble(left));
|
||||
intRight = builder_.GetInt32OfTInt(right);
|
||||
builder_.Jump(&doIntOp);
|
||||
};
|
||||
auto LowerIntOpDouble = [&]() -> void {
|
||||
intLeft = builder_.GetInt32OfTInt(left);
|
||||
intRight = TruncDoubleToInt(builder_.GetDoubleOfTDouble(right));
|
||||
builder_.Jump(&doIntOp);
|
||||
};
|
||||
auto LowerDoubleOpDouble = [&]() -> void {
|
||||
intLeft = TruncDoubleToInt(builder_.GetDoubleOfTDouble(left));
|
||||
intRight = TruncDoubleToInt(builder_.GetDoubleOfTDouble(right));
|
||||
builder_.Jump(&doIntOp);
|
||||
};
|
||||
auto LowerRightWhenLeftIsInt = [&]() -> void {
|
||||
if (rightType.IsIntType()) {
|
||||
LowerIntOpInt();
|
||||
} else if (rightType.IsDoubleType()) {
|
||||
LowerIntOpDouble();
|
||||
} else {
|
||||
builder_.Branch(builder_.TaggedIsInt(right), &leftIsIntRightIsInt, &leftIsIntRightIsDouble);
|
||||
builder_.Bind(&leftIsIntRightIsInt);
|
||||
LowerIntOpInt();
|
||||
builder_.Bind(&leftIsIntRightIsDouble);
|
||||
LowerIntOpDouble();
|
||||
}
|
||||
};
|
||||
auto LowerRightWhenLeftIsDouble = [&]() -> void {
|
||||
if (rightType.IsIntType()) {
|
||||
LowerDoubleOpInt();
|
||||
} else if (rightType.IsDoubleType()) {
|
||||
LowerDoubleOpDouble();
|
||||
} else {
|
||||
builder_.Branch(builder_.TaggedIsInt(right), &rightIsInt, &rightIsDouble);
|
||||
builder_.Bind(&rightIsInt);
|
||||
LowerDoubleOpInt();
|
||||
builder_.Bind(&rightIsDouble);
|
||||
LowerDoubleOpDouble();
|
||||
}
|
||||
};
|
||||
|
||||
if (leftType.IsIntType()) {
|
||||
// left is int
|
||||
LowerRightWhenLeftIsInt();
|
||||
} else if (leftType.IsDoubleType()) {
|
||||
// left is double
|
||||
LowerRightWhenLeftIsDouble();
|
||||
} else {
|
||||
// left is number and need typecheck in runtime
|
||||
builder_.Branch(builder_.TaggedIsInt(left), &leftIsInt, &leftIsDouble);
|
||||
builder_.Bind(&leftIsInt);
|
||||
LowerRightWhenLeftIsInt();
|
||||
builder_.Bind(&leftIsDouble);
|
||||
LowerRightWhenLeftIsDouble();
|
||||
}
|
||||
builder_.Bind(&doIntOp);
|
||||
{
|
||||
GateRef res = Circuit::NullGate();
|
||||
GateRef shift = builder_.Int32And(*intRight, builder_.Int32(0x1f));
|
||||
switch (Op) {
|
||||
case OpCode::LSL: {
|
||||
res = builder_.Int32LSL(*intLeft, shift);
|
||||
break;
|
||||
}
|
||||
case OpCode::LSR: {
|
||||
res = builder_.Int32LSR(*intLeft, shift);
|
||||
break;
|
||||
}
|
||||
case OpCode::ASR: {
|
||||
res = builder_.Int32ASR(*intLeft, shift);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
result = IntToTaggedIntPtr(res);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
auto ret = *result;
|
||||
env->SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<OpCode::Op Op>
|
||||
GateRef TypeLowering::FastAddOrSubOrMul(GateRef left, GateRef right)
|
||||
{
|
||||
@ -1080,6 +1287,11 @@ GateRef TypeLowering::ChangeInt32ToFloat64(GateRef gate)
|
||||
return builder_.ChangeInt32ToFloat64(gate);
|
||||
}
|
||||
|
||||
GateRef TypeLowering::TruncDoubleToInt(GateRef gate)
|
||||
{
|
||||
return builder_.ChangeInt64ToInt32(builder_.TruncFloatToInt64(gate));
|
||||
}
|
||||
|
||||
GateRef TypeLowering::Int32Mod(GateRef left, GateRef right)
|
||||
{
|
||||
return BinaryOp<OpCode::SMOD, MachineType::I32>(left, right);
|
||||
@ -1387,6 +1599,166 @@ GateRef TypeLowering::FastDiv(GateRef left, GateRef right)
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef TypeLowering::ModNumbers(GateRef left, GateRef right, GateType leftType, GateType rightType)
|
||||
{
|
||||
auto env = builder_.GetCurrentEnvironment();
|
||||
Label entry(&builder_);
|
||||
env->SubCfgEntry(&entry);
|
||||
DEFVAlUE(result, (&builder_), VariableType::JS_ANY(), builder_.HoleConstant());
|
||||
DEFVAlUE(intLeft, (&builder_), VariableType::INT32(), builder_.Int32(0));
|
||||
DEFVAlUE(intRight, (&builder_), VariableType::INT32(), builder_.Int32(0));
|
||||
DEFVAlUE(doubleLeft, (&builder_), VariableType::FLOAT64(), builder_.Double(0));
|
||||
DEFVAlUE(doubleRight, (&builder_), VariableType::FLOAT64(), builder_.Double(0));
|
||||
|
||||
Label exit(&builder_);
|
||||
Label doFloatOp(&builder_);
|
||||
Label doIntOp(&builder_);
|
||||
Label leftIsIntRightIsDouble(&builder_);
|
||||
Label rightIsInt(&builder_);
|
||||
Label rightIsDouble(&builder_);
|
||||
Label leftIsInt(&builder_);
|
||||
Label leftIsDouble(&builder_);
|
||||
bool intOptAccessed = false;
|
||||
|
||||
auto LowerIntOpInt = [&]() -> void {
|
||||
builder_.Jump(&doIntOp);
|
||||
intOptAccessed = true;
|
||||
};
|
||||
auto LowerDoubleOpInt = [&]() -> void {
|
||||
doubleLeft = builder_.GetDoubleOfTDouble(left);
|
||||
doubleRight = ChangeInt32ToFloat64(builder_.GetInt32OfTInt(right));
|
||||
builder_.Jump(&doFloatOp);
|
||||
};
|
||||
auto LowerIntOpDouble = [&]() -> void {
|
||||
doubleLeft = ChangeInt32ToFloat64(builder_.GetInt32OfTInt(left));
|
||||
doubleRight = builder_.GetDoubleOfTDouble(right);
|
||||
builder_.Jump(&doFloatOp);
|
||||
};
|
||||
auto LowerDoubleOpDouble = [&]() -> void {
|
||||
doubleLeft = builder_.GetDoubleOfTDouble(left);
|
||||
doubleRight = builder_.GetDoubleOfTDouble(right);
|
||||
builder_.Jump(&doFloatOp);
|
||||
};
|
||||
auto LowerRightWhenLeftIsInt = [&]() -> void {
|
||||
if (rightType.IsIntType()) {
|
||||
LowerIntOpInt();
|
||||
} else if (rightType.IsDoubleType()) {
|
||||
LowerIntOpDouble();
|
||||
} else {
|
||||
builder_.Branch(builder_.TaggedIsInt(right), &doIntOp, &leftIsIntRightIsDouble);
|
||||
intOptAccessed = true;
|
||||
builder_.Bind(&leftIsIntRightIsDouble);
|
||||
LowerIntOpDouble();
|
||||
}
|
||||
};
|
||||
auto LowerRightWhenLeftIsDouble = [&]() -> void {
|
||||
if (rightType.IsIntType()) {
|
||||
LowerDoubleOpInt();
|
||||
} else if (rightType.IsDoubleType()) {
|
||||
LowerDoubleOpDouble();
|
||||
} else {
|
||||
builder_.Branch(builder_.TaggedIsInt(right), &rightIsInt, &rightIsDouble);
|
||||
builder_.Bind(&rightIsInt);
|
||||
LowerDoubleOpInt();
|
||||
builder_.Bind(&rightIsDouble);
|
||||
LowerDoubleOpDouble();
|
||||
}
|
||||
};
|
||||
|
||||
if (leftType.IsIntType()) {
|
||||
// left is int
|
||||
LowerRightWhenLeftIsInt();
|
||||
} else if (leftType.IsDoubleType()) {
|
||||
// left is double
|
||||
LowerRightWhenLeftIsDouble();
|
||||
} else {
|
||||
// left is number and need typecheck in runtime
|
||||
builder_.Branch(builder_.TaggedIsInt(left), &leftIsInt, &leftIsDouble);
|
||||
builder_.Bind(&leftIsInt);
|
||||
LowerRightWhenLeftIsInt();
|
||||
builder_.Bind(&leftIsDouble);
|
||||
LowerRightWhenLeftIsDouble();
|
||||
}
|
||||
if (intOptAccessed) {
|
||||
builder_.Bind(&doIntOp);
|
||||
{
|
||||
intLeft = builder_.GetInt32OfTInt(left);
|
||||
intRight = builder_.GetInt32OfTInt(right);
|
||||
doubleLeft = ChangeInt32ToFloat64(builder_.GetInt32OfTInt(left));
|
||||
doubleRight = ChangeInt32ToFloat64(builder_.GetInt32OfTInt(right));
|
||||
Label leftGreaterZero(&builder_);
|
||||
builder_.Branch(builder_.Int32GreaterThan(*intLeft, builder_.Int32(0)),
|
||||
&leftGreaterZero, &doFloatOp);
|
||||
builder_.Bind(&leftGreaterZero);
|
||||
{
|
||||
Label rightGreaterZero(&builder_);
|
||||
builder_.Branch(builder_.Int32GreaterThan(*intRight, builder_.Int32(0)),
|
||||
&rightGreaterZero, &doFloatOp);
|
||||
builder_.Bind(&rightGreaterZero);
|
||||
{
|
||||
result = IntToTaggedIntPtr(Int32Mod(*intLeft, *intRight));
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
builder_.Bind(&doFloatOp);
|
||||
{
|
||||
Label rightNotZero(&builder_);
|
||||
Label rightIsZeroOrNanOrLeftIsNanOrInf(&builder_);
|
||||
Label rightNotZeroAndNanAndLeftNotNanAndInf(&builder_);
|
||||
builder_.Branch(builder_.Equal(*doubleRight, builder_.Double(0.0)), &rightIsZeroOrNanOrLeftIsNanOrInf,
|
||||
&rightNotZero);
|
||||
builder_.Bind(&rightNotZero);
|
||||
{
|
||||
Label rightNotNan(&builder_);
|
||||
builder_.Branch(builder_.DoubleIsNAN(*doubleRight), &rightIsZeroOrNanOrLeftIsNanOrInf, &rightNotNan);
|
||||
builder_.Bind(&rightNotNan);
|
||||
{
|
||||
Label leftNotNan(&builder_);
|
||||
builder_.Branch(builder_.DoubleIsNAN(*doubleLeft), &rightIsZeroOrNanOrLeftIsNanOrInf, &leftNotNan);
|
||||
builder_.Bind(&leftNotNan);
|
||||
builder_.Branch(DoubleIsINF(*doubleLeft), &rightIsZeroOrNanOrLeftIsNanOrInf,
|
||||
&rightNotZeroAndNanAndLeftNotNanAndInf);
|
||||
}
|
||||
}
|
||||
builder_.Bind(&rightIsZeroOrNanOrLeftIsNanOrInf);
|
||||
{
|
||||
result = DoubleToTaggedDoublePtr(builder_.Double(base::NAN_VALUE));
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&rightNotZeroAndNanAndLeftNotNanAndInf);
|
||||
{
|
||||
Label leftNotZero(&builder_);
|
||||
Label leftIsZeroOrRightIsInf(&builder_);
|
||||
builder_.Branch(builder_.Equal(*doubleLeft, builder_.Double(0.0)), &leftIsZeroOrRightIsInf,
|
||||
&leftNotZero);
|
||||
builder_.Bind(&leftNotZero);
|
||||
{
|
||||
Label rightNotInf(&builder_);
|
||||
builder_.Branch(DoubleIsINF(*doubleRight), &leftIsZeroOrRightIsInf, &rightNotInf);
|
||||
builder_.Bind(&rightNotInf);
|
||||
{
|
||||
ArgumentAccessor argAcc(circuit_);
|
||||
auto glue = argAcc.GetCommonArgGate(CommonArgIdx::GLUE);
|
||||
result = builder_.CallNGCRuntime(
|
||||
glue, RTSTUB_ID(AotFloatMod), Gate::InvalidGateRef, { *doubleLeft, *doubleRight });
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
}
|
||||
builder_.Bind(&leftIsZeroOrRightIsInf);
|
||||
{
|
||||
result = DoubleToTaggedDoublePtr(*doubleLeft);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
}
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
auto ret = *result;
|
||||
env->SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef TypeLowering::DivNumbers(GateRef left, GateRef right, GateType leftType, GateType rightType)
|
||||
{
|
||||
auto env = builder_.GetCurrentEnvironment();
|
||||
|
@ -135,6 +135,9 @@ private:
|
||||
void LowerTypedDiv(GateRef gate);
|
||||
void LowerTypedEq(GateRef gate);
|
||||
void LowerTypedNotEq(GateRef gate);
|
||||
void LowerTypedShl(GateRef gate);
|
||||
void LowerTypedShr(GateRef gate);
|
||||
void LowerTypedAshr(GateRef gate);
|
||||
void LowerTypedInc(GateRef gate);
|
||||
void LowerTypedDec(GateRef gate);
|
||||
void LowerTypedNot(GateRef gate);
|
||||
@ -153,6 +156,9 @@ private:
|
||||
void LowerNumberDiv(GateRef gate);
|
||||
void LowerNumberEq(GateRef gate);
|
||||
void LowerNumberNotEq(GateRef gate);
|
||||
void LowerNumberShl(GateRef gate);
|
||||
void LowerNumberShr(GateRef gate);
|
||||
void LowerNumberAshr(GateRef gate);
|
||||
void LowerNumberInc(GateRef gate);
|
||||
void LowerNumberDec(GateRef gate);
|
||||
void LowerNumberNot(GateRef gate);
|
||||
@ -161,6 +167,8 @@ private:
|
||||
GateRef FastAddOrSubOrMul(GateRef left, GateRef right);
|
||||
template<OpCode::Op Op>
|
||||
GateRef CalculateNumbers(GateRef left, GateRef right, GateType leftType, GateType rightType);
|
||||
template<OpCode::Op Op>
|
||||
GateRef ShiftNumber(GateRef left, GateRef right, GateType leftType, GateType rightType);
|
||||
template<TypedBinOp Op>
|
||||
GateRef CompareNumbers(GateRef left, GateRef right, GateType leftType, GateType rightType);
|
||||
template<TypedBinOp Op>
|
||||
@ -173,6 +181,7 @@ private:
|
||||
GateRef BinaryOp(GateRef x, GateRef y);
|
||||
GateRef DoubleToTaggedDoublePtr(GateRef gate);
|
||||
GateRef ChangeInt32ToFloat64(GateRef gate);
|
||||
GateRef TruncDoubleToInt(GateRef gate);
|
||||
GateRef Int32Mod(GateRef left, GateRef right);
|
||||
GateRef DoubleMod(GateRef left, GateRef right);
|
||||
GateRef IntToTaggedIntPtr(GateRef x);
|
||||
@ -180,6 +189,7 @@ private:
|
||||
GateRef Less(GateRef left, GateRef right);
|
||||
GateRef LessEq(GateRef left, GateRef right);
|
||||
GateRef FastDiv(GateRef left, GateRef right);
|
||||
GateRef ModNumbers(GateRef left, GateRef right, GateType leftType, GateType rightType);
|
||||
GateRef DivNumbers(GateRef left, GateRef right, GateType leftType, GateType rightType);
|
||||
GateRef FastEqual(GateRef left, GateRef right);
|
||||
|
||||
|
@ -2074,6 +2074,12 @@ int32_t RuntimeStubs::FindElementWithCache(uintptr_t argGlue, JSTaggedType hclas
|
||||
return index;
|
||||
}
|
||||
|
||||
JSTaggedType RuntimeStubs::AotFloatMod(double x, double y)
|
||||
{
|
||||
double result = std::fmod(x, y);
|
||||
return JSTaggedValue(result).GetRawData();
|
||||
}
|
||||
|
||||
JSTaggedType RuntimeStubs::FloatMod(double x, double y)
|
||||
{
|
||||
double result = std::fmod(x, y);
|
||||
|
@ -91,6 +91,7 @@ using JSFunctionEntryType = JSTaggedValue (*)(uintptr_t glue, uintptr_t prevFp,
|
||||
V(MarkingBarrier) \
|
||||
V(StoreBarrier) \
|
||||
V(DoubleToInt) \
|
||||
V(AotFloatMod) \
|
||||
V(FloatMod) \
|
||||
V(FindElementWithCache) \
|
||||
V(CreateArrayFromList) \
|
||||
@ -340,6 +341,7 @@ public:
|
||||
static JSTaggedType CreateArrayFromList([[maybe_unused]]uintptr_t argGlue, int32_t argc, JSTaggedValue *argv);
|
||||
static void InsertOldToNewRSet([[maybe_unused]]uintptr_t argGlue, uintptr_t object, size_t offset);
|
||||
static int32_t DoubleToInt(double x);
|
||||
static JSTaggedType AotFloatMod(double x, double y);
|
||||
static JSTaggedType FloatMod(double x, double y);
|
||||
static int32_t FindElementWithCache(uintptr_t argGlue, JSTaggedType hclass,
|
||||
JSTaggedType key, int32_t num);
|
||||
|
@ -13,3 +13,11 @@
|
||||
|
||||
1
|
||||
4.5
|
||||
0
|
||||
NaN
|
||||
NaN
|
||||
45.5
|
||||
45.5
|
||||
NaN
|
||||
NaN
|
||||
NaN
|
||||
|
@ -23,3 +23,15 @@ print(res)
|
||||
var num3: number = 50
|
||||
var num4: number = 45.5
|
||||
print(num3 % num4)
|
||||
var num5:number = Number.NaN;
|
||||
var num6:number = Number.NEGATIVE_INFINITY;
|
||||
var num7:number = Number.POSITIVE_INFINITY;
|
||||
var num8:number = 0.0;
|
||||
print(num8 % num4)
|
||||
print(num4 % num8)
|
||||
print(num4 % num5)
|
||||
print(num4 % num6)
|
||||
print(num4 % num7)
|
||||
print(num5 % num4)
|
||||
print(num6 % num4)
|
||||
print(num7 % num4)
|
||||
|
Loading…
Reference in New Issue
Block a user