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

Side by Side Diff: src/arm/assembler-arm.cc

Issue 110573004: Merge bleeding_edge 17696:18016. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years 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
OLDNEW
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions 5 // modification, are permitted provided that the following conditions
6 // are met: 6 // are met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 const Instr kLdrStrInstrTypeMask = 0xffff0000; 510 const Instr kLdrStrInstrTypeMask = 0xffff0000;
511 const Instr kLdrStrInstrArgumentMask = 0x0000ffff; 511 const Instr kLdrStrInstrArgumentMask = 0x0000ffff;
512 const Instr kLdrStrOffsetMask = 0x00000fff; 512 const Instr kLdrStrOffsetMask = 0x00000fff;
513 513
514 514
515 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) 515 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
516 : AssemblerBase(isolate, buffer, buffer_size), 516 : AssemblerBase(isolate, buffer, buffer_size),
517 recorded_ast_id_(TypeFeedbackId::None()), 517 recorded_ast_id_(TypeFeedbackId::None()),
518 positions_recorder_(this) { 518 positions_recorder_(this) {
519 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); 519 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
520 num_pending_reloc_info_ = 0; 520 num_pending_32_bit_reloc_info_ = 0;
521 num_pending_64_bit_reloc_info_ = 0; 521 num_pending_64_bit_reloc_info_ = 0;
522 next_buffer_check_ = 0; 522 next_buffer_check_ = 0;
523 const_pool_blocked_nesting_ = 0; 523 const_pool_blocked_nesting_ = 0;
524 no_const_pool_before_ = 0; 524 no_const_pool_before_ = 0;
525 first_const_pool_use_ = -1; 525 first_const_pool_32_use_ = -1;
526 first_const_pool_64_use_ = -1;
526 last_bound_pos_ = 0; 527 last_bound_pos_ = 0;
527 ClearRecordedAstId(); 528 ClearRecordedAstId();
528 } 529 }
529 530
530 531
531 Assembler::~Assembler() { 532 Assembler::~Assembler() {
532 ASSERT(const_pool_blocked_nesting_ == 0); 533 ASSERT(const_pool_blocked_nesting_ == 0);
533 } 534 }
534 535
535 536
536 void Assembler::GetCode(CodeDesc* desc) { 537 void Assembler::GetCode(CodeDesc* desc) {
537 // Emit constant pool if necessary. 538 // Emit constant pool if necessary.
538 CheckConstPool(true, false); 539 CheckConstPool(true, false);
539 ASSERT(num_pending_reloc_info_ == 0); 540 ASSERT(num_pending_32_bit_reloc_info_ == 0);
540 ASSERT(num_pending_64_bit_reloc_info_ == 0); 541 ASSERT(num_pending_64_bit_reloc_info_ == 0);
541 542
542 // Set up code descriptor. 543 // Set up code descriptor.
543 desc->buffer = buffer_; 544 desc->buffer = buffer_;
544 desc->buffer_size = buffer_size_; 545 desc->buffer_size = buffer_size_;
545 desc->instr_size = pc_offset(); 546 desc->instr_size = pc_offset();
546 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos(); 547 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
548 desc->origin = this;
547 } 549 }
548 550
549 551
550 void Assembler::Align(int m) { 552 void Assembler::Align(int m) {
551 ASSERT(m >= 4 && IsPowerOf2(m)); 553 ASSERT(m >= 4 && IsPowerOf2(m));
552 while ((pc_offset() & (m - 1)) != 0) { 554 while ((pc_offset() & (m - 1)) != 0) {
553 nop(); 555 nop();
554 } 556 }
555 } 557 }
556 558
(...skipping 2585 matching lines...) Expand 10 before | Expand all | Expand 10 after
3142 buffer_size_ = desc.buffer_size; 3144 buffer_size_ = desc.buffer_size;
3143 pc_ += pc_delta; 3145 pc_ += pc_delta;
3144 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 3146 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
3145 reloc_info_writer.last_pc() + pc_delta); 3147 reloc_info_writer.last_pc() + pc_delta);
3146 3148
3147 // None of our relocation types are pc relative pointing outside the code 3149 // None of our relocation types are pc relative pointing outside the code
3148 // buffer nor pc absolute pointing inside the code buffer, so there is no need 3150 // buffer nor pc absolute pointing inside the code buffer, so there is no need
3149 // to relocate any emitted relocation entries. 3151 // to relocate any emitted relocation entries.
3150 3152
3151 // Relocate pending relocation entries. 3153 // Relocate pending relocation entries.
3152 for (int i = 0; i < num_pending_reloc_info_; i++) { 3154 for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) {
3153 RelocInfo& rinfo = pending_reloc_info_[i]; 3155 RelocInfo& rinfo = pending_32_bit_reloc_info_[i];
3154 ASSERT(rinfo.rmode() != RelocInfo::COMMENT && 3156 ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
3155 rinfo.rmode() != RelocInfo::POSITION); 3157 rinfo.rmode() != RelocInfo::POSITION);
3156 if (rinfo.rmode() != RelocInfo::JS_RETURN) { 3158 if (rinfo.rmode() != RelocInfo::JS_RETURN) {
3157 rinfo.set_pc(rinfo.pc() + pc_delta); 3159 rinfo.set_pc(rinfo.pc() + pc_delta);
3158 } 3160 }
3159 } 3161 }
3162 for (int i = 0; i < num_pending_64_bit_reloc_info_; i++) {
3163 RelocInfo& rinfo = pending_64_bit_reloc_info_[i];
3164 ASSERT(rinfo.rmode() == RelocInfo::NONE64);
3165 rinfo.set_pc(rinfo.pc() + pc_delta);
3166 }
3160 } 3167 }
3161 3168
3162 3169
3163 void Assembler::db(uint8_t data) { 3170 void Assembler::db(uint8_t data) {
3164 // No relocation info should be pending while using db. db is used 3171 // No relocation info should be pending while using db. db is used
3165 // to write pure data with no pointers and the constant pool should 3172 // to write pure data with no pointers and the constant pool should
3166 // be emitted before using db. 3173 // be emitted before using db.
3167 ASSERT(num_pending_reloc_info_ == 0); 3174 ASSERT(num_pending_32_bit_reloc_info_ == 0);
3168 ASSERT(num_pending_64_bit_reloc_info_ == 0); 3175 ASSERT(num_pending_64_bit_reloc_info_ == 0);
3169 CheckBuffer(); 3176 CheckBuffer();
3170 *reinterpret_cast<uint8_t*>(pc_) = data; 3177 *reinterpret_cast<uint8_t*>(pc_) = data;
3171 pc_ += sizeof(uint8_t); 3178 pc_ += sizeof(uint8_t);
3172 } 3179 }
3173 3180
3174 3181
3175 void Assembler::dd(uint32_t data) { 3182 void Assembler::dd(uint32_t data) {
3176 // No relocation info should be pending while using dd. dd is used 3183 // No relocation info should be pending while using dd. dd is used
3177 // to write pure data with no pointers and the constant pool should 3184 // to write pure data with no pointers and the constant pool should
3178 // be emitted before using dd. 3185 // be emitted before using dd.
3179 ASSERT(num_pending_reloc_info_ == 0); 3186 ASSERT(num_pending_32_bit_reloc_info_ == 0);
3180 ASSERT(num_pending_64_bit_reloc_info_ == 0); 3187 ASSERT(num_pending_64_bit_reloc_info_ == 0);
3181 CheckBuffer(); 3188 CheckBuffer();
3182 *reinterpret_cast<uint32_t*>(pc_) = data; 3189 *reinterpret_cast<uint32_t*>(pc_) = data;
3183 pc_ += sizeof(uint32_t); 3190 pc_ += sizeof(uint32_t);
3184 } 3191 }
3185 3192
3186 3193
3187 void Assembler::emit_code_stub_address(Code* stub) { 3194 void Assembler::emit_code_stub_address(Code* stub) {
3188 CheckBuffer(); 3195 CheckBuffer();
3189 *reinterpret_cast<uint32_t*>(pc_) = 3196 *reinterpret_cast<uint32_t*>(pc_) =
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3239 3246
3240 3247
3241 void Assembler::RecordRelocInfo(double data) { 3248 void Assembler::RecordRelocInfo(double data) {
3242 // We do not try to reuse pool constants. 3249 // We do not try to reuse pool constants.
3243 RelocInfo rinfo(pc_, data); 3250 RelocInfo rinfo(pc_, data);
3244 RecordRelocInfoConstantPoolEntryHelper(rinfo); 3251 RecordRelocInfoConstantPoolEntryHelper(rinfo);
3245 } 3252 }
3246 3253
3247 3254
3248 void Assembler::RecordRelocInfoConstantPoolEntryHelper(const RelocInfo& rinfo) { 3255 void Assembler::RecordRelocInfoConstantPoolEntryHelper(const RelocInfo& rinfo) {
3249 ASSERT(num_pending_reloc_info_ < kMaxNumPendingRelocInfo); 3256 if (rinfo.rmode() == RelocInfo::NONE64) {
3250 if (num_pending_reloc_info_ == 0) { 3257 ASSERT(num_pending_64_bit_reloc_info_ < kMaxNumPending64RelocInfo);
3251 first_const_pool_use_ = pc_offset(); 3258 if (num_pending_64_bit_reloc_info_ == 0) {
3259 first_const_pool_64_use_ = pc_offset();
3260 }
3261 pending_64_bit_reloc_info_[num_pending_64_bit_reloc_info_++] = rinfo;
3262 } else {
3263 ASSERT(num_pending_32_bit_reloc_info_ < kMaxNumPending32RelocInfo);
3264 if (num_pending_32_bit_reloc_info_ == 0) {
3265 first_const_pool_32_use_ = pc_offset();
3266 }
3267 pending_32_bit_reloc_info_[num_pending_32_bit_reloc_info_++] = rinfo;
3252 } 3268 }
3253 pending_reloc_info_[num_pending_reloc_info_++] = rinfo;
3254 if (rinfo.rmode() == RelocInfo::NONE64) {
3255 ++num_pending_64_bit_reloc_info_;
3256 }
3257 ASSERT(num_pending_64_bit_reloc_info_ <= num_pending_reloc_info_);
3258 // Make sure the constant pool is not emitted in place of the next 3269 // Make sure the constant pool is not emitted in place of the next
3259 // instruction for which we just recorded relocation info. 3270 // instruction for which we just recorded relocation info.
3260 BlockConstPoolFor(1); 3271 BlockConstPoolFor(1);
3261 } 3272 }
3262 3273
3263 3274
3264 void Assembler::BlockConstPoolFor(int instructions) { 3275 void Assembler::BlockConstPoolFor(int instructions) {
3265 int pc_limit = pc_offset() + instructions * kInstrSize; 3276 int pc_limit = pc_offset() + instructions * kInstrSize;
3266 if (no_const_pool_before_ < pc_limit) { 3277 if (no_const_pool_before_ < pc_limit) {
3267 // If there are some pending entries, the constant pool cannot be blocked 3278 // Max pool start (if we need a jump and an alignment).
3268 // further than constant pool instruction's reach. 3279 #ifdef DEBUG
3269 ASSERT((num_pending_reloc_info_ == 0) || 3280 int start = pc_limit + kInstrSize + 2 * kPointerSize;
3270 (pc_limit - first_const_pool_use_ < kMaxDistToIntPool)); 3281 ASSERT((num_pending_32_bit_reloc_info_ == 0) ||
3271 // TODO(jfb) Also check 64-bit entries are in range (requires splitting 3282 (start - first_const_pool_32_use_ +
3272 // them up from 32-bit entries). 3283 num_pending_64_bit_reloc_info_ * kDoubleSize < kMaxDistToIntPool));
3284 ASSERT((num_pending_64_bit_reloc_info_ == 0) ||
3285 (start - first_const_pool_64_use_ < kMaxDistToFPPool));
3286 #endif
3273 no_const_pool_before_ = pc_limit; 3287 no_const_pool_before_ = pc_limit;
3274 } 3288 }
3275 3289
3276 if (next_buffer_check_ < no_const_pool_before_) { 3290 if (next_buffer_check_ < no_const_pool_before_) {
3277 next_buffer_check_ = no_const_pool_before_; 3291 next_buffer_check_ = no_const_pool_before_;
3278 } 3292 }
3279 } 3293 }
3280 3294
3281 3295
3282 void Assembler::CheckConstPool(bool force_emit, bool require_jump) { 3296 void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
3283 // Some short sequence of instruction mustn't be broken up by constant pool 3297 // Some short sequence of instruction mustn't be broken up by constant pool
3284 // emission, such sequences are protected by calls to BlockConstPoolFor and 3298 // emission, such sequences are protected by calls to BlockConstPoolFor and
3285 // BlockConstPoolScope. 3299 // BlockConstPoolScope.
3286 if (is_const_pool_blocked()) { 3300 if (is_const_pool_blocked()) {
3287 // Something is wrong if emission is forced and blocked at the same time. 3301 // Something is wrong if emission is forced and blocked at the same time.
3288 ASSERT(!force_emit); 3302 ASSERT(!force_emit);
3289 return; 3303 return;
3290 } 3304 }
3291 3305
3292 // There is nothing to do if there are no pending constant pool entries. 3306 // There is nothing to do if there are no pending constant pool entries.
3293 if (num_pending_reloc_info_ == 0) { 3307 if ((num_pending_32_bit_reloc_info_ == 0) &&
3294 ASSERT(num_pending_64_bit_reloc_info_ == 0); 3308 (num_pending_64_bit_reloc_info_ == 0)) {
3295 // Calculate the offset of the next check. 3309 // Calculate the offset of the next check.
3296 next_buffer_check_ = pc_offset() + kCheckPoolInterval; 3310 next_buffer_check_ = pc_offset() + kCheckPoolInterval;
3297 return; 3311 return;
3298 } 3312 }
3299 3313
3300 // Check that the code buffer is large enough before emitting the constant 3314 // Check that the code buffer is large enough before emitting the constant
3301 // pool (include the jump over the pool and the constant pool marker and 3315 // pool (include the jump over the pool and the constant pool marker and
3302 // the gap to the relocation information). 3316 // the gap to the relocation information).
3303 // Note 64-bit values are wider, and the first one needs to be 64-bit aligned.
3304 int jump_instr = require_jump ? kInstrSize : 0; 3317 int jump_instr = require_jump ? kInstrSize : 0;
3305 int size_up_to_marker = jump_instr + kInstrSize; 3318 int size_up_to_marker = jump_instr + kInstrSize;
3306 int size_after_marker = num_pending_reloc_info_ * kPointerSize; 3319 int size_after_marker = num_pending_32_bit_reloc_info_ * kPointerSize;
3307 bool has_fp_values = (num_pending_64_bit_reloc_info_ > 0); 3320 bool has_fp_values = (num_pending_64_bit_reloc_info_ > 0);
3308 // 64-bit values must be 64-bit aligned. 3321 bool require_64_bit_align = false;
3309 // We'll start emitting at PC: branch+marker, then 32-bit values, then 3322 if (has_fp_values) {
3310 // 64-bit values which might need to be aligned. 3323 require_64_bit_align = (((uintptr_t)pc_ + size_up_to_marker) & 0x7);
3311 bool require_64_bit_align = has_fp_values && 3324 if (require_64_bit_align) {
3312 (((uintptr_t)pc_ + size_up_to_marker + size_after_marker) & 0x3); 3325 size_after_marker += kInstrSize;
3313 if (require_64_bit_align) { 3326 }
3314 size_after_marker += kInstrSize; 3327 size_after_marker += num_pending_64_bit_reloc_info_ * kDoubleSize;
3315 } 3328 }
3316 // num_pending_reloc_info_ also contains 64-bit entries, the above code
3317 // therefore already counted half of the size for 64-bit entries. Add the
3318 // remaining size.
3319 STATIC_ASSERT(kPointerSize == kDoubleSize / 2);
3320 size_after_marker += num_pending_64_bit_reloc_info_ * (kDoubleSize / 2);
3321 3329
3322 int size = size_up_to_marker + size_after_marker; 3330 int size = size_up_to_marker + size_after_marker;
3323 3331
3324 // We emit a constant pool when: 3332 // We emit a constant pool when:
3325 // * requested to do so by parameter force_emit (e.g. after each function). 3333 // * requested to do so by parameter force_emit (e.g. after each function).
3326 // * the distance from the first instruction accessing the constant pool to 3334 // * the distance from the first instruction accessing the constant pool to
3327 // any of the constant pool entries will exceed its limit the next 3335 // any of the constant pool entries will exceed its limit the next
3328 // time the pool is checked. This is overly restrictive, but we don't emit 3336 // time the pool is checked. This is overly restrictive, but we don't emit
3329 // constant pool entries in-order so it's conservatively correct. 3337 // constant pool entries in-order so it's conservatively correct.
3330 // * the instruction doesn't require a jump after itself to jump over the 3338 // * the instruction doesn't require a jump after itself to jump over the
3331 // constant pool, and we're getting close to running out of range. 3339 // constant pool, and we're getting close to running out of range.
3332 if (!force_emit) { 3340 if (!force_emit) {
3333 ASSERT((first_const_pool_use_ >= 0) && (num_pending_reloc_info_ > 0)); 3341 ASSERT((first_const_pool_32_use_ >= 0) || (first_const_pool_64_use_ >= 0));
3334 int dist = pc_offset() + size - first_const_pool_use_; 3342 bool need_emit = false;
3335 if (has_fp_values) { 3343 if (has_fp_values) {
3336 if ((dist < kMaxDistToFPPool - kCheckPoolInterval) && 3344 int dist64 = pc_offset() +
3337 (require_jump || (dist < kMaxDistToFPPool / 2))) { 3345 size -
3338 return; 3346 num_pending_32_bit_reloc_info_ * kPointerSize -
3339 } 3347 first_const_pool_64_use_;
3340 } else { 3348 if ((dist64 >= kMaxDistToFPPool - kCheckPoolInterval) ||
3341 if ((dist < kMaxDistToIntPool - kCheckPoolInterval) && 3349 (!require_jump && (dist64 >= kMaxDistToFPPool / 2))) {
3342 (require_jump || (dist < kMaxDistToIntPool / 2))) { 3350 need_emit = true;
3343 return;
3344 } 3351 }
3345 } 3352 }
3353 int dist32 =
3354 pc_offset() + size - first_const_pool_32_use_;
3355 if ((dist32 >= kMaxDistToIntPool - kCheckPoolInterval) ||
3356 (!require_jump && (dist32 >= kMaxDistToIntPool / 2))) {
3357 need_emit = true;
3358 }
3359 if (!need_emit) return;
3346 } 3360 }
3347 3361
3348 int needed_space = size + kGap; 3362 int needed_space = size + kGap;
3349 while (buffer_space() <= needed_space) GrowBuffer(); 3363 while (buffer_space() <= needed_space) GrowBuffer();
3350 3364
3351 { 3365 {
3352 // Block recursive calls to CheckConstPool. 3366 // Block recursive calls to CheckConstPool.
3353 BlockConstPoolScope block_const_pool(this); 3367 BlockConstPoolScope block_const_pool(this);
3354 RecordComment("[ Constant Pool"); 3368 RecordComment("[ Constant Pool");
3355 RecordConstPool(size); 3369 RecordConstPool(size);
3356 3370
3357 // Emit jump over constant pool if necessary. 3371 // Emit jump over constant pool if necessary.
3358 Label after_pool; 3372 Label after_pool;
3359 if (require_jump) { 3373 if (require_jump) {
3360 b(&after_pool); 3374 b(&after_pool);
3361 } 3375 }
3362 3376
3363 // Put down constant pool marker "Undefined instruction". 3377 // Put down constant pool marker "Undefined instruction".
3364 // The data size helps disassembly know what to print. 3378 // The data size helps disassembly know what to print.
3365 emit(kConstantPoolMarker | 3379 emit(kConstantPoolMarker |
3366 EncodeConstantPoolLength(size_after_marker / kPointerSize)); 3380 EncodeConstantPoolLength(size_after_marker / kPointerSize));
3367 3381
3368 if (require_64_bit_align) { 3382 if (require_64_bit_align) {
3369 emit(kConstantPoolMarker); 3383 emit(kConstantPoolMarker);
3370 } 3384 }
3371 3385
3372 // Emit 64-bit constant pool entries first: their range is smaller than 3386 // Emit 64-bit constant pool entries first: their range is smaller than
3373 // 32-bit entries. 3387 // 32-bit entries.
3374 for (int i = 0; i < num_pending_reloc_info_; i++) { 3388 for (int i = 0; i < num_pending_64_bit_reloc_info_; i++) {
3375 RelocInfo& rinfo = pending_reloc_info_[i]; 3389 RelocInfo& rinfo = pending_64_bit_reloc_info_[i];
3376 3390
3377 if (rinfo.rmode() != RelocInfo::NONE64) { 3391 ASSERT(!((uintptr_t)pc_ & 0x7)); // Check 64-bit alignment.
3378 // 32-bit values emitted later.
3379 continue;
3380 }
3381
3382 ASSERT(!((uintptr_t)pc_ & 0x3)); // Check 64-bit alignment.
3383 3392
3384 Instr instr = instr_at(rinfo.pc()); 3393 Instr instr = instr_at(rinfo.pc());
3385 // Instruction to patch must be 'vldr rd, [pc, #offset]' with offset == 0. 3394 // Instruction to patch must be 'vldr rd, [pc, #offset]' with offset == 0.
3386 ASSERT((IsVldrDPcImmediateOffset(instr) && 3395 ASSERT((IsVldrDPcImmediateOffset(instr) &&
3387 GetVldrDRegisterImmediateOffset(instr) == 0)); 3396 GetVldrDRegisterImmediateOffset(instr) == 0));
3388 3397
3389 int delta = pc_ - rinfo.pc() - kPcLoadDelta; 3398 int delta = pc_ - rinfo.pc() - kPcLoadDelta;
3390 ASSERT(is_uint10(delta)); 3399 ASSERT(is_uint10(delta));
3391 3400
3401 bool found = false;
3402 uint64_t value = rinfo.raw_data64();
3403 for (int j = 0; j < i; j++) {
3404 RelocInfo& rinfo2 = pending_64_bit_reloc_info_[j];
3405 if (value == rinfo2.raw_data64()) {
3406 found = true;
3407 ASSERT(rinfo2.rmode() == RelocInfo::NONE64);
3408 Instr instr2 = instr_at(rinfo2.pc());
3409 ASSERT(IsVldrDPcImmediateOffset(instr2));
3410 delta = GetVldrDRegisterImmediateOffset(instr2);
3411 delta += rinfo2.pc() - rinfo.pc();
3412 break;
3413 }
3414 }
3415
3392 instr_at_put(rinfo.pc(), SetVldrDRegisterImmediateOffset(instr, delta)); 3416 instr_at_put(rinfo.pc(), SetVldrDRegisterImmediateOffset(instr, delta));
3393 3417
3394 const double double_data = rinfo.data64(); 3418 if (!found) {
3395 uint64_t uint_data = 0; 3419 uint64_t uint_data = rinfo.raw_data64();
3396 OS::MemCopy(&uint_data, &double_data, sizeof(double_data)); 3420 emit(uint_data & 0xFFFFFFFF);
3397 emit(uint_data & 0xFFFFFFFF); 3421 emit(uint_data >> 32);
3398 emit(uint_data >> 32); 3422 }
3399 } 3423 }
3400 3424
3401 // Emit 32-bit constant pool entries. 3425 // Emit 32-bit constant pool entries.
3402 for (int i = 0; i < num_pending_reloc_info_; i++) { 3426 for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) {
3403 RelocInfo& rinfo = pending_reloc_info_[i]; 3427 RelocInfo& rinfo = pending_32_bit_reloc_info_[i];
3404 ASSERT(rinfo.rmode() != RelocInfo::COMMENT && 3428 ASSERT(rinfo.rmode() != RelocInfo::COMMENT &&
3405 rinfo.rmode() != RelocInfo::POSITION && 3429 rinfo.rmode() != RelocInfo::POSITION &&
3406 rinfo.rmode() != RelocInfo::STATEMENT_POSITION && 3430 rinfo.rmode() != RelocInfo::STATEMENT_POSITION &&
3407 rinfo.rmode() != RelocInfo::CONST_POOL); 3431 rinfo.rmode() != RelocInfo::CONST_POOL &&
3408 3432 rinfo.rmode() != RelocInfo::NONE64);
3409 if (rinfo.rmode() == RelocInfo::NONE64) {
3410 // 64-bit values emitted earlier.
3411 continue;
3412 }
3413 3433
3414 Instr instr = instr_at(rinfo.pc()); 3434 Instr instr = instr_at(rinfo.pc());
3415 3435
3416 // 64-bit loads shouldn't get here. 3436 // 64-bit loads shouldn't get here.
3417 ASSERT(!IsVldrDPcImmediateOffset(instr)); 3437 ASSERT(!IsVldrDPcImmediateOffset(instr));
3418 3438
3419 int delta = pc_ - rinfo.pc() - kPcLoadDelta;
3420 // 0 is the smallest delta:
3421 // ldr rd, [pc, #0]
3422 // constant pool marker
3423 // data
3424
3425 if (IsLdrPcImmediateOffset(instr) && 3439 if (IsLdrPcImmediateOffset(instr) &&
3426 GetLdrRegisterImmediateOffset(instr) == 0) { 3440 GetLdrRegisterImmediateOffset(instr) == 0) {
3441 int delta = pc_ - rinfo.pc() - kPcLoadDelta;
3427 ASSERT(is_uint12(delta)); 3442 ASSERT(is_uint12(delta));
3443 // 0 is the smallest delta:
3444 // ldr rd, [pc, #0]
3445 // constant pool marker
3446 // data
3447
3448 bool found = false;
3449 if (!Serializer::enabled() && (rinfo.rmode() >= RelocInfo::CELL)) {
3450 for (int j = 0; j < i; j++) {
3451 RelocInfo& rinfo2 = pending_32_bit_reloc_info_[j];
3452
3453 if ((rinfo2.data() == rinfo.data()) &&
3454 (rinfo2.rmode() == rinfo.rmode())) {
3455 Instr instr2 = instr_at(rinfo2.pc());
3456 if (IsLdrPcImmediateOffset(instr2)) {
3457 delta = GetLdrRegisterImmediateOffset(instr2);
3458 delta += rinfo2.pc() - rinfo.pc();
3459 found = true;
3460 break;
3461 }
3462 }
3463 }
3464 }
3465
3428 instr_at_put(rinfo.pc(), SetLdrRegisterImmediateOffset(instr, delta)); 3466 instr_at_put(rinfo.pc(), SetLdrRegisterImmediateOffset(instr, delta));
3429 emit(rinfo.data()); 3467
3468 if (!found) {
3469 emit(rinfo.data());
3470 }
3430 } else { 3471 } else {
3431 ASSERT(IsMovW(instr)); 3472 ASSERT(IsMovW(instr));
3432 emit(rinfo.data());
3433 } 3473 }
3434 } 3474 }
3435 3475
3436 num_pending_reloc_info_ = 0; 3476 num_pending_32_bit_reloc_info_ = 0;
3437 num_pending_64_bit_reloc_info_ = 0; 3477 num_pending_64_bit_reloc_info_ = 0;
3438 first_const_pool_use_ = -1; 3478 first_const_pool_32_use_ = -1;
3479 first_const_pool_64_use_ = -1;
3439 3480
3440 RecordComment("]"); 3481 RecordComment("]");
3441 3482
3442 if (after_pool.is_linked()) { 3483 if (after_pool.is_linked()) {
3443 bind(&after_pool); 3484 bind(&after_pool);
3444 } 3485 }
3445 } 3486 }
3446 3487
3447 // Since a constant pool was just emitted, move the check offset forward by 3488 // Since a constant pool was just emitted, move the check offset forward by
3448 // the standard interval. 3489 // the standard interval.
3449 next_buffer_check_ = pc_offset() + kCheckPoolInterval; 3490 next_buffer_check_ = pc_offset() + kCheckPoolInterval;
3450 } 3491 }
3451 3492
3452 3493
3453 } } // namespace v8::internal 3494 } } // namespace v8::internal
3454 3495
3455 #endif // V8_TARGET_ARCH_ARM 3496 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698