Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement CompareDoubleResult #2

Open
wants to merge 3 commits into
base: cachet-cacheir-compiler
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions js/src/jit/CacheIRCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include "jit/SharedICHelpers-inl.h"
#include "jit/VMFunctionList-inl.h"


using namespace js;
using namespace js::jit;

Expand Down Expand Up @@ -6600,6 +6601,11 @@ bool CacheIRCompiler::emitComparePointerResultShared(JSOp op,
TypedOperandId lhsId,
TypedOperandId rhsId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
#ifdef JS_CACHET
if (isCachetEnabled_) {
cachet::Impl_CacheIR::Op_ComparePointerResult(cachet::CachetContext {this, cx_}, masm, op, lhsId, rhsId);
} else {
#endif
AutoOutputRegister output(*this);

Register left = allocator.useRegister(masm, lhsId);
Expand All @@ -6617,6 +6623,9 @@ bool CacheIRCompiler::emitComparePointerResultShared(JSOp op,
masm.bind(&ifTrue);
EmitStoreBoolean(masm, true, output);
masm.bind(&done);
#ifdef JS_CACHET
}
#endif
return true;
}

Expand Down Expand Up @@ -6662,6 +6671,11 @@ bool CacheIRCompiler::emitCompareInt32Result(JSOp op, Int32OperandId lhsId,
bool CacheIRCompiler::emitCompareDoubleResult(JSOp op, NumberOperandId lhsId,
NumberOperandId rhsId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
#ifdef JS_CACHET
if (isCachetEnabled_) {
cachet::Impl_CacheIR::Op_CompareDoubleResult(cachet::CachetContext {this, cx_}, masm, op, lhsId, rhsId);
} else {
#endif
AutoOutputRegister output(*this);

// Float register must be preserved. The Compare ICs use the fact that
Expand All @@ -6686,6 +6700,9 @@ bool CacheIRCompiler::emitCompareDoubleResult(JSOp op, NumberOperandId lhsId,
masm.bind(&ifTrue);
EmitStoreBoolean(masm, true, output);
masm.bind(&done);
#ifdef JS_CACHET
}
#endif
return true;
}

Expand Down
18 changes: 18 additions & 0 deletions js/src/jit/CachetCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1365,6 +1365,15 @@ void EmitOp_BranchTest32Imm(Cachet_ContextRef cx,
ops.branchTest32(param_condition, param_lhsReg, Imm32(param_rhsInt32), param_branch);
}

void EmitOp_BranchDouble(Cachet_ContextRef cx,
IR_MASM::OpsRef ops,
Type_DoubleCondition::Ref param_condition,
Type_FloatReg::Ref param_lhsReg,
Type_FloatReg::Ref param_rhsReg,
IR_MASM::LabelRef param_branch) {
ops.branchDouble(param_condition, param_lhsReg, param_rhsReg, param_branch);
}

void EmitOp_BranchAdd32(Cachet_ContextRef cx,
IR_MASM::OpsRef ops,
Type_Condition::Ref param_condition,
Expand Down Expand Up @@ -1608,6 +1617,11 @@ Type_ValueReg::Val Fn_useValueId(Cachet_ContextRef cx, IR_MASM::OpsRef ops,
return detail::CompilerInternals::allocator(cx).useValueRegister(ops, param_valueId);
}

Type_Reg::Val Fn_useTypedId(Cachet_ContextRef cx, IR_MASM::OpsRef ops,
Type_TypedId::Ref param_typedId) {
return detail::CompilerInternals::allocator(cx).useRegister(ops, param_typedId);
}

Type_Reg::Val Fn_useObjectId(Cachet_ContextRef cx, IR_MASM::OpsRef ops,
Type_ObjectId::Ref param_objectId) {
return detail::CompilerInternals::allocator(cx).useRegister(ops, param_objectId);
Expand Down Expand Up @@ -1707,6 +1721,10 @@ Type_Bool::Val Fn_objectGuardNeedsSpectreMitigations(
return detail::CompilerInternals::objectGuardNeedsSpectreMitigations(cx, param_objectId);
}

void Fn_ensureDoubleRegister(Cachet_ContextRef cx, IR_MASM::OpsRef ops, Type_NumberId::Ref op, Type_FloatReg::Ref dest) {
detail::CompilerInternals::allocator(cx).ensureDoubleRegister(detail::CompilerInternals::masm(cx), op, dest);
}

}; // namespace Impl_CacheIR

Type_Bool::Val Fn_isCacheableProtoChain(Cachet_ContextRef cx,
Expand Down
65 changes: 65 additions & 0 deletions js/src/jit/CachetCompiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ using Type_GeneralRegSet = PrimitiveType<GeneralRegisterSet>;
using Type_FloatRegSet = PrimitiveType<FloatRegisterSet>;
using Type_LiveRegSet = PrimitiveType<LiveRegisterSet>;
using Type_Condition = PrimitiveType<Assembler::Condition>;
using Type_DoubleCondition = PrimitiveType<Assembler::DoubleCondition>;
using Type_Address = StructType<js::jit::Address>;
using Type_Scale = PrimitiveType<js::jit::Scale>;
using Type_BaseIndex = StructType<js::jit::BaseIndex>;
Expand Down Expand Up @@ -674,6 +675,10 @@ inline Type_PhyFloatReg::Ref Variant_Xmm0(Cachet_ContextRef cx) {
return X86Encoding::xmm0;
}

inline Type_PhyFloatReg::Ref Variant_Xmm1(Cachet_ContextRef cx) {
return X86Encoding::xmm1;
}

inline Type_PhyFloatReg::Ref Variant_Xmm15(Cachet_ContextRef cx) {
return X86Encoding::xmm15;
}
Expand Down Expand Up @@ -760,6 +765,66 @@ inline Type_Condition::Ref Variant_BelowOrEqual(Cachet_ContextRef cx) {

}; // namespace Impl_Condition

namespace Impl_DoubleCondition {

inline Type_DoubleCondition::Ref Variant_Ordered(Cachet_ContextRef cx) {
return Assembler::DoubleCondition::DoubleOrdered;
}

inline Type_DoubleCondition::Ref Variant_Equal(Cachet_ContextRef cx) {
return Assembler::DoubleCondition::DoubleEqual;
}

inline Type_DoubleCondition::Ref Variant_NotEqual(Cachet_ContextRef cx) {
return Assembler::DoubleCondition::DoubleNotEqual;
}

inline Type_DoubleCondition::Ref Variant_GreaterThan(Cachet_ContextRef cx) {
return Assembler::DoubleCondition::DoubleGreaterThan;
}

inline Type_DoubleCondition::Ref Variant_GreaterThanOrEqual(Cachet_ContextRef cx) {
return Assembler::DoubleCondition::DoubleGreaterThanOrEqual;
}

inline Type_DoubleCondition::Ref Variant_LessThan(Cachet_ContextRef cx) {
return Assembler::DoubleCondition::DoubleLessThan;
}

inline Type_DoubleCondition::Ref Variant_LessThanOrEqual(Cachet_ContextRef cx) {
return Assembler::DoubleCondition::DoubleLessThanOrEqual;
}

inline Type_DoubleCondition::Ref Variant_Unordered(Cachet_ContextRef cx) {
return Assembler::DoubleCondition::DoubleUnordered;
}

inline Type_DoubleCondition::Ref Variant_EqualOrUnordered(Cachet_ContextRef cx) {
return Assembler::DoubleCondition::DoubleEqualOrUnordered;
}

inline Type_DoubleCondition::Ref Variant_NotEqualOrUnordered(Cachet_ContextRef cx) {
return Assembler::DoubleCondition::DoubleNotEqualOrUnordered;
}

inline Type_DoubleCondition::Ref Variant_GreaterThanOrUnordered(Cachet_ContextRef cx) {
return Assembler::DoubleCondition::DoubleGreaterThanOrUnordered;
}

inline Type_DoubleCondition::Ref Variant_GreaterThanOrEqualOrUnordered(Cachet_ContextRef cx) {
return Assembler::DoubleCondition::DoubleGreaterThanOrEqualOrUnordered;
}

inline Type_DoubleCondition::Ref Variant_LessThanOrUnordered(Cachet_ContextRef cx) {
return Assembler::DoubleCondition::DoubleLessThanOrUnordered;
}

inline Type_DoubleCondition::Ref Variant_LessThanOrEqualOrUnordered(Cachet_ContextRef cx) {
return Assembler::DoubleCondition::DoubleLessThanOrEqualOrUnordered;
}

}; // namespace Impl_DoubleCondition

namespace Impl_Scale {

inline Type_Scale::Ref Variant_TimesOne(Cachet_ContextRef cx) {
Expand Down
2 changes: 1 addition & 1 deletion js/src/jit/GenerateCachetFiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def generate_cachet_impl(c_out, cachet_src):
script_file_path = os.path.abspath(__file__)
jit_dir_path = os.path.dirname(script_file_path)
cachet_compiler_exe_path = os.path.abspath(os.path.join(jit_dir_path,
"..", "..", "..", "..", "cachet", "target", "debug", "cachet-compiler"))
"..", "..", "..", "..", "cachet", "target", "release", "cachet-compiler"))
p = subprocess.Popen([cachet_compiler_exe_path, cachet_src, "--cpp-decls", h_tmp,
"--cpp-defs", inc_tmp], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

Expand Down
41 changes: 41 additions & 0 deletions js/src/jit/cachet/CacheIR.cachet
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,22 @@ ir CacheIR emits MASM {
bind done;
}

op ComparePointerResult(jsop: JSOp, lhsId: TypedId, rhsId: TypedId) {
let lhsReg = CacheIR::useTypedId(lhsId);
let rhsReg = CacheIR::useTypedId(rhsId);

label ifTrue: MASM;
label done: MASM;

emit MASM::Branch32(Condition::fromJSOp(jsop, true), lhsReg, rhsReg, ifTrue);
CacheIR::emitStoreBool(false, CacheIR::outputReg);
emit MASM::Jump(done);

bind ifTrue;
CacheIR::emitStoreBool(true, CacheIR::outputReg);
bind done;
}

op CompareNullUndefinedResult(jsop: JSOp, isUndefined: Bool, inputId: ValueId) {
let inputReg = CacheIR::useValueId(inputId);
let scratchReg = CacheIR::allocateReg();
Expand Down Expand Up @@ -1318,6 +1334,31 @@ ir CacheIR emits MASM {

}

op CompareDoubleResult(jsop: JSOp, lhsId: NumberId, rhsId: NumberId) {
// TODO(jlwoodwa): elided AutoAvailableFloatRegister; check that this is safe
let floatScratch0 = FloatReg::floatReg0();
let floatScratch1 = FloatReg::floatReg1();

// let failure = CacheIR::addFailurePath();
// TODO(jlwoodwa): is this as pointless as it looks?

CacheIR::ensureDoubleRegister(lhsId, floatScratch0);
CacheIR::ensureDoubleRegister(rhsId, floatScratch1);

label ifTrue: MASM;
label done: MASM;

emit MASM::BranchDouble(DoubleCondition::fromJSOp(jsop), floatScratch0, floatScratch1, ifTrue);
CacheIR::emitStoreBool(false, CacheIR::outputReg);
emit MASM::Jump(done);

bind ifTrue;
CacheIR::emitStoreBool(true, CacheIR::outputReg);
bind done;

// CacheIR::releaseFailurePath();
}

op Int32AddResult(lhsId: Int32Id, rhsId: Int32Id) {
let lhsReg = CacheIR::useInt32Id(lhsId);
let rhsReg = CacheIR::useInt32Id(rhsId);
Expand Down
106 changes: 106 additions & 0 deletions js/src/jit/cachet/MacroAssembler.cachet
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ impl FloatReg {
FloatReg::newDouble(PhyFloatReg::Xmm0)
}

fn floatReg1() -> FloatReg {
FloatReg::newDouble(PhyFloatReg::Xmm1)
}

fn doubleScratchReg() -> FloatReg {
FloatReg::newDouble(PhyFloatReg::Xmm15)
}
Expand Down Expand Up @@ -623,6 +627,43 @@ impl Condition {
}
}

enum DoubleCondition {
Ordered,
Equal,
NotEqual,
GreaterThan,
GreaterThanOrEqual,
LessThan,
LessThanOrEqual,
Unordered,
EqualOrUnordered,
NotEqualOrUnordered,
GreaterThanOrUnordered,
GreaterThanOrEqualOrUnordered,
LessThanOrUnordered,
LessThanOrEqualOrUnordered,
}

impl DoubleCondition {
fn fromJSOp(jsop: JSOp) -> DoubleCondition {
if jsop == JSOp::Eq || jsop == JSOp::StrictEq {
return DoubleCondition::Equal;
} else if jsop == JSOp::Ne || jsop == JSOp::StrictNe {
return DoubleCondition::NotEqualOrUnordered;
} else if jsop == JSOp::Lt {
return DoubleCondition::LessThan;
} else if jsop == JSOp::Le {
return DoubleCondition::LessThanOrEqual;
} else if jsop == JSOp::Gt {
return DoubleCondition::GreaterThan;
} else if jsop == JSOp::Ge {
return DoubleCondition::GreaterThanOrEqual;
}
assert false;
return DoubleCondition::Ordered; // TODO(jlwoodwa): this workaround should not be necessary
}
}

struct Address {
base: Reg,
offset: Int32,
Expand Down Expand Up @@ -1750,6 +1791,71 @@ ir MASM {
}
}

op BranchDouble(condition: DoubleCondition, lhs: FloatReg, rhs: FloatReg, label branch: MASM) {
let lhsDouble = MASM::getDouble(lhs);
let rhsDouble = MASM::getDouble(rhs);

if condition == DoubleCondition::Ordered {
if Float64::ordered(lhsDouble, rhsDouble) {
goto branch;
}
} else if condition == DoubleCondition::Equal {
if Float64::equal(lhsDouble, rhsDouble) {
goto branch;
}
} else if condition == DoubleCondition::NotEqual {
if Float64::notEqual(lhsDouble, rhsDouble) {
goto branch;
}
} else if condition == DoubleCondition::GreaterThan {
if Float64::greaterThan(lhsDouble, rhsDouble) {
goto branch;
}
} else if condition == DoubleCondition::GreaterThanOrEqual {
if Float64::greaterThanOrEqual(lhsDouble, rhsDouble) {
goto branch;
}
} else if condition == DoubleCondition::LessThan {
if Float64::lessThan(lhsDouble, rhsDouble) {
goto branch;
}
} else if condition == DoubleCondition::LessThanOrEqual {
if Float64::lessThanOrEqual(lhsDouble, rhsDouble) {
goto branch;
}
} else if condition == DoubleCondition::Unordered {
if Float64::unordered(lhsDouble, rhsDouble) {
goto branch;
}
} else if condition == DoubleCondition::EqualOrUnordered {
if Float64::equalOrUnordered(lhsDouble, rhsDouble) {
goto branch;
}
} else if condition == DoubleCondition::NotEqualOrUnordered {
if Float64::notEqualOrUnordered(lhsDouble, rhsDouble) {
goto branch;
}
} else if condition == DoubleCondition::GreaterThanOrUnordered {
if Float64::greaterThanOrUnordered(lhsDouble, rhsDouble) {
goto branch;
}
} else if condition == DoubleCondition::GreaterThanOrEqualOrUnordered {
if Float64::greaterThanOrEqualOrUnordered(lhsDouble, rhsDouble) {
goto branch;
}
} else if condition == DoubleCondition::LessThanOrUnordered {
if Float64::lessThanOrUnordered(lhsDouble, rhsDouble) {
goto branch;
}
} else if condition == DoubleCondition::LessThanOrEqualOrUnordered {
if Float64::lessThanOrEqualOrUnordered(lhsDouble, rhsDouble) {
goto branch;
}
} else {
assert false;
}
}

op BranchAdd32(condition: Condition, srcReg: Reg, dstReg: Reg, label branch: MASM) {
let lhsInt32 = MASM::getInt32(srcReg);
let rhsInt32 = MASM::getInt32(dstReg);
Expand Down
15 changes: 15 additions & 0 deletions js/src/jit/cachet/VM.cachet
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,21 @@ impl Float64 {
}

unsafe fn fromUInt32Unchecked(uint32: UInt32) -> Float64;

fn ordered(lhs: Float64, rhs: Float64) -> Bool;
fn equal(lhs: Float64, rhs: Float64) -> Bool;
fn notEqual(lhs: Float64, rhs: Float64) -> Bool;
fn greaterThan(lhs: Float64, rhs: Float64) -> Bool;
fn greaterThanOrEqual(lhs: Float64, rhs: Float64) -> Bool;
fn lessThan(lhs: Float64, rhs: Float64) -> Bool;
fn lessThanOrEqual(lhs: Float64, rhs: Float64) -> Bool;
fn unordered(lhs: Float64, rhs: Float64) -> Bool;
fn equalOrUnordered(lhs: Float64, rhs: Float64) -> Bool;
fn notEqualOrUnordered(lhs: Float64, rhs: Float64) -> Bool;
fn greaterThanOrUnordered(lhs: Float64, rhs: Float64) -> Bool;
fn greaterThanOrEqualOrUnordered(lhs: Float64, rhs: Float64) -> Bool;
fn lessThanOrUnordered(lhs: Float64, rhs: Float64) -> Bool;
fn lessThanOrEqualOrUnordered(lhs: Float64, rhs: Float64) -> Bool;
}

struct Simd128;
Expand Down