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

Side by Side Diff: src/mips/code-stubs-mips.h

Issue 7060010: Merge bleeding edge into the GC branch up to 7948. The asserts (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mips/builtins-mips.cc ('k') | src/mips/code-stubs-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
(...skipping 20 matching lines...) Expand all
32 32
33 33
34 namespace v8 { 34 namespace v8 {
35 namespace internal { 35 namespace internal {
36 36
37 37
38 // Compute a transcendental math function natively, or call the 38 // Compute a transcendental math function natively, or call the
39 // TranscendentalCache runtime function. 39 // TranscendentalCache runtime function.
40 class TranscendentalCacheStub: public CodeStub { 40 class TranscendentalCacheStub: public CodeStub {
41 public: 41 public:
42 explicit TranscendentalCacheStub(TranscendentalCache::Type type) 42 enum ArgumentType {
43 : type_(type) {} 43 TAGGED = 0 << TranscendentalCache::kTranscendentalTypeBits,
44 UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits
45 };
46
47 TranscendentalCacheStub(TranscendentalCache::Type type,
48 ArgumentType argument_type)
49 : type_(type), argument_type_(argument_type) { }
44 void Generate(MacroAssembler* masm); 50 void Generate(MacroAssembler* masm);
45 private: 51 private:
46 TranscendentalCache::Type type_; 52 TranscendentalCache::Type type_;
53 ArgumentType argument_type_;
54 void GenerateCallCFunction(MacroAssembler* masm, Register scratch);
55
47 Major MajorKey() { return TranscendentalCache; } 56 Major MajorKey() { return TranscendentalCache; }
48 int MinorKey() { return type_; } 57 int MinorKey() { return type_ | argument_type_; }
49 Runtime::FunctionId RuntimeFunction(); 58 Runtime::FunctionId RuntimeFunction();
50 }; 59 };
51 60
52 61
53 class ToBooleanStub: public CodeStub { 62 class ToBooleanStub: public CodeStub {
54 public: 63 public:
55 explicit ToBooleanStub(Register tos) : tos_(tos) { } 64 explicit ToBooleanStub(Register tos) : tos_(tos) { }
56 65
57 void Generate(MacroAssembler* masm); 66 void Generate(MacroAssembler* masm);
58 67
59 private: 68 private:
60 Register tos_; 69 Register tos_;
61 Major MajorKey() { return ToBoolean; } 70 Major MajorKey() { return ToBoolean; }
62 int MinorKey() { return tos_.code(); } 71 int MinorKey() { return tos_.code(); }
63 }; 72 };
64 73
65 74
66 class GenericBinaryOpStub : public CodeStub { 75 class TypeRecordingUnaryOpStub: public CodeStub {
67 public: 76 public:
68 static const int kUnknownIntValue = -1; 77 TypeRecordingUnaryOpStub(Token::Value op, UnaryOverwriteMode mode)
69
70 GenericBinaryOpStub(Token::Value op,
71 OverwriteMode mode,
72 Register lhs,
73 Register rhs,
74 int constant_rhs = kUnknownIntValue)
75 : op_(op), 78 : op_(op),
76 mode_(mode), 79 mode_(mode),
77 lhs_(lhs), 80 operand_type_(TRUnaryOpIC::UNINITIALIZED),
78 rhs_(rhs), 81 name_(NULL) {
79 constant_rhs_(constant_rhs), 82 }
80 specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op, constant_rhs)),
81 runtime_operands_type_(BinaryOpIC::UNINIT_OR_SMI),
82 name_(NULL) { }
83 83
84 GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) 84 TypeRecordingUnaryOpStub(
85 int key,
86 TRUnaryOpIC::TypeInfo operand_type)
85 : op_(OpBits::decode(key)), 87 : op_(OpBits::decode(key)),
86 mode_(ModeBits::decode(key)), 88 mode_(ModeBits::decode(key)),
87 lhs_(LhsRegister(RegisterBits::decode(key))), 89 operand_type_(operand_type),
88 rhs_(RhsRegister(RegisterBits::decode(key))), 90 name_(NULL) {
89 constant_rhs_(KnownBitsForMinorKey(KnownIntBits::decode(key))), 91 }
90 specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op_, constant_rhs_)),
91 runtime_operands_type_(type_info),
92 name_(NULL) { }
93 92
94 private: 93 private:
95 Token::Value op_; 94 Token::Value op_;
96 OverwriteMode mode_; 95 UnaryOverwriteMode mode_;
97 Register lhs_; 96
98 Register rhs_; 97 // Operand type information determined at runtime.
99 int constant_rhs_; 98 TRUnaryOpIC::TypeInfo operand_type_;
100 bool specialized_on_rhs_; 99
101 BinaryOpIC::TypeInfo runtime_operands_type_;
102 char* name_; 100 char* name_;
103 101
104 static const int kMaxKnownRhs = 0x40000000;
105 static const int kKnownRhsKeyBits = 6;
106
107 // Minor key encoding in 16 bits.
108 class ModeBits: public BitField<OverwriteMode, 0, 2> {};
109 class OpBits: public BitField<Token::Value, 2, 6> {};
110 class TypeInfoBits: public BitField<int, 8, 3> {};
111 class RegisterBits: public BitField<bool, 11, 1> {};
112 class KnownIntBits: public BitField<int, 12, kKnownRhsKeyBits> {};
113
114 Major MajorKey() { return GenericBinaryOp; }
115 int MinorKey() {
116 ASSERT((lhs_.is(a0) && rhs_.is(a1)) ||
117 (lhs_.is(a1) && rhs_.is(a0)));
118 // Encode the parameters in a unique 16 bit value.
119 return OpBits::encode(op_)
120 | ModeBits::encode(mode_)
121 | KnownIntBits::encode(MinorKeyForKnownInt())
122 | TypeInfoBits::encode(runtime_operands_type_)
123 | RegisterBits::encode(lhs_.is(a0));
124 }
125
126 void Generate(MacroAssembler* masm);
127 void HandleNonSmiBitwiseOp(MacroAssembler* masm,
128 Register lhs,
129 Register rhs);
130 void HandleBinaryOpSlowCases(MacroAssembler* masm,
131 Label* not_smi,
132 Register lhs,
133 Register rhs,
134 const Builtins::JavaScript& builtin);
135 void GenerateTypeTransition(MacroAssembler* masm);
136
137 static bool RhsIsOneWeWantToOptimizeFor(Token::Value op, int constant_rhs) {
138 if (constant_rhs == kUnknownIntValue) return false;
139 if (op == Token::DIV) return constant_rhs >= 2 && constant_rhs <= 3;
140 if (op == Token::MOD) {
141 if (constant_rhs <= 1) return false;
142 if (constant_rhs <= 10) return true;
143 if (constant_rhs <= kMaxKnownRhs && IsPowerOf2(constant_rhs)) return true;
144 return false;
145 }
146 return false;
147 }
148
149 int MinorKeyForKnownInt() {
150 if (!specialized_on_rhs_) return 0;
151 if (constant_rhs_ <= 10) return constant_rhs_ + 1;
152 ASSERT(IsPowerOf2(constant_rhs_));
153 int key = 12;
154 int d = constant_rhs_;
155 while ((d & 1) == 0) {
156 key++;
157 d >>= 1;
158 }
159 ASSERT(key >= 0 && key < (1 << kKnownRhsKeyBits));
160 return key;
161 }
162
163 int KnownBitsForMinorKey(int key) {
164 if (!key) return 0;
165 if (key <= 11) return key - 1;
166 int d = 1;
167 while (key != 12) {
168 key--;
169 d <<= 1;
170 }
171 return d;
172 }
173
174 Register LhsRegister(bool lhs_is_a0) {
175 return lhs_is_a0 ? a0 : a1;
176 }
177
178 Register RhsRegister(bool lhs_is_a0) {
179 return lhs_is_a0 ? a1 : a0;
180 }
181
182 bool HasSmiSmiFastPath() {
183 return op_ != Token::DIV;
184 }
185
186 bool ShouldGenerateSmiCode() {
187 return ((op_ != Token::DIV && op_ != Token::MOD) || specialized_on_rhs_) &&
188 runtime_operands_type_ != BinaryOpIC::HEAP_NUMBERS &&
189 runtime_operands_type_ != BinaryOpIC::STRINGS;
190 }
191
192 bool ShouldGenerateFPCode() {
193 return runtime_operands_type_ != BinaryOpIC::STRINGS;
194 }
195
196 virtual int GetCodeKind() { return Code::BINARY_OP_IC; }
197
198 virtual InlineCacheState GetICState() {
199 return BinaryOpIC::ToState(runtime_operands_type_);
200 }
201
202 const char* GetName(); 102 const char* GetName();
203 103
204 virtual void FinishCode(Code* code) { 104 #ifdef DEBUG
205 code->set_binary_op_type(runtime_operands_type_); 105 void Print() {
106 PrintF("TypeRecordingUnaryOpStub %d (op %s), "
107 "(mode %d, runtime_type_info %s)\n",
108 MinorKey(),
109 Token::String(op_),
110 static_cast<int>(mode_),
111 TRUnaryOpIC::GetName(operand_type_));
112 }
113 #endif
114
115 class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
116 class OpBits: public BitField<Token::Value, 1, 7> {};
117 class OperandTypeInfoBits: public BitField<TRUnaryOpIC::TypeInfo, 8, 3> {};
118
119 Major MajorKey() { return TypeRecordingUnaryOp; }
120 int MinorKey() {
121 return ModeBits::encode(mode_)
122 | OpBits::encode(op_)
123 | OperandTypeInfoBits::encode(operand_type_);
206 } 124 }
207 125
208 #ifdef DEBUG 126 // Note: A lot of the helper functions below will vanish when we use virtual
209 void Print() { 127 // function instead of switch more often.
210 if (!specialized_on_rhs_) { 128 void Generate(MacroAssembler* masm);
211 PrintF("GenericBinaryOpStub (%s)\n", Token::String(op_)); 129
212 } else { 130 void GenerateTypeTransition(MacroAssembler* masm);
213 PrintF("GenericBinaryOpStub (%s by %d)\n", 131
214 Token::String(op_), 132 void GenerateSmiStub(MacroAssembler* masm);
215 constant_rhs_); 133 void GenerateSmiStubSub(MacroAssembler* masm);
216 } 134 void GenerateSmiStubBitNot(MacroAssembler* masm);
135 void GenerateSmiCodeSub(MacroAssembler* masm, Label* non_smi, Label* slow);
136 void GenerateSmiCodeBitNot(MacroAssembler* masm, Label* slow);
137
138 void GenerateHeapNumberStub(MacroAssembler* masm);
139 void GenerateHeapNumberStubSub(MacroAssembler* masm);
140 void GenerateHeapNumberStubBitNot(MacroAssembler* masm);
141 void GenerateHeapNumberCodeSub(MacroAssembler* masm, Label* slow);
142 void GenerateHeapNumberCodeBitNot(MacroAssembler* masm, Label* slow);
143
144 void GenerateGenericStub(MacroAssembler* masm);
145 void GenerateGenericStubSub(MacroAssembler* masm);
146 void GenerateGenericStubBitNot(MacroAssembler* masm);
147 void GenerateGenericCodeFallback(MacroAssembler* masm);
148
149 virtual int GetCodeKind() { return Code::TYPE_RECORDING_UNARY_OP_IC; }
150
151 virtual InlineCacheState GetICState() {
152 return TRUnaryOpIC::ToState(operand_type_);
217 } 153 }
218 #endif 154
155 virtual void FinishCode(Code* code) {
156 code->set_type_recording_unary_op_type(operand_type_);
157 }
219 }; 158 };
220 159
160
221 class TypeRecordingBinaryOpStub: public CodeStub { 161 class TypeRecordingBinaryOpStub: public CodeStub {
222 public: 162 public:
223 TypeRecordingBinaryOpStub(Token::Value op, OverwriteMode mode) 163 TypeRecordingBinaryOpStub(Token::Value op, OverwriteMode mode)
224 : op_(op), 164 : op_(op),
225 mode_(mode), 165 mode_(mode),
226 operands_type_(TRBinaryOpIC::UNINITIALIZED), 166 operands_type_(TRBinaryOpIC::UNINITIALIZED),
227 result_type_(TRBinaryOpIC::UNINITIALIZED), 167 result_type_(TRBinaryOpIC::UNINITIALIZED),
228 name_(NULL) { 168 name_(NULL) {
229 UNIMPLEMENTED_MIPS(); 169 use_fpu_ = CpuFeatures::IsSupported(FPU);
170 ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
230 } 171 }
231 172
232 TypeRecordingBinaryOpStub( 173 TypeRecordingBinaryOpStub(
233 int key, 174 int key,
234 TRBinaryOpIC::TypeInfo operands_type, 175 TRBinaryOpIC::TypeInfo operands_type,
235 TRBinaryOpIC::TypeInfo result_type = TRBinaryOpIC::UNINITIALIZED) 176 TRBinaryOpIC::TypeInfo result_type = TRBinaryOpIC::UNINITIALIZED)
236 : op_(OpBits::decode(key)), 177 : op_(OpBits::decode(key)),
237 mode_(ModeBits::decode(key)), 178 mode_(ModeBits::decode(key)),
238 use_fpu_(FPUBits::decode(key)), 179 use_fpu_(FPUBits::decode(key)),
239 operands_type_(operands_type), 180 operands_type_(operands_type),
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 } 227 }
287 228
288 void Generate(MacroAssembler* masm); 229 void Generate(MacroAssembler* masm);
289 void GenerateGeneric(MacroAssembler* masm); 230 void GenerateGeneric(MacroAssembler* masm);
290 void GenerateSmiSmiOperation(MacroAssembler* masm); 231 void GenerateSmiSmiOperation(MacroAssembler* masm);
291 void GenerateFPOperation(MacroAssembler* masm, 232 void GenerateFPOperation(MacroAssembler* masm,
292 bool smi_operands, 233 bool smi_operands,
293 Label* not_numbers, 234 Label* not_numbers,
294 Label* gc_required); 235 Label* gc_required);
295 void GenerateSmiCode(MacroAssembler* masm, 236 void GenerateSmiCode(MacroAssembler* masm,
237 Label* use_runtime,
296 Label* gc_required, 238 Label* gc_required,
297 SmiCodeGenerateHeapNumberResults heapnumber_results); 239 SmiCodeGenerateHeapNumberResults heapnumber_results);
298 void GenerateLoadArguments(MacroAssembler* masm); 240 void GenerateLoadArguments(MacroAssembler* masm);
299 void GenerateReturn(MacroAssembler* masm); 241 void GenerateReturn(MacroAssembler* masm);
300 void GenerateUninitializedStub(MacroAssembler* masm); 242 void GenerateUninitializedStub(MacroAssembler* masm);
301 void GenerateSmiStub(MacroAssembler* masm); 243 void GenerateSmiStub(MacroAssembler* masm);
302 void GenerateInt32Stub(MacroAssembler* masm); 244 void GenerateInt32Stub(MacroAssembler* masm);
303 void GenerateHeapNumberStub(MacroAssembler* masm); 245 void GenerateHeapNumberStub(MacroAssembler* masm);
246 void GenerateOddballStub(MacroAssembler* masm);
304 void GenerateStringStub(MacroAssembler* masm); 247 void GenerateStringStub(MacroAssembler* masm);
248 void GenerateBothStringStub(MacroAssembler* masm);
305 void GenerateGenericStub(MacroAssembler* masm); 249 void GenerateGenericStub(MacroAssembler* masm);
306 void GenerateAddStrings(MacroAssembler* masm); 250 void GenerateAddStrings(MacroAssembler* masm);
307 void GenerateCallRuntime(MacroAssembler* masm); 251 void GenerateCallRuntime(MacroAssembler* masm);
308 252
309 void GenerateHeapResultAllocation(MacroAssembler* masm, 253 void GenerateHeapResultAllocation(MacroAssembler* masm,
310 Register result, 254 Register result,
311 Register heap_number_map, 255 Register heap_number_map,
312 Register scratch1, 256 Register scratch1,
313 Register scratch2, 257 Register scratch2,
314 Label* gc_required); 258 Label* gc_required);
(...skipping 12 matching lines...) Expand all
327 code->set_type_recording_binary_op_result_type(result_type_); 271 code->set_type_recording_binary_op_result_type(result_type_);
328 } 272 }
329 273
330 friend class CodeGenerator; 274 friend class CodeGenerator;
331 }; 275 };
332 276
333 277
334 // Flag that indicates how to generate code for the stub StringAddStub. 278 // Flag that indicates how to generate code for the stub StringAddStub.
335 enum StringAddFlags { 279 enum StringAddFlags {
336 NO_STRING_ADD_FLAGS = 0, 280 NO_STRING_ADD_FLAGS = 0,
337 NO_STRING_CHECK_IN_STUB = 1 << 0 // Omit string check in stub. 281 // Omit left string check in stub (left is definitely a string).
282 NO_STRING_CHECK_LEFT_IN_STUB = 1 << 0,
283 // Omit right string check in stub (right is definitely a string).
284 NO_STRING_CHECK_RIGHT_IN_STUB = 1 << 1,
285 // Omit both string checks in stub.
286 NO_STRING_CHECK_IN_STUB =
287 NO_STRING_CHECK_LEFT_IN_STUB | NO_STRING_CHECK_RIGHT_IN_STUB
338 }; 288 };
339 289
340 290
341 class StringAddStub: public CodeStub { 291 class StringAddStub: public CodeStub {
342 public: 292 public:
343 explicit StringAddStub(StringAddFlags flags) { 293 explicit StringAddStub(StringAddFlags flags) : flags_(flags) {}
344 string_check_ = ((flags & NO_STRING_CHECK_IN_STUB) == 0);
345 }
346 294
347 private: 295 private:
348 Major MajorKey() { return StringAdd; } 296 Major MajorKey() { return StringAdd; }
349 int MinorKey() { return string_check_ ? 0 : 1; } 297 int MinorKey() { return flags_; }
350 298
351 void Generate(MacroAssembler* masm); 299 void Generate(MacroAssembler* masm);
352 300
353 // Should the stub check whether arguments are strings? 301 void GenerateConvertArgument(MacroAssembler* masm,
354 bool string_check_; 302 int stack_offset,
303 Register arg,
304 Register scratch1,
305 Register scratch2,
306 Register scratch3,
307 Register scratch4,
308 Label* slow);
309
310 const StringAddFlags flags_;
355 }; 311 };
356 312
357 313
358 class SubStringStub: public CodeStub { 314 class SubStringStub: public CodeStub {
359 public: 315 public:
360 SubStringStub() {} 316 SubStringStub() {}
361 317
362 private: 318 private:
363 Major MajorKey() { return SubString; } 319 Major MajorKey() { return SubString; }
364 int MinorKey() { return 0; } 320 int MinorKey() { return 0; }
365 321
366 void Generate(MacroAssembler* masm); 322 void Generate(MacroAssembler* masm);
367 }; 323 };
368 324
369 325
370 class StringCompareStub: public CodeStub { 326 class StringCompareStub: public CodeStub {
371 public: 327 public:
372 StringCompareStub() { } 328 StringCompareStub() { }
373 329
374 // Compare two flat ASCII strings and returns result in v0. 330 // Compare two flat ASCII strings and returns result in v0.
375 // Does not use the stack.
376 static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm, 331 static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
377 Register left, 332 Register left,
378 Register right, 333 Register right,
379 Register scratch1, 334 Register scratch1,
380 Register scratch2, 335 Register scratch2,
381 Register scratch3, 336 Register scratch3,
382 Register scratch4); 337 Register scratch4);
383 338
339 // Compares two flat ASCII strings for equality and returns result
340 // in v0.
341 static void GenerateFlatAsciiStringEquals(MacroAssembler* masm,
342 Register left,
343 Register right,
344 Register scratch1,
345 Register scratch2,
346 Register scratch3);
347
384 private: 348 private:
385 Major MajorKey() { return StringCompare; } 349 virtual Major MajorKey() { return StringCompare; }
386 int MinorKey() { return 0; } 350 virtual int MinorKey() { return 0; }
351 virtual void Generate(MacroAssembler* masm);
387 352
388 void Generate(MacroAssembler* masm); 353 static void GenerateAsciiCharsCompareLoop(MacroAssembler* masm,
354 Register left,
355 Register right,
356 Register length,
357 Register scratch1,
358 Register scratch2,
359 Register scratch3,
360 Label* chars_not_equal);
389 }; 361 };
390 362
391 363
392 // This stub can convert a signed int32 to a heap number (double). It does 364 // This stub can convert a signed int32 to a heap number (double). It does
393 // not work for int32s that are in Smi range! No GC occurs during this stub 365 // not work for int32s that are in Smi range! No GC occurs during this stub
394 // so you don't have to set up the frame. 366 // so you don't have to set up the frame.
395 class WriteInt32ToHeapNumberStub : public CodeStub { 367 class WriteInt32ToHeapNumberStub : public CodeStub {
396 public: 368 public:
397 WriteInt32ToHeapNumberStub(Register the_int, 369 WriteInt32ToHeapNumberStub(Register the_int,
398 Register the_heap_number, 370 Register the_heap_number,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 449
478 private: 450 private:
479 Major MajorKey() { return RegExpCEntry; } 451 Major MajorKey() { return RegExpCEntry; }
480 int MinorKey() { return 0; } 452 int MinorKey() { return 0; }
481 453
482 bool NeedsImmovableCode() { return true; } 454 bool NeedsImmovableCode() { return true; }
483 455
484 const char* GetName() { return "RegExpCEntryStub"; } 456 const char* GetName() { return "RegExpCEntryStub"; }
485 }; 457 };
486 458
487 459 // Trampoline stub to call into native code. To call safely into native code
488 // Generate code the to load an element from a pixel array. The receiver is 460 // in the presence of compacting GC (which can move code objects) we need to
489 // assumed to not be a smi and to have elements, the caller must guarantee this 461 // keep the code which called into native pinned in the memory. Currently the
490 // precondition. If the receiver does not have elements that are pixel arrays, 462 // simplest approach is to generate such stub early enough so it can never be
491 // the generated code jumps to not_pixel_array. If key is not a smi, then the 463 // moved by GC
492 // generated code branches to key_not_smi. Callers can specify NULL for 464 class DirectCEntryStub: public CodeStub {
493 // key_not_smi to signal that a smi check has already been performed on key so 465 public:
494 // that the smi check is not generated . If key is not a valid index within the 466 DirectCEntryStub() {}
495 // bounds of the pixel array, the generated code jumps to out_of_range. 467 void Generate(MacroAssembler* masm);
496 void GenerateFastPixelArrayLoad(MacroAssembler* masm, 468 void GenerateCall(MacroAssembler* masm,
497 Register receiver, 469 ExternalReference function);
498 Register key, 470 void GenerateCall(MacroAssembler* masm, Register target);
499 Register elements_map, 471
500 Register elements, 472 private:
473 Major MajorKey() { return DirectCEntry; }
474 int MinorKey() { return 0; }
475
476 bool NeedsImmovableCode() { return true; }
477
478 const char* GetName() { return "DirectCEntryStub"; }
479 };
480
481 class FloatingPointHelper : public AllStatic {
482 public:
483
484 enum Destination {
485 kFPURegisters,
486 kCoreRegisters
487 };
488
489
490 // Loads smis from a0 and a1 (right and left in binary operations) into
491 // floating point registers. Depending on the destination the values ends up
492 // either f14 and f12 or in a2/a3 and a0/a1 respectively. If the destination
493 // is floating point registers FPU must be supported. If core registers are
494 // requested when FPU is supported f12 and f14 will be scratched.
495 static void LoadSmis(MacroAssembler* masm,
496 Destination destination,
497 Register scratch1,
498 Register scratch2);
499
500 // Loads objects from a0 and a1 (right and left in binary operations) into
501 // floating point registers. Depending on the destination the values ends up
502 // either f14 and f12 or in a2/a3 and a0/a1 respectively. If the destination
503 // is floating point registers FPU must be supported. If core registers are
504 // requested when FPU is supported f12 and f14 will still be scratched. If
505 // either a0 or a1 is not a number (not smi and not heap number object) the
506 // not_number label is jumped to with a0 and a1 intact.
507 static void LoadOperands(MacroAssembler* masm,
508 FloatingPointHelper::Destination destination,
509 Register heap_number_map,
510 Register scratch1,
511 Register scratch2,
512 Label* not_number);
513
514 // Convert the smi or heap number in object to an int32 using the rules
515 // for ToInt32 as described in ECMAScript 9.5.: the value is truncated
516 // and brought into the range -2^31 .. +2^31 - 1.
517 static void ConvertNumberToInt32(MacroAssembler* masm,
518 Register object,
519 Register dst,
520 Register heap_number_map,
521 Register scratch1,
522 Register scratch2,
523 Register scratch3,
524 FPURegister double_scratch,
525 Label* not_int32);
526
527 // Converts the integer (untagged smi) in |int_scratch| to a double, storing
528 // the result either in |double_dst| or |dst2:dst1|, depending on
529 // |destination|.
530 // Warning: The value in |int_scratch| will be changed in the process!
531 static void ConvertIntToDouble(MacroAssembler* masm,
532 Register int_scratch,
533 Destination destination,
534 FPURegister double_dst,
535 Register dst1,
536 Register dst2,
537 Register scratch2,
538 FPURegister single_scratch);
539
540 // Load the number from object into double_dst in the double format.
541 // Control will jump to not_int32 if the value cannot be exactly represented
542 // by a 32-bit integer.
543 // Floating point value in the 32-bit integer range that are not exact integer
544 // won't be loaded.
545 static void LoadNumberAsInt32Double(MacroAssembler* masm,
546 Register object,
547 Destination destination,
548 FPURegister double_dst,
549 Register dst1,
550 Register dst2,
551 Register heap_number_map,
552 Register scratch1,
553 Register scratch2,
554 FPURegister single_scratch,
555 Label* not_int32);
556
557 // Loads the number from object into dst as a 32-bit integer.
558 // Control will jump to not_int32 if the object cannot be exactly represented
559 // by a 32-bit integer.
560 // Floating point value in the 32-bit integer range that are not exact integer
561 // won't be converted.
562 // scratch3 is not used when FPU is supported.
563 static void LoadNumberAsInt32(MacroAssembler* masm,
564 Register object,
565 Register dst,
566 Register heap_number_map,
501 Register scratch1, 567 Register scratch1,
502 Register scratch2, 568 Register scratch2,
503 Register result, 569 Register scratch3,
504 Label* not_pixel_array, 570 FPURegister double_scratch,
505 Label* key_not_smi, 571 Label* not_int32);
506 Label* out_of_range); 572
573 // Generate non FPU code to check if a double can be exactly represented by a
574 // 32-bit integer. This does not check for 0 or -0, which need
575 // to be checked for separately.
576 // Control jumps to not_int32 if the value is not a 32-bit integer, and falls
577 // through otherwise.
578 // src1 and src2 will be cloberred.
579 //
580 // Expected input:
581 // - src1: higher (exponent) part of the double value.
582 // - src2: lower (mantissa) part of the double value.
583 // Output status:
584 // - dst: 32 higher bits of the mantissa. (mantissa[51:20])
585 // - src2: contains 1.
586 // - other registers are clobbered.
587 static void DoubleIs32BitInteger(MacroAssembler* masm,
588 Register src1,
589 Register src2,
590 Register dst,
591 Register scratch,
592 Label* not_int32);
593
594 // Generates code to call a C function to do a double operation using core
595 // registers. (Used when FPU is not supported.)
596 // This code never falls through, but returns with a heap number containing
597 // the result in v0.
598 // Register heapnumber_result must be a heap number in which the
599 // result of the operation will be stored.
600 // Requires the following layout on entry:
601 // a0: Left value (least significant part of mantissa).
602 // a1: Left value (sign, exponent, top of mantissa).
603 // a2: Right value (least significant part of mantissa).
604 // a3: Right value (sign, exponent, top of mantissa).
605 static void CallCCodeForDoubleOperation(MacroAssembler* masm,
606 Token::Value op,
607 Register heap_number_result,
608 Register scratch);
609
610 private:
611 static void LoadNumber(MacroAssembler* masm,
612 FloatingPointHelper::Destination destination,
613 Register object,
614 FPURegister dst,
615 Register dst1,
616 Register dst2,
617 Register heap_number_map,
618 Register scratch1,
619 Register scratch2,
620 Label* not_number);
621 };
622
623
624 class StringDictionaryLookupStub: public CodeStub {
625 public:
626 enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
627
628 explicit StringDictionaryLookupStub(LookupMode mode) : mode_(mode) { }
629
630 void Generate(MacroAssembler* masm);
631
632 MUST_USE_RESULT static MaybeObject* GenerateNegativeLookup(
633 MacroAssembler* masm,
634 Label* miss,
635 Label* done,
636 Register receiver,
637 Register properties,
638 String* name,
639 Register scratch0);
640
641 static void GeneratePositiveLookup(MacroAssembler* masm,
642 Label* miss,
643 Label* done,
644 Register elements,
645 Register name,
646 Register r0,
647 Register r1);
648
649 private:
650 static const int kInlinedProbes = 4;
651 static const int kTotalProbes = 20;
652
653 static const int kCapacityOffset =
654 StringDictionary::kHeaderSize +
655 StringDictionary::kCapacityIndex * kPointerSize;
656
657 static const int kElementsStartOffset =
658 StringDictionary::kHeaderSize +
659 StringDictionary::kElementsStartIndex * kPointerSize;
660
661
662 #ifdef DEBUG
663 void Print() {
664 PrintF("StringDictionaryLookupStub\n");
665 }
666 #endif
667
668 Major MajorKey() { return StringDictionaryNegativeLookup; }
669
670 int MinorKey() {
671 return LookupModeBits::encode(mode_);
672 }
673
674 class LookupModeBits: public BitField<LookupMode, 0, 1> {};
675
676 LookupMode mode_;
677 };
507 678
508 679
509 } } // namespace v8::internal 680 } } // namespace v8::internal
510 681
511 #endif // V8_MIPS_CODE_STUBS_ARM_H_ 682 #endif // V8_MIPS_CODE_STUBS_ARM_H_
OLDNEW
« no previous file with comments | « src/mips/builtins-mips.cc ('k') | src/mips/code-stubs-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698