| 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) {
|
|
|