summaryrefslogtreecommitdiff
path: root/deps/v8/src/arm64/codegen-arm64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/arm64/codegen-arm64.cc')
-rw-r--r--deps/v8/src/arm64/codegen-arm64.cc206
1 files changed, 12 insertions, 194 deletions
diff --git a/deps/v8/src/arm64/codegen-arm64.cc b/deps/v8/src/arm64/codegen-arm64.cc
index c2073f1f4b..edd289900e 100644
--- a/deps/v8/src/arm64/codegen-arm64.cc
+++ b/deps/v8/src/arm64/codegen-arm64.cc
@@ -15,66 +15,6 @@ namespace internal {
#define __ ACCESS_MASM(masm)
-#if defined(USE_SIMULATOR)
-byte* fast_exp_arm64_machine_code = nullptr;
-double fast_exp_simulator(double x, Isolate* isolate) {
- Simulator * simulator = Simulator::current(isolate);
- Simulator::CallArgument args[] = {
- Simulator::CallArgument(x),
- Simulator::CallArgument::End()
- };
- return simulator->CallDouble(fast_exp_arm64_machine_code, args);
-}
-#endif
-
-
-UnaryMathFunctionWithIsolate CreateExpFunction(Isolate* isolate) {
- // Use the Math.exp implemetation in MathExpGenerator::EmitMathExp() to create
- // an AAPCS64-compliant exp() function. This will be faster than the C
- // library's exp() function, but probably less accurate.
- size_t actual_size;
- byte* buffer =
- static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true));
- if (buffer == nullptr) return nullptr;
-
- ExternalReference::InitializeMathExpData();
- MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size),
- CodeObjectRequired::kNo);
- masm.SetStackPointer(csp);
-
- // The argument will be in d0 on entry.
- DoubleRegister input = d0;
- // Use other caller-saved registers for all other values.
- DoubleRegister result = d1;
- DoubleRegister double_temp1 = d2;
- DoubleRegister double_temp2 = d3;
- Register temp1 = x10;
- Register temp2 = x11;
- Register temp3 = x12;
-
- MathExpGenerator::EmitMathExp(&masm, input, result,
- double_temp1, double_temp2,
- temp1, temp2, temp3);
- // Move the result to the return register.
- masm.Fmov(d0, result);
- masm.Ret();
-
- CodeDesc desc;
- masm.GetCode(&desc);
- DCHECK(!RelocInfo::RequiresRelocation(desc));
-
- Assembler::FlushICache(isolate, buffer, actual_size);
- base::OS::ProtectCode(buffer, actual_size);
-
-#if !defined(USE_SIMULATOR)
- return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
-#else
- fast_exp_arm64_machine_code = buffer;
- return &fast_exp_simulator;
-#endif
-}
-
-
UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
return nullptr;
}
@@ -175,8 +115,8 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
Register map_root = array_size;
__ LoadRoot(map_root, Heap::kFixedDoubleArrayMapRootIndex);
__ SmiTag(x11, length);
- __ Str(x11, MemOperand(array, FixedDoubleArray::kLengthOffset));
- __ Str(map_root, MemOperand(array, HeapObject::kMapOffset));
+ __ Str(x11, FieldMemOperand(array, FixedDoubleArray::kLengthOffset));
+ __ Str(map_root, FieldMemOperand(array, HeapObject::kMapOffset));
__ Str(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
__ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, scratch,
@@ -184,18 +124,18 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
OMIT_SMI_CHECK);
// Replace receiver's backing store with newly created FixedDoubleArray.
- __ Add(x10, array, kHeapObjectTag);
- __ Str(x10, FieldMemOperand(receiver, JSObject::kElementsOffset));
- __ RecordWriteField(receiver, JSObject::kElementsOffset, x10,
- scratch, kLRHasBeenSaved, kDontSaveFPRegs,
- EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+ __ Move(x10, array);
+ __ Str(array, FieldMemOperand(receiver, JSObject::kElementsOffset));
+ __ RecordWriteField(receiver, JSObject::kElementsOffset, x10, scratch,
+ kLRHasBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
+ OMIT_SMI_CHECK);
// Prepare for conversion loop.
Register src_elements = x10;
Register dst_elements = x11;
Register dst_end = x12;
__ Add(src_elements, elements, FixedArray::kHeaderSize - kHeapObjectTag);
- __ Add(dst_elements, array, FixedDoubleArray::kHeaderSize);
+ __ Add(dst_elements, array, FixedDoubleArray::kHeaderSize - kHeapObjectTag);
__ Add(dst_end, dst_elements, Operand(length, LSL, kDoubleSizeLog2));
FPRegister nan_d = d1;
@@ -282,8 +222,8 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
Register map_root = array_size;
__ LoadRoot(map_root, Heap::kFixedArrayMapRootIndex);
__ SmiTag(x11, length);
- __ Str(x11, MemOperand(array, FixedDoubleArray::kLengthOffset));
- __ Str(map_root, MemOperand(array, HeapObject::kMapOffset));
+ __ Str(x11, FieldMemOperand(array, FixedDoubleArray::kLengthOffset));
+ __ Str(map_root, FieldMemOperand(array, HeapObject::kMapOffset));
// Prepare for conversion loop.
Register src_elements = x10;
@@ -293,7 +233,7 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
__ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex);
__ Add(src_elements, elements,
FixedDoubleArray::kHeaderSize - kHeapObjectTag);
- __ Add(dst_elements, array, FixedArray::kHeaderSize);
+ __ Add(dst_elements, array, FixedArray::kHeaderSize - kHeapObjectTag);
__ Add(dst_end, dst_elements, Operand(length, LSL, kPointerSizeLog2));
// Allocating heap numbers in the loop below can fail and cause a jump to
@@ -307,8 +247,7 @@ void ElementsTransitionGenerator::GenerateDoubleToObject(
__ Cmp(dst_elements, dst_end);
__ B(lt, &initialization_loop);
- __ Add(dst_elements, array, FixedArray::kHeaderSize);
- __ Add(array, array, kHeapObjectTag);
+ __ Add(dst_elements, array, FixedArray::kHeaderSize - kHeapObjectTag);
Register heap_num_map = x15;
__ LoadRoot(heap_num_map, Heap::kHeapNumberMapRootIndex);
@@ -511,127 +450,6 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm,
__ Bind(&done);
}
-
-static MemOperand ExpConstant(Register base, int index) {
- return MemOperand(base, index * kDoubleSize);
-}
-
-
-void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
- DoubleRegister input,
- DoubleRegister result,
- DoubleRegister double_temp1,
- DoubleRegister double_temp2,
- Register temp1,
- Register temp2,
- Register temp3) {
- // TODO(jbramley): There are several instances where fnmsub could be used
- // instead of fmul and fsub. Doing this changes the result, but since this is
- // an estimation anyway, does it matter?
-
- DCHECK(!AreAliased(input, result,
- double_temp1, double_temp2,
- temp1, temp2, temp3));
- DCHECK(ExternalReference::math_exp_constants(0).address() != NULL);
- DCHECK(!masm->serializer_enabled()); // External references not serializable.
-
- Label done;
- DoubleRegister double_temp3 = result;
- Register constants = temp3;
-
- // The algorithm used relies on some magic constants which are initialized in
- // ExternalReference::InitializeMathExpData().
-
- // Load the address of the start of the array.
- __ Mov(constants, ExternalReference::math_exp_constants(0));
-
- // We have to do a four-way split here:
- // - If input <= about -708.4, the output always rounds to zero.
- // - If input >= about 709.8, the output always rounds to +infinity.
- // - If the input is NaN, the output is NaN.
- // - Otherwise, the result needs to be calculated.
- Label result_is_finite_non_zero;
- // Assert that we can load offset 0 (the small input threshold) and offset 1
- // (the large input threshold) with a single ldp.
- DCHECK(kDRegSize == (ExpConstant(constants, 1).offset() -
- ExpConstant(constants, 0).offset()));
- __ Ldp(double_temp1, double_temp2, ExpConstant(constants, 0));
-
- __ Fcmp(input, double_temp1);
- __ Fccmp(input, double_temp2, NoFlag, hi);
- // At this point, the condition flags can be in one of five states:
- // NZCV
- // 1000 -708.4 < input < 709.8 result = exp(input)
- // 0110 input == 709.8 result = +infinity
- // 0010 input > 709.8 result = +infinity
- // 0011 input is NaN result = input
- // 0000 input <= -708.4 result = +0.0
-
- // Continue the common case first. 'mi' tests N == 1.
- __ B(&result_is_finite_non_zero, mi);
-
- // TODO(jbramley): Consider adding a +infinity register for ARM64.
- __ Ldr(double_temp2, ExpConstant(constants, 2)); // Synthesize +infinity.
-
- // Select between +0.0 and +infinity. 'lo' tests C == 0.
- __ Fcsel(result, fp_zero, double_temp2, lo);
- // Select between {+0.0 or +infinity} and input. 'vc' tests V == 0.
- __ Fcsel(result, result, input, vc);
- __ B(&done);
-
- // The rest is magic, as described in InitializeMathExpData().
- __ Bind(&result_is_finite_non_zero);
-
- // Assert that we can load offset 3 and offset 4 with a single ldp.
- DCHECK(kDRegSize == (ExpConstant(constants, 4).offset() -
- ExpConstant(constants, 3).offset()));
- __ Ldp(double_temp1, double_temp3, ExpConstant(constants, 3));
- __ Fmadd(double_temp1, double_temp1, input, double_temp3);
- __ Fmov(temp2.W(), double_temp1.S());
- __ Fsub(double_temp1, double_temp1, double_temp3);
-
- // Assert that we can load offset 5 and offset 6 with a single ldp.
- DCHECK(kDRegSize == (ExpConstant(constants, 6).offset() -
- ExpConstant(constants, 5).offset()));
- __ Ldp(double_temp2, double_temp3, ExpConstant(constants, 5));
- // TODO(jbramley): Consider using Fnmsub here.
- __ Fmul(double_temp1, double_temp1, double_temp2);
- __ Fsub(double_temp1, double_temp1, input);
-
- __ Fmul(double_temp2, double_temp1, double_temp1);
- __ Fsub(double_temp3, double_temp3, double_temp1);
- __ Fmul(double_temp3, double_temp3, double_temp2);
-
- __ Mov(temp1.W(), Operand(temp2.W(), LSR, 11));
-
- __ Ldr(double_temp2, ExpConstant(constants, 7));
- // TODO(jbramley): Consider using Fnmsub here.
- __ Fmul(double_temp3, double_temp3, double_temp2);
- __ Fsub(double_temp3, double_temp3, double_temp1);
-
- // The 8th constant is 1.0, so use an immediate move rather than a load.
- // We can't generate a runtime assertion here as we would need to call Abort
- // in the runtime and we don't have an Isolate when we generate this code.
- __ Fmov(double_temp2, 1.0);
- __ Fadd(double_temp3, double_temp3, double_temp2);
-
- __ And(temp2, temp2, 0x7ff);
- __ Add(temp1, temp1, 0x3ff);
-
- // Do the final table lookup.
- __ Mov(temp3, ExternalReference::math_exp_log_table());
-
- __ Add(temp3, temp3, Operand(temp2, LSL, kDRegSizeLog2));
- __ Ldp(temp2.W(), temp3.W(), MemOperand(temp3));
- __ Orr(temp1.W(), temp3.W(), Operand(temp1.W(), LSL, 20));
- __ Bfi(temp2, temp1, 32, 32);
- __ Fmov(double_temp1, temp2);
-
- __ Fmul(result, double_temp3, double_temp1);
-
- __ Bind(&done);
-}
-
#undef __
} // namespace internal