summaryrefslogtreecommitdiff
path: root/deps/v8/src/arm/macro-assembler-arm.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/arm/macro-assembler-arm.cc')
-rw-r--r--deps/v8/src/arm/macro-assembler-arm.cc987
1 files changed, 350 insertions, 637 deletions
diff --git a/deps/v8/src/arm/macro-assembler-arm.cc b/deps/v8/src/arm/macro-assembler-arm.cc
index 7256086b1d..4fda72574a 100644
--- a/deps/v8/src/arm/macro-assembler-arm.cc
+++ b/deps/v8/src/arm/macro-assembler-arm.cc
@@ -14,6 +14,7 @@
#include "src/codegen.h"
#include "src/counters.h"
#include "src/debug/debug.h"
+#include "src/double.h"
#include "src/objects-inl.h"
#include "src/register-configuration.h"
#include "src/runtime/runtime.h"
@@ -25,55 +26,39 @@ namespace internal {
MacroAssembler::MacroAssembler(Isolate* isolate, void* buffer, int size,
CodeObjectRequired create_code_object)
- : Assembler(isolate, buffer, size),
- generating_stub_(false),
- has_frame_(false),
- isolate_(isolate),
+ : TurboAssembler(isolate, buffer, size, create_code_object),
jit_cookie_(0) {
if (FLAG_mask_constants_with_cookie) {
jit_cookie_ = isolate->random_number_generator()->NextInt();
}
- if (create_code_object == CodeObjectRequired::kYes) {
- code_object_ =
- Handle<Object>::New(isolate_->heap()->undefined_value(), isolate_);
- }
}
+void TurboAssembler::Jump(Register target, Condition cond) { bx(target, cond); }
-void MacroAssembler::Jump(Register target, Condition cond) {
- bx(target, cond);
-}
-
-
-void MacroAssembler::Jump(intptr_t target, RelocInfo::Mode rmode,
+void TurboAssembler::Jump(intptr_t target, RelocInfo::Mode rmode,
Condition cond) {
DCHECK(RelocInfo::IsCodeTarget(rmode));
mov(pc, Operand(target, rmode), LeaveCC, cond);
}
-
-void MacroAssembler::Jump(Address target, RelocInfo::Mode rmode,
+void TurboAssembler::Jump(Address target, RelocInfo::Mode rmode,
Condition cond) {
DCHECK(!RelocInfo::IsCodeTarget(rmode));
Jump(reinterpret_cast<intptr_t>(target), rmode, cond);
}
-
-void MacroAssembler::Jump(Handle<Code> code, RelocInfo::Mode rmode,
+void TurboAssembler::Jump(Handle<Code> code, RelocInfo::Mode rmode,
Condition cond) {
DCHECK(RelocInfo::IsCodeTarget(rmode));
// 'code' is always generated ARM code, never THUMB code
- AllowDeferredHandleDereference embedding_raw_address;
- Jump(reinterpret_cast<intptr_t>(code.location()), rmode, cond);
+ Jump(reinterpret_cast<intptr_t>(code.address()), rmode, cond);
}
-
-int MacroAssembler::CallSize(Register target, Condition cond) {
+int TurboAssembler::CallSize(Register target, Condition cond) {
return kInstrSize;
}
-
-void MacroAssembler::Call(Register target, Condition cond) {
+void TurboAssembler::Call(Register target, Condition cond) {
// Block constant pool for the call instruction sequence.
BlockConstPoolScope block_const_pool(this);
Label start;
@@ -82,22 +67,19 @@ void MacroAssembler::Call(Register target, Condition cond) {
DCHECK_EQ(CallSize(target, cond), SizeOfCodeGeneratedSince(&start));
}
-
-int MacroAssembler::CallSize(
- Address target, RelocInfo::Mode rmode, Condition cond) {
+int TurboAssembler::CallSize(Address target, RelocInfo::Mode rmode,
+ Condition cond) {
Instr mov_instr = cond | MOV | LeaveCC;
Operand mov_operand = Operand(reinterpret_cast<intptr_t>(target), rmode);
return kInstrSize +
- mov_operand.instructions_required(this, mov_instr) * kInstrSize;
+ mov_operand.InstructionsRequired(this, mov_instr) * kInstrSize;
}
-
-int MacroAssembler::CallStubSize(
- CodeStub* stub, TypeFeedbackId ast_id, Condition cond) {
- return CallSize(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id, cond);
+int TurboAssembler::CallStubSize() {
+ return CallSize(Handle<Code>(), RelocInfo::CODE_TARGET, al);
}
-void MacroAssembler::Call(Address target, RelocInfo::Mode rmode, Condition cond,
+void TurboAssembler::Call(Address target, RelocInfo::Mode rmode, Condition cond,
TargetAddressStorageMode mode,
bool check_constant_pool) {
// Check if we have to emit the constant pool before we block it.
@@ -118,6 +100,9 @@ void MacroAssembler::Call(Address target, RelocInfo::Mode rmode, Condition cond,
int expected_size = CallSize(target, rmode, cond);
#endif
+ // Use ip directly instead of using UseScratchRegisterScope, as we do not
+ // preserve scratch registers across calls.
+
// Call sequence on V7 or later may be :
// movw ip, #... @ call address low 16
// movt ip, #... @ call address high 16
@@ -138,29 +123,17 @@ void MacroAssembler::Call(Address target, RelocInfo::Mode rmode, Condition cond,
}
}
-
-int MacroAssembler::CallSize(Handle<Code> code,
- RelocInfo::Mode rmode,
- TypeFeedbackId ast_id,
+int TurboAssembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode,
Condition cond) {
- AllowDeferredHandleDereference using_raw_address;
- return CallSize(reinterpret_cast<Address>(code.location()), rmode, cond);
+ return CallSize(code.address(), rmode, cond);
}
-void MacroAssembler::Call(Handle<Code> code, RelocInfo::Mode rmode,
- TypeFeedbackId ast_id, Condition cond,
- TargetAddressStorageMode mode,
+void TurboAssembler::Call(Handle<Code> code, RelocInfo::Mode rmode,
+ Condition cond, TargetAddressStorageMode mode,
bool check_constant_pool) {
- Label start;
- bind(&start);
DCHECK(RelocInfo::IsCodeTarget(rmode));
- if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) {
- SetRecordedAstId(ast_id);
- rmode = RelocInfo::CODE_TARGET_WITH_ID;
- }
// 'code' is always generated ARM code, never THUMB code
- AllowDeferredHandleDereference embedding_raw_address;
- Call(reinterpret_cast<Address>(code.location()), rmode, cond, mode);
+ Call(code.address(), rmode, cond, mode);
}
void MacroAssembler::CallDeoptimizer(Address target) {
@@ -168,6 +141,9 @@ void MacroAssembler::CallDeoptimizer(Address target) {
uintptr_t target_raw = reinterpret_cast<uintptr_t>(target);
+ // Use ip directly instead of using UseScratchRegisterScope, as we do not
+ // preserve scratch registers across calls.
+
// We use blx, like a call, but it does not return here. The link register is
// used by the deoptimizer to work out what called it.
if (CpuFeatures::IsSupported(ARMv7)) {
@@ -198,22 +174,19 @@ int MacroAssembler::CallDeoptimizerSize() {
return 3 * kInstrSize;
}
-void MacroAssembler::Ret(Condition cond) {
- bx(lr, cond);
-}
-
+void TurboAssembler::Ret(Condition cond) { bx(lr, cond); }
-void MacroAssembler::Drop(int count, Condition cond) {
+void TurboAssembler::Drop(int count, Condition cond) {
if (count > 0) {
add(sp, sp, Operand(count * kPointerSize), LeaveCC, cond);
}
}
-void MacroAssembler::Drop(Register count, Condition cond) {
+void TurboAssembler::Drop(Register count, Condition cond) {
add(sp, sp, Operand(count, LSL, kPointerSizeLog2), LeaveCC, cond);
}
-void MacroAssembler::Ret(int drop, Condition cond) {
+void TurboAssembler::Ret(int drop, Condition cond) {
Drop(drop, cond);
Ret(cond);
}
@@ -234,53 +207,63 @@ void MacroAssembler::Swap(Register reg1,
}
}
+void TurboAssembler::Call(Label* target) { bl(target); }
-void MacroAssembler::Call(Label* target) {
- bl(target);
+void TurboAssembler::Push(Handle<HeapObject> handle) {
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ mov(scratch, Operand(handle));
+ push(scratch);
}
-
-void MacroAssembler::Push(Handle<Object> handle) {
- mov(ip, Operand(handle));
- push(ip);
+void TurboAssembler::Push(Smi* smi) {
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ mov(scratch, Operand(smi));
+ push(scratch);
}
-void MacroAssembler::Push(Smi* smi) { Push(Handle<Smi>(smi, isolate())); }
+void MacroAssembler::PushObject(Handle<Object> handle) {
+ if (handle->IsHeapObject()) {
+ Push(Handle<HeapObject>::cast(handle));
+ } else {
+ Push(Smi::cast(*handle));
+ }
+}
-void MacroAssembler::Move(Register dst, Smi* smi) { mov(dst, Operand(smi)); }
+void TurboAssembler::Move(Register dst, Smi* smi) { mov(dst, Operand(smi)); }
-void MacroAssembler::Move(Register dst, Handle<Object> value) {
+void TurboAssembler::Move(Register dst, Handle<HeapObject> value) {
mov(dst, Operand(value));
}
-
-void MacroAssembler::Move(Register dst, Register src, Condition cond) {
+void TurboAssembler::Move(Register dst, Register src, Condition cond) {
if (!dst.is(src)) {
mov(dst, src, LeaveCC, cond);
}
}
-void MacroAssembler::Move(SwVfpRegister dst, SwVfpRegister src,
+void TurboAssembler::Move(SwVfpRegister dst, SwVfpRegister src,
Condition cond) {
if (!dst.is(src)) {
vmov(dst, src, cond);
}
}
-void MacroAssembler::Move(DwVfpRegister dst, DwVfpRegister src,
+void TurboAssembler::Move(DwVfpRegister dst, DwVfpRegister src,
Condition cond) {
if (!dst.is(src)) {
vmov(dst, src, cond);
}
}
-void MacroAssembler::Move(QwNeonRegister dst, QwNeonRegister src) {
+void TurboAssembler::Move(QwNeonRegister dst, QwNeonRegister src) {
if (!dst.is(src)) {
vmov(dst, src);
}
}
-void MacroAssembler::Swap(DwVfpRegister srcdst0, DwVfpRegister srcdst1) {
+void TurboAssembler::Swap(DwVfpRegister srcdst0, DwVfpRegister srcdst1) {
if (srcdst0.is(srcdst1)) return; // Swapping aliased registers emits nothing.
DCHECK(VfpRegisterIsAvailable(srcdst0));
@@ -297,7 +280,7 @@ void MacroAssembler::Swap(DwVfpRegister srcdst0, DwVfpRegister srcdst1) {
}
}
-void MacroAssembler::Swap(QwNeonRegister srcdst0, QwNeonRegister srcdst1) {
+void TurboAssembler::Swap(QwNeonRegister srcdst0, QwNeonRegister srcdst1) {
if (!srcdst0.is(srcdst1)) {
vswp(srcdst0, srcdst1);
}
@@ -309,23 +292,24 @@ void MacroAssembler::Mls(Register dst, Register src1, Register src2,
CpuFeatureScope scope(this, ARMv7);
mls(dst, src1, src2, srcA, cond);
} else {
- DCHECK(!srcA.is(ip));
- mul(ip, src1, src2, LeaveCC, cond);
- sub(dst, srcA, ip, LeaveCC, cond);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ DCHECK(!srcA.is(scratch));
+ mul(scratch, src1, src2, LeaveCC, cond);
+ sub(dst, srcA, scratch, LeaveCC, cond);
}
}
void MacroAssembler::And(Register dst, Register src1, const Operand& src2,
Condition cond) {
- if (!src2.is_reg() &&
- !src2.must_output_reloc_info(this) &&
+ if (!src2.IsRegister() && !src2.MustOutputRelocInfo(this) &&
src2.immediate() == 0) {
mov(dst, Operand::Zero(), LeaveCC, cond);
- } else if (!(src2.instructions_required(this) == 1) &&
- !src2.must_output_reloc_info(this) &&
+ } else if (!(src2.InstructionsRequired(this) == 1) &&
+ !src2.MustOutputRelocInfo(this) &&
CpuFeatures::IsSupported(ARMv7) &&
- base::bits::IsPowerOfTwo32(src2.immediate() + 1)) {
+ base::bits::IsPowerOfTwo(src2.immediate() + 1)) {
CpuFeatureScope scope(this, ARMv7);
ubfx(dst, src1, 0,
WhichPowerOf2(static_cast<uint32_t>(src2.immediate()) + 1), cond);
@@ -395,8 +379,7 @@ void MacroAssembler::Bfi(Register dst,
}
}
-
-void MacroAssembler::Bfc(Register dst, Register src, int lsb, int width,
+void TurboAssembler::Bfc(Register dst, Register src, int lsb, int width,
Condition cond) {
DCHECK(lsb < 32);
if (!CpuFeatures::IsSupported(ARMv7) || predictable_code_size()) {
@@ -446,9 +429,7 @@ void MacroAssembler::Store(Register src,
}
}
-
-void MacroAssembler::LoadRoot(Register destination,
- Heap::RootListIndex index,
+void TurboAssembler::LoadRoot(Register destination, Heap::RootListIndex index,
Condition cond) {
ldr(destination, MemOperand(kRootRegister, index << kPointerSizeLog2), cond);
}
@@ -522,9 +503,8 @@ void MacroAssembler::RecordWriteField(
}
}
-
-// Will clobber 4 registers: object, map, dst, ip. The
-// register 'object' contains a heap object pointer.
+// Will clobber 3 registers: object, map and dst. The register 'object' contains
+// a heap object pointer. A scratch register also needs to be available.
void MacroAssembler::RecordWriteForMap(Register object,
Register map,
Register dst,
@@ -541,8 +521,10 @@ void MacroAssembler::RecordWriteForMap(Register object,
}
if (emit_debug_code()) {
- ldr(ip, FieldMemOperand(object, HeapObject::kMapOffset));
- cmp(ip, map);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ ldr(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
+ cmp(scratch, map);
Check(eq, kWrongAddressOrValuePassedToRecordWrite);
}
@@ -582,7 +564,11 @@ void MacroAssembler::RecordWriteForMap(Register object,
// Count number of write barriers in generated code.
isolate()->counters()->write_barriers_static()->Increment();
- IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1, ip, dst);
+ {
+ UseScratchRegisterScope temps(this);
+ IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1,
+ temps.Acquire(), dst);
+ }
// Clobber clobbered registers when running with the debug-code flag
// turned on to provoke errors.
@@ -592,10 +578,9 @@ void MacroAssembler::RecordWriteForMap(Register object,
}
}
-
-// Will clobber 4 registers: object, address, scratch, ip. The
-// register 'object' contains a heap object pointer. The heap object
-// tag is shifted away.
+// Will clobber 3 registers: object, address, and value. The register 'object'
+// contains a heap object pointer. The heap object tag is shifted away.
+// A scratch register also needs to be available.
void MacroAssembler::RecordWrite(
Register object,
Register address,
@@ -607,8 +592,10 @@ void MacroAssembler::RecordWrite(
PointersToHereCheck pointers_to_here_check_for_value) {
DCHECK(!object.is(value));
if (emit_debug_code()) {
- ldr(ip, MemOperand(address));
- cmp(ip, value);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ ldr(scratch, MemOperand(address));
+ cmp(scratch, value);
Check(eq, kWrongAddressOrValuePassedToRecordWrite);
}
@@ -653,8 +640,11 @@ void MacroAssembler::RecordWrite(
// Count number of write barriers in generated code.
isolate()->counters()->write_barriers_static()->Increment();
- IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1, ip,
- value);
+ {
+ UseScratchRegisterScope temps(this);
+ IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1,
+ temps.Acquire(), value);
+ }
// Clobber clobbered registers when running with the debug-code flag
// turned on to provoke errors.
@@ -681,8 +671,8 @@ void MacroAssembler::RecordWriteCodeEntryField(Register js_function,
if (emit_debug_code()) {
add(scratch, js_function, Operand(offset - kHeapObjectTag));
- ldr(ip, MemOperand(scratch));
- cmp(ip, code_entry);
+ ldr(scratch, MemOperand(scratch));
+ cmp(scratch, code_entry);
Check(eq, kWrongAddressOrValuePassedToRecordWrite);
}
@@ -706,7 +696,7 @@ void MacroAssembler::RecordWriteCodeEntryField(Register js_function,
stm(db_w, sp, (kCallerSaved | lr.bit()));
int argument_count = 3;
- PrepareCallCFunction(argument_count, code_entry);
+ PrepareCallCFunction(argument_count);
mov(r0, js_function);
mov(r1, dst);
@@ -741,14 +731,16 @@ void MacroAssembler::RememberedSetHelper(Register object, // For debug tests.
bind(&ok);
}
// Load store buffer top.
- ExternalReference store_buffer =
- ExternalReference::store_buffer_top(isolate());
- mov(ip, Operand(store_buffer));
- ldr(scratch, MemOperand(ip));
- // Store pointer to buffer and increment buffer top.
- str(address, MemOperand(scratch, kPointerSize, PostIndex));
- // Write back new top of buffer.
- str(scratch, MemOperand(ip));
+ {
+ UseScratchRegisterScope temps(this);
+ Register store_buffer = temps.Acquire();
+ mov(store_buffer, Operand(ExternalReference::store_buffer_top(isolate())));
+ ldr(scratch, MemOperand(store_buffer));
+ // Store pointer to buffer and increment buffer top.
+ str(address, MemOperand(scratch, kPointerSize, PostIndex));
+ // Write back new top of buffer.
+ str(scratch, MemOperand(store_buffer));
+ }
// Call stub on end of buffer.
// Check for end of buffer.
tst(scratch, Operand(StoreBuffer::kStoreBufferMask));
@@ -768,7 +760,7 @@ void MacroAssembler::RememberedSetHelper(Register object, // For debug tests.
}
}
-void MacroAssembler::PushCommonFrame(Register marker_reg) {
+void TurboAssembler::PushCommonFrame(Register marker_reg) {
if (marker_reg.is_valid()) {
if (marker_reg.code() > fp.code()) {
stm(db_w, sp, fp.bit() | lr.bit());
@@ -797,7 +789,7 @@ void MacroAssembler::PopCommonFrame(Register marker_reg) {
}
}
-void MacroAssembler::PushStandardFrame(Register function_reg) {
+void TurboAssembler::PushStandardFrame(Register function_reg) {
DCHECK(!function_reg.is_valid() || function_reg.code() < cp.code());
stm(db_w, sp, (function_reg.is_valid() ? function_reg.bit() : 0) | cp.bit() |
fp.bit() | lr.bit());
@@ -927,7 +919,7 @@ void MacroAssembler::Strd(Register src1, Register src2,
}
}
-void MacroAssembler::VFPCanonicalizeNaN(const DwVfpRegister dst,
+void TurboAssembler::VFPCanonicalizeNaN(const DwVfpRegister dst,
const DwVfpRegister src,
const Condition cond) {
// Subtracting 0.0 preserves all inputs except for signalling NaNs, which
@@ -936,38 +928,35 @@ void MacroAssembler::VFPCanonicalizeNaN(const DwVfpRegister dst,
vsub(dst, src, kDoubleRegZero, cond);
}
-
-void MacroAssembler::VFPCompareAndSetFlags(const SwVfpRegister src1,
+void TurboAssembler::VFPCompareAndSetFlags(const SwVfpRegister src1,
const SwVfpRegister src2,
const Condition cond) {
// Compare and move FPSCR flags to the normal condition flags.
VFPCompareAndLoadFlags(src1, src2, pc, cond);
}
-void MacroAssembler::VFPCompareAndSetFlags(const SwVfpRegister src1,
+void TurboAssembler::VFPCompareAndSetFlags(const SwVfpRegister src1,
const float src2,
const Condition cond) {
// Compare and move FPSCR flags to the normal condition flags.
VFPCompareAndLoadFlags(src1, src2, pc, cond);
}
-
-void MacroAssembler::VFPCompareAndSetFlags(const DwVfpRegister src1,
+void TurboAssembler::VFPCompareAndSetFlags(const DwVfpRegister src1,
const DwVfpRegister src2,
const Condition cond) {
// Compare and move FPSCR flags to the normal condition flags.
VFPCompareAndLoadFlags(src1, src2, pc, cond);
}
-void MacroAssembler::VFPCompareAndSetFlags(const DwVfpRegister src1,
+void TurboAssembler::VFPCompareAndSetFlags(const DwVfpRegister src1,
const double src2,
const Condition cond) {
// Compare and move FPSCR flags to the normal condition flags.
VFPCompareAndLoadFlags(src1, src2, pc, cond);
}
-
-void MacroAssembler::VFPCompareAndLoadFlags(const SwVfpRegister src1,
+void TurboAssembler::VFPCompareAndLoadFlags(const SwVfpRegister src1,
const SwVfpRegister src2,
const Register fpscr_flags,
const Condition cond) {
@@ -976,7 +965,7 @@ void MacroAssembler::VFPCompareAndLoadFlags(const SwVfpRegister src1,
vmrs(fpscr_flags, cond);
}
-void MacroAssembler::VFPCompareAndLoadFlags(const SwVfpRegister src1,
+void TurboAssembler::VFPCompareAndLoadFlags(const SwVfpRegister src1,
const float src2,
const Register fpscr_flags,
const Condition cond) {
@@ -985,8 +974,7 @@ void MacroAssembler::VFPCompareAndLoadFlags(const SwVfpRegister src1,
vmrs(fpscr_flags, cond);
}
-
-void MacroAssembler::VFPCompareAndLoadFlags(const DwVfpRegister src1,
+void TurboAssembler::VFPCompareAndLoadFlags(const DwVfpRegister src1,
const DwVfpRegister src2,
const Register fpscr_flags,
const Condition cond) {
@@ -995,7 +983,7 @@ void MacroAssembler::VFPCompareAndLoadFlags(const DwVfpRegister src1,
vmrs(fpscr_flags, cond);
}
-void MacroAssembler::VFPCompareAndLoadFlags(const DwVfpRegister src1,
+void TurboAssembler::VFPCompareAndLoadFlags(const DwVfpRegister src1,
const double src2,
const Register fpscr_flags,
const Condition cond) {
@@ -1004,23 +992,20 @@ void MacroAssembler::VFPCompareAndLoadFlags(const DwVfpRegister src1,
vmrs(fpscr_flags, cond);
}
-
-void MacroAssembler::Vmov(const DwVfpRegister dst,
- const double imm,
+void MacroAssembler::Vmov(const DwVfpRegister dst, Double imm,
const Register scratch) {
- int64_t imm_bits = bit_cast<int64_t>(imm);
+ uint64_t imm_bits = imm.AsUint64();
// Handle special values first.
- if (imm_bits == bit_cast<int64_t>(0.0)) {
+ if (imm_bits == Double(0.0).AsUint64()) {
vmov(dst, kDoubleRegZero);
- } else if (imm_bits == bit_cast<int64_t>(-0.0)) {
+ } else if (imm_bits == Double(-0.0).AsUint64()) {
vneg(dst, kDoubleRegZero);
} else {
vmov(dst, imm, scratch);
}
}
-
-void MacroAssembler::VmovHigh(Register dst, DwVfpRegister src) {
+void TurboAssembler::VmovHigh(Register dst, DwVfpRegister src) {
if (src.code() < 16) {
const LowDwVfpRegister loc = LowDwVfpRegister::from_code(src.code());
vmov(dst, loc.high());
@@ -1029,8 +1014,7 @@ void MacroAssembler::VmovHigh(Register dst, DwVfpRegister src) {
}
}
-
-void MacroAssembler::VmovHigh(DwVfpRegister dst, Register src) {
+void TurboAssembler::VmovHigh(DwVfpRegister dst, Register src) {
if (dst.code() < 16) {
const LowDwVfpRegister loc = LowDwVfpRegister::from_code(dst.code());
vmov(loc.high(), src);
@@ -1039,8 +1023,7 @@ void MacroAssembler::VmovHigh(DwVfpRegister dst, Register src) {
}
}
-
-void MacroAssembler::VmovLow(Register dst, DwVfpRegister src) {
+void TurboAssembler::VmovLow(Register dst, DwVfpRegister src) {
if (src.code() < 16) {
const LowDwVfpRegister loc = LowDwVfpRegister::from_code(src.code());
vmov(dst, loc.low());
@@ -1049,8 +1032,7 @@ void MacroAssembler::VmovLow(Register dst, DwVfpRegister src) {
}
}
-
-void MacroAssembler::VmovLow(DwVfpRegister dst, Register src) {
+void TurboAssembler::VmovLow(DwVfpRegister dst, Register src) {
if (dst.code() < 16) {
const LowDwVfpRegister loc = LowDwVfpRegister::from_code(dst.code());
vmov(loc.low(), src);
@@ -1059,7 +1041,7 @@ void MacroAssembler::VmovLow(DwVfpRegister dst, Register src) {
}
}
-void MacroAssembler::VmovExtended(Register dst, int src_code) {
+void TurboAssembler::VmovExtended(Register dst, int src_code) {
DCHECK_LE(SwVfpRegister::kMaxNumRegisters, src_code);
DCHECK_GT(SwVfpRegister::kMaxNumRegisters * 2, src_code);
if (src_code & 0x1) {
@@ -1069,7 +1051,7 @@ void MacroAssembler::VmovExtended(Register dst, int src_code) {
}
}
-void MacroAssembler::VmovExtended(int dst_code, Register src) {
+void TurboAssembler::VmovExtended(int dst_code, Register src) {
DCHECK_LE(SwVfpRegister::kMaxNumRegisters, dst_code);
DCHECK_GT(SwVfpRegister::kMaxNumRegisters * 2, dst_code);
if (dst_code & 0x1) {
@@ -1079,7 +1061,7 @@ void MacroAssembler::VmovExtended(int dst_code, Register src) {
}
}
-void MacroAssembler::VmovExtended(int dst_code, int src_code) {
+void TurboAssembler::VmovExtended(int dst_code, int src_code) {
if (src_code == dst_code) return;
if (src_code < SwVfpRegister::kMaxNumRegisters &&
@@ -1143,7 +1125,7 @@ void MacroAssembler::VmovExtended(int dst_code, int src_code) {
}
}
-void MacroAssembler::VmovExtended(int dst_code, const MemOperand& src) {
+void TurboAssembler::VmovExtended(int dst_code, const MemOperand& src) {
if (dst_code < SwVfpRegister::kMaxNumRegisters) {
vldr(SwVfpRegister::from_code(dst_code), src);
} else {
@@ -1155,7 +1137,7 @@ void MacroAssembler::VmovExtended(int dst_code, const MemOperand& src) {
}
}
-void MacroAssembler::VmovExtended(const MemOperand& dst, int src_code) {
+void TurboAssembler::VmovExtended(const MemOperand& dst, int src_code) {
if (src_code < SwVfpRegister::kMaxNumRegisters) {
vstr(SwVfpRegister::from_code(src_code), dst);
} else {
@@ -1166,7 +1148,7 @@ void MacroAssembler::VmovExtended(const MemOperand& dst, int src_code) {
}
}
-void MacroAssembler::ExtractLane(Register dst, QwNeonRegister src,
+void TurboAssembler::ExtractLane(Register dst, QwNeonRegister src,
NeonDataType dt, int lane) {
int size = NeonSz(dt); // 0, 1, 2
int byte = lane << size;
@@ -1178,7 +1160,7 @@ void MacroAssembler::ExtractLane(Register dst, QwNeonRegister src,
vmov(dt, dst, double_source, double_lane);
}
-void MacroAssembler::ExtractLane(Register dst, DwVfpRegister src,
+void TurboAssembler::ExtractLane(Register dst, DwVfpRegister src,
NeonDataType dt, int lane) {
int size = NeonSz(dt); // 0, 1, 2
int byte = lane << size;
@@ -1187,13 +1169,13 @@ void MacroAssembler::ExtractLane(Register dst, DwVfpRegister src,
vmov(dt, dst, src, double_lane);
}
-void MacroAssembler::ExtractLane(SwVfpRegister dst, QwNeonRegister src,
+void TurboAssembler::ExtractLane(SwVfpRegister dst, QwNeonRegister src,
int lane) {
int s_code = src.code() * 4 + lane;
VmovExtended(dst.code(), s_code);
}
-void MacroAssembler::ReplaceLane(QwNeonRegister dst, QwNeonRegister src,
+void TurboAssembler::ReplaceLane(QwNeonRegister dst, QwNeonRegister src,
Register src_lane, NeonDataType dt, int lane) {
Move(dst, src);
int size = NeonSz(dt); // 0, 1, 2
@@ -1206,14 +1188,14 @@ void MacroAssembler::ReplaceLane(QwNeonRegister dst, QwNeonRegister src,
vmov(dt, double_dst, double_lane, src_lane);
}
-void MacroAssembler::ReplaceLane(QwNeonRegister dst, QwNeonRegister src,
+void TurboAssembler::ReplaceLane(QwNeonRegister dst, QwNeonRegister src,
SwVfpRegister src_lane, int lane) {
Move(dst, src);
int s_code = dst.code() * 4 + lane;
VmovExtended(s_code, src_lane.code());
}
-void MacroAssembler::LslPair(Register dst_low, Register dst_high,
+void TurboAssembler::LslPair(Register dst_low, Register dst_high,
Register src_low, Register src_high,
Register scratch, Register shift) {
DCHECK(!AreAliased(dst_high, src_low));
@@ -1236,7 +1218,7 @@ void MacroAssembler::LslPair(Register dst_low, Register dst_high,
bind(&done);
}
-void MacroAssembler::LslPair(Register dst_low, Register dst_high,
+void TurboAssembler::LslPair(Register dst_low, Register dst_high,
Register src_low, Register src_high,
uint32_t shift) {
DCHECK(!AreAliased(dst_high, src_low));
@@ -1259,7 +1241,7 @@ void MacroAssembler::LslPair(Register dst_low, Register dst_high,
}
}
-void MacroAssembler::LsrPair(Register dst_low, Register dst_high,
+void TurboAssembler::LsrPair(Register dst_low, Register dst_high,
Register src_low, Register src_high,
Register scratch, Register shift) {
DCHECK(!AreAliased(dst_low, src_high));
@@ -1283,7 +1265,7 @@ void MacroAssembler::LsrPair(Register dst_low, Register dst_high,
bind(&done);
}
-void MacroAssembler::LsrPair(Register dst_low, Register dst_high,
+void TurboAssembler::LsrPair(Register dst_low, Register dst_high,
Register src_low, Register src_high,
uint32_t shift) {
DCHECK(!AreAliased(dst_low, src_high));
@@ -1306,7 +1288,7 @@ void MacroAssembler::LsrPair(Register dst_low, Register dst_high,
}
}
-void MacroAssembler::AsrPair(Register dst_low, Register dst_high,
+void TurboAssembler::AsrPair(Register dst_low, Register dst_high,
Register src_low, Register src_high,
Register scratch, Register shift) {
DCHECK(!AreAliased(dst_low, src_high));
@@ -1329,7 +1311,7 @@ void MacroAssembler::AsrPair(Register dst_low, Register dst_high,
bind(&done);
}
-void MacroAssembler::AsrPair(Register dst_low, Register dst_high,
+void TurboAssembler::AsrPair(Register dst_low, Register dst_high,
Register src_low, Register src_high,
uint32_t shift) {
DCHECK(!AreAliased(dst_low, src_high));
@@ -1352,12 +1334,14 @@ void MacroAssembler::AsrPair(Register dst_low, Register dst_high,
}
}
-void MacroAssembler::StubPrologue(StackFrame::Type type) {
- mov(ip, Operand(StackFrame::TypeToMarker(type)));
- PushCommonFrame(ip);
+void TurboAssembler::StubPrologue(StackFrame::Type type) {
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ mov(scratch, Operand(StackFrame::TypeToMarker(type)));
+ PushCommonFrame(scratch);
}
-void MacroAssembler::Prologue(bool code_pre_aging) {
+void TurboAssembler::Prologue(bool code_pre_aging) {
{ PredictableCodeSizeScope predictible_code_size_scope(
this, kNoCodeAgeSequenceLength);
// The following three instructions must remain together and unmodified
@@ -1381,20 +1365,20 @@ void MacroAssembler::EmitLoadFeedbackVector(Register vector) {
ldr(vector, FieldMemOperand(vector, Cell::kValueOffset));
}
-
-void MacroAssembler::EnterFrame(StackFrame::Type type,
+void TurboAssembler::EnterFrame(StackFrame::Type type,
bool load_constant_pool_pointer_reg) {
// r0-r3: preserved
- mov(ip, Operand(StackFrame::TypeToMarker(type)));
- PushCommonFrame(ip);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ mov(scratch, Operand(StackFrame::TypeToMarker(type)));
+ PushCommonFrame(scratch);
if (type == StackFrame::INTERNAL) {
- mov(ip, Operand(CodeObject()));
- push(ip);
+ mov(scratch, Operand(CodeObject()));
+ push(scratch);
}
}
-
-int MacroAssembler::LeaveFrame(StackFrame::Type type) {
+int TurboAssembler::LeaveFrame(StackFrame::Type type) {
// r0: preserved
// r1: preserved
// r2: preserved
@@ -1424,31 +1408,35 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space,
StackFrame::Type frame_type) {
DCHECK(frame_type == StackFrame::EXIT ||
frame_type == StackFrame::BUILTIN_EXIT);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
// Set up the frame structure on the stack.
DCHECK_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement);
DCHECK_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset);
DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset);
- mov(ip, Operand(StackFrame::TypeToMarker(frame_type)));
- PushCommonFrame(ip);
+ mov(scratch, Operand(StackFrame::TypeToMarker(frame_type)));
+ PushCommonFrame(scratch);
// Reserve room for saved entry sp and code object.
sub(sp, fp, Operand(ExitFrameConstants::kFixedFrameSizeFromFp));
if (emit_debug_code()) {
- mov(ip, Operand::Zero());
- str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset));
+ mov(scratch, Operand::Zero());
+ str(scratch, MemOperand(fp, ExitFrameConstants::kSPOffset));
}
- mov(ip, Operand(CodeObject()));
- str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset));
+ mov(scratch, Operand(CodeObject()));
+ str(scratch, MemOperand(fp, ExitFrameConstants::kCodeOffset));
// Save the frame pointer and the context in top.
- mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
- str(fp, MemOperand(ip));
- mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
- str(cp, MemOperand(ip));
+ mov(scratch, Operand(ExternalReference(IsolateAddressId::kCEntryFPAddress,
+ isolate())));
+ str(fp, MemOperand(scratch));
+ mov(scratch,
+ Operand(ExternalReference(IsolateAddressId::kContextAddress, isolate())));
+ str(cp, MemOperand(scratch));
// Optionally save all double registers.
if (save_doubles) {
- SaveFPRegs(sp, ip);
+ SaveFPRegs(sp, scratch);
// Note that d0 will be accessible at
// fp - ExitFrameConstants::kFrameSize -
// DwVfpRegister::kMaxNumRegisters * kDoubleSize,
@@ -1460,17 +1448,17 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space,
const int frame_alignment = MacroAssembler::ActivationFrameAlignment();
sub(sp, sp, Operand((stack_space + 1) * kPointerSize));
if (frame_alignment > 0) {
- DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
+ DCHECK(base::bits::IsPowerOfTwo(frame_alignment));
and_(sp, sp, Operand(-frame_alignment));
}
// Set the exit frame sp value to point just before the return address
// location.
- add(ip, sp, Operand(kPointerSize));
- str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset));
+ add(scratch, sp, Operand(kPointerSize));
+ str(scratch, MemOperand(fp, ExitFrameConstants::kSPOffset));
}
-int MacroAssembler::ActivationFrameAlignment() {
+int TurboAssembler::ActivationFrameAlignment() {
#if V8_HOST_ARCH_ARM
// Running on the real platform. Use the alignment as mandated by the local
// environment.
@@ -1491,6 +1479,8 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count,
bool restore_context,
bool argument_count_is_length) {
ConstantPoolUnavailableScope constant_pool_unavailable(this);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
// Optionally restore all double registers.
if (save_doubles) {
@@ -1498,22 +1488,25 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count,
const int offset = ExitFrameConstants::kFixedFrameSizeFromFp;
sub(r3, fp,
Operand(offset + DwVfpRegister::kMaxNumRegisters * kDoubleSize));
- RestoreFPRegs(r3, ip);
+ RestoreFPRegs(r3, scratch);
}
// Clear top frame.
mov(r3, Operand::Zero());
- mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
- str(r3, MemOperand(ip));
+ mov(scratch, Operand(ExternalReference(IsolateAddressId::kCEntryFPAddress,
+ isolate())));
+ str(r3, MemOperand(scratch));
// Restore current context from top and clear it in debug mode.
if (restore_context) {
- mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
- ldr(cp, MemOperand(ip));
+ mov(scratch, Operand(ExternalReference(IsolateAddressId::kContextAddress,
+ isolate())));
+ ldr(cp, MemOperand(scratch));
}
#ifdef DEBUG
- mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
- str(r3, MemOperand(ip));
+ mov(scratch,
+ Operand(ExternalReference(IsolateAddressId::kContextAddress, isolate())));
+ str(r3, MemOperand(scratch));
#endif
// Tear down the exit frame, pop the arguments, and return.
@@ -1528,8 +1521,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count,
}
}
-
-void MacroAssembler::MovFromFloatResult(const DwVfpRegister dst) {
+void TurboAssembler::MovFromFloatResult(const DwVfpRegister dst) {
if (use_eabi_hardfloat()) {
Move(dst, d0);
} else {
@@ -1539,11 +1531,11 @@ void MacroAssembler::MovFromFloatResult(const DwVfpRegister dst) {
// On ARM this is just a synonym to make the purpose clear.
-void MacroAssembler::MovFromFloatParameter(DwVfpRegister dst) {
+void TurboAssembler::MovFromFloatParameter(DwVfpRegister dst) {
MovFromFloatResult(dst);
}
-void MacroAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
+void TurboAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
Register caller_args_count_reg,
Register scratch0, Register scratch1) {
#if DEBUG
@@ -1778,7 +1770,6 @@ void MacroAssembler::InvokeFunction(Register fun,
ldr(expected_reg,
FieldMemOperand(temp_reg,
SharedFunctionInfo::kFormalParameterCountOffset));
- SmiUntag(expected_reg);
ParameterCount expected(expected_reg);
InvokeFunctionCode(fun, new_target, expected, actual, flag, call_wrapper);
@@ -1850,7 +1841,8 @@ void MacroAssembler::PushStackHandler() {
STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
// Link the current handler as the next handler.
- mov(r6, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
+ mov(r6,
+ Operand(ExternalReference(IsolateAddressId::kHandlerAddress, isolate())));
ldr(r5, MemOperand(r6));
push(r5);
@@ -1860,11 +1852,14 @@ void MacroAssembler::PushStackHandler() {
void MacroAssembler::PopStackHandler() {
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
pop(r1);
- mov(ip, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
+ mov(scratch,
+ Operand(ExternalReference(IsolateAddressId::kHandlerAddress, isolate())));
add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize));
- str(r1, MemOperand(ip));
+ str(r1, MemOperand(scratch));
}
@@ -1907,7 +1902,6 @@ void MacroAssembler::Allocate(int object_size,
Label* gc_required,
AllocationFlags flags) {
DCHECK(object_size <= kMaxRegularHeapObjectSize);
- DCHECK((flags & ALLOCATION_FOLDED) == 0);
if (!FLAG_inline_new) {
if (emit_debug_code()) {
// Trash the registers to simulate an allocation failure.
@@ -1919,7 +1913,7 @@ void MacroAssembler::Allocate(int object_size,
return;
}
- DCHECK(!AreAliased(result, scratch1, scratch2, ip));
+ DCHECK(!AreAliased(result, scratch1, scratch2));
// Make object size into bytes.
if ((flags & SIZE_IN_WORDS) != 0) {
@@ -1939,13 +1933,12 @@ void MacroAssembler::Allocate(int object_size,
intptr_t top = reinterpret_cast<intptr_t>(allocation_top.address());
intptr_t limit = reinterpret_cast<intptr_t>(allocation_limit.address());
DCHECK((limit - top) == kPointerSize);
- DCHECK(result.code() < ip.code());
+
+ UseScratchRegisterScope temps(this);
// Set up allocation top address register.
Register top_address = scratch1;
- // This code stores a temporary value in ip. This is OK, as the code below
- // does not need ip for implicit literal generation.
- Register alloc_limit = ip;
+ Register alloc_limit = temps.Acquire();
Register result_end = scratch2;
mov(top_address, Operand(allocation_top));
@@ -1980,8 +1973,8 @@ void MacroAssembler::Allocate(int object_size,
}
// Calculate new top and bail out if new space is exhausted. Use result
- // to calculate the new top. We must preserve the ip register at this
- // point, so we cannot just use add().
+ // to calculate the new top. We have already acquired the scratch register at
+ // this point, so we cannot just use add().
DCHECK(object_size > 0);
Register source = result;
int shift = 0;
@@ -1993,7 +1986,7 @@ void MacroAssembler::Allocate(int object_size,
object_size -= bits;
shift += 8;
Operand bits_operand(bits);
- DCHECK(bits_operand.instructions_required(this) == 1);
+ DCHECK(bits_operand.InstructionsRequired(this) == 1);
add(result_end, source, bits_operand);
source = result_end;
}
@@ -2002,10 +1995,7 @@ void MacroAssembler::Allocate(int object_size,
cmp(result_end, Operand(alloc_limit));
b(hi, gc_required);
- if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) {
- // The top pointer is not updated for allocation folding dominators.
- str(result_end, MemOperand(top_address));
- }
+ str(result_end, MemOperand(top_address));
// Tag object.
add(result, result, Operand(kHeapObjectTag));
@@ -2015,7 +2005,6 @@ void MacroAssembler::Allocate(int object_size,
void MacroAssembler::Allocate(Register object_size, Register result,
Register result_end, Register scratch,
Label* gc_required, AllocationFlags flags) {
- DCHECK((flags & ALLOCATION_FOLDED) == 0);
if (!FLAG_inline_new) {
if (emit_debug_code()) {
// Trash the registers to simulate an allocation failure.
@@ -2029,8 +2018,7 @@ void MacroAssembler::Allocate(Register object_size, Register result,
// |object_size| and |result_end| may overlap if the DOUBLE_ALIGNMENT flag
// is not specified. Other registers must not overlap.
- DCHECK(!AreAliased(object_size, result, scratch, ip));
- DCHECK(!AreAliased(result_end, result, scratch, ip));
+ DCHECK(!AreAliased(object_size, result, scratch, result_end));
DCHECK((flags & DOUBLE_ALIGNMENT) == 0 || !object_size.is(result_end));
// Check relative positions of allocation top and limit addresses.
@@ -2044,13 +2032,12 @@ void MacroAssembler::Allocate(Register object_size, Register result,
intptr_t top = reinterpret_cast<intptr_t>(allocation_top.address());
intptr_t limit = reinterpret_cast<intptr_t>(allocation_limit.address());
DCHECK((limit - top) == kPointerSize);
- DCHECK(result.code() < ip.code());
+
+ UseScratchRegisterScope temps(this);
// Set up allocation top address and allocation limit registers.
Register top_address = scratch;
- // This code stores a temporary value in ip. This is OK, as the code below
- // does not need ip for implicit literal generation.
- Register alloc_limit = ip;
+ Register alloc_limit = temps.Acquire();
mov(top_address, Operand(allocation_top));
if ((flags & RESULT_CONTAINS_TOP) == 0) {
@@ -2100,118 +2087,9 @@ void MacroAssembler::Allocate(Register object_size, Register result,
tst(result_end, Operand(kObjectAlignmentMask));
Check(eq, kUnalignedAllocationInNewSpace);
}
- if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) {
- // The top pointer is not updated for allocation folding dominators.
- str(result_end, MemOperand(top_address));
- }
-
- // Tag object.
- add(result, result, Operand(kHeapObjectTag));
-}
-
-void MacroAssembler::FastAllocate(Register object_size, Register result,
- Register result_end, Register scratch,
- AllocationFlags flags) {
- // |object_size| and |result_end| may overlap if the DOUBLE_ALIGNMENT flag
- // is not specified. Other registers must not overlap.
- DCHECK(!AreAliased(object_size, result, scratch, ip));
- DCHECK(!AreAliased(result_end, result, scratch, ip));
- DCHECK((flags & DOUBLE_ALIGNMENT) == 0 || !object_size.is(result_end));
-
- ExternalReference allocation_top =
- AllocationUtils::GetAllocationTopReference(isolate(), flags);
-
- Register top_address = scratch;
- mov(top_address, Operand(allocation_top));
- ldr(result, MemOperand(top_address));
-
- if ((flags & DOUBLE_ALIGNMENT) != 0) {
- // Align the next allocation. Storing the filler map without checking top is
- // safe in new-space because the limit of the heap is aligned there.
- DCHECK(kPointerAlignment * 2 == kDoubleAlignment);
- and_(result_end, result, Operand(kDoubleAlignmentMask), SetCC);
- Label aligned;
- b(eq, &aligned);
- mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
- str(result_end, MemOperand(result, kDoubleSize / 2, PostIndex));
- bind(&aligned);
- }
-
- // Calculate new top using result. Object size may be in words so a shift is
- // required to get the number of bytes.
- if ((flags & SIZE_IN_WORDS) != 0) {
- add(result_end, result, Operand(object_size, LSL, kPointerSizeLog2), SetCC);
- } else {
- add(result_end, result, Operand(object_size), SetCC);
- }
-
- // Update allocation top. result temporarily holds the new top.
- if (emit_debug_code()) {
- tst(result_end, Operand(kObjectAlignmentMask));
- Check(eq, kUnalignedAllocationInNewSpace);
- }
- // The top pointer is not updated for allocation folding dominators.
- str(result_end, MemOperand(top_address));
-
- add(result, result, Operand(kHeapObjectTag));
-}
-
-void MacroAssembler::FastAllocate(int object_size, Register result,
- Register scratch1, Register scratch2,
- AllocationFlags flags) {
- DCHECK(object_size <= kMaxRegularHeapObjectSize);
- DCHECK(!AreAliased(result, scratch1, scratch2, ip));
-
- // Make object size into bytes.
- if ((flags & SIZE_IN_WORDS) != 0) {
- object_size *= kPointerSize;
- }
- DCHECK_EQ(0, object_size & kObjectAlignmentMask);
-
- ExternalReference allocation_top =
- AllocationUtils::GetAllocationTopReference(isolate(), flags);
-
- // Set up allocation top address register.
- Register top_address = scratch1;
- Register result_end = scratch2;
- mov(top_address, Operand(allocation_top));
- ldr(result, MemOperand(top_address));
-
- if ((flags & DOUBLE_ALIGNMENT) != 0) {
- // Align the next allocation. Storing the filler map without checking top is
- // safe in new-space because the limit of the heap is aligned there.
- STATIC_ASSERT(kPointerAlignment * 2 == kDoubleAlignment);
- and_(result_end, result, Operand(kDoubleAlignmentMask), SetCC);
- Label aligned;
- b(eq, &aligned);
- mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
- str(result_end, MemOperand(result, kDoubleSize / 2, PostIndex));
- bind(&aligned);
- }
-
- // Calculate new top using result. Object size may be in words so a shift is
- // required to get the number of bytes. We must preserve the ip register at
- // this point, so we cannot just use add().
- DCHECK(object_size > 0);
- Register source = result;
- int shift = 0;
- while (object_size != 0) {
- if (((object_size >> shift) & 0x03) == 0) {
- shift += 2;
- } else {
- int bits = object_size & (0xff << shift);
- object_size -= bits;
- shift += 8;
- Operand bits_operand(bits);
- DCHECK(bits_operand.instructions_required(this) == 1);
- add(result_end, source, bits_operand);
- source = result_end;
- }
- }
-
- // The top pointer is not updated for allocation folding dominators.
str(result_end, MemOperand(top_address));
+ // Tag object.
add(result, result, Operand(kHeapObjectTag));
}
@@ -2219,7 +2097,8 @@ void MacroAssembler::CompareObjectType(Register object,
Register map,
Register type_reg,
InstanceType type) {
- const Register temp = type_reg.is(no_reg) ? ip : type_reg;
+ UseScratchRegisterScope temps(this);
+ const Register temp = type_reg.is(no_reg) ? temps.Acquire() : type_reg;
ldr(map, FieldMemOperand(object, HeapObject::kMapOffset));
CompareInstanceType(map, temp, type);
@@ -2229,11 +2108,6 @@ void MacroAssembler::CompareObjectType(Register object,
void MacroAssembler::CompareInstanceType(Register map,
Register type_reg,
InstanceType type) {
- // Registers map and type_reg can be ip. These two lines assert
- // that ip can be used with the two instructions (the constants
- // will never need ip).
- STATIC_ASSERT(Map::kInstanceTypeOffset < 4096);
- STATIC_ASSERT(LAST_TYPE < 256);
ldrb(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset));
cmp(type_reg, Operand(type));
}
@@ -2241,9 +2115,11 @@ void MacroAssembler::CompareInstanceType(Register map,
void MacroAssembler::CompareRoot(Register obj,
Heap::RootListIndex index) {
- DCHECK(!obj.is(ip));
- LoadRoot(ip, index);
- cmp(obj, ip);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ DCHECK(!obj.is(scratch));
+ LoadRoot(scratch, index);
+ cmp(obj, scratch);
}
void MacroAssembler::CompareMap(Register obj,
@@ -2277,18 +2153,17 @@ void MacroAssembler::CheckMap(Register obj,
bind(&success);
}
-
-void MacroAssembler::CheckMap(Register obj,
- Register scratch,
- Heap::RootListIndex index,
- Label* fail,
+void MacroAssembler::CheckMap(Register obj, Register scratch,
+ Heap::RootListIndex index, Label* fail,
SmiCheckType smi_check_type) {
+ UseScratchRegisterScope temps(this);
+ Register root_register = temps.Acquire();
if (smi_check_type == DO_SMI_CHECK) {
JumpIfSmi(obj, fail);
}
ldr(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
- LoadRoot(ip, index);
- cmp(scratch, ip);
+ LoadRoot(root_register, index);
+ cmp(scratch, root_register);
b(ne, fail);
}
@@ -2319,21 +2194,49 @@ void MacroAssembler::GetMapConstructor(Register result, Register map,
}
void MacroAssembler::CallStub(CodeStub* stub,
- TypeFeedbackId ast_id,
Condition cond) {
DCHECK(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs.
- Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id, cond,
- CAN_INLINE_TARGET_ADDRESS, false);
+ Call(stub->GetCode(), RelocInfo::CODE_TARGET, cond, CAN_INLINE_TARGET_ADDRESS,
+ false);
}
+void TurboAssembler::CallStubDelayed(CodeStub* stub) {
+ DCHECK(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs.
+
+ // Block constant pool for the call instruction sequence.
+ BlockConstPoolScope block_const_pool(this);
+ Label start;
+ bind(&start);
+
+#ifdef DEBUG
+ // Check the expected size before generating code to ensure we assume the same
+ // constant pool availability (e.g., whether constant pool is full or not).
+ int expected_size = CallStubSize();
+#endif
+
+ // Call sequence on V7 or later may be :
+ // movw ip, #... @ call address low 16
+ // movt ip, #... @ call address high 16
+ // blx ip
+ // @ return address
+ // Or for pre-V7 or values that may be back-patched
+ // to avoid ICache flushes:
+ // ldr ip, [pc, #...] @ call address
+ // blx ip
+ // @ return address
+
+ mov(ip, Operand::EmbeddedCode(stub));
+ blx(ip, al);
+
+ DCHECK_EQ(expected_size, SizeOfCodeGeneratedSince(&start));
+}
void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) {
Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond);
}
-
-bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
- return has_frame_ || !stub->SometimesSetsUpAFrame();
+bool TurboAssembler::AllowThisStubCall(CodeStub* stub) {
+ return has_frame() || !stub->SometimesSetsUpAFrame();
}
void MacroAssembler::SmiToDouble(LowDwVfpRegister value, Register smi) {
@@ -2342,8 +2245,10 @@ void MacroAssembler::SmiToDouble(LowDwVfpRegister value, Register smi) {
vmov(value.low(), smi);
vcvt_f64_s32(value, 1);
} else {
- SmiUntag(ip, smi);
- vmov(value.low(), ip);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ SmiUntag(scratch, smi);
+ vmov(value.low(), scratch);
vcvt_f64_s32(value, value.low());
}
}
@@ -2415,22 +2320,24 @@ void MacroAssembler::TryInt32Floor(Register result,
bind(&exception);
}
-void MacroAssembler::TryInlineTruncateDoubleToI(Register result,
+void TurboAssembler::TryInlineTruncateDoubleToI(Register result,
DwVfpRegister double_input,
Label* done) {
LowDwVfpRegister double_scratch = kScratchDoubleReg;
vcvt_s32_f64(double_scratch.low(), double_input);
vmov(result, double_scratch.low());
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+
// If result is not saturated (0x7fffffff or 0x80000000), we are done.
- sub(ip, result, Operand(1));
- cmp(ip, Operand(0x7ffffffe));
+ sub(scratch, result, Operand(1));
+ cmp(scratch, Operand(0x7ffffffe));
b(lt, done);
}
-
-void MacroAssembler::TruncateDoubleToI(Register result,
- DwVfpRegister double_input) {
+void TurboAssembler::TruncateDoubleToIDelayed(Zone* zone, Register result,
+ DwVfpRegister double_input) {
Label done;
TryInlineTruncateDoubleToI(result, double_input, &done);
@@ -2440,8 +2347,7 @@ void MacroAssembler::TruncateDoubleToI(Register result,
sub(sp, sp, Operand(kDoubleSize)); // Put input on stack.
vstr(double_input, MemOperand(sp, 0));
- DoubleToIStub stub(isolate(), sp, result, 0, true, true);
- CallStub(&stub);
+ CallStubDelayed(new (zone) DoubleToIStub(nullptr, sp, result, 0, true, true));
add(sp, sp, Operand(kDoubleSize));
pop(lr);
@@ -2449,48 +2355,6 @@ void MacroAssembler::TruncateDoubleToI(Register result,
bind(&done);
}
-
-void MacroAssembler::TruncateHeapNumberToI(Register result,
- Register object) {
- Label done;
- LowDwVfpRegister double_scratch = kScratchDoubleReg;
- DCHECK(!result.is(object));
-
- vldr(double_scratch,
- MemOperand(object, HeapNumber::kValueOffset - kHeapObjectTag));
- TryInlineTruncateDoubleToI(result, double_scratch, &done);
-
- // If we fell through then inline version didn't succeed - call stub instead.
- push(lr);
- DoubleToIStub stub(isolate(),
- object,
- result,
- HeapNumber::kValueOffset - kHeapObjectTag,
- true,
- true);
- CallStub(&stub);
- pop(lr);
-
- bind(&done);
-}
-
-
-void MacroAssembler::TruncateNumberToI(Register object,
- Register result,
- Register heap_number_map,
- Register scratch1,
- Label* not_number) {
- Label done;
- DCHECK(!result.is(object));
-
- UntagAndJumpIfSmi(result, object, &done);
- JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number);
- TruncateHeapNumberToI(result, object);
-
- bind(&done);
-}
-
-
void MacroAssembler::GetLeastBitsFromSmi(Register dst,
Register src,
int num_least_bits) {
@@ -2510,6 +2374,17 @@ void MacroAssembler::GetLeastBitsFromInt32(Register dst,
and_(dst, src, Operand((1 << num_least_bits) - 1));
}
+void TurboAssembler::CallRuntimeDelayed(Zone* zone, Runtime::FunctionId fid,
+ SaveFPRegsMode save_doubles) {
+ const Runtime::Function* f = Runtime::FunctionForId(fid);
+ // TODO(1236192): Most runtime routines don't need the number of
+ // arguments passed in because it is constant. At some point we
+ // should remove this need and make the runtime routine entry code
+ // smarter.
+ mov(r0, Operand(f->nargs));
+ mov(r1, Operand(ExternalReference(f, isolate())));
+ CallStubDelayed(new (zone) CEntryStub(nullptr, 1, save_doubles));
+}
void MacroAssembler::CallRuntime(const Runtime::Function* f,
int num_arguments,
@@ -2567,16 +2442,6 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin,
Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
}
-void MacroAssembler::SetCounter(StatsCounter* counter, int value,
- Register scratch1, Register scratch2) {
- if (FLAG_native_code_counters && counter->Enabled()) {
- mov(scratch1, Operand(value));
- mov(scratch2, Operand(ExternalReference(counter)));
- str(scratch1, MemOperand(scratch2));
- }
-}
-
-
void MacroAssembler::IncrementCounter(StatsCounter* counter, int value,
Register scratch1, Register scratch2) {
DCHECK(value > 0);
@@ -2600,15 +2465,12 @@ void MacroAssembler::DecrementCounter(StatsCounter* counter, int value,
}
}
-
-void MacroAssembler::Assert(Condition cond, BailoutReason reason) {
+void TurboAssembler::Assert(Condition cond, BailoutReason reason) {
if (emit_debug_code())
Check(cond, reason);
}
-
-
-void MacroAssembler::Check(Condition cond, BailoutReason reason) {
+void TurboAssembler::Check(Condition cond, BailoutReason reason) {
Label L;
b(cond, &L);
Abort(reason);
@@ -2616,8 +2478,7 @@ void MacroAssembler::Check(Condition cond, BailoutReason reason) {
bind(&L);
}
-
-void MacroAssembler::Abort(BailoutReason reason) {
+void TurboAssembler::Abort(BailoutReason reason) {
Label abort_start;
bind(&abort_start);
#ifdef DEBUG
@@ -2633,13 +2494,10 @@ void MacroAssembler::Abort(BailoutReason reason) {
}
#endif
- // Check if Abort() has already been initialized.
- DCHECK(isolate()->builtins()->Abort()->IsHeapObject());
-
Move(r1, Smi::FromInt(static_cast<int>(reason)));
// Disable stub call restrictions to always allow calls to abort.
- if (!has_frame_) {
+ if (!has_frame()) {
// We don't actually want to generate a pile of code for this, so just
// claim there is a stack frame, without generating one.
FrameScope scope(this, StackFrame::NONE);
@@ -2698,7 +2556,7 @@ void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
}
}
-void MacroAssembler::InitializeRootRegister() {
+void TurboAssembler::InitializeRootRegister() {
ExternalReference roots_array_start =
ExternalReference::roots_array_start(isolate());
mov(kRootRegister, Operand(roots_array_start));
@@ -2759,7 +2617,7 @@ void MacroAssembler::NonNegativeSmiTst(Register value) {
tst(value, Operand(kSmiTagMask | kSmiSignMask));
}
-void MacroAssembler::JumpIfSmi(Register value, Label* smi_label) {
+void TurboAssembler::JumpIfSmi(Register value, Label* smi_label) {
tst(value, Operand(kSmiTagMask));
b(eq, smi_label);
}
@@ -2795,6 +2653,17 @@ void MacroAssembler::AssertSmi(Register object) {
}
}
+void MacroAssembler::AssertFixedArray(Register object) {
+ if (emit_debug_code()) {
+ STATIC_ASSERT(kSmiTag == 0);
+ tst(object, Operand(kSmiTagMask));
+ Check(ne, kOperandIsASmiAndNotAFixedArray);
+ push(object);
+ CompareObjectType(object, object, object, FIXED_ARRAY_TYPE);
+ pop(object);
+ Check(eq, kOperandIsNotAFixedArray);
+ }
+}
void MacroAssembler::AssertFunction(Register object) {
if (emit_debug_code()) {
@@ -2821,8 +2690,7 @@ void MacroAssembler::AssertBoundFunction(Register object) {
}
}
-void MacroAssembler::AssertGeneratorObject(Register object, Register flags) {
- // `flags` should be an untagged integer. See `SuspendFlags` in src/globals.h
+void MacroAssembler::AssertGeneratorObject(Register object) {
if (!emit_debug_code()) return;
tst(object, Operand(kSmiTagMask));
Check(ne, kOperandIsASmiAndNotAGeneratorObject);
@@ -2832,17 +2700,14 @@ void MacroAssembler::AssertGeneratorObject(Register object, Register flags) {
push(object);
ldr(map, FieldMemOperand(object, HeapObject::kMapOffset));
- Label async, do_check;
- tst(flags, Operand(static_cast<int>(SuspendFlags::kGeneratorTypeMask)));
- b(ne, &async);
-
// Check if JSGeneratorObject
- CompareInstanceType(map, object, JS_GENERATOR_OBJECT_TYPE);
- jmp(&do_check);
+ Label do_check;
+ Register instance_type = object;
+ CompareInstanceType(map, instance_type, JS_GENERATOR_OBJECT_TYPE);
+ b(eq, &do_check);
- bind(&async);
- // Check if JSAsyncGeneratorObject
- CompareInstanceType(map, object, JS_ASYNC_GENERATOR_OBJECT_TYPE);
+ // Check if JSAsyncGeneratorObject (See MacroAssembler::CompareInstanceType)
+ cmp(instance_type, Operand(JS_ASYNC_GENERATOR_OBJECT_TYPE));
bind(&do_check);
// Restore generator object to register and perform assertion
@@ -2975,25 +2840,12 @@ void MacroAssembler::AllocateJSValue(Register result, Register constructor,
LoadGlobalFunctionInitialMap(constructor, scratch1, scratch2);
str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset));
LoadRoot(scratch1, Heap::kEmptyFixedArrayRootIndex);
- str(scratch1, FieldMemOperand(result, JSObject::kPropertiesOffset));
+ str(scratch1, FieldMemOperand(result, JSObject::kPropertiesOrHashOffset));
str(scratch1, FieldMemOperand(result, JSObject::kElementsOffset));
str(value, FieldMemOperand(result, JSValue::kValueOffset));
STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
}
-void MacroAssembler::InitializeFieldsWithFiller(Register current_address,
- Register end_address,
- Register filler) {
- Label loop, entry;
- b(&entry);
- bind(&loop);
- str(filler, MemOperand(current_address, kPointerSize, PostIndex));
- bind(&entry);
- cmp(current_address, end_address);
- b(lo, &loop);
-}
-
-
void MacroAssembler::CheckFor32DRegs(Register scratch) {
mov(scratch, Operand(ExternalReference::cpu_features()));
ldr(scratch, MemOperand(scratch));
@@ -3019,7 +2871,7 @@ void MacroAssembler::RestoreFPRegs(Register location, Register scratch) {
}
template <typename T>
-void MacroAssembler::FloatMaxHelper(T result, T left, T right,
+void TurboAssembler::FloatMaxHelper(T result, T left, T right,
Label* out_of_line) {
// This trivial case is caught sooner, so that the out-of-line code can be
// completely avoided.
@@ -3050,7 +2902,7 @@ void MacroAssembler::FloatMaxHelper(T result, T left, T right,
}
template <typename T>
-void MacroAssembler::FloatMaxOutOfLineHelper(T result, T left, T right) {
+void TurboAssembler::FloatMaxOutOfLineHelper(T result, T left, T right) {
DCHECK(!left.is(right));
// ARMv8: At least one of left and right is a NaN.
@@ -3063,7 +2915,7 @@ void MacroAssembler::FloatMaxOutOfLineHelper(T result, T left, T right) {
}
template <typename T>
-void MacroAssembler::FloatMinHelper(T result, T left, T right,
+void TurboAssembler::FloatMinHelper(T result, T left, T right,
Label* out_of_line) {
// This trivial case is caught sooner, so that the out-of-line code can be
// completely avoided.
@@ -3109,7 +2961,7 @@ void MacroAssembler::FloatMinHelper(T result, T left, T right,
}
template <typename T>
-void MacroAssembler::FloatMinOutOfLineHelper(T result, T left, T right) {
+void TurboAssembler::FloatMinOutOfLineHelper(T result, T left, T right) {
DCHECK(!left.is(right));
// At least one of left and right is a NaN. Use vadd to propagate the NaN
@@ -3117,42 +2969,42 @@ void MacroAssembler::FloatMinOutOfLineHelper(T result, T left, T right) {
vadd(result, left, right);
}
-void MacroAssembler::FloatMax(SwVfpRegister result, SwVfpRegister left,
+void TurboAssembler::FloatMax(SwVfpRegister result, SwVfpRegister left,
SwVfpRegister right, Label* out_of_line) {
FloatMaxHelper(result, left, right, out_of_line);
}
-void MacroAssembler::FloatMin(SwVfpRegister result, SwVfpRegister left,
+void TurboAssembler::FloatMin(SwVfpRegister result, SwVfpRegister left,
SwVfpRegister right, Label* out_of_line) {
FloatMinHelper(result, left, right, out_of_line);
}
-void MacroAssembler::FloatMax(DwVfpRegister result, DwVfpRegister left,
+void TurboAssembler::FloatMax(DwVfpRegister result, DwVfpRegister left,
DwVfpRegister right, Label* out_of_line) {
FloatMaxHelper(result, left, right, out_of_line);
}
-void MacroAssembler::FloatMin(DwVfpRegister result, DwVfpRegister left,
+void TurboAssembler::FloatMin(DwVfpRegister result, DwVfpRegister left,
DwVfpRegister right, Label* out_of_line) {
FloatMinHelper(result, left, right, out_of_line);
}
-void MacroAssembler::FloatMaxOutOfLine(SwVfpRegister result, SwVfpRegister left,
+void TurboAssembler::FloatMaxOutOfLine(SwVfpRegister result, SwVfpRegister left,
SwVfpRegister right) {
FloatMaxOutOfLineHelper(result, left, right);
}
-void MacroAssembler::FloatMinOutOfLine(SwVfpRegister result, SwVfpRegister left,
+void TurboAssembler::FloatMinOutOfLine(SwVfpRegister result, SwVfpRegister left,
SwVfpRegister right) {
FloatMinOutOfLineHelper(result, left, right);
}
-void MacroAssembler::FloatMaxOutOfLine(DwVfpRegister result, DwVfpRegister left,
+void TurboAssembler::FloatMaxOutOfLine(DwVfpRegister result, DwVfpRegister left,
DwVfpRegister right) {
FloatMaxOutOfLineHelper(result, left, right);
}
-void MacroAssembler::FloatMinOutOfLine(DwVfpRegister result, DwVfpRegister left,
+void TurboAssembler::FloatMinOutOfLine(DwVfpRegister result, DwVfpRegister left,
DwVfpRegister right) {
FloatMinOutOfLineHelper(result, left, right);
}
@@ -3174,8 +3026,7 @@ void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte(
static const int kRegisterPassedArguments = 4;
-
-int MacroAssembler::CalculateStackPassedWords(int num_reg_arguments,
+int TurboAssembler::CalculateStackPassedWords(int num_reg_arguments,
int num_double_arguments) {
int stack_passed_words = 0;
if (use_eabi_hardfloat()) {
@@ -3197,55 +3048,19 @@ int MacroAssembler::CalculateStackPassedWords(int num_reg_arguments,
return stack_passed_words;
}
-
-void MacroAssembler::EmitSeqStringSetCharCheck(Register string,
- Register index,
- Register value,
- uint32_t encoding_mask) {
- Label is_object;
- SmiTst(string);
- Check(ne, kNonObject);
-
- ldr(ip, FieldMemOperand(string, HeapObject::kMapOffset));
- ldrb(ip, FieldMemOperand(ip, Map::kInstanceTypeOffset));
-
- and_(ip, ip, Operand(kStringRepresentationMask | kStringEncodingMask));
- cmp(ip, Operand(encoding_mask));
- Check(eq, kUnexpectedStringType);
-
- // The index is assumed to be untagged coming in, tag it to compare with the
- // string length without using a temp register, it is restored at the end of
- // this function.
- Label index_tag_ok, index_tag_bad;
- TrySmiTag(index, index, &index_tag_bad);
- b(&index_tag_ok);
- bind(&index_tag_bad);
- Abort(kIndexIsTooLarge);
- bind(&index_tag_ok);
-
- ldr(ip, FieldMemOperand(string, String::kLengthOffset));
- cmp(index, ip);
- Check(lt, kIndexIsTooLarge);
-
- cmp(index, Operand(Smi::kZero));
- Check(ge, kIndexIsNegative);
-
- SmiUntag(index, index);
-}
-
-
-void MacroAssembler::PrepareCallCFunction(int num_reg_arguments,
- int num_double_arguments,
- Register scratch) {
+void TurboAssembler::PrepareCallCFunction(int num_reg_arguments,
+ int num_double_arguments) {
int frame_alignment = ActivationFrameAlignment();
int stack_passed_arguments = CalculateStackPassedWords(
num_reg_arguments, num_double_arguments);
if (frame_alignment > kPointerSize) {
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
// Make stack end at alignment and make room for num_arguments - 4 words
// and the original value of sp.
mov(scratch, sp);
sub(sp, sp, Operand((stack_passed_arguments + 1) * kPointerSize));
- DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
+ DCHECK(base::bits::IsPowerOfTwo(frame_alignment));
and_(sp, sp, Operand(-frame_alignment));
str(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize));
} else {
@@ -3253,14 +3068,7 @@ void MacroAssembler::PrepareCallCFunction(int num_reg_arguments,
}
}
-
-void MacroAssembler::PrepareCallCFunction(int num_reg_arguments,
- Register scratch) {
- PrepareCallCFunction(num_reg_arguments, 0, scratch);
-}
-
-
-void MacroAssembler::MovToFloatParameter(DwVfpRegister src) {
+void TurboAssembler::MovToFloatParameter(DwVfpRegister src) {
DCHECK(src.is(d0));
if (!use_eabi_hardfloat()) {
vmov(r0, r1, src);
@@ -3269,12 +3077,11 @@ void MacroAssembler::MovToFloatParameter(DwVfpRegister src) {
// On ARM this is just a synonym to make the purpose clear.
-void MacroAssembler::MovToFloatResult(DwVfpRegister src) {
+void TurboAssembler::MovToFloatResult(DwVfpRegister src) {
MovToFloatParameter(src);
}
-
-void MacroAssembler::MovToFloatParameters(DwVfpRegister src1,
+void TurboAssembler::MovToFloatParameters(DwVfpRegister src1,
DwVfpRegister src2) {
DCHECK(src1.is(d0));
DCHECK(src2.is(d1));
@@ -3284,35 +3091,30 @@ void MacroAssembler::MovToFloatParameters(DwVfpRegister src1,
}
}
-
-void MacroAssembler::CallCFunction(ExternalReference function,
+void TurboAssembler::CallCFunction(ExternalReference function,
int num_reg_arguments,
int num_double_arguments) {
- mov(ip, Operand(function));
- CallCFunctionHelper(ip, num_reg_arguments, num_double_arguments);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ mov(scratch, Operand(function));
+ CallCFunctionHelper(scratch, num_reg_arguments, num_double_arguments);
}
-
-void MacroAssembler::CallCFunction(Register function,
- int num_reg_arguments,
+void TurboAssembler::CallCFunction(Register function, int num_reg_arguments,
int num_double_arguments) {
CallCFunctionHelper(function, num_reg_arguments, num_double_arguments);
}
-
-void MacroAssembler::CallCFunction(ExternalReference function,
+void TurboAssembler::CallCFunction(ExternalReference function,
int num_arguments) {
CallCFunction(function, num_arguments, 0);
}
-
-void MacroAssembler::CallCFunction(Register function,
- int num_arguments) {
+void TurboAssembler::CallCFunction(Register function, int num_arguments) {
CallCFunction(function, num_arguments, 0);
}
-
-void MacroAssembler::CallCFunctionHelper(Register function,
+void TurboAssembler::CallCFunctionHelper(Register function,
int num_reg_arguments,
int num_double_arguments) {
DCHECK_LE(num_reg_arguments + num_double_arguments, kMaxCParameters);
@@ -3325,7 +3127,7 @@ void MacroAssembler::CallCFunctionHelper(Register function,
int frame_alignment = base::OS::ActivationFrameAlignment();
int frame_alignment_mask = frame_alignment - 1;
if (frame_alignment > kPointerSize) {
- DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
+ DCHECK(base::bits::IsPowerOfTwo(frame_alignment));
Label alignment_as_expected;
tst(sp, Operand(frame_alignment_mask));
b(eq, &alignment_as_expected);
@@ -3350,13 +3152,8 @@ void MacroAssembler::CallCFunctionHelper(Register function,
}
}
-
-void MacroAssembler::CheckPageFlag(
- Register object,
- Register scratch,
- int mask,
- Condition cc,
- Label* condition_met) {
+void TurboAssembler::CheckPageFlag(Register object, Register scratch, int mask,
+ Condition cc, Label* condition_met) {
DCHECK(cc == eq || cc == ne);
Bfc(scratch, object, 0, kPageSizeBits);
ldr(scratch, MemOperand(scratch, MemoryChunk::kFlagsOffset));
@@ -3385,19 +3182,22 @@ void MacroAssembler::HasColor(Register object,
GetMarkBits(object, bitmap_scratch, mask_scratch);
Label other_color, word_boundary;
- ldr(ip, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
- tst(ip, Operand(mask_scratch));
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ ldr(scratch, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
+ tst(scratch, Operand(mask_scratch));
b(first_bit == 1 ? eq : ne, &other_color);
// Shift left 1 by adding.
add(mask_scratch, mask_scratch, Operand(mask_scratch), SetCC);
b(eq, &word_boundary);
- tst(ip, Operand(mask_scratch));
+ tst(scratch, Operand(mask_scratch));
b(second_bit == 1 ? ne : eq, has_color);
jmp(&other_color);
bind(&word_boundary);
- ldr(ip, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize + kPointerSize));
- tst(ip, Operand(1));
+ ldr(scratch,
+ MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize + kPointerSize));
+ tst(scratch, Operand(1));
b(second_bit == 1 ? ne : eq, has_color);
bind(&other_color);
}
@@ -3410,17 +3210,19 @@ void MacroAssembler::GetMarkBits(Register addr_reg,
and_(bitmap_reg, addr_reg, Operand(~Page::kPageAlignmentMask));
Ubfx(mask_reg, addr_reg, kPointerSizeLog2, Bitmap::kBitsPerCellLog2);
const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2;
- Ubfx(ip, addr_reg, kLowBits, kPageSizeBits - kLowBits);
- add(bitmap_reg, bitmap_reg, Operand(ip, LSL, kPointerSizeLog2));
- mov(ip, Operand(1));
- mov(mask_reg, Operand(ip, LSL, mask_reg));
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ Ubfx(scratch, addr_reg, kLowBits, kPageSizeBits - kLowBits);
+ add(bitmap_reg, bitmap_reg, Operand(scratch, LSL, kPointerSizeLog2));
+ mov(scratch, Operand(1));
+ mov(mask_reg, Operand(scratch, LSL, mask_reg));
}
void MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch,
Register mask_scratch, Register load_scratch,
Label* value_is_white) {
- DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, ip));
+ DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch));
GetMarkBits(value, bitmap_scratch, mask_scratch);
// If the value is black or grey we don't need to do anything.
@@ -3442,26 +3244,6 @@ void MacroAssembler::ClampUint8(Register output_reg, Register input_reg) {
}
-void MacroAssembler::ClampDoubleToUint8(Register result_reg,
- DwVfpRegister input_reg,
- LowDwVfpRegister double_scratch) {
- Label done;
-
- // Handle inputs >= 255 (including +infinity).
- Vmov(double_scratch, 255.0, result_reg);
- mov(result_reg, Operand(255));
- VFPCompareAndSetFlags(input_reg, double_scratch);
- b(ge, &done);
-
- // For inputs < 255 (including negative) vcvt_u32_f64 with round-to-nearest
- // rounding mode will provide the correct result.
- vcvt_u32_f64(double_scratch.low(), input_reg, kFPSCRRounding);
- vmov(result_reg, double_scratch.low());
-
- bind(&done);
-}
-
-
void MacroAssembler::LoadInstanceDescriptors(Register map,
Register descriptors) {
ldr(descriptors, FieldMemOperand(map, Map::kDescriptorsOffset));
@@ -3556,51 +3338,6 @@ void MacroAssembler::CheckEnumCache(Label* call_runtime) {
b(ne, &next);
}
-void MacroAssembler::TestJSArrayForAllocationMemento(
- Register receiver_reg,
- Register scratch_reg,
- Label* no_memento_found) {
- Label map_check;
- Label top_check;
- ExternalReference new_space_allocation_top_adr =
- ExternalReference::new_space_allocation_top_address(isolate());
- const int kMementoMapOffset = JSArray::kSize - kHeapObjectTag;
- const int kMementoLastWordOffset =
- kMementoMapOffset + AllocationMemento::kSize - kPointerSize;
-
- // Bail out if the object is not in new space.
- JumpIfNotInNewSpace(receiver_reg, scratch_reg, no_memento_found);
- // If the object is in new space, we need to check whether it is on the same
- // page as the current top.
- add(scratch_reg, receiver_reg, Operand(kMementoLastWordOffset));
- mov(ip, Operand(new_space_allocation_top_adr));
- ldr(ip, MemOperand(ip));
- eor(scratch_reg, scratch_reg, Operand(ip));
- tst(scratch_reg, Operand(~Page::kPageAlignmentMask));
- b(eq, &top_check);
- // The object is on a different page than allocation top. Bail out if the
- // object sits on the page boundary as no memento can follow and we cannot
- // touch the memory following it.
- add(scratch_reg, receiver_reg, Operand(kMementoLastWordOffset));
- eor(scratch_reg, scratch_reg, Operand(receiver_reg));
- tst(scratch_reg, Operand(~Page::kPageAlignmentMask));
- b(ne, no_memento_found);
- // Continue with the actual map check.
- jmp(&map_check);
- // If top is on the same page as the current object, we need to check whether
- // we are below top.
- bind(&top_check);
- add(scratch_reg, receiver_reg, Operand(kMementoLastWordOffset));
- mov(ip, Operand(new_space_allocation_top_adr));
- ldr(ip, MemOperand(ip));
- cmp(scratch_reg, ip);
- b(ge, no_memento_found);
- // Memento map check.
- bind(&map_check);
- ldr(scratch_reg, MemOperand(receiver_reg, kMementoMapOffset));
- cmp(scratch_reg, Operand(isolate()->factory()->allocation_memento_map()));
-}
-
Register GetRegisterThatIsNotOneOf(Register reg1,
Register reg2,
Register reg3,
@@ -3623,7 +3360,6 @@ Register GetRegisterThatIsNotOneOf(Register reg1,
return candidate;
}
UNREACHABLE();
- return no_reg;
}
#ifdef DEBUG
@@ -3699,29 +3435,6 @@ void CodePatcher::EmitCondition(Condition cond) {
masm_.emit(instr);
}
-
-void MacroAssembler::TruncatingDiv(Register result,
- Register dividend,
- int32_t divisor) {
- DCHECK(!dividend.is(result));
- DCHECK(!dividend.is(ip));
- DCHECK(!result.is(ip));
- base::MagicNumbersForDivision<uint32_t> mag =
- base::SignedDivisionByConstant(bit_cast<uint32_t>(divisor));
- mov(ip, Operand(mag.multiplier));
- bool neg = (mag.multiplier & (1U << 31)) != 0;
- if (divisor > 0 && neg) {
- smmla(result, dividend, ip, dividend);
- } else {
- smmul(result, dividend, ip);
- if (divisor < 0 && !neg && mag.multiplier > 0) {
- sub(result, result, Operand(dividend));
- }
- }
- if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift));
- add(result, result, Operand(dividend, LSR, 31));
-}
-
} // namespace internal
} // namespace v8