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

Unified Diff: src/arm/macro-assembler-arm.cc

Issue 6677076: Merge up to bleeding_edge r7201 to isolates branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/isolates
Patch Set: Fix lint. Created 9 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/arm/macro-assembler-arm.h ('k') | src/arm/simulator-arm.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/macro-assembler-arm.cc
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 035b045c6200b08dc81c7f5cd8bfab692587f75e..ce653eaadb854b2dcb085190f1718f37b5b7e82f 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -113,6 +113,8 @@ int MacroAssembler::CallSize(Register target, Condition cond) {
void MacroAssembler::Call(Register target, Condition cond) {
+ // Block constant pool for the call instruction sequence.
+ BlockConstPoolScope block_const_pool(this);
#ifdef DEBUG
int pre_position = pc_offset();
#endif
@@ -121,10 +123,8 @@ void MacroAssembler::Call(Register target, Condition cond) {
blx(target, cond);
#else
// set lr for return at current pc + 8
- { BlockConstPoolScope block_const_pool(this);
- mov(lr, Operand(pc), LeaveCC, cond);
- mov(pc, Operand(target), LeaveCC, cond);
- }
+ mov(lr, Operand(pc), LeaveCC, cond);
+ mov(pc, Operand(target), LeaveCC, cond);
#endif
#ifdef DEBUG
@@ -147,6 +147,8 @@ int MacroAssembler::CallSize(
void MacroAssembler::Call(
intptr_t target, RelocInfo::Mode rmode, Condition cond) {
+ // Block constant pool for the call instruction sequence.
+ BlockConstPoolScope block_const_pool(this);
#ifdef DEBUG
int pre_position = pc_offset();
#endif
@@ -156,28 +158,21 @@ void MacroAssembler::Call(
// ldr ip, [pc, #...]
// blx ip
- // The two instructions (ldr and blx) could be separated by a constant
- // pool and the code would still work. The issue comes from the
- // patching code which expect the ldr to be just above the blx.
- { BlockConstPoolScope block_const_pool(this);
- // Statement positions are expected to be recorded when the target
- // address is loaded. The mov method will automatically record
- // positions when pc is the target, since this is not the case here
- // we have to do it explicitly.
- positions_recorder()->WriteRecordedPositions();
+ // Statement positions are expected to be recorded when the target
+ // address is loaded. The mov method will automatically record
+ // positions when pc is the target, since this is not the case here
+ // we have to do it explicitly.
+ positions_recorder()->WriteRecordedPositions();
- mov(ip, Operand(target, rmode), LeaveCC, cond);
- blx(ip, cond);
- }
+ mov(ip, Operand(target, rmode), LeaveCC, cond);
+ blx(ip, cond);
ASSERT(kCallTargetAddressOffset == 2 * kInstrSize);
#else
- { BlockConstPoolScope block_const_pool(this);
- // Set lr for return at current pc + 8.
- mov(lr, Operand(pc), LeaveCC, cond);
- // Emit a ldr<cond> pc, [pc + offset of target in constant pool].
- mov(pc, Operand(target, rmode), LeaveCC, cond);
- }
+ // Set lr for return at current pc + 8.
+ mov(lr, Operand(pc), LeaveCC, cond);
+ // Emit a ldr<cond> pc, [pc + offset of target in constant pool].
+ mov(pc, Operand(target, rmode), LeaveCC, cond);
ASSERT(kCallTargetAddressOffset == kInstrSize);
#endif
@@ -438,7 +433,7 @@ void MacroAssembler::StoreRoot(Register source,
void MacroAssembler::RecordWriteHelper(Register object,
Register address,
Register scratch) {
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
// Check that the object is not in new space.
Label not_in_new_space;
InNewSpace(object, scratch, ne, &not_in_new_space);
@@ -500,7 +495,7 @@ void MacroAssembler::RecordWrite(Register object,
// Clobber all input registers when running with the debug-code flag
// turned on to provoke errors.
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
mov(object, Operand(BitCast<int32_t>(kZapValue)));
mov(scratch0, Operand(BitCast<int32_t>(kZapValue)));
mov(scratch1, Operand(BitCast<int32_t>(kZapValue)));
@@ -532,7 +527,7 @@ void MacroAssembler::RecordWrite(Register object,
// Clobber all input registers when running with the debug-code flag
// turned on to provoke errors.
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
mov(object, Operand(BitCast<int32_t>(kZapValue)));
mov(address, Operand(BitCast<int32_t>(kZapValue)));
mov(scratch, Operand(BitCast<int32_t>(kZapValue)));
@@ -736,7 +731,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
mov(fp, Operand(sp)); // Setup new frame pointer.
// Reserve room for saved entry sp and code object.
sub(sp, sp, Operand(2 * kPointerSize));
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
mov(ip, Operand(0));
str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset));
}
@@ -1143,7 +1138,7 @@ void MacroAssembler::Throw(Register value) {
// Restore cp otherwise.
ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
#ifdef DEBUG
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
mov(lr, Operand(pc));
}
#endif
@@ -1217,7 +1212,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
// Restore cp otherwise.
ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
#ifdef DEBUG
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
mov(lr, Operand(pc));
}
#endif
@@ -1249,7 +1244,7 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
ldr(scratch, FieldMemOperand(scratch, GlobalObject::kGlobalContextOffset));
// Check the context is a global context.
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
// TODO(119): avoid push(holder_reg)/pop(holder_reg)
// Cannot use ip as a temporary in this verification code. Due to the fact
// that ip is clobbered as part of cmp with an object Operand.
@@ -1268,7 +1263,7 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
b(eq, &same_contexts);
// Check the context is a global context.
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
// TODO(119): avoid push(holder_reg)/pop(holder_reg)
// Cannot use ip as a temporary in this verification code. Due to the fact
// that ip is clobbered as part of cmp with an object Operand.
@@ -1310,7 +1305,7 @@ void MacroAssembler::AllocateInNewSpace(int object_size,
Label* gc_required,
AllocationFlags flags) {
if (!FLAG_inline_new) {
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
// Trash the registers to simulate an allocation failure.
mov(result, Operand(0x7091));
mov(scratch1, Operand(0x7191));
@@ -1359,7 +1354,7 @@ void MacroAssembler::AllocateInNewSpace(int object_size,
// Load allocation top into result and allocation limit into ip.
ldm(ia, topaddr, result.bit() | ip.bit());
} else {
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
// Assert that result actually contains top on entry. ip is used
// immediately below so this use of ip does not cause difference with
// respect to register content between debug and release mode.
@@ -1393,7 +1388,7 @@ void MacroAssembler::AllocateInNewSpace(Register object_size,
Label* gc_required,
AllocationFlags flags) {
if (!FLAG_inline_new) {
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
// Trash the registers to simulate an allocation failure.
mov(result, Operand(0x7091));
mov(scratch1, Operand(0x7191));
@@ -1437,7 +1432,7 @@ void MacroAssembler::AllocateInNewSpace(Register object_size,
// Load allocation top into result and allocation limit into ip.
ldm(ia, topaddr, result.bit() | ip.bit());
} else {
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
// Assert that result actually contains top on entry. ip is used
// immediately below so this use of ip does not cause difference with
// respect to register content between debug and release mode.
@@ -1462,7 +1457,7 @@ void MacroAssembler::AllocateInNewSpace(Register object_size,
b(hi, gc_required);
// Update allocation top. result temporarily holds the new top.
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
tst(scratch2, Operand(kObjectAlignmentMask));
Check(eq, "Unaligned allocation in new space");
}
@@ -1766,7 +1761,7 @@ MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(
// No more valid handles (the result handle was the last one). Restore
// previous handle scope.
str(r4, MemOperand(r7, kNextOffset));
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
ldr(r1, MemOperand(r7, kLevelOffset));
cmp(r1, r6);
Check(eq, "Unexpected level after return from api call");
@@ -2039,6 +2034,121 @@ void MacroAssembler::EmitVFPTruncate(VFPRoundingMode rounding_mode,
}
+void MacroAssembler::EmitOutOfInt32RangeTruncate(Register result,
+ Register input_high,
+ Register input_low,
+ Register scratch) {
+ Label done, normal_exponent, restore_sign;
+
+ // Extract the biased exponent in result.
+ Ubfx(result,
+ input_high,
+ HeapNumber::kExponentShift,
+ HeapNumber::kExponentBits);
+
+ // Check for Infinity and NaNs, which should return 0.
+ cmp(result, Operand(HeapNumber::kExponentMask));
+ mov(result, Operand(0), LeaveCC, eq);
+ b(eq, &done);
+
+ // Express exponent as delta to (number of mantissa bits + 31).
+ sub(result,
+ result,
+ Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits + 31),
+ SetCC);
+
+ // If the delta is strictly positive, all bits would be shifted away,
+ // which means that we can return 0.
+ b(le, &normal_exponent);
+ mov(result, Operand(0));
+ b(&done);
+
+ bind(&normal_exponent);
+ const int kShiftBase = HeapNumber::kNonMantissaBitsInTopWord - 1;
+ // Calculate shift.
+ add(scratch, result, Operand(kShiftBase + HeapNumber::kMantissaBits), SetCC);
+
+ // Save the sign.
+ Register sign = result;
+ result = no_reg;
+ and_(sign, input_high, Operand(HeapNumber::kSignMask));
+
+ // Set the implicit 1 before the mantissa part in input_high.
+ orr(input_high,
+ input_high,
+ Operand(1 << HeapNumber::kMantissaBitsInTopWord));
+ // Shift the mantissa bits to the correct position.
+ // We don't need to clear non-mantissa bits as they will be shifted away.
+ // If they weren't, it would mean that the answer is in the 32bit range.
+ mov(input_high, Operand(input_high, LSL, scratch));
+
+ // Replace the shifted bits with bits from the lower mantissa word.
+ Label pos_shift, shift_done;
+ rsb(scratch, scratch, Operand(32), SetCC);
+ b(&pos_shift, ge);
+
+ // Negate scratch.
+ rsb(scratch, scratch, Operand(0));
+ mov(input_low, Operand(input_low, LSL, scratch));
+ b(&shift_done);
+
+ bind(&pos_shift);
+ mov(input_low, Operand(input_low, LSR, scratch));
+
+ bind(&shift_done);
+ orr(input_high, input_high, Operand(input_low));
+ // Restore sign if necessary.
+ cmp(sign, Operand(0));
+ result = sign;
+ sign = no_reg;
+ rsb(result, input_high, Operand(0), LeaveCC, ne);
+ mov(result, input_high, LeaveCC, eq);
+ bind(&done);
+}
+
+
+void MacroAssembler::EmitECMATruncate(Register result,
+ DwVfpRegister double_input,
+ SwVfpRegister single_scratch,
+ Register scratch,
+ Register input_high,
+ Register input_low) {
+ CpuFeatures::Scope scope(VFP3);
+ ASSERT(!input_high.is(result));
+ ASSERT(!input_low.is(result));
+ ASSERT(!input_low.is(input_high));
+ ASSERT(!scratch.is(result) &&
+ !scratch.is(input_high) &&
+ !scratch.is(input_low));
+ ASSERT(!single_scratch.is(double_input.low()) &&
+ !single_scratch.is(double_input.high()));
+
+ Label done;
+
+ // Clear cumulative exception flags.
+ ClearFPSCRBits(kVFPExceptionMask, scratch);
+ // Try a conversion to a signed integer.
+ vcvt_s32_f64(single_scratch, double_input);
+ vmov(result, single_scratch);
+ // Retrieve he FPSCR.
+ vmrs(scratch);
+ // Check for overflow and NaNs.
+ tst(scratch, Operand(kVFPOverflowExceptionBit |
+ kVFPUnderflowExceptionBit |
+ kVFPInvalidOpExceptionBit));
+ // If we had no exceptions we are done.
+ b(eq, &done);
+
+ // Load the double value and perform a manual truncation.
+ vmov(input_low, input_high, double_input);
+ EmitOutOfInt32RangeTruncate(result,
+ input_high,
+ input_low,
+ scratch);
+ bind(&done);
+}
+
+
void MacroAssembler::GetLeastBitsFromSmi(Register dst,
Register src,
int num_least_bits) {
@@ -2228,14 +2338,14 @@ void MacroAssembler::DecrementCounter(StatsCounter* counter, int value,
void MacroAssembler::Assert(Condition cond, const char* msg) {
- if (FLAG_debug_code)
+ if (emit_debug_code())
Check(cond, msg);
}
void MacroAssembler::AssertRegisterIsRoot(Register reg,
Heap::RootListIndex index) {
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
LoadRoot(ip, index);
cmp(reg, ip);
Check(eq, "Register did not match expected root");
@@ -2244,7 +2354,7 @@ void MacroAssembler::AssertRegisterIsRoot(Register reg,
void MacroAssembler::AssertFastElements(Register elements) {
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
ASSERT(!elements.is(ip));
Label ok;
push(elements);
@@ -2332,7 +2442,7 @@ void MacroAssembler::LoadContext(Register dst, int context_chain_length) {
// (i.e., the static scope chain and runtime context chain do not agree).
// A variable occurring in such a scope should have slot type LOOKUP and
// not CONTEXT.
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
ldr(ip, MemOperand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX)));
cmp(dst, ip);
Check(eq, "Yo dawg, I heard you liked function contexts "
@@ -2357,7 +2467,7 @@ void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
Register scratch) {
// Load the initial map. The global functions all have initial maps.
ldr(map, FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
Label ok, fail;
CheckMap(map, scratch, Heap::kMetaMapRootIndex, &fail, false);
b(&ok);
@@ -2565,7 +2675,7 @@ void MacroAssembler::CopyBytes(Register src,
// Copy bytes in word size chunks.
bind(&word_loop);
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
tst(src, Operand(kPointerSize - 1));
Assert(eq, "Expecting alignment for CopyBytes");
}
@@ -2725,7 +2835,7 @@ void MacroAssembler::CallCFunctionHelper(Register function,
// running in the simulator. The simulator has its own alignment check which
// provides more information.
#if defined(V8_HOST_ARCH_ARM)
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
int frame_alignment = OS::ActivationFrameAlignment();
int frame_alignment_mask = frame_alignment - 1;
if (frame_alignment > kPointerSize) {
@@ -2764,7 +2874,7 @@ void MacroAssembler::GetRelocatedValueLocation(Register ldr_location,
const uint32_t kLdrOffsetMask = (1 << 12) - 1;
const int32_t kPCRegOffset = 2 * kPointerSize;
ldr(result, MemOperand(ldr_location));
- if (FLAG_debug_code) {
+ if (emit_debug_code()) {
// Check that the instruction is a ldr reg, [pc + offset] .
and_(result, result, Operand(kLdrPCPattern));
cmp(result, Operand(kLdrPCPattern));
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/arm/simulator-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698