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

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

Issue 3195022: Move code stubs from codegen*.* files to code-stub*.* files. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 4 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/SConscript ('k') | src/arm/code-stubs-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
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_ARM_CODE_STUBS_ARM_H_
29 #define V8_ARM_CODE_STUBS_ARM_H_
30
31 #include "codegen-inl.h"
32 #include "ic-inl.h"
33 #include "ast.h"
34
35 namespace v8 {
36 namespace internal {
37
38
39 // Compute a transcendental math function natively, or call the
40 // TranscendentalCache runtime function.
41 class TranscendentalCacheStub: public CodeStub {
42 public:
43 explicit TranscendentalCacheStub(TranscendentalCache::Type type)
44 : type_(type) {}
45 void Generate(MacroAssembler* masm);
46 private:
47 TranscendentalCache::Type type_;
48 Major MajorKey() { return TranscendentalCache; }
49 int MinorKey() { return type_; }
50 Runtime::FunctionId RuntimeFunction();
51 };
52
53
54 class ToBooleanStub: public CodeStub {
55 public:
56 explicit ToBooleanStub(Register tos) : tos_(tos) { }
57
58 void Generate(MacroAssembler* masm);
59
60 private:
61 Register tos_;
62 Major MajorKey() { return ToBoolean; }
63 int MinorKey() { return tos_.code(); }
64 };
65
66
67 class GenericBinaryOpStub : public CodeStub {
68 public:
69 GenericBinaryOpStub(Token::Value op,
70 OverwriteMode mode,
71 Register lhs,
72 Register rhs,
73 int constant_rhs = CodeGenerator::kUnknownIntValue)
74 : op_(op),
75 mode_(mode),
76 lhs_(lhs),
77 rhs_(rhs),
78 constant_rhs_(constant_rhs),
79 specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op, constant_rhs)),
80 runtime_operands_type_(BinaryOpIC::DEFAULT),
81 name_(NULL) { }
82
83 GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info)
84 : op_(OpBits::decode(key)),
85 mode_(ModeBits::decode(key)),
86 lhs_(LhsRegister(RegisterBits::decode(key))),
87 rhs_(RhsRegister(RegisterBits::decode(key))),
88 constant_rhs_(KnownBitsForMinorKey(KnownIntBits::decode(key))),
89 specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op_, constant_rhs_)),
90 runtime_operands_type_(type_info),
91 name_(NULL) { }
92
93 private:
94 Token::Value op_;
95 OverwriteMode mode_;
96 Register lhs_;
97 Register rhs_;
98 int constant_rhs_;
99 bool specialized_on_rhs_;
100 BinaryOpIC::TypeInfo runtime_operands_type_;
101 char* name_;
102
103 static const int kMaxKnownRhs = 0x40000000;
104 static const int kKnownRhsKeyBits = 6;
105
106 // Minor key encoding in 17 bits.
107 class ModeBits: public BitField<OverwriteMode, 0, 2> {};
108 class OpBits: public BitField<Token::Value, 2, 6> {};
109 class TypeInfoBits: public BitField<int, 8, 2> {};
110 class RegisterBits: public BitField<bool, 10, 1> {};
111 class KnownIntBits: public BitField<int, 11, kKnownRhsKeyBits> {};
112
113 Major MajorKey() { return GenericBinaryOp; }
114 int MinorKey() {
115 ASSERT((lhs_.is(r0) && rhs_.is(r1)) ||
116 (lhs_.is(r1) && rhs_.is(r0)));
117 // Encode the parameters in a unique 18 bit value.
118 return OpBits::encode(op_)
119 | ModeBits::encode(mode_)
120 | KnownIntBits::encode(MinorKeyForKnownInt())
121 | TypeInfoBits::encode(runtime_operands_type_)
122 | RegisterBits::encode(lhs_.is(r0));
123 }
124
125 void Generate(MacroAssembler* masm);
126 void HandleNonSmiBitwiseOp(MacroAssembler* masm,
127 Register lhs,
128 Register rhs);
129 void HandleBinaryOpSlowCases(MacroAssembler* masm,
130 Label* not_smi,
131 Register lhs,
132 Register rhs,
133 const Builtins::JavaScript& builtin);
134 void GenerateTypeTransition(MacroAssembler* masm);
135
136 static bool RhsIsOneWeWantToOptimizeFor(Token::Value op, int constant_rhs) {
137 if (constant_rhs == CodeGenerator::kUnknownIntValue) return false;
138 if (op == Token::DIV) return constant_rhs >= 2 && constant_rhs <= 3;
139 if (op == Token::MOD) {
140 if (constant_rhs <= 1) return false;
141 if (constant_rhs <= 10) return true;
142 if (constant_rhs <= kMaxKnownRhs && IsPowerOf2(constant_rhs)) return true;
143 return false;
144 }
145 return false;
146 }
147
148 int MinorKeyForKnownInt() {
149 if (!specialized_on_rhs_) return 0;
150 if (constant_rhs_ <= 10) return constant_rhs_ + 1;
151 ASSERT(IsPowerOf2(constant_rhs_));
152 int key = 12;
153 int d = constant_rhs_;
154 while ((d & 1) == 0) {
155 key++;
156 d >>= 1;
157 }
158 ASSERT(key >= 0 && key < (1 << kKnownRhsKeyBits));
159 return key;
160 }
161
162 int KnownBitsForMinorKey(int key) {
163 if (!key) return 0;
164 if (key <= 11) return key - 1;
165 int d = 1;
166 while (key != 12) {
167 key--;
168 d <<= 1;
169 }
170 return d;
171 }
172
173 Register LhsRegister(bool lhs_is_r0) {
174 return lhs_is_r0 ? r0 : r1;
175 }
176
177 Register RhsRegister(bool lhs_is_r0) {
178 return lhs_is_r0 ? r1 : r0;
179 }
180
181 bool ShouldGenerateSmiCode() {
182 return ((op_ != Token::DIV && op_ != Token::MOD) || specialized_on_rhs_) &&
183 runtime_operands_type_ != BinaryOpIC::HEAP_NUMBERS &&
184 runtime_operands_type_ != BinaryOpIC::STRINGS;
185 }
186
187 bool ShouldGenerateFPCode() {
188 return runtime_operands_type_ != BinaryOpIC::STRINGS;
189 }
190
191 virtual int GetCodeKind() { return Code::BINARY_OP_IC; }
192
193 virtual InlineCacheState GetICState() {
194 return BinaryOpIC::ToState(runtime_operands_type_);
195 }
196
197 const char* GetName();
198
199 #ifdef DEBUG
200 void Print() {
201 if (!specialized_on_rhs_) {
202 PrintF("GenericBinaryOpStub (%s)\n", Token::String(op_));
203 } else {
204 PrintF("GenericBinaryOpStub (%s by %d)\n",
205 Token::String(op_),
206 constant_rhs_);
207 }
208 }
209 #endif
210 };
211
212
213 // Flag that indicates how to generate code for the stub StringAddStub.
214 enum StringAddFlags {
215 NO_STRING_ADD_FLAGS = 0,
216 NO_STRING_CHECK_IN_STUB = 1 << 0 // Omit string check in stub.
217 };
218
219
220 class StringAddStub: public CodeStub {
221 public:
222 explicit StringAddStub(StringAddFlags flags) {
223 string_check_ = ((flags & NO_STRING_CHECK_IN_STUB) == 0);
224 }
225
226 private:
227 Major MajorKey() { return StringAdd; }
228 int MinorKey() { return string_check_ ? 0 : 1; }
229
230 void Generate(MacroAssembler* masm);
231
232 // Should the stub check whether arguments are strings?
233 bool string_check_;
234 };
235
236
237 class SubStringStub: public CodeStub {
238 public:
239 SubStringStub() {}
240
241 private:
242 Major MajorKey() { return SubString; }
243 int MinorKey() { return 0; }
244
245 void Generate(MacroAssembler* masm);
246 };
247
248
249
250 class StringCompareStub: public CodeStub {
251 public:
252 StringCompareStub() { }
253
254 // Compare two flat ASCII strings and returns result in r0.
255 // Does not use the stack.
256 static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
257 Register left,
258 Register right,
259 Register scratch1,
260 Register scratch2,
261 Register scratch3,
262 Register scratch4);
263
264 private:
265 Major MajorKey() { return StringCompare; }
266 int MinorKey() { return 0; }
267
268 void Generate(MacroAssembler* masm);
269 };
270
271
272 // This stub can do a fast mod operation without using fp.
273 // It is tail called from the GenericBinaryOpStub and it always
274 // returns an answer. It never causes GC so it doesn't need a real frame.
275 //
276 // The inputs are always positive Smis. This is never called
277 // where the denominator is a power of 2. We handle that separately.
278 //
279 // If we consider the denominator as an odd number multiplied by a power of 2,
280 // then:
281 // * The exponent (power of 2) is in the shift_distance register.
282 // * The odd number is in the odd_number register. It is always in the range
283 // of 3 to 25.
284 // * The bits from the numerator that are to be copied to the answer (there are
285 // shift_distance of them) are in the mask_bits register.
286 // * The other bits of the numerator have been shifted down and are in the lhs
287 // register.
288 class IntegerModStub : public CodeStub {
289 public:
290 IntegerModStub(Register result,
291 Register shift_distance,
292 Register odd_number,
293 Register mask_bits,
294 Register lhs,
295 Register scratch)
296 : result_(result),
297 shift_distance_(shift_distance),
298 odd_number_(odd_number),
299 mask_bits_(mask_bits),
300 lhs_(lhs),
301 scratch_(scratch) {
302 // We don't code these in the minor key, so they should always be the same.
303 // We don't really want to fix that since this stub is rather large and we
304 // don't want many copies of it.
305 ASSERT(shift_distance_.is(r9));
306 ASSERT(odd_number_.is(r4));
307 ASSERT(mask_bits_.is(r3));
308 ASSERT(scratch_.is(r5));
309 }
310
311 private:
312 Register result_;
313 Register shift_distance_;
314 Register odd_number_;
315 Register mask_bits_;
316 Register lhs_;
317 Register scratch_;
318
319 // Minor key encoding in 16 bits.
320 class ResultRegisterBits: public BitField<int, 0, 4> {};
321 class LhsRegisterBits: public BitField<int, 4, 4> {};
322
323 Major MajorKey() { return IntegerMod; }
324 int MinorKey() {
325 // Encode the parameters in a unique 16 bit value.
326 return ResultRegisterBits::encode(result_.code())
327 | LhsRegisterBits::encode(lhs_.code());
328 }
329
330 void Generate(MacroAssembler* masm);
331
332 const char* GetName() { return "IntegerModStub"; }
333
334 // Utility functions.
335 void DigitSum(MacroAssembler* masm,
336 Register lhs,
337 int mask,
338 int shift,
339 Label* entry);
340 void DigitSum(MacroAssembler* masm,
341 Register lhs,
342 Register scratch,
343 int mask,
344 int shift1,
345 int shift2,
346 Label* entry);
347 void ModGetInRangeBySubtraction(MacroAssembler* masm,
348 Register lhs,
349 int shift,
350 int rhs);
351 void ModReduce(MacroAssembler* masm,
352 Register lhs,
353 int max,
354 int denominator);
355 void ModAnswer(MacroAssembler* masm,
356 Register result,
357 Register shift_distance,
358 Register mask_bits,
359 Register sum_of_digits);
360
361
362 #ifdef DEBUG
363 void Print() { PrintF("IntegerModStub\n"); }
364 #endif
365 };
366
367
368 // This stub can convert a signed int32 to a heap number (double). It does
369 // not work for int32s that are in Smi range! No GC occurs during this stub
370 // so you don't have to set up the frame.
371 class WriteInt32ToHeapNumberStub : public CodeStub {
372 public:
373 WriteInt32ToHeapNumberStub(Register the_int,
374 Register the_heap_number,
375 Register scratch)
376 : the_int_(the_int),
377 the_heap_number_(the_heap_number),
378 scratch_(scratch) { }
379
380 private:
381 Register the_int_;
382 Register the_heap_number_;
383 Register scratch_;
384
385 // Minor key encoding in 16 bits.
386 class IntRegisterBits: public BitField<int, 0, 4> {};
387 class HeapNumberRegisterBits: public BitField<int, 4, 4> {};
388 class ScratchRegisterBits: public BitField<int, 8, 4> {};
389
390 Major MajorKey() { return WriteInt32ToHeapNumber; }
391 int MinorKey() {
392 // Encode the parameters in a unique 16 bit value.
393 return IntRegisterBits::encode(the_int_.code())
394 | HeapNumberRegisterBits::encode(the_heap_number_.code())
395 | ScratchRegisterBits::encode(scratch_.code());
396 }
397
398 void Generate(MacroAssembler* masm);
399
400 const char* GetName() { return "WriteInt32ToHeapNumberStub"; }
401
402 #ifdef DEBUG
403 void Print() { PrintF("WriteInt32ToHeapNumberStub\n"); }
404 #endif
405 };
406
407
408 class NumberToStringStub: public CodeStub {
409 public:
410 NumberToStringStub() { }
411
412 // Generate code to do a lookup in the number string cache. If the number in
413 // the register object is found in the cache the generated code falls through
414 // with the result in the result register. The object and the result register
415 // can be the same. If the number is not found in the cache the code jumps to
416 // the label not_found with only the content of register object unchanged.
417 static void GenerateLookupNumberStringCache(MacroAssembler* masm,
418 Register object,
419 Register result,
420 Register scratch1,
421 Register scratch2,
422 Register scratch3,
423 bool object_is_smi,
424 Label* not_found);
425
426 private:
427 Major MajorKey() { return NumberToString; }
428 int MinorKey() { return 0; }
429
430 void Generate(MacroAssembler* masm);
431
432 const char* GetName() { return "NumberToStringStub"; }
433 };
434
435
436 class RecordWriteStub : public CodeStub {
437 public:
438 RecordWriteStub(Register object, Register offset, Register scratch)
439 : object_(object), offset_(offset), scratch_(scratch) { }
440
441 void Generate(MacroAssembler* masm);
442
443 private:
444 Register object_;
445 Register offset_;
446 Register scratch_;
447
448 // Minor key encoding in 12 bits. 4 bits for each of the three
449 // registers (object, offset and scratch) OOOOAAAASSSS.
450 class ScratchBits: public BitField<uint32_t, 0, 4> {};
451 class OffsetBits: public BitField<uint32_t, 4, 4> {};
452 class ObjectBits: public BitField<uint32_t, 8, 4> {};
453
454 Major MajorKey() { return RecordWrite; }
455
456 int MinorKey() {
457 // Encode the registers.
458 return ObjectBits::encode(object_.code()) |
459 OffsetBits::encode(offset_.code()) |
460 ScratchBits::encode(scratch_.code());
461 }
462
463 #ifdef DEBUG
464 void Print() {
465 PrintF("RecordWriteStub (object reg %d), (offset reg %d),"
466 " (scratch reg %d)\n",
467 object_.code(), offset_.code(), scratch_.code());
468 }
469 #endif
470 };
471
472
473 } } // namespace v8::internal
474
475 #endif // V8_ARM_CODE_STUBS_ARM_H_
OLDNEW
« no previous file with comments | « src/SConscript ('k') | src/arm/code-stubs-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698