Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Unified Diff: src/compiler/code-stub-assembler.cc

Issue 1841993002: [builtins] Make Math.ceil, Math.trunc and Math.round optimizable. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/code-stub-assembler.h ('k') | src/compiler/js-builtin-reducer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/code-stub-assembler.cc
diff --git a/src/compiler/code-stub-assembler.cc b/src/compiler/code-stub-assembler.cc
index 104b123f3b241a17db2399464f4c91477b7f27bb..008b61ca5da9cbbc5ed3c00071adc514e0ee5fc9 100644
--- a/src/compiler/code-stub-assembler.cc
+++ b/src/compiler/code-stub-assembler.cc
@@ -47,8 +47,10 @@ CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone,
CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone,
CallDescriptor* call_descriptor,
Code::Flags flags, const char* name)
- : raw_assembler_(new RawMachineAssembler(isolate, new (zone) Graph(zone),
- call_descriptor)),
+ : raw_assembler_(new RawMachineAssembler(
+ isolate, new (zone) Graph(zone), call_descriptor,
+ MachineType::PointerRepresentation(),
+ InstructionSelector::SupportedMachineOperatorFlags())),
flags_(flags),
name_(name),
code_generated_(false),
@@ -152,110 +154,189 @@ Node* CodeStubAssembler::SmiShiftBitsConstant() {
return IntPtrConstant(kSmiShiftSize + kSmiTagSize);
}
+Node* CodeStubAssembler::Float64Round(Node* x) {
+ Node* one = Float64Constant(1.0);
+ Node* one_half = Float64Constant(0.5);
+
+ Variable var_x(this, MachineRepresentation::kFloat64);
+ Label return_x(this);
+
+ // Round up {x} towards Infinity.
+ var_x.Bind(Float64Ceil(x));
+
+ GotoIf(Float64LessThanOrEqual(Float64Sub(var_x.value(), one_half), x),
+ &return_x);
+ var_x.Bind(Float64Sub(var_x.value(), one));
+ Goto(&return_x);
+
+ Bind(&return_x);
+ return var_x.value();
+}
+
+Node* CodeStubAssembler::Float64Ceil(Node* x) {
+ if (raw_assembler_->machine()->Float64RoundUp().IsSupported()) {
+ return raw_assembler_->Float64RoundUp(x);
+ }
+
+ Node* one = Float64Constant(1.0);
+ Node* zero = Float64Constant(0.0);
+ Node* two_52 = Float64Constant(4503599627370496.0E0);
+ Node* minus_two_52 = Float64Constant(-4503599627370496.0E0);
+
+ Variable var_x(this, MachineRepresentation::kFloat64);
+ Label return_x(this), return_minus_x(this);
+ var_x.Bind(x);
+
+ // Check if {x} is greater than zero.
+ Label if_xgreaterthanzero(this), if_xnotgreaterthanzero(this);
+ Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero,
+ &if_xnotgreaterthanzero);
+
+ Bind(&if_xgreaterthanzero);
+ {
+ // Just return {x} unless it's in the range ]0,2^52[.
+ GotoIf(Float64GreaterThanOrEqual(x, two_52), &return_x);
+
+ // Round positive {x} towards Infinity.
+ var_x.Bind(Float64Sub(Float64Add(two_52, x), two_52));
+ GotoUnless(Float64LessThan(var_x.value(), x), &return_x);
+ var_x.Bind(Float64Add(var_x.value(), one));
+ Goto(&return_x);
+ }
+
+ Bind(&if_xnotgreaterthanzero);
+ {
+ // Just return {x} unless it's in the range ]-2^52,0[
+ GotoIf(Float64LessThanOrEqual(x, minus_two_52), &return_x);
+ GotoUnless(Float64LessThan(x, zero), &return_x);
+
+ // Round negated {x} towards Infinity and return the result negated.
+ Node* minus_x = Float64Neg(x);
+ var_x.Bind(Float64Sub(Float64Add(two_52, minus_x), two_52));
+ GotoUnless(Float64GreaterThan(var_x.value(), minus_x), &return_minus_x);
+ var_x.Bind(Float64Sub(var_x.value(), one));
+ Goto(&return_minus_x);
+ }
+
+ Bind(&return_minus_x);
+ var_x.Bind(Float64Neg(var_x.value()));
+ Goto(&return_x);
+
+ Bind(&return_x);
+ return var_x.value();
+}
+
Node* CodeStubAssembler::Float64Floor(Node* x) {
if (raw_assembler_->machine()->Float64RoundDown().IsSupported()) {
return raw_assembler_->Float64RoundDown(x);
}
+ Node* one = Float64Constant(1.0);
+ Node* zero = Float64Constant(0.0);
Node* two_52 = Float64Constant(4503599627370496.0E0);
Node* minus_two_52 = Float64Constant(-4503599627370496.0E0);
Variable var_x(this, MachineRepresentation::kFloat64);
+ Label return_x(this), return_minus_x(this);
var_x.Bind(x);
- Label return_x(this);
-
- // Check if {x} is a large positive integer.
- Label if_xlargeposint(this), if_xnotlargeposint(this);
- Branch(Float64GreaterThanOrEqual(x, two_52), &if_xlargeposint,
- &if_xnotlargeposint);
+ // Check if {x} is greater than zero.
+ Label if_xgreaterthanzero(this), if_xnotgreaterthanzero(this);
+ Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero,
+ &if_xnotgreaterthanzero);
- Bind(&if_xlargeposint);
+ Bind(&if_xgreaterthanzero);
{
- // The {x} is already an even integer.
+ // Just return {x} unless it's in the range ]0,2^52[.
+ GotoIf(Float64GreaterThanOrEqual(x, two_52), &return_x);
+
+ // Round positive {x} towards -Infinity.
+ var_x.Bind(Float64Sub(Float64Add(two_52, x), two_52));
+ GotoUnless(Float64GreaterThan(var_x.value(), x), &return_x);
+ var_x.Bind(Float64Sub(var_x.value(), one));
Goto(&return_x);
}
- Bind(&if_xnotlargeposint);
+ Bind(&if_xnotgreaterthanzero);
{
- // Check if {x} is negative.
- Label if_xnegative(this), if_xpositive(this);
- Branch(Float64LessThan(x, Float64Constant(0.0)), &if_xnegative,
- &if_xpositive);
-
- Bind(&if_xnegative);
- {
- // Check if {x} is a large negative integer.
- Label if_xlargenegint(this), if_xnotlargenegint(this);
- Branch(Float64LessThanOrEqual(x, minus_two_52), &if_xlargenegint,
- &if_xnotlargenegint);
+ // Just return {x} unless it's in the range ]-2^52,0[
+ GotoIf(Float64LessThanOrEqual(x, minus_two_52), &return_x);
+ GotoUnless(Float64LessThan(x, zero), &return_x);
+
+ // Round negated {x} towards -Infinity and return the result negated.
+ Node* minus_x = Float64Neg(x);
+ var_x.Bind(Float64Sub(Float64Add(two_52, minus_x), two_52));
+ GotoUnless(Float64LessThan(var_x.value(), minus_x), &return_minus_x);
+ var_x.Bind(Float64Add(var_x.value(), one));
+ Goto(&return_minus_x);
+ }
- Bind(&if_xlargenegint);
- {
- // The {x} is already an even integer.
- Goto(&return_x);
- }
+ Bind(&return_minus_x);
+ var_x.Bind(Float64Neg(var_x.value()));
+ Goto(&return_x);
- Bind(&if_xnotlargenegint);
- {
- // Round negative {x} towards -Infinity.
- Node* z = Float64Sub(Float64Constant(-0.0), x);
- Node* y = Float64Sub(Float64Add(two_52, z), two_52);
-
- // Check if we need to adjust {y}.
- Label if_adjust(this), if_notadjust(this);
- Branch(Float64GreaterThan(z, y), &if_adjust, &if_notadjust);
-
- Bind(&if_adjust);
- {
- var_x.Bind(Float64Sub(Float64Constant(-1.0), y));
- Goto(&return_x);
- }
+ Bind(&return_x);
+ return var_x.value();
+}
- Bind(&if_notadjust);
- {
- var_x.Bind(Float64Sub(Float64Constant(-0.0), y));
- Goto(&return_x);
- }
- }
- }
+Node* CodeStubAssembler::Float64Trunc(Node* x) {
+ if (raw_assembler_->machine()->Float64RoundTruncate().IsSupported()) {
+ return raw_assembler_->Float64RoundTruncate(x);
+ }
- Bind(&if_xpositive);
- {
- // Check if {x} is zero (either positive or negative).
- Label if_xzero(this), if_xnotzero(this);
- Branch(Float64Equal(x, Float64Constant(0.0)), &if_xzero, &if_xnotzero);
+ Node* one = Float64Constant(1.0);
+ Node* zero = Float64Constant(0.0);
+ Node* two_52 = Float64Constant(4503599627370496.0E0);
+ Node* minus_two_52 = Float64Constant(-4503599627370496.0E0);
- Bind(&if_xzero);
- {
- // We have to return both 0.0 and -0.0 as is.
- Goto(&return_x);
- }
+ Variable var_x(this, MachineRepresentation::kFloat64);
+ Label return_x(this), return_minus_x(this);
+ var_x.Bind(x);
- Bind(&if_xnotzero);
- {
- // Round positive {x} towards -Infinity.
- Node* y = Float64Sub(Float64Add(two_52, x), two_52);
+ // Check if {x} is greater than 0.
+ Label if_xgreaterthanzero(this), if_xnotgreaterthanzero(this);
+ Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero,
+ &if_xnotgreaterthanzero);
- // Check if we need to adjust {y}.
- Label if_adjust(this), if_notadjust(this);
- Branch(Float64LessThan(x, y), &if_adjust, &if_notadjust);
+ Bind(&if_xgreaterthanzero);
+ {
+ if (raw_assembler_->machine()->Float64RoundDown().IsSupported()) {
+ var_x.Bind(raw_assembler_->Float64RoundDown(x));
+ } else {
+ // Just return {x} unless it's in the range ]0,2^52[.
+ GotoIf(Float64GreaterThanOrEqual(x, two_52), &return_x);
- Bind(&if_adjust);
- {
- var_x.Bind(Float64Sub(y, Float64Constant(1.0)));
- Goto(&return_x);
- }
+ // Round positive {x} towards -Infinity.
+ var_x.Bind(Float64Sub(Float64Add(two_52, x), two_52));
+ GotoUnless(Float64GreaterThan(var_x.value(), x), &return_x);
+ var_x.Bind(Float64Sub(var_x.value(), one));
+ }
+ Goto(&return_x);
+ }
- Bind(&if_notadjust);
- {
- var_x.Bind(y);
- Goto(&return_x);
- }
- }
+ Bind(&if_xnotgreaterthanzero);
+ {
+ if (raw_assembler_->machine()->Float64RoundUp().IsSupported()) {
+ var_x.Bind(raw_assembler_->Float64RoundUp(x));
+ Goto(&return_x);
+ } else {
+ // Just return {x} unless its in the range ]-2^52,0[.
+ GotoIf(Float64LessThanOrEqual(x, minus_two_52), &return_x);
+ GotoUnless(Float64LessThan(x, zero), &return_x);
+
+ // Round negated {x} towards -Infinity and return result negated.
+ Node* minus_x = Float64Neg(x);
+ var_x.Bind(Float64Sub(Float64Add(two_52, minus_x), two_52));
+ GotoUnless(Float64GreaterThan(var_x.value(), minus_x), &return_minus_x);
+ var_x.Bind(Float64Sub(var_x.value(), one));
+ Goto(&return_minus_x);
}
}
+ Bind(&return_minus_x);
+ var_x.Bind(Float64Neg(var_x.value()));
+ Goto(&return_x);
+
Bind(&return_x);
return var_x.value();
}
@@ -1036,6 +1117,18 @@ void CodeStubAssembler::Goto(CodeStubAssembler::Label* label) {
raw_assembler_->Goto(label->label_);
}
+void CodeStubAssembler::GotoIf(Node* condition, Label* true_label) {
+ Label false_label(this);
+ Branch(condition, true_label, &false_label);
+ Bind(&false_label);
+}
+
+void CodeStubAssembler::GotoUnless(Node* condition, Label* false_label) {
+ Label true_label(this);
+ Branch(condition, &true_label, false_label);
+ Bind(&true_label);
+}
+
void CodeStubAssembler::Branch(Node* condition,
CodeStubAssembler::Label* true_label,
CodeStubAssembler::Label* false_label) {
« no previous file with comments | « src/compiler/code-stub-assembler.h ('k') | src/compiler/js-builtin-reducer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698