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

Unified Diff: src/arm/lithium-codegen-arm.cc

Issue 6124005: Implementing a few more missing stubs on ARM:... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 11 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 | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/lithium-codegen-arm.cc
===================================================================
--- src/arm/lithium-codegen-arm.cc (revision 6231)
+++ src/arm/lithium-codegen-arm.cc (working copy)
@@ -1380,15 +1380,64 @@
}
-// Branches to a label or falls through with the answer in the z flag. Trashes
-// the temp registers, but not the input. Only input and temp2 may alias.
+// Branches to a label or falls through with the answer in the z flag. Trashes
+// the temp registers, but not the input. Only input and temp2 may alias.
Søren Thygesen Gjesse 2011/01/10 09:56:08 input is trashed if temp2 aliases it.
Alexandre 2011/01/10 10:48:27 Indeed. Changed the code to have input and temp2 a
void LCodeGen::EmitClassOfTest(Label* is_true,
Label* is_false,
Handle<String>class_name,
Register input,
Register temp,
Register temp2) {
- Abort("EmitClassOfTest unimplemented.");
+ ASSERT(!input.is(temp));
+ ASSERT(!temp.is(temp2)); // But input and temp2 may be the same register.
+
+ __ BranchOnSmi(input, is_false);
+
+ __ CompareObjectType(input, temp, temp2, FIRST_JS_OBJECT_TYPE);
+ __ b(lt, is_false);
+
Søren Thygesen Gjesse 2011/01/10 09:56:08 How about just // temp: map of input // temp2: o
Alexandre 2011/01/10 10:48:27 Done.
+ // After CompareObjectType:
+ // - Input's map is in temp.
+ // - Input's type is in temp2.
+
+ // Functions have class 'Function'.
+ __ cmp(temp2, Operand(JS_FUNCTION_TYPE));
+ if (class_name->IsEqualTo(CStrVector("Function"))) {
+ __ b(eq, is_true);
+ } else {
+ __ b(eq, is_false);
+ }
+
+ // Check if the constructor in the map is a function.
+ __ ldr(temp, FieldMemOperand(temp, Map::kConstructorOffset));
Søren Thygesen Gjesse 2011/01/10 09:56:08 After this // temp: constructor
Alexandre 2011/01/10 10:48:27 Done.
+
+ // As long as JS_FUNCTION_TYPE is the last instance type and it is
+ // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
+ // LAST_JS_OBJECT_TYPE.
+ ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+ ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
+
+ // Objects with a non-function constructor have class 'Object'.
+ __ CompareObjectType(temp, temp2, temp2, JS_FUNCTION_TYPE);
+ if (class_name->IsEqualTo(CStrVector("Object"))) {
+ __ b(ne, is_true);
+ } else {
+ __ b(ne, is_false);
+ }
+
Søren Thygesen Gjesse 2011/01/10 09:56:08 Change comment to // Get the instance class name
Alexandre 2011/01/10 10:48:27 Done.
+ // temp now contains the constructor function. Grab the
+ // instance class name from there.
+ __ ldr(temp, FieldMemOperand(temp, JSFunction::kSharedFunctionInfoOffset));
+ __ ldr(temp, FieldMemOperand(temp,
+ SharedFunctionInfo::kInstanceClassNameOffset));
+ // The class name we are testing against is a symbol because it's a literal.
+ // The name in the constructor is a symbol because of the way the context is
+ // booted. This routine isn't expected to work for random API-created
+ // classes and it doesn't have to because you can't access it with natives
+ // syntax. Since both sides are symbols it is sufficient to use an identity
+ // comparison.
+ __ cmp(temp, Operand(class_name));
+ // End with the answer in the z flag.
}
@@ -1398,7 +1447,26 @@
void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
- Abort("DoClassOfTestAndBranch unimplemented.");
+ Register input = ToRegister(instr->input());
+ Register temp = ToRegister(instr->temporary());
+ Register temp2 = ToRegister(instr->temporary2());
+ if (input.is(temp)) {
+ // Swap.
Søren Thygesen Gjesse 2011/01/10 09:56:08 There is a Swap instruction in the macro assembler
Alexandre 2011/01/10 10:48:27 Removed. Not needed anymore, as all these register
+ Register swapper = temp;
+ temp = temp2;
+ temp2 = swapper;
+ }
+ Handle<String> class_name = instr->hydrogen()->class_name();
+
+ int true_block = chunk_->LookupDestination(instr->true_block_id());
+ int false_block = chunk_->LookupDestination(instr->false_block_id());
+
+ Label* true_label = chunk_->GetAssemblyLabel(true_block);
+ Label* false_label = chunk_->GetAssemblyLabel(false_block);
+
+ EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
+
+ EmitBranch(true_block, false_block, eq);
}
@@ -1784,12 +1852,42 @@
void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
- Abort("DoMathFloor unimplemented.");
+ DoubleRegister input_reg = ToDoubleRegister(instr->input());
Søren Thygesen Gjesse 2011/01/10 09:56:08 input_reg -> input?
+ SwVfpRegister single_precision_scratch = s0;
Søren Thygesen Gjesse 2011/01/10 09:56:08 Please add double_scratch0() and single_scratch0()
+ Register result = ToRegister(instr->result());
+ Register scratch = scratch0();
+
+ // Set custom FPCSR:
+ // - Set rounding mode to "Round towards Minus Infinity"
Søren Thygesen Gjesse 2011/01/10 09:56:08 No need to refer to specific bit numbers in the co
+ // (ie bits [23:22] = 0b10).
+ // - Clear vfp cumulative exception flags (bits [3:0]).
+ // - Make sure Flush-to-zero mode control bit is unset (bit 22).
+ __ vmrs(scratch);
Søren Thygesen Gjesse 2011/01/10 09:56:08 Don't we need to backup and restore FPSCR here? Th
+ __ bic(scratch, scratch,
+ Operand(kVFPExceptionMask | kVFPRoundingModeMask | kVFPFlushToZeroMask));
+ __ orr(scratch, scratch, Operand(kVFPRoundToMinusInfinityBits));
+ __ vmsr(scratch);
+
+ // Convert the argument to an integer.
+ __ vcvt_s32_f64(single_precision_scratch,
+ input_reg,
+ Assembler::FPSCRRounding,
+ al);
+
+ // Retrieve FPSCR and check for vfp exceptions.
+ __ vmrs(scratch);
+ __ tst(scratch, Operand(kVFPExceptionMask));
+ DeoptimizeIf(ne, instr->environment());
+
+ // Move the result back to general purpose register r0.
+ __ vmov(result, single_precision_scratch);
}
void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
- Abort("DoMathSqrt unimplemented.");
+ DoubleRegister input_reg = ToDoubleRegister(instr->input());
Søren Thygesen Gjesse 2011/01/10 09:56:08 input_reg -> input?
Alexandre 2011/01/10 10:48:27 Done.
+ ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
+ __ vsqrt(input_reg, input_reg);
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698