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

Unified Diff: src/mips/code-stubs-mips.cc

Issue 6966031: MIPS: Update for 23-May commits, and a few older ones. (Closed)
Patch Set: Created 9 years, 7 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
Index: src/mips/code-stubs-mips.cc
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index bb009218db07bc33f3bbc94fb9eeeea56bb19b26..4b5e0e6c437bfb84c1f09819d85dd0eba2af301c 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -388,11 +388,8 @@ void FloatingPointHelper::LoadSmis(MacroAssembler* masm,
__ mtc1(scratch1, f12);
__ cvt_d_w(f12, f12);
if (destination == kCoreRegisters) {
- __ mfc1(a2, f14);
- __ mfc1(a3, f15);
-
- __ mfc1(a0, f12);
- __ mfc1(a1, f13);
+ __ Move(a2, a3, f14);
+ __ Move(a0, a1, f12);
}
} else {
ASSERT(destination == kCoreRegisters);
@@ -478,8 +475,7 @@ void FloatingPointHelper::LoadNumber(MacroAssembler* masm,
__ cvt_d_w(dst, dst);
if (destination == kCoreRegisters) {
// Load the converted smi to dst1 and dst2 in double format.
- __ mfc1(dst1, dst);
- __ mfc1(dst2, FPURegister::from_code(dst.code() + 1));
+ __ Move(dst1, dst2, dst);
}
} else {
ASSERT(destination == kCoreRegisters);
@@ -550,6 +546,8 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm,
Register scratch2,
FPURegister single_scratch) {
ASSERT(!int_scratch.is(scratch2));
+ ASSERT(!int_scratch.is(dst1));
+ ASSERT(!int_scratch.is(dst2));
Label done;
@@ -558,8 +556,7 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm,
__ mtc1(int_scratch, single_scratch);
__ cvt_d_w(double_dst, single_scratch);
if (destination == kCoreRegisters) {
- __ mfc1(dst1, double_dst);
- __ mfc1(dst2, FPURegister::from_code(double_dst.code() + 1));
+ __ Move(dst1, dst2, double_dst);
}
} else {
Label fewer_than_20_useful_bits;
@@ -683,8 +680,7 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
__ Branch(not_int32, ne, scratch2, Operand(zero_reg));
if (destination == kCoreRegisters) {
- __ mfc1(dst1, double_dst);
- __ mfc1(dst2, FPURegister::from_code(double_dst.code() + 1));
+ __ Move(dst1, dst2, double_dst);
}
} else {
@@ -891,10 +887,8 @@ void FloatingPointHelper::CallCCodeForDoubleOperation(
// calling is compiled with hard-float flag and expecting hard float ABI
// (parameters in f12/f14 registers). We need to copy parameters from
// a0-a3 registers to f12/f14 register pairs.
- __ mtc1(a0, f12);
- __ mtc1(a1, f13);
- __ mtc1(a2, f14);
- __ mtc1(a3, f15);
+ __ Move(f12, a0, a1);
+ __ Move(f14, a2, a3);
}
// Call C routine that may not cause GC or other trouble.
__ CallCFunction(ExternalReference::double_fp_operation(op, masm->isolate()),
@@ -1171,10 +1165,8 @@ void EmitNanCheck(MacroAssembler* masm, Condition cc) {
if (CpuFeatures::IsSupported(FPU)) {
CpuFeatures::Scope scope(FPU);
// Lhs and rhs are already loaded to f12 and f14 register pairs.
- __ mfc1(t0, f14); // f14 has LS 32 bits of rhs.
- __ mfc1(t1, f15); // f15 has MS 32 bits of rhs.
- __ mfc1(t2, f12); // f12 has LS 32 bits of lhs.
- __ mfc1(t3, f13); // f13 has MS 32 bits of lhs.
+ __ Move(t0, t1, f14);
+ __ Move(t2, t3, f12);
} else {
// Lhs and rhs are already loaded to GP registers.
__ mov(t0, a0); // a0 has LS 32 bits of rhs.
@@ -1237,12 +1229,10 @@ static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm, Condition cc) {
// Exception: 0 and -0.
bool exp_first = (HeapNumber::kExponentOffset == HeapNumber::kValueOffset);
if (CpuFeatures::IsSupported(FPU)) {
- CpuFeatures::Scope scope(FPU);
+ CpuFeatures::Scope scope(FPU);
// Lhs and rhs are already loaded to f12 and f14 register pairs.
- __ mfc1(t0, f14); // f14 has LS 32 bits of rhs.
- __ mfc1(t1, f15); // f15 has MS 32 bits of rhs.
- __ mfc1(t2, f12); // f12 has LS 32 bits of lhs.
- __ mfc1(t3, f13); // f13 has MS 32 bits of lhs.
+ __ Move(t0, t1, f14);
+ __ Move(t2, t3, f12);
} else {
// Lhs and rhs are already loaded to GP registers.
__ mov(t0, a0); // a0 has LS 32 bits of rhs.
@@ -1284,10 +1274,8 @@ static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm, Condition cc) {
// calling is compiled with hard-float flag and expecting hard float ABI
// (parameters in f12/f14 registers). We need to copy parameters from
// a0-a3 registers to f12/f14 register pairs.
- __ mtc1(a0, f12);
- __ mtc1(a1, f13);
- __ mtc1(a2, f14);
- __ mtc1(a3, f15);
+ __ Move(f12, a0, a1);
+ __ Move(f14, a2, a3);
}
__ CallCFunction(ExternalReference::compare_doubles(masm->isolate()), 4);
__ pop(ra); // Because this function returns int, result is in v0.
@@ -3192,8 +3180,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
__ sra(t0, a0, kSmiTagSize);
__ mtc1(t0, f4);
__ cvt_d_w(f4, f4);
- __ mfc1(a2, f4);
- __ mfc1(a3, f5);
+ __ Move(a2, a3, f4);
__ Branch(&loaded);
__ bind(&input_not_smi);
@@ -3209,8 +3196,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
__ lw(a3, FieldMemOperand(a0, HeapNumber::kValueOffset + 4));
} else {
// Input is untagged double in f4. Output goes to f4.
- __ mfc1(a2, f4);
- __ mfc1(a3, f5);
+ __ Move(a2, a3, f4);
}
__ bind(&loaded);
// a2 = low 32 bits of double value.
@@ -3354,8 +3340,11 @@ void TranscendentalCacheStub::GenerateCallCFunction(MacroAssembler* masm,
Register scratch) {
__ push(ra);
__ PrepareCallCFunction(2, scratch);
- __ mfc1(v0, f4);
- __ mfc1(v1, f5);
+ if (IsMipsSoftFloatABI) {
+ __ Move(v0, v1, f4);
+ } else {
+ __ mov_d(f12, f4);
+ }
switch (type_) {
case TranscendentalCache::SIN:
__ CallCFunction(
@@ -3451,16 +3440,9 @@ void MathPowStub::Generate(MacroAssembler* masm) {
&call_runtime);
__ push(ra);
__ PrepareCallCFunction(3, scratch);
- // ABI (o32) for func(double d, int x): d in f12, x in a2.
- ASSERT(double_base.is(f12));
- ASSERT(exponent.is(a2));
- if (IsMipsSoftFloatABI) {
- // Simulator case, supports FPU, but with soft-float passing.
- __ mfc1(a0, double_base);
- __ mfc1(a1, FPURegister::from_code(double_base.code() + 1));
- }
+ __ SetCallCDoubleArguments(double_base, double_exponent);
__ CallCFunction(
- ExternalReference::power_double_int_function(masm->isolate()), 3);
+ ExternalReference::power_double_int_function(masm->isolate()), 4);
__ pop(ra);
__ GetCFunctionDoubleResult(double_result);
__ sdc1(double_result,
@@ -3489,12 +3471,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
// ABI (o32) for func(double a, double b): a in f12, b in f14.
ASSERT(double_base.is(f12));
ASSERT(double_exponent.is(f14));
- if (IsMipsSoftFloatABI) {
- __ mfc1(a0, double_base);
- __ mfc1(a1, FPURegister::from_code(double_base.code() + 1));
- __ mfc1(a2, double_exponent);
- __ mfc1(a3, FPURegister::from_code(double_exponent.code() + 1));
- }
+ __ SetCallCDoubleArguments(double_base, double_exponent);
__ CallCFunction(
ExternalReference::power_double_double_function(masm->isolate()), 4);
__ pop(ra);
@@ -3892,18 +3869,31 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
}
-// Uses registers a0 to t0. Expected input is
-// object in a0 (or at sp+1*kPointerSize) and function in
-// a1 (or at sp), depending on whether or not
-// args_in_registers() is true.
+// Uses registers a0 to t0.
+// Expected input (depending on whether args are in registers or on the stack):
+// * object: a0 or at sp + 1 * kPointerSize.
+// * function: a1 or at sp.
+//
+// Inlined call site patching is a crankshaft-specific feature that is not
+// implemented on MIPS.
void InstanceofStub::Generate(MacroAssembler* masm) {
+ // This is a crankshaft-specific feature that has not been implemented yet.
+ ASSERT(!HasCallSiteInlineCheck());
+ // Call site inlining and patching implies arguments in registers.
+ ASSERT(HasArgsInRegisters() || !HasCallSiteInlineCheck());
+ // ReturnTrueFalse is only implemented for inlined call sites.
+ ASSERT(!ReturnTrueFalseObject() || HasCallSiteInlineCheck());
+
// Fixed register usage throughout the stub:
const Register object = a0; // Object (lhs).
- const Register map = a3; // Map of the object.
+ Register map = a3; // Map of the object.
const Register function = a1; // Function (rhs).
const Register prototype = t0; // Prototype of the function.
+ const Register inline_site = t5;
const Register scratch = a2;
+
Label slow, loop, is_instance, is_not_instance, not_js_object;
+
if (!HasArgsInRegisters()) {
__ lw(object, MemOperand(sp, 1 * kPointerSize));
__ lw(function, MemOperand(sp, 0));
@@ -3913,47 +3903,70 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
__ JumpIfSmi(object, &not_js_object);
__ IsObjectJSObjectType(object, map, scratch, &not_js_object);
- // Look up the function and the map in the instanceof cache.
- Label miss;
- __ LoadRoot(t1, Heap::kInstanceofCacheFunctionRootIndex);
- __ Branch(&miss, ne, function, Operand(t1));
- __ LoadRoot(t1, Heap::kInstanceofCacheMapRootIndex);
- __ Branch(&miss, ne, map, Operand(t1));
- __ LoadRoot(v0, Heap::kInstanceofCacheAnswerRootIndex);
- __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
+ // If there is a call site cache don't look in the global cache, but do the
+ // real lookup and update the call site cache.
+ if (!HasCallSiteInlineCheck()) {
+ Label miss;
+ __ LoadRoot(t1, Heap::kInstanceofCacheFunctionRootIndex);
+ __ Branch(&miss, ne, function, Operand(t1));
+ __ LoadRoot(t1, Heap::kInstanceofCacheMapRootIndex);
+ __ Branch(&miss, ne, map, Operand(t1));
+ __ LoadRoot(v0, Heap::kInstanceofCacheAnswerRootIndex);
+ __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
+
+ __ bind(&miss);
+ }
- __ bind(&miss);
+ // Get the prototype of the function.
__ TryGetFunctionPrototype(function, prototype, scratch, &slow);
// Check that the function prototype is a JS object.
__ JumpIfSmi(prototype, &slow);
__ IsObjectJSObjectType(prototype, scratch, scratch, &slow);
- __ StoreRoot(function, Heap::kInstanceofCacheFunctionRootIndex);
- __ StoreRoot(map, Heap::kInstanceofCacheMapRootIndex);
+ // Update the global instanceof or call site inlined cache with the current
+ // map and function. The cached answer will be set when it is known below.
+ if (!HasCallSiteInlineCheck()) {
+ __ StoreRoot(function, Heap::kInstanceofCacheFunctionRootIndex);
+ __ StoreRoot(map, Heap::kInstanceofCacheMapRootIndex);
+ } else {
+ UNIMPLEMENTED_MIPS();
+ }
// Register mapping: a3 is object map and t0 is function prototype.
// Get prototype of object into a2.
__ lw(scratch, FieldMemOperand(map, Map::kPrototypeOffset));
+ // We don't need map any more. Use it as a scratch register.
+ Register scratch2 = map;
+ map = no_reg;
+
// Loop through the prototype chain looking for the function prototype.
+ __ LoadRoot(scratch2, Heap::kNullValueRootIndex);
__ bind(&loop);
__ Branch(&is_instance, eq, scratch, Operand(prototype));
- __ LoadRoot(t1, Heap::kNullValueRootIndex);
- __ Branch(&is_not_instance, eq, scratch, Operand(t1));
+ __ Branch(&is_not_instance, eq, scratch, Operand(scratch2));
__ lw(scratch, FieldMemOperand(scratch, HeapObject::kMapOffset));
__ lw(scratch, FieldMemOperand(scratch, Map::kPrototypeOffset));
__ Branch(&loop);
__ bind(&is_instance);
ASSERT(Smi::FromInt(0) == 0);
- __ mov(v0, zero_reg);
- __ StoreRoot(v0, Heap::kInstanceofCacheAnswerRootIndex);
+ if (!HasCallSiteInlineCheck()) {
+ __ mov(v0, zero_reg);
+ __ StoreRoot(v0, Heap::kInstanceofCacheAnswerRootIndex);
+ } else {
+ UNIMPLEMENTED_MIPS();
+ }
__ DropAndRet(HasArgsInRegisters() ? 0 : 2);
__ bind(&is_not_instance);
- __ li(v0, Operand(Smi::FromInt(1)));
- __ StoreRoot(v0, Heap::kInstanceofCacheAnswerRootIndex);
+ if (!HasCallSiteInlineCheck()) {
+ __ li(v0, Operand(Smi::FromInt(1)));
+ __ StoreRoot(v0, Heap::kInstanceofCacheAnswerRootIndex);
+ } else {
+ UNIMPLEMENTED_MIPS();
+ }
__ DropAndRet(HasArgsInRegisters() ? 0 : 2);
Label object_not_null, object_not_null_or_smi;
@@ -3961,7 +3974,7 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
// Before null, smi and string value checks, check that the rhs is a function
// as for a non-function rhs an exception needs to be thrown.
__ JumpIfSmi(function, &slow);
- __ GetObjectType(function, map, scratch);
+ __ GetObjectType(function, scratch2, scratch);
__ Branch(&slow, ne, scratch, Operand(JS_FUNCTION_TYPE));
// Null is not instance of anything.
@@ -3984,13 +3997,31 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
// Slow-case. Tail call builtin.
__ bind(&slow);
- if (HasArgsInRegisters()) {
+ if (!ReturnTrueFalseObject()) {
+ if (HasArgsInRegisters()) {
+ __ Push(a0, a1);
+ }
+ __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
+ } else {
+ __ EnterInternalFrame();
__ Push(a0, a1);
+ __ InvokeBuiltin(Builtins::INSTANCE_OF, CALL_FUNCTION);
+ __ LeaveInternalFrame();
+ __ mov(a0, v0);
+ __ LoadRoot(v0, Heap::kTrueValueRootIndex);
+ __ DropAndRet(HasArgsInRegisters() ? 0 : 2, eq, a0, Operand(zero_reg));
+ __ LoadRoot(v0, Heap::kFalseValueRootIndex);
+ __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
}
- __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
}
+Register InstanceofStub::left() { return a0; }
+
+
+Register InstanceofStub::right() { return a1; }
+
+
void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
// The displacement is the offset of the last parameter (if any)
// relative to the frame pointer.
« no previous file with comments | « SConstruct ('k') | src/mips/codegen-mips.h » ('j') | src/mips/macro-assembler-mips.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698