OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #if V8_TARGET_ARCH_ARM | 9 #if V8_TARGET_ARCH_ARM |
10 | 10 |
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
684 pop(lr); | 684 pop(lr); |
685 bind(&done); | 685 bind(&done); |
686 if (and_then == kReturnAtEnd) { | 686 if (and_then == kReturnAtEnd) { |
687 Ret(); | 687 Ret(); |
688 } | 688 } |
689 } | 689 } |
690 | 690 |
691 | 691 |
692 void MacroAssembler::PushFixedFrame(Register marker_reg) { | 692 void MacroAssembler::PushFixedFrame(Register marker_reg) { |
693 DCHECK(!marker_reg.is_valid() || marker_reg.code() < cp.code()); | 693 DCHECK(!marker_reg.is_valid() || marker_reg.code() < cp.code()); |
694 stm(db_w, sp, (marker_reg.is_valid() ? marker_reg.bit() : 0) | | 694 stm(db_w, sp, (marker_reg.is_valid() ? marker_reg.bit() : 0) | cp.bit() | |
695 cp.bit() | | 695 (FLAG_enable_embedded_constant_pool ? pp.bit() : 0) | |
696 (FLAG_enable_ool_constant_pool ? pp.bit() : 0) | | 696 fp.bit() | lr.bit()); |
697 fp.bit() | | |
698 lr.bit()); | |
699 } | 697 } |
700 | 698 |
701 | 699 |
702 void MacroAssembler::PopFixedFrame(Register marker_reg) { | 700 void MacroAssembler::PopFixedFrame(Register marker_reg) { |
703 DCHECK(!marker_reg.is_valid() || marker_reg.code() < cp.code()); | 701 DCHECK(!marker_reg.is_valid() || marker_reg.code() < cp.code()); |
704 ldm(ia_w, sp, (marker_reg.is_valid() ? marker_reg.bit() : 0) | | 702 ldm(ia_w, sp, (marker_reg.is_valid() ? marker_reg.bit() : 0) | cp.bit() | |
705 cp.bit() | | 703 (FLAG_enable_embedded_constant_pool ? pp.bit() : 0) | |
706 (FLAG_enable_ool_constant_pool ? pp.bit() : 0) | | 704 fp.bit() | lr.bit()); |
707 fp.bit() | | |
708 lr.bit()); | |
709 } | 705 } |
710 | 706 |
711 | 707 |
712 // Push and pop all registers that can hold pointers. | 708 // Push and pop all registers that can hold pointers. |
713 void MacroAssembler::PushSafepointRegisters() { | 709 void MacroAssembler::PushSafepointRegisters() { |
714 // Safepoints expect a block of contiguous register values starting with r0: | 710 // Safepoints expect a block of contiguous register values starting with r0: |
715 DCHECK(((1 << kNumSafepointSavedRegisters) - 1) == kSafepointSavedRegisters); | 711 DCHECK(((1 << kNumSafepointSavedRegisters) - 1) == kSafepointSavedRegisters); |
716 // Safepoints expect a block of kNumSafepointRegisters values on the | 712 // Safepoints expect a block of kNumSafepointRegisters values on the |
717 // stack, so adjust the stack for unsaved registers. | 713 // stack, so adjust the stack for unsaved registers. |
718 const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters; | 714 const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters; |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
978 void MacroAssembler::VmovLow(DwVfpRegister dst, Register src) { | 974 void MacroAssembler::VmovLow(DwVfpRegister dst, Register src) { |
979 if (dst.code() < 16) { | 975 if (dst.code() < 16) { |
980 const LowDwVfpRegister loc = LowDwVfpRegister::from_code(dst.code()); | 976 const LowDwVfpRegister loc = LowDwVfpRegister::from_code(dst.code()); |
981 vmov(loc.low(), src); | 977 vmov(loc.low(), src); |
982 } else { | 978 } else { |
983 vmov(dst, VmovIndexLo, src); | 979 vmov(dst, VmovIndexLo, src); |
984 } | 980 } |
985 } | 981 } |
986 | 982 |
987 | 983 |
984 void MacroAssembler::LoadTargetConstantPoolPointerRegister(Register target) { | |
rmcilroy
2015/05/20 14:32:10
/s/LoadTargetConstantPoolPointerRegister/LoadConst
MTBrandyberry
2015/05/20 22:28:22
Done.
| |
985 DCHECK(FLAG_enable_embedded_constant_pool); | |
986 ldr(pp, MemOperand(target, Code::kConstantPoolOffset - Code::kHeaderSize)); | |
987 add(pp, pp, target); | |
988 } | |
989 | |
990 | |
988 void MacroAssembler::LoadConstantPoolPointerRegister() { | 991 void MacroAssembler::LoadConstantPoolPointerRegister() { |
989 if (FLAG_enable_ool_constant_pool) { | 992 DCHECK(FLAG_enable_embedded_constant_pool); |
990 int constant_pool_offset = Code::kConstantPoolOffset - Code::kHeaderSize - | 993 int entry_offset = pc_offset() + Instruction::kPCReadOffset; |
991 pc_offset() - Instruction::kPCReadOffset; | 994 sub(ip, pc, Operand(entry_offset)); |
992 DCHECK(ImmediateFitsAddrMode2Instruction(constant_pool_offset)); | 995 LoadTargetConstantPoolPointerRegister(ip); |
993 ldr(pp, MemOperand(pc, constant_pool_offset)); | |
994 } | |
995 } | 996 } |
996 | 997 |
997 | 998 |
998 void MacroAssembler::StubPrologue() { | 999 void MacroAssembler::StubPrologue() { |
999 PushFixedFrame(); | 1000 PushFixedFrame(); |
1000 Push(Smi::FromInt(StackFrame::STUB)); | 1001 Push(Smi::FromInt(StackFrame::STUB)); |
1001 // Adjust FP to point to saved FP. | 1002 // Adjust FP to point to saved FP. |
1002 add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | 1003 add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
1003 if (FLAG_enable_ool_constant_pool) { | 1004 if (FLAG_enable_embedded_constant_pool) { |
1004 LoadConstantPoolPointerRegister(); | 1005 LoadConstantPoolPointerRegister(); |
1005 set_ool_constant_pool_available(true); | 1006 set_constant_pool_available(true); |
1006 } | 1007 } |
1007 } | 1008 } |
1008 | 1009 |
1009 | 1010 |
1010 void MacroAssembler::Prologue(bool code_pre_aging) { | 1011 void MacroAssembler::Prologue(bool code_pre_aging) { |
1011 { PredictableCodeSizeScope predictible_code_size_scope( | 1012 { PredictableCodeSizeScope predictible_code_size_scope( |
1012 this, kNoCodeAgeSequenceLength); | 1013 this, kNoCodeAgeSequenceLength); |
1013 // The following three instructions must remain together and unmodified | 1014 // The following three instructions must remain together and unmodified |
1014 // for code aging to work properly. | 1015 // for code aging to work properly. |
1015 if (code_pre_aging) { | 1016 if (code_pre_aging) { |
1016 // Pre-age the code. | 1017 // Pre-age the code. |
1017 Code* stub = Code::GetPreAgedCodeAgeStub(isolate()); | 1018 Code* stub = Code::GetPreAgedCodeAgeStub(isolate()); |
1018 add(r0, pc, Operand(-8)); | 1019 add(r0, pc, Operand(-8)); |
1019 ldr(pc, MemOperand(pc, -4)); | 1020 ldr(pc, MemOperand(pc, -4)); |
1020 emit_code_stub_address(stub); | 1021 emit_code_stub_address(stub); |
1021 } else { | 1022 } else { |
1022 PushFixedFrame(r1); | 1023 PushFixedFrame(r1); |
1023 nop(ip.code()); | 1024 nop(ip.code()); |
1024 // Adjust FP to point to saved FP. | 1025 // Adjust FP to point to saved FP. |
1025 add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | 1026 add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
1026 } | 1027 } |
1027 } | 1028 } |
1028 if (FLAG_enable_ool_constant_pool) { | 1029 if (FLAG_enable_embedded_constant_pool) { |
1029 LoadConstantPoolPointerRegister(); | 1030 LoadConstantPoolPointerRegister(); |
1030 set_ool_constant_pool_available(true); | 1031 set_constant_pool_available(true); |
1031 } | 1032 } |
1032 } | 1033 } |
1033 | 1034 |
1034 | 1035 |
1035 void MacroAssembler::EnterFrame(StackFrame::Type type, | 1036 void MacroAssembler::EnterFrame(StackFrame::Type type, |
1036 bool load_constant_pool_pointer_reg) { | 1037 bool load_constant_pool_pointer_reg) { |
1037 // r0-r3: preserved | 1038 // r0-r3: preserved |
1038 PushFixedFrame(); | 1039 PushFixedFrame(); |
1039 if (FLAG_enable_ool_constant_pool && load_constant_pool_pointer_reg) { | 1040 if (FLAG_enable_embedded_constant_pool && load_constant_pool_pointer_reg) { |
1040 LoadConstantPoolPointerRegister(); | 1041 LoadConstantPoolPointerRegister(); |
1041 } | 1042 } |
1042 mov(ip, Operand(Smi::FromInt(type))); | 1043 mov(ip, Operand(Smi::FromInt(type))); |
1043 push(ip); | 1044 push(ip); |
1044 mov(ip, Operand(CodeObject())); | 1045 mov(ip, Operand(CodeObject())); |
1045 push(ip); | 1046 push(ip); |
1046 // Adjust FP to point to saved FP. | 1047 // Adjust FP to point to saved FP. |
1047 add(fp, sp, | 1048 add(fp, sp, |
1048 Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize)); | 1049 Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize)); |
1049 } | 1050 } |
1050 | 1051 |
1051 | 1052 |
1052 int MacroAssembler::LeaveFrame(StackFrame::Type type) { | 1053 int MacroAssembler::LeaveFrame(StackFrame::Type type) { |
1053 // r0: preserved | 1054 // r0: preserved |
1054 // r1: preserved | 1055 // r1: preserved |
1055 // r2: preserved | 1056 // r2: preserved |
1056 | 1057 |
1057 // Drop the execution stack down to the frame pointer and restore | 1058 // Drop the execution stack down to the frame pointer and restore |
1058 // the caller frame pointer, return address and constant pool pointer | 1059 // the caller frame pointer, return address and constant pool pointer |
1059 // (if FLAG_enable_ool_constant_pool). | 1060 // (if FLAG_enable_embedded_constant_pool). |
1060 int frame_ends; | 1061 int frame_ends; |
1061 if (FLAG_enable_ool_constant_pool) { | 1062 if (FLAG_enable_embedded_constant_pool) { |
1062 add(sp, fp, Operand(StandardFrameConstants::kConstantPoolOffset)); | 1063 add(sp, fp, Operand(StandardFrameConstants::kConstantPoolOffset)); |
1063 frame_ends = pc_offset(); | 1064 frame_ends = pc_offset(); |
1064 ldm(ia_w, sp, pp.bit() | fp.bit() | lr.bit()); | 1065 ldm(ia_w, sp, pp.bit() | fp.bit() | lr.bit()); |
1065 } else { | 1066 } else { |
1066 mov(sp, fp); | 1067 mov(sp, fp); |
1067 frame_ends = pc_offset(); | 1068 frame_ends = pc_offset(); |
1068 ldm(ia_w, sp, fp.bit() | lr.bit()); | 1069 ldm(ia_w, sp, fp.bit() | lr.bit()); |
1069 } | 1070 } |
1070 return frame_ends; | 1071 return frame_ends; |
1071 } | 1072 } |
1072 | 1073 |
1073 | 1074 |
1074 void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) { | 1075 void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) { |
1075 // Set up the frame structure on the stack. | 1076 // Set up the frame structure on the stack. |
1076 DCHECK_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); | 1077 DCHECK_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); |
1077 DCHECK_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); | 1078 DCHECK_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); |
1078 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); | 1079 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); |
1079 Push(lr, fp); | 1080 Push(lr, fp); |
1080 mov(fp, Operand(sp)); // Set up new frame pointer. | 1081 mov(fp, Operand(sp)); // Set up new frame pointer. |
1081 // Reserve room for saved entry sp and code object. | 1082 // Reserve room for saved entry sp and code object. |
1082 sub(sp, sp, Operand(ExitFrameConstants::kFrameSize)); | 1083 sub(sp, sp, Operand(ExitFrameConstants::kFrameSize)); |
1083 if (emit_debug_code()) { | 1084 if (emit_debug_code()) { |
1084 mov(ip, Operand::Zero()); | 1085 mov(ip, Operand::Zero()); |
1085 str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 1086 str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
1086 } | 1087 } |
1087 if (FLAG_enable_ool_constant_pool) { | 1088 if (FLAG_enable_embedded_constant_pool) { |
1088 str(pp, MemOperand(fp, ExitFrameConstants::kConstantPoolOffset)); | 1089 str(pp, MemOperand(fp, ExitFrameConstants::kConstantPoolOffset)); |
1089 } | 1090 } |
1090 mov(ip, Operand(CodeObject())); | 1091 mov(ip, Operand(CodeObject())); |
1091 str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset)); | 1092 str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset)); |
1092 | 1093 |
1093 // Save the frame pointer and the context in top. | 1094 // Save the frame pointer and the context in top. |
1094 mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); | 1095 mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); |
1095 str(fp, MemOperand(ip)); | 1096 str(fp, MemOperand(ip)); |
1096 mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); | 1097 mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); |
1097 str(cp, MemOperand(ip)); | 1098 str(cp, MemOperand(ip)); |
1098 | 1099 |
1099 // Optionally save all double registers. | 1100 // Optionally save all double registers. |
1100 if (save_doubles) { | 1101 if (save_doubles) { |
1101 SaveFPRegs(sp, ip); | 1102 SaveFPRegs(sp, ip); |
1102 // Note that d0 will be accessible at | 1103 // Note that d0 will be accessible at |
1103 // fp - ExitFrameConstants::kFrameSize - | 1104 // fp - ExitFrameConstants::kFrameSize - |
1104 // DwVfpRegister::kMaxNumRegisters * kDoubleSize, | 1105 // DwVfpRegister::kMaxNumRegisters * kDoubleSize, |
1105 // since the sp slot, code slot and constant pool slot (if | 1106 // since the sp slot, code slot and constant pool slot (if |
1106 // FLAG_enable_ool_constant_pool) were pushed after the fp. | 1107 // FLAG_enable_embedded_constant_pool) were pushed after the fp. |
1107 } | 1108 } |
1108 | 1109 |
1109 // Reserve place for the return address and stack space and align the frame | 1110 // Reserve place for the return address and stack space and align the frame |
1110 // preparing for calling the runtime function. | 1111 // preparing for calling the runtime function. |
1111 const int frame_alignment = MacroAssembler::ActivationFrameAlignment(); | 1112 const int frame_alignment = MacroAssembler::ActivationFrameAlignment(); |
1112 sub(sp, sp, Operand((stack_space + 1) * kPointerSize)); | 1113 sub(sp, sp, Operand((stack_space + 1) * kPointerSize)); |
1113 if (frame_alignment > 0) { | 1114 if (frame_alignment > 0) { |
1114 DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); | 1115 DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); |
1115 and_(sp, sp, Operand(-frame_alignment)); | 1116 and_(sp, sp, Operand(-frame_alignment)); |
1116 } | 1117 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1176 if (restore_context) { | 1177 if (restore_context) { |
1177 mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); | 1178 mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); |
1178 ldr(cp, MemOperand(ip)); | 1179 ldr(cp, MemOperand(ip)); |
1179 } | 1180 } |
1180 #ifdef DEBUG | 1181 #ifdef DEBUG |
1181 mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); | 1182 mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); |
1182 str(r3, MemOperand(ip)); | 1183 str(r3, MemOperand(ip)); |
1183 #endif | 1184 #endif |
1184 | 1185 |
1185 // Tear down the exit frame, pop the arguments, and return. | 1186 // Tear down the exit frame, pop the arguments, and return. |
1186 if (FLAG_enable_ool_constant_pool) { | 1187 if (FLAG_enable_embedded_constant_pool) { |
1187 ldr(pp, MemOperand(fp, ExitFrameConstants::kConstantPoolOffset)); | 1188 ldr(pp, MemOperand(fp, ExitFrameConstants::kConstantPoolOffset)); |
1188 } | 1189 } |
1189 mov(sp, Operand(fp)); | 1190 mov(sp, Operand(fp)); |
1190 ldm(ia_w, sp, fp.bit() | lr.bit()); | 1191 ldm(ia_w, sp, fp.bit() | lr.bit()); |
1191 if (argument_count.is_valid()) { | 1192 if (argument_count.is_valid()) { |
1192 if (argument_count_is_length) { | 1193 if (argument_count_is_length) { |
1193 add(sp, sp, argument_count); | 1194 add(sp, sp, argument_count); |
1194 } else { | 1195 } else { |
1195 add(sp, sp, Operand(argument_count, LSL, kPointerSizeLog2)); | 1196 add(sp, sp, Operand(argument_count, LSL, kPointerSizeLog2)); |
1196 } | 1197 } |
(...skipping 2197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3394 } | 3395 } |
3395 } | 3396 } |
3396 | 3397 |
3397 | 3398 |
3398 void MacroAssembler::GetRelocatedValueLocation(Register ldr_location, | 3399 void MacroAssembler::GetRelocatedValueLocation(Register ldr_location, |
3399 Register result, | 3400 Register result, |
3400 Register scratch) { | 3401 Register scratch) { |
3401 Label small_constant_pool_load, load_result; | 3402 Label small_constant_pool_load, load_result; |
3402 ldr(result, MemOperand(ldr_location)); | 3403 ldr(result, MemOperand(ldr_location)); |
3403 | 3404 |
3404 if (FLAG_enable_ool_constant_pool) { | 3405 if (FLAG_enable_embedded_constant_pool) { |
3405 // Check if this is an extended constant pool load. | 3406 // Check if this is an extended constant pool load. |
3406 and_(scratch, result, Operand(GetConsantPoolLoadMask())); | 3407 and_(scratch, result, Operand(GetConsantPoolLoadMask())); |
3407 teq(scratch, Operand(GetConsantPoolLoadPattern())); | 3408 teq(scratch, Operand(GetConsantPoolLoadPattern())); |
3408 b(eq, &small_constant_pool_load); | 3409 b(eq, &small_constant_pool_load); |
3409 if (emit_debug_code()) { | 3410 if (emit_debug_code()) { |
3410 // Check that the instruction sequence is: | 3411 // Check that the instruction sequence is: |
3411 // movw reg, #offset_low | 3412 // movw reg, #offset_low |
3412 // movt reg, #offset_high | 3413 // movt reg, #offset_high |
3413 // ldr reg, [pp, reg] | 3414 // ldr reg, [pp, reg] |
3414 Instr patterns[] = {GetMovWPattern(), GetMovTPattern(), | 3415 Instr patterns[] = {GetMovWPattern(), GetMovTPattern(), |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3448 // Result was clobbered. Restore it. | 3449 // Result was clobbered. Restore it. |
3449 ldr(result, MemOperand(ldr_location)); | 3450 ldr(result, MemOperand(ldr_location)); |
3450 } | 3451 } |
3451 | 3452 |
3452 // Get the offset into the constant pool. | 3453 // Get the offset into the constant pool. |
3453 const uint32_t kLdrOffsetMask = (1 << 12) - 1; | 3454 const uint32_t kLdrOffsetMask = (1 << 12) - 1; |
3454 and_(result, result, Operand(kLdrOffsetMask)); | 3455 and_(result, result, Operand(kLdrOffsetMask)); |
3455 | 3456 |
3456 bind(&load_result); | 3457 bind(&load_result); |
3457 // Get the address of the constant. | 3458 // Get the address of the constant. |
3458 if (FLAG_enable_ool_constant_pool) { | 3459 if (FLAG_enable_embedded_constant_pool) { |
3459 add(result, pp, Operand(result)); | 3460 add(result, pp, Operand(result)); |
3460 } else { | 3461 } else { |
3461 add(result, ldr_location, Operand(result)); | 3462 add(result, ldr_location, Operand(result)); |
3462 add(result, result, Operand(Instruction::kPCReadOffset)); | 3463 add(result, result, Operand(Instruction::kPCReadOffset)); |
3463 } | 3464 } |
3464 } | 3465 } |
3465 | 3466 |
3466 | 3467 |
3467 void MacroAssembler::CheckPageFlag( | 3468 void MacroAssembler::CheckPageFlag( |
3468 Register object, | 3469 Register object, |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3908 } | 3909 } |
3909 } | 3910 } |
3910 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); | 3911 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); |
3911 add(result, result, Operand(dividend, LSR, 31)); | 3912 add(result, result, Operand(dividend, LSR, 31)); |
3912 } | 3913 } |
3913 | 3914 |
3914 } // namespace internal | 3915 } // namespace internal |
3915 } // namespace v8 | 3916 } // namespace v8 |
3916 | 3917 |
3917 #endif // V8_TARGET_ARCH_ARM | 3918 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |