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

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

Issue 6759025: Version 3.2.6 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 9 years, 8 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
(Empty)
1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #ifndef V8_MIPS_CODE_STUBS_ARM_H_
29 #define V8_MIPS_CODE_STUBS_ARM_H_
30
31 #include "ic-inl.h"
32
33
34 namespace v8 {
35 namespace internal {
36
37
38 // Compute a transcendental math function natively, or call the
39 // TranscendentalCache runtime function.
40 class TranscendentalCacheStub: public CodeStub {
41 public:
42 explicit TranscendentalCacheStub(TranscendentalCache::Type type)
43 : type_(type) {}
44 void Generate(MacroAssembler* masm);
45 private:
46 TranscendentalCache::Type type_;
47 Major MajorKey() { return TranscendentalCache; }
48 int MinorKey() { return type_; }
49 Runtime::FunctionId RuntimeFunction();
50 };
51
52
53 class ToBooleanStub: public CodeStub {
54 public:
55 explicit ToBooleanStub(Register tos) : tos_(tos) { }
56
57 void Generate(MacroAssembler* masm);
58
59 private:
60 Register tos_;
61 Major MajorKey() { return ToBoolean; }
62 int MinorKey() { return tos_.code(); }
63 };
64
65
66 class GenericBinaryOpStub : public CodeStub {
67 public:
68 static const int kUnknownIntValue = -1;
69
70 GenericBinaryOpStub(Token::Value op,
71 OverwriteMode mode,
72 Register lhs,
73 Register rhs,
74 int constant_rhs = kUnknownIntValue)
75 : op_(op),
76 mode_(mode),
77 lhs_(lhs),
78 rhs_(rhs),
79 constant_rhs_(constant_rhs),
80 specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op, constant_rhs)),
81 runtime_operands_type_(BinaryOpIC::UNINIT_OR_SMI),
82 name_(NULL) { }
83
84 GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info)
85 : op_(OpBits::decode(key)),
86 mode_(ModeBits::decode(key)),
87 lhs_(LhsRegister(RegisterBits::decode(key))),
88 rhs_(RhsRegister(RegisterBits::decode(key))),
89 constant_rhs_(KnownBitsForMinorKey(KnownIntBits::decode(key))),
90 specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op_, constant_rhs_)),
91 runtime_operands_type_(type_info),
92 name_(NULL) { }
93
94 private:
95 Token::Value op_;
96 OverwriteMode mode_;
97 Register lhs_;
98 Register rhs_;
99 int constant_rhs_;
100 bool specialized_on_rhs_;
101 BinaryOpIC::TypeInfo runtime_operands_type_;
102 char* name_;
103
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();
203
204 virtual void FinishCode(Code* code) {
205 code->set_binary_op_type(runtime_operands_type_);
206 }
207
208 #ifdef DEBUG
209 void Print() {
210 if (!specialized_on_rhs_) {
211 PrintF("GenericBinaryOpStub (%s)\n", Token::String(op_));
212 } else {
213 PrintF("GenericBinaryOpStub (%s by %d)\n",
214 Token::String(op_),
215 constant_rhs_);
216 }
217 }
218 #endif
219 };
220
221 class TypeRecordingBinaryOpStub: public CodeStub {
222 public:
223 TypeRecordingBinaryOpStub(Token::Value op, OverwriteMode mode)
224 : op_(op),
225 mode_(mode),
226 operands_type_(TRBinaryOpIC::UNINITIALIZED),
227 result_type_(TRBinaryOpIC::UNINITIALIZED),
228 name_(NULL) {
229 UNIMPLEMENTED_MIPS();
230 }
231
232 TypeRecordingBinaryOpStub(
233 int key,
234 TRBinaryOpIC::TypeInfo operands_type,
235 TRBinaryOpIC::TypeInfo result_type = TRBinaryOpIC::UNINITIALIZED)
236 : op_(OpBits::decode(key)),
237 mode_(ModeBits::decode(key)),
238 use_fpu_(FPUBits::decode(key)),
239 operands_type_(operands_type),
240 result_type_(result_type),
241 name_(NULL) { }
242
243 private:
244 enum SmiCodeGenerateHeapNumberResults {
245 ALLOW_HEAPNUMBER_RESULTS,
246 NO_HEAPNUMBER_RESULTS
247 };
248
249 Token::Value op_;
250 OverwriteMode mode_;
251 bool use_fpu_;
252
253 // Operand type information determined at runtime.
254 TRBinaryOpIC::TypeInfo operands_type_;
255 TRBinaryOpIC::TypeInfo result_type_;
256
257 char* name_;
258
259 const char* GetName();
260
261 #ifdef DEBUG
262 void Print() {
263 PrintF("TypeRecordingBinaryOpStub %d (op %s), "
264 "(mode %d, runtime_type_info %s)\n",
265 MinorKey(),
266 Token::String(op_),
267 static_cast<int>(mode_),
268 TRBinaryOpIC::GetName(operands_type_));
269 }
270 #endif
271
272 // Minor key encoding in 16 bits RRRTTTVOOOOOOOMM.
273 class ModeBits: public BitField<OverwriteMode, 0, 2> {};
274 class OpBits: public BitField<Token::Value, 2, 7> {};
275 class FPUBits: public BitField<bool, 9, 1> {};
276 class OperandTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 10, 3> {};
277 class ResultTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 13, 3> {};
278
279 Major MajorKey() { return TypeRecordingBinaryOp; }
280 int MinorKey() {
281 return OpBits::encode(op_)
282 | ModeBits::encode(mode_)
283 | FPUBits::encode(use_fpu_)
284 | OperandTypeInfoBits::encode(operands_type_)
285 | ResultTypeInfoBits::encode(result_type_);
286 }
287
288 void Generate(MacroAssembler* masm);
289 void GenerateGeneric(MacroAssembler* masm);
290 void GenerateSmiSmiOperation(MacroAssembler* masm);
291 void GenerateFPOperation(MacroAssembler* masm,
292 bool smi_operands,
293 Label* not_numbers,
294 Label* gc_required);
295 void GenerateSmiCode(MacroAssembler* masm,
296 Label* gc_required,
297 SmiCodeGenerateHeapNumberResults heapnumber_results);
298 void GenerateLoadArguments(MacroAssembler* masm);
299 void GenerateReturn(MacroAssembler* masm);
300 void GenerateUninitializedStub(MacroAssembler* masm);
301 void GenerateSmiStub(MacroAssembler* masm);
302 void GenerateInt32Stub(MacroAssembler* masm);
303 void GenerateHeapNumberStub(MacroAssembler* masm);
304 void GenerateStringStub(MacroAssembler* masm);
305 void GenerateGenericStub(MacroAssembler* masm);
306 void GenerateAddStrings(MacroAssembler* masm);
307 void GenerateCallRuntime(MacroAssembler* masm);
308
309 void GenerateHeapResultAllocation(MacroAssembler* masm,
310 Register result,
311 Register heap_number_map,
312 Register scratch1,
313 Register scratch2,
314 Label* gc_required);
315 void GenerateRegisterArgsPush(MacroAssembler* masm);
316 void GenerateTypeTransition(MacroAssembler* masm);
317 void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm);
318
319 virtual int GetCodeKind() { return Code::TYPE_RECORDING_BINARY_OP_IC; }
320
321 virtual InlineCacheState GetICState() {
322 return TRBinaryOpIC::ToState(operands_type_);
323 }
324
325 virtual void FinishCode(Code* code) {
326 code->set_type_recording_binary_op_type(operands_type_);
327 code->set_type_recording_binary_op_result_type(result_type_);
328 }
329
330 friend class CodeGenerator;
331 };
332
333
334 // Flag that indicates how to generate code for the stub StringAddStub.
335 enum StringAddFlags {
336 NO_STRING_ADD_FLAGS = 0,
337 NO_STRING_CHECK_IN_STUB = 1 << 0 // Omit string check in stub.
338 };
339
340
341 class StringAddStub: public CodeStub {
342 public:
343 explicit StringAddStub(StringAddFlags flags) {
344 string_check_ = ((flags & NO_STRING_CHECK_IN_STUB) == 0);
345 }
346
347 private:
348 Major MajorKey() { return StringAdd; }
349 int MinorKey() { return string_check_ ? 0 : 1; }
350
351 void Generate(MacroAssembler* masm);
352
353 // Should the stub check whether arguments are strings?
354 bool string_check_;
355 };
356
357
358 class SubStringStub: public CodeStub {
359 public:
360 SubStringStub() {}
361
362 private:
363 Major MajorKey() { return SubString; }
364 int MinorKey() { return 0; }
365
366 void Generate(MacroAssembler* masm);
367 };
368
369
370 class StringCompareStub: public CodeStub {
371 public:
372 StringCompareStub() { }
373
374 // Compare two flat ASCII strings and returns result in v0.
375 // Does not use the stack.
376 static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
377 Register left,
378 Register right,
379 Register scratch1,
380 Register scratch2,
381 Register scratch3,
382 Register scratch4);
383
384 private:
385 Major MajorKey() { return StringCompare; }
386 int MinorKey() { return 0; }
387
388 void Generate(MacroAssembler* masm);
389 };
390
391
392 // 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
394 // so you don't have to set up the frame.
395 class WriteInt32ToHeapNumberStub : public CodeStub {
396 public:
397 WriteInt32ToHeapNumberStub(Register the_int,
398 Register the_heap_number,
399 Register scratch,
400 Register scratch2)
401 : the_int_(the_int),
402 the_heap_number_(the_heap_number),
403 scratch_(scratch),
404 sign_(scratch2) { }
405
406 private:
407 Register the_int_;
408 Register the_heap_number_;
409 Register scratch_;
410 Register sign_;
411
412 // Minor key encoding in 16 bits.
413 class IntRegisterBits: public BitField<int, 0, 4> {};
414 class HeapNumberRegisterBits: public BitField<int, 4, 4> {};
415 class ScratchRegisterBits: public BitField<int, 8, 4> {};
416
417 Major MajorKey() { return WriteInt32ToHeapNumber; }
418 int MinorKey() {
419 // Encode the parameters in a unique 16 bit value.
420 return IntRegisterBits::encode(the_int_.code())
421 | HeapNumberRegisterBits::encode(the_heap_number_.code())
422 | ScratchRegisterBits::encode(scratch_.code());
423 }
424
425 void Generate(MacroAssembler* masm);
426
427 const char* GetName() { return "WriteInt32ToHeapNumberStub"; }
428
429 #ifdef DEBUG
430 void Print() { PrintF("WriteInt32ToHeapNumberStub\n"); }
431 #endif
432 };
433
434
435 class NumberToStringStub: public CodeStub {
436 public:
437 NumberToStringStub() { }
438
439 // Generate code to do a lookup in the number string cache. If the number in
440 // the register object is found in the cache the generated code falls through
441 // with the result in the result register. The object and the result register
442 // can be the same. If the number is not found in the cache the code jumps to
443 // the label not_found with only the content of register object unchanged.
444 static void GenerateLookupNumberStringCache(MacroAssembler* masm,
445 Register object,
446 Register result,
447 Register scratch1,
448 Register scratch2,
449 Register scratch3,
450 bool object_is_smi,
451 Label* not_found);
452
453 private:
454 Major MajorKey() { return NumberToString; }
455 int MinorKey() { return 0; }
456
457 void Generate(MacroAssembler* masm);
458
459 const char* GetName() { return "NumberToStringStub"; }
460
461 #ifdef DEBUG
462 void Print() {
463 PrintF("NumberToStringStub\n");
464 }
465 #endif
466 };
467
468
469 // Enter C code from generated RegExp code in a way that allows
470 // the C code to fix the return address in case of a GC.
471 // Currently only needed on ARM and MIPS.
472 class RegExpCEntryStub: public CodeStub {
473 public:
474 RegExpCEntryStub() {}
475 virtual ~RegExpCEntryStub() {}
476 void Generate(MacroAssembler* masm);
477
478 private:
479 Major MajorKey() { return RegExpCEntry; }
480 int MinorKey() { return 0; }
481
482 bool NeedsImmovableCode() { return true; }
483
484 const char* GetName() { return "RegExpCEntryStub"; }
485 };
486
487
488 // Generate code the to load an element from a pixel array. The receiver is
489 // assumed to not be a smi and to have elements, the caller must guarantee this
490 // precondition. If the receiver does not have elements that are pixel arrays,
491 // the generated code jumps to not_pixel_array. If key is not a smi, then the
492 // generated code branches to key_not_smi. Callers can specify NULL for
493 // key_not_smi to signal that a smi check has already been performed on key so
494 // that the smi check is not generated . If key is not a valid index within the
495 // bounds of the pixel array, the generated code jumps to out_of_range.
496 void GenerateFastPixelArrayLoad(MacroAssembler* masm,
497 Register receiver,
498 Register key,
499 Register elements_map,
500 Register elements,
501 Register scratch1,
502 Register scratch2,
503 Register result,
504 Label* not_pixel_array,
505 Label* key_not_smi,
506 Label* out_of_range);
507
508
509 } } // namespace v8::internal
510
511 #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