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

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

Issue 23515007: ARM: remove the regexp specific literal pool. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 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/arm/assembler-arm.h ('k') | src/arm/constants-arm.h » ('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 (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 21 matching lines...) Expand all
32 32
33 // The original source code covered by the above license above has been 33 // The original source code covered by the above license above has been
34 // modified significantly by Google Inc. 34 // modified significantly by Google Inc.
35 // Copyright 2012 the V8 project authors. All rights reserved. 35 // Copyright 2012 the V8 project authors. All rights reserved.
36 36
37 #include "v8.h" 37 #include "v8.h"
38 38
39 #if V8_TARGET_ARCH_ARM 39 #if V8_TARGET_ARCH_ARM
40 40
41 #include "arm/assembler-arm-inl.h" 41 #include "arm/assembler-arm-inl.h"
42 #include "macro-assembler.h"
42 #include "serialize.h" 43 #include "serialize.h"
43 44
44 namespace v8 { 45 namespace v8 {
45 namespace internal { 46 namespace internal {
46 47
47 #ifdef DEBUG 48 #ifdef DEBUG
48 bool CpuFeatures::initialized_ = false; 49 bool CpuFeatures::initialized_ = false;
49 #endif 50 #endif
50 unsigned CpuFeatures::supported_ = 0; 51 unsigned CpuFeatures::supported_ = 0;
51 unsigned CpuFeatures::found_by_runtime_probing_only_ = 0; 52 unsigned CpuFeatures::found_by_runtime_probing_only_ = 0;
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 // The linked labels form a link chain by making the branch offset 772 // The linked labels form a link chain by making the branch offset
772 // in the instruction steam to point to the previous branch 773 // in the instruction steam to point to the previous branch
773 // instruction using the same label. 774 // instruction using the same label.
774 // 775 //
775 // The link chain is terminated by a branch offset pointing to the 776 // The link chain is terminated by a branch offset pointing to the
776 // same position. 777 // same position.
777 778
778 779
779 int Assembler::target_at(int pos) { 780 int Assembler::target_at(int pos) {
780 Instr instr = instr_at(pos); 781 Instr instr = instr_at(pos);
781 if ((instr & ~kImm24Mask) == 0) { 782 if (is_uint24(instr)) {
782 // Emitted label constant, not part of a branch. 783 // Emitted link to a label, not part of a branch.
783 return instr - (Code::kHeaderSize - kHeapObjectTag); 784 return instr;
784 } 785 }
785 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 786 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24
786 int imm26 = ((instr & kImm24Mask) << 8) >> 6; 787 int imm26 = ((instr & kImm24Mask) << 8) >> 6;
787 if ((Instruction::ConditionField(instr) == kSpecialCondition) && 788 if ((Instruction::ConditionField(instr) == kSpecialCondition) &&
788 ((instr & B24) != 0)) { 789 ((instr & B24) != 0)) {
789 // blx uses bit 24 to encode bit 2 of imm26 790 // blx uses bit 24 to encode bit 2 of imm26
790 imm26 += 2; 791 imm26 += 2;
791 } 792 }
792 return pos + kPcLoadDelta + imm26; 793 return pos + kPcLoadDelta + imm26;
793 } 794 }
794 795
795 796
796 void Assembler::target_at_put(int pos, int target_pos) { 797 void Assembler::target_at_put(int pos, int target_pos) {
797 Instr instr = instr_at(pos); 798 Instr instr = instr_at(pos);
798 if ((instr & ~kImm24Mask) == 0) { 799 if (is_uint24(instr)) {
799 ASSERT(target_pos == pos || target_pos >= 0); 800 ASSERT(target_pos == pos || target_pos >= 0);
800 // Emitted label constant, not part of a branch. 801 // Emitted link to a label, not part of a branch.
801 // Make label relative to Code* of generated Code object. 802 // Load the position of the label relative to the generated code object
802 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); 803 // pointer in a register.
804
805 // Here are the instructions we need to emit:
806 // For ARMv7: target24 => target16_1:target16_0
807 // movw dst, #target16_0
808 // movt dst, #target16_1
809 // For ARMv6: target24 => target8_2:target8_1:target8_0
810 // mov dst, #target8_0
811 // orr dst, dst, #target8_1 << 8
812 // orr dst, dst, #target8_2 << 16
813
814 // We extract the destination register from the emitted nop instruction.
815 Register dst = Register::from_code(
816 Instruction::RmValue(instr_at(pos + kInstrSize)));
817 ASSERT(IsNop(instr_at(pos + kInstrSize), dst.code()));
818 uint32_t target24 = target_pos + (Code::kHeaderSize - kHeapObjectTag);
819 ASSERT(is_uint24(target24));
820 if (is_uint8(target24)) {
821 // If the target fits in a byte then only patch with a mov
822 // instruction.
823 CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
824 1,
825 CodePatcher::DONT_FLUSH);
826 patcher.masm()->mov(dst, Operand(target24));
827 } else {
828 uint16_t target16_0 = target24 & kImm16Mask;
829 uint16_t target16_1 = target24 >> 16;
830 if (CpuFeatures::IsSupported(ARMv7)) {
831 // Patch with movw/movt.
832 if (target16_1 == 0) {
833 CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
834 1,
835 CodePatcher::DONT_FLUSH);
836 patcher.masm()->movw(dst, target16_0);
837 } else {
838 CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
839 2,
840 CodePatcher::DONT_FLUSH);
841 patcher.masm()->movw(dst, target16_0);
842 patcher.masm()->movt(dst, target16_1);
843 }
844 } else {
845 // Patch with a sequence of mov/orr/orr instructions.
846 uint8_t target8_0 = target16_0 & kImm8Mask;
847 uint8_t target8_1 = target16_0 >> 8;
848 uint8_t target8_2 = target16_1 & kImm8Mask;
849 if (target8_2 == 0) {
850 CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
851 2,
852 CodePatcher::DONT_FLUSH);
853 patcher.masm()->mov(dst, Operand(target8_0));
854 patcher.masm()->orr(dst, dst, Operand(target8_1 << 8));
855 } else {
856 CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos),
857 3,
858 CodePatcher::DONT_FLUSH);
859 patcher.masm()->mov(dst, Operand(target8_0));
860 patcher.masm()->orr(dst, dst, Operand(target8_1 << 8));
861 patcher.masm()->orr(dst, dst, Operand(target8_2 << 16));
862 }
863 }
864 }
803 return; 865 return;
804 } 866 }
805 int imm26 = target_pos - (pos + kPcLoadDelta); 867 int imm26 = target_pos - (pos + kPcLoadDelta);
806 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 868 ASSERT((instr & 7*B25) == 5*B25); // b, bl, or blx imm24
807 if (Instruction::ConditionField(instr) == kSpecialCondition) { 869 if (Instruction::ConditionField(instr) == kSpecialCondition) {
808 // blx uses bit 24 to encode bit 2 of imm26 870 // blx uses bit 24 to encode bit 2 of imm26
809 ASSERT((imm26 & 1) == 0); 871 ASSERT((imm26 & 1) == 0);
810 instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1)*B24; 872 instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1)*B24;
811 } else { 873 } else {
812 ASSERT((imm26 & 3) == 0); 874 ASSERT((imm26 & 3) == 0);
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 L->link_to(pc_offset()); 1287 L->link_to(pc_offset());
1226 } 1288 }
1227 1289
1228 // Block the emission of the constant pool, since the branch instruction must 1290 // Block the emission of the constant pool, since the branch instruction must
1229 // be emitted at the pc offset recorded by the label. 1291 // be emitted at the pc offset recorded by the label.
1230 BlockConstPoolFor(1); 1292 BlockConstPoolFor(1);
1231 return target_pos - (pc_offset() + kPcLoadDelta); 1293 return target_pos - (pc_offset() + kPcLoadDelta);
1232 } 1294 }
1233 1295
1234 1296
1235 void Assembler::label_at_put(Label* L, int at_offset) {
1236 int target_pos;
1237 ASSERT(!L->is_bound());
1238 if (L->is_linked()) {
1239 // Point to previous instruction that uses the link.
1240 target_pos = L->pos();
1241 } else {
1242 // First entry of the link chain points to itself.
1243 target_pos = at_offset;
1244 }
1245 L->link_to(at_offset);
1246 instr_at_put(at_offset, target_pos + (Code::kHeaderSize - kHeapObjectTag));
1247 }
1248
1249
1250 // Branch instructions. 1297 // Branch instructions.
1251 void Assembler::b(int branch_offset, Condition cond) { 1298 void Assembler::b(int branch_offset, Condition cond) {
1252 ASSERT((branch_offset & 3) == 0); 1299 ASSERT((branch_offset & 3) == 0);
1253 int imm24 = branch_offset >> 2; 1300 int imm24 = branch_offset >> 2;
1254 ASSERT(is_int24(imm24)); 1301 ASSERT(is_int24(imm24));
1255 emit(cond | B27 | B25 | (imm24 & kImm24Mask)); 1302 emit(cond | B27 | B25 | (imm24 & kImm24Mask));
1256 1303
1257 if (cond == al) { 1304 if (cond == al) {
1258 // Dead code is a good location to emit the constant pool. 1305 // Dead code is a good location to emit the constant pool.
1259 CheckConstPool(false, false); 1306 CheckConstPool(false, false);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1382 positions_recorder()->WriteRecordedPositions(); 1429 positions_recorder()->WriteRecordedPositions();
1383 } 1430 }
1384 // Don't allow nop instructions in the form mov rn, rn to be generated using 1431 // Don't allow nop instructions in the form mov rn, rn to be generated using
1385 // the mov instruction. They must be generated using nop(int/NopMarkerTypes) 1432 // the mov instruction. They must be generated using nop(int/NopMarkerTypes)
1386 // or MarkCode(int/NopMarkerTypes) pseudo instructions. 1433 // or MarkCode(int/NopMarkerTypes) pseudo instructions.
1387 ASSERT(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al)); 1434 ASSERT(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al));
1388 addrmod1(cond | MOV | s, r0, dst, src); 1435 addrmod1(cond | MOV | s, r0, dst, src);
1389 } 1436 }
1390 1437
1391 1438
1439 void Assembler::mov_label_offset(Register dst, Label* label) {
1440 if (label->is_bound()) {
1441 mov(dst, Operand(label->pos() + (Code::kHeaderSize - kHeapObjectTag)));
1442 } else {
1443 // Emit the link to the label in the code stream followed by extra nop
1444 // instructions.
1445 // If the label is not linked, then start a new link chain by linking it to
1446 // itself, emitting pc_offset().
1447 int link = label->is_linked() ? label->pos() : pc_offset();
1448 label->link_to(pc_offset());
1449
1450 // When the label is bound, these instructions will be patched with a
1451 // sequence of movw/movt or mov/orr/orr instructions. They will load the
1452 // destination register with the position of the label from the beginning
1453 // of the code.
1454 //
1455 // The link will be extracted from the first instruction and the destination
1456 // register from the second.
1457 // For ARMv7:
1458 // link
1459 // mov dst, dst
1460 // For ARMv6:
1461 // link
1462 // mov dst, dst
1463 // mov dst, dst
1464 //
1465 // When the label gets bound: target_at extracts the link and target_at_put
1466 // patches the instructions.
1467 ASSERT(is_uint24(link));
1468 BlockConstPoolScope block_const_pool(this);
1469 emit(link);
1470 nop(dst.code());
1471 if (!CpuFeatures::IsSupported(ARMv7)) {
1472 nop(dst.code());
1473 }
1474 }
1475 }
1476
1477
1392 void Assembler::movw(Register reg, uint32_t immediate, Condition cond) { 1478 void Assembler::movw(Register reg, uint32_t immediate, Condition cond) {
1393 ASSERT(immediate < 0x10000); 1479 ASSERT(immediate < 0x10000);
1394 // May use movw if supported, but on unsupported platforms will try to use 1480 // May use movw if supported, but on unsupported platforms will try to use
1395 // equivalent rotated immed_8 value and other tricks before falling back to a 1481 // equivalent rotated immed_8 value and other tricks before falling back to a
1396 // constant pool load. 1482 // constant pool load.
1397 mov(reg, Operand(immediate), LeaveCC, cond); 1483 mov(reg, Operand(immediate), LeaveCC, cond);
1398 } 1484 }
1399 1485
1400 1486
1401 void Assembler::movt(Register reg, uint32_t immediate, Condition cond) { 1487 void Assembler::movt(Register reg, uint32_t immediate, Condition cond) {
(...skipping 1952 matching lines...) Expand 10 before | Expand all | Expand 10 after
3354 3440
3355 // Since a constant pool was just emitted, move the check offset forward by 3441 // Since a constant pool was just emitted, move the check offset forward by
3356 // the standard interval. 3442 // the standard interval.
3357 next_buffer_check_ = pc_offset() + kCheckPoolInterval; 3443 next_buffer_check_ = pc_offset() + kCheckPoolInterval;
3358 } 3444 }
3359 3445
3360 3446
3361 } } // namespace v8::internal 3447 } } // namespace v8::internal
3362 3448
3363 #endif // V8_TARGET_ARCH_ARM 3449 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/constants-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698