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

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

Issue 6965006: Update mips infrastructure files. (Closed) Base URL: http://github.com/v8/v8.git@bleeding_edge
Patch Set: Fix additional style issues. 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
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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
488 // Generate code the to load an element from a pixel array. The receiver is 460 class FloatingPointHelper : public AllStatic {
489 // assumed to not be a smi and to have elements, the caller must guarantee this 461 public:
490 // precondition. If the receiver does not have elements that are pixel arrays, 462
491 // the generated code jumps to not_pixel_array. If key is not a smi, then the 463 enum Destination {
492 // generated code branches to key_not_smi. Callers can specify NULL for 464 kFPURegisters,
493 // key_not_smi to signal that a smi check has already been performed on key so 465 kCoreRegisters
494 // that the smi check is not generated . If key is not a valid index within the 466 };
495 // bounds of the pixel array, the generated code jumps to out_of_range. 467
496 void GenerateFastPixelArrayLoad(MacroAssembler* masm, 468
497 Register receiver, 469 // Loads smis from a0 and a1 (right and left in binary operations) into
498 Register key, 470 // floating point registers. Depending on the destination the values ends up
499 Register elements_map, 471 // either f14 and f12 or in a2/a3 and a0/a1 respectively. If the destination
500 Register elements, 472 // is floating point registers FPU must be supported. If core registers are
473 // requested when FPU is supported f12 and f14 will be scratched.
474 static void LoadSmis(MacroAssembler* masm,
475 Destination destination,
476 Register scratch1,
477 Register scratch2);
478
479 // Loads objects from a0 and a1 (right and left in binary operations) into
480 // floating point registers. Depending on the destination the values ends up
481 // either f14 and f12 or in a2/a3 and a0/a1 respectively. If the destination
482 // is floating point registers FPU must be supported. If core registers are
483 // requested when FPU is supported f12 and f14 will still be scratched. If
484 // either a0 or a1 is not a number (not smi and not heap number object) the
485 // not_number label is jumped to with a0 and a1 intact.
486 static void LoadOperands(MacroAssembler* masm,
487 FloatingPointHelper::Destination destination,
488 Register heap_number_map,
489 Register scratch1,
490 Register scratch2,
491 Label* not_number);
492
493 // Convert the smi or heap number in object to an int32 using the rules
494 // for ToInt32 as described in ECMAScript 9.5.: the value is truncated
495 // and brought into the range -2^31 .. +2^31 - 1.
496 static void ConvertNumberToInt32(MacroAssembler* masm,
497 Register object,
498 Register dst,
499 Register heap_number_map,
500 Register scratch1,
501 Register scratch2,
502 Register scratch3,
503 FPURegister double_scratch,
504 Label* not_int32);
505
506 // Converts the integer (untagged smi) in |int_scratch| to a double, storing
507 // the result either in |double_dst| or |dst2:dst1|, depending on
508 // |destination|.
509 // Warning: The value in |int_scratch| will be changed in the process!
510 static void ConvertIntToDouble(MacroAssembler* masm,
511 Register int_scratch,
512 Destination destination,
513 FPURegister double_dst,
514 Register dst1,
515 Register dst2,
516 Register scratch2,
517 FPURegister single_scratch);
518
519 // Load the number from object into double_dst in the double format.
520 // Control will jump to not_int32 if the value cannot be exactly represented
521 // by a 32-bit integer.
522 // Floating point value in the 32-bit integer range that are not exact integer
523 // won't be loaded.
524 static void LoadNumberAsInt32Double(MacroAssembler* masm,
525 Register object,
526 Destination destination,
527 FPURegister double_dst,
528 Register dst1,
529 Register dst2,
530 Register heap_number_map,
531 Register scratch1,
532 Register scratch2,
533 FPURegister single_scratch,
534 Label* not_int32);
535
536 // Loads the number from object into dst as a 32-bit integer.
537 // Control will jump to not_int32 if the object cannot be exactly represented
538 // by a 32-bit integer.
539 // Floating point value in the 32-bit integer range that are not exact integer
540 // won't be converted.
541 // scratch3 is not used when FPU is supported.
542 static void LoadNumberAsInt32(MacroAssembler* masm,
543 Register object,
544 Register dst,
545 Register heap_number_map,
501 Register scratch1, 546 Register scratch1,
502 Register scratch2, 547 Register scratch2,
503 Register result, 548 Register scratch3,
504 Label* not_pixel_array, 549 FPURegister double_scratch,
505 Label* key_not_smi, 550 Label* not_int32);
506 Label* out_of_range); 551
552 // Generate non FPU code to check if a double can be exactly represented by a
553 // 32-bit integer. This does not check for 0 or -0, which need
554 // to be checked for separately.
555 // Control jumps to not_int32 if the value is not a 32-bit integer, and falls
556 // through otherwise.
557 // src1 and src2 will be cloberred.
558 //
559 // Expected input:
560 // - src1: higher (exponent) part of the double value.
561 // - src2: lower (mantissa) part of the double value.
562 // Output status:
563 // - dst: 32 higher bits of the mantissa. (mantissa[51:20])
564 // - src2: contains 1.
565 // - other registers are clobbered.
566 static void DoubleIs32BitInteger(MacroAssembler* masm,
567 Register src1,
568 Register src2,
569 Register dst,
570 Register scratch,
571 Label* not_int32);
572
573 // Generates code to call a C function to do a double operation using core
574 // registers. (Used when FPU is not supported.)
575 // This code never falls through, but returns with a heap number containing
576 // the result in v0.
577 // Register heapnumber_result must be a heap number in which the
578 // result of the operation will be stored.
579 // Requires the following layout on entry:
580 // a0: Left value (least significant part of mantissa).
581 // a1: Left value (sign, exponent, top of mantissa).
582 // a2: Right value (least significant part of mantissa).
583 // a3: Right value (sign, exponent, top of mantissa).
584 static void CallCCodeForDoubleOperation(MacroAssembler* masm,
585 Token::Value op,
586 Register heap_number_result,
587 Register scratch);
588
589 private:
590 static void LoadNumber(MacroAssembler* masm,
591 FloatingPointHelper::Destination destination,
592 Register object,
593 FPURegister dst,
594 Register dst1,
595 Register dst2,
596 Register heap_number_map,
597 Register scratch1,
598 Register scratch2,
599 Label* not_number);
600 };
601
602
603 class StringDictionaryLookupStub: public CodeStub {
604 public:
605 enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
606
607 explicit StringDictionaryLookupStub(LookupMode mode) : mode_(mode) { }
608
609 void Generate(MacroAssembler* masm);
610
611 static void GenerateNegativeLookup(MacroAssembler* masm,
612 Label* miss,
613 Label* done,
614 Register receiver,
615 Register properties,
616 String* name,
617 Register scratch0) ;
618
619 static void GeneratePositiveLookup(MacroAssembler* masm,
620 Label* miss,
621 Label* done,
622 Register elements,
623 Register name,
624 Register r0,
625 Register r1);
626
627 private:
628 static const int kInlinedProbes = 4;
629 static const int kTotalProbes = 20;
630
631 static const int kCapacityOffset =
632 StringDictionary::kHeaderSize +
633 StringDictionary::kCapacityIndex * kPointerSize;
634
635 static const int kElementsStartOffset =
636 StringDictionary::kHeaderSize +
637 StringDictionary::kElementsStartIndex * kPointerSize;
638
639
640 #ifdef DEBUG
641 void Print() {
642 PrintF("StringDictionaryLookupStub\n");
643 }
644 #endif
645
646 Major MajorKey() { return StringDictionaryNegativeLookup; }
647
648 int MinorKey() {
649 return LookupModeBits::encode(mode_);
650 }
651
652 class LookupModeBits: public BitField<LookupMode, 0, 1> {};
653
654 LookupMode mode_;
655 };
507 656
508 657
509 } } // namespace v8::internal 658 } } // namespace v8::internal
510 659
511 #endif // V8_MIPS_CODE_STUBS_ARM_H_ 660 #endif // V8_MIPS_CODE_STUBS_ARM_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698