| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 #if defined(V8_TARGET_ARCH_ARM) | 32 #if defined(V8_TARGET_ARCH_ARM) |
| 33 | 33 |
| 34 #include "bootstrapper.h" | 34 #include "bootstrapper.h" |
| 35 #include "codegen-inl.h" | 35 #include "codegen-inl.h" |
| 36 #include "debug.h" | 36 #include "debug.h" |
| 37 #include "runtime.h" | 37 #include "runtime.h" |
| 38 | 38 |
| 39 namespace v8 { | 39 namespace v8 { |
| 40 namespace internal { | 40 namespace internal { |
| 41 | 41 |
| 42 MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size) | 42 MacroAssembler::MacroAssembler(void* buffer, int size) |
| 43 : Assembler(arg_isolate, buffer, size), | 43 : Assembler(buffer, size), |
| 44 generating_stub_(false), | 44 generating_stub_(false), |
| 45 allow_stub_calls_(true) { | 45 allow_stub_calls_(true), |
| 46 if (isolate() != NULL) { | 46 code_object_(HEAP->undefined_value()) { |
| 47 code_object_ = Handle<Object>(isolate()->heap()->undefined_value(), | |
| 48 isolate()); | |
| 49 } | |
| 50 } | 47 } |
| 51 | 48 |
| 52 | 49 |
| 53 // We always generate arm code, never thumb code, even if V8 is compiled to | 50 // We always generate arm code, never thumb code, even if V8 is compiled to |
| 54 // thumb, so we require inter-working support | 51 // thumb, so we require inter-working support |
| 55 #if defined(__thumb__) && !defined(USE_THUMB_INTERWORK) | 52 #if defined(__thumb__) && !defined(USE_THUMB_INTERWORK) |
| 56 #error "flag -mthumb-interwork missing" | 53 #error "flag -mthumb-interwork missing" |
| 57 #endif | 54 #endif |
| 58 | 55 |
| 59 | 56 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 | 285 |
| 289 void MacroAssembler::And(Register dst, Register src1, const Operand& src2, | 286 void MacroAssembler::And(Register dst, Register src1, const Operand& src2, |
| 290 Condition cond) { | 287 Condition cond) { |
| 291 if (!src2.is_reg() && | 288 if (!src2.is_reg() && |
| 292 !src2.must_use_constant_pool() && | 289 !src2.must_use_constant_pool() && |
| 293 src2.immediate() == 0) { | 290 src2.immediate() == 0) { |
| 294 mov(dst, Operand(0, RelocInfo::NONE), LeaveCC, cond); | 291 mov(dst, Operand(0, RelocInfo::NONE), LeaveCC, cond); |
| 295 | 292 |
| 296 } else if (!src2.is_single_instruction() && | 293 } else if (!src2.is_single_instruction() && |
| 297 !src2.must_use_constant_pool() && | 294 !src2.must_use_constant_pool() && |
| 298 CpuFeatures::IsSupported(ARMv7) && | 295 Isolate::Current()->cpu_features()->IsSupported(ARMv7) && |
| 299 IsPowerOf2(src2.immediate() + 1)) { | 296 IsPowerOf2(src2.immediate() + 1)) { |
| 300 ubfx(dst, src1, 0, WhichPowerOf2(src2.immediate() + 1), cond); | 297 ubfx(dst, src1, 0, WhichPowerOf2(src2.immediate() + 1), cond); |
| 301 | 298 |
| 302 } else { | 299 } else { |
| 303 and_(dst, src1, src2, LeaveCC, cond); | 300 and_(dst, src1, src2, LeaveCC, cond); |
| 304 } | 301 } |
| 305 } | 302 } |
| 306 | 303 |
| 307 | 304 |
| 308 void MacroAssembler::Ubfx(Register dst, Register src1, int lsb, int width, | 305 void MacroAssembler::Ubfx(Register dst, Register src1, int lsb, int width, |
| 309 Condition cond) { | 306 Condition cond) { |
| 310 ASSERT(lsb < 32); | 307 ASSERT(lsb < 32); |
| 311 if (!CpuFeatures::IsSupported(ARMv7)) { | 308 if (!Isolate::Current()->cpu_features()->IsSupported(ARMv7)) { |
| 312 int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1); | 309 int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1); |
| 313 and_(dst, src1, Operand(mask), LeaveCC, cond); | 310 and_(dst, src1, Operand(mask), LeaveCC, cond); |
| 314 if (lsb != 0) { | 311 if (lsb != 0) { |
| 315 mov(dst, Operand(dst, LSR, lsb), LeaveCC, cond); | 312 mov(dst, Operand(dst, LSR, lsb), LeaveCC, cond); |
| 316 } | 313 } |
| 317 } else { | 314 } else { |
| 318 ubfx(dst, src1, lsb, width, cond); | 315 ubfx(dst, src1, lsb, width, cond); |
| 319 } | 316 } |
| 320 } | 317 } |
| 321 | 318 |
| 322 | 319 |
| 323 void MacroAssembler::Sbfx(Register dst, Register src1, int lsb, int width, | 320 void MacroAssembler::Sbfx(Register dst, Register src1, int lsb, int width, |
| 324 Condition cond) { | 321 Condition cond) { |
| 325 ASSERT(lsb < 32); | 322 ASSERT(lsb < 32); |
| 326 if (!CpuFeatures::IsSupported(ARMv7)) { | 323 if (!Isolate::Current()->cpu_features()->IsSupported(ARMv7)) { |
| 327 int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1); | 324 int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1); |
| 328 and_(dst, src1, Operand(mask), LeaveCC, cond); | 325 and_(dst, src1, Operand(mask), LeaveCC, cond); |
| 329 int shift_up = 32 - lsb - width; | 326 int shift_up = 32 - lsb - width; |
| 330 int shift_down = lsb + shift_up; | 327 int shift_down = lsb + shift_up; |
| 331 if (shift_up != 0) { | 328 if (shift_up != 0) { |
| 332 mov(dst, Operand(dst, LSL, shift_up), LeaveCC, cond); | 329 mov(dst, Operand(dst, LSL, shift_up), LeaveCC, cond); |
| 333 } | 330 } |
| 334 if (shift_down != 0) { | 331 if (shift_down != 0) { |
| 335 mov(dst, Operand(dst, ASR, shift_down), LeaveCC, cond); | 332 mov(dst, Operand(dst, ASR, shift_down), LeaveCC, cond); |
| 336 } | 333 } |
| 337 } else { | 334 } else { |
| 338 sbfx(dst, src1, lsb, width, cond); | 335 sbfx(dst, src1, lsb, width, cond); |
| 339 } | 336 } |
| 340 } | 337 } |
| 341 | 338 |
| 342 | 339 |
| 343 void MacroAssembler::Bfi(Register dst, | 340 void MacroAssembler::Bfi(Register dst, |
| 344 Register src, | 341 Register src, |
| 345 Register scratch, | 342 Register scratch, |
| 346 int lsb, | 343 int lsb, |
| 347 int width, | 344 int width, |
| 348 Condition cond) { | 345 Condition cond) { |
| 349 ASSERT(0 <= lsb && lsb < 32); | 346 ASSERT(0 <= lsb && lsb < 32); |
| 350 ASSERT(0 <= width && width < 32); | 347 ASSERT(0 <= width && width < 32); |
| 351 ASSERT(lsb + width < 32); | 348 ASSERT(lsb + width < 32); |
| 352 ASSERT(!scratch.is(dst)); | 349 ASSERT(!scratch.is(dst)); |
| 353 if (width == 0) return; | 350 if (width == 0) return; |
| 354 if (!CpuFeatures::IsSupported(ARMv7)) { | 351 if (!Isolate::Current()->cpu_features()->IsSupported(ARMv7)) { |
| 355 int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1); | 352 int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1); |
| 356 bic(dst, dst, Operand(mask)); | 353 bic(dst, dst, Operand(mask)); |
| 357 and_(scratch, src, Operand((1 << width) - 1)); | 354 and_(scratch, src, Operand((1 << width) - 1)); |
| 358 mov(scratch, Operand(scratch, LSL, lsb)); | 355 mov(scratch, Operand(scratch, LSL, lsb)); |
| 359 orr(dst, dst, scratch); | 356 orr(dst, dst, scratch); |
| 360 } else { | 357 } else { |
| 361 bfi(dst, src, lsb, width, cond); | 358 bfi(dst, src, lsb, width, cond); |
| 362 } | 359 } |
| 363 } | 360 } |
| 364 | 361 |
| 365 | 362 |
| 366 void MacroAssembler::Bfc(Register dst, int lsb, int width, Condition cond) { | 363 void MacroAssembler::Bfc(Register dst, int lsb, int width, Condition cond) { |
| 367 ASSERT(lsb < 32); | 364 ASSERT(lsb < 32); |
| 368 if (!CpuFeatures::IsSupported(ARMv7)) { | 365 if (!Isolate::Current()->cpu_features()->IsSupported(ARMv7)) { |
| 369 int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1); | 366 int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1); |
| 370 bic(dst, dst, Operand(mask)); | 367 bic(dst, dst, Operand(mask)); |
| 371 } else { | 368 } else { |
| 372 bfc(dst, lsb, width, cond); | 369 bfc(dst, lsb, width, cond); |
| 373 } | 370 } |
| 374 } | 371 } |
| 375 | 372 |
| 376 | 373 |
| 377 void MacroAssembler::Usat(Register dst, int satpos, const Operand& src, | 374 void MacroAssembler::Usat(Register dst, int satpos, const Operand& src, |
| 378 Condition cond) { | 375 Condition cond) { |
| 379 if (!CpuFeatures::IsSupported(ARMv7)) { | 376 if (!Isolate::Current()->cpu_features()->IsSupported(ARMv7)) { |
| 380 ASSERT(!dst.is(pc) && !src.rm().is(pc)); | 377 ASSERT(!dst.is(pc) && !src.rm().is(pc)); |
| 381 ASSERT((satpos >= 0) && (satpos <= 31)); | 378 ASSERT((satpos >= 0) && (satpos <= 31)); |
| 382 | 379 |
| 383 // These asserts are required to ensure compatibility with the ARMv7 | 380 // These asserts are required to ensure compatibility with the ARMv7 |
| 384 // implementation. | 381 // implementation. |
| 385 ASSERT((src.shift_op() == ASR) || (src.shift_op() == LSL)); | 382 ASSERT((src.shift_op() == ASR) || (src.shift_op() == LSL)); |
| 386 ASSERT(src.rs().is(no_reg)); | 383 ASSERT(src.rs().is(no_reg)); |
| 387 | 384 |
| 388 Label done; | 385 Label done; |
| 389 int satval = (1 << satpos) - 1; | 386 int satval = (1 << satpos) - 1; |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 | 612 |
| 616 | 613 |
| 617 void MacroAssembler::Ldrd(Register dst1, Register dst2, | 614 void MacroAssembler::Ldrd(Register dst1, Register dst2, |
| 618 const MemOperand& src, Condition cond) { | 615 const MemOperand& src, Condition cond) { |
| 619 ASSERT(src.rm().is(no_reg)); | 616 ASSERT(src.rm().is(no_reg)); |
| 620 ASSERT(!dst1.is(lr)); // r14. | 617 ASSERT(!dst1.is(lr)); // r14. |
| 621 ASSERT_EQ(0, dst1.code() % 2); | 618 ASSERT_EQ(0, dst1.code() % 2); |
| 622 ASSERT_EQ(dst1.code() + 1, dst2.code()); | 619 ASSERT_EQ(dst1.code() + 1, dst2.code()); |
| 623 | 620 |
| 624 // Generate two ldr instructions if ldrd is not available. | 621 // Generate two ldr instructions if ldrd is not available. |
| 625 if (CpuFeatures::IsSupported(ARMv7)) { | 622 if (Isolate::Current()->cpu_features()->IsSupported(ARMv7)) { |
| 626 CpuFeatures::Scope scope(ARMv7); | 623 CpuFeatures::Scope scope(ARMv7); |
| 627 ldrd(dst1, dst2, src, cond); | 624 ldrd(dst1, dst2, src, cond); |
| 628 } else { | 625 } else { |
| 629 MemOperand src2(src); | 626 MemOperand src2(src); |
| 630 src2.set_offset(src2.offset() + 4); | 627 src2.set_offset(src2.offset() + 4); |
| 631 if (dst1.is(src.rn())) { | 628 if (dst1.is(src.rn())) { |
| 632 ldr(dst2, src2, cond); | 629 ldr(dst2, src2, cond); |
| 633 ldr(dst1, src, cond); | 630 ldr(dst1, src, cond); |
| 634 } else { | 631 } else { |
| 635 ldr(dst1, src, cond); | 632 ldr(dst1, src, cond); |
| 636 ldr(dst2, src2, cond); | 633 ldr(dst2, src2, cond); |
| 637 } | 634 } |
| 638 } | 635 } |
| 639 } | 636 } |
| 640 | 637 |
| 641 | 638 |
| 642 void MacroAssembler::Strd(Register src1, Register src2, | 639 void MacroAssembler::Strd(Register src1, Register src2, |
| 643 const MemOperand& dst, Condition cond) { | 640 const MemOperand& dst, Condition cond) { |
| 644 ASSERT(dst.rm().is(no_reg)); | 641 ASSERT(dst.rm().is(no_reg)); |
| 645 ASSERT(!src1.is(lr)); // r14. | 642 ASSERT(!src1.is(lr)); // r14. |
| 646 ASSERT_EQ(0, src1.code() % 2); | 643 ASSERT_EQ(0, src1.code() % 2); |
| 647 ASSERT_EQ(src1.code() + 1, src2.code()); | 644 ASSERT_EQ(src1.code() + 1, src2.code()); |
| 648 | 645 |
| 649 // Generate two str instructions if strd is not available. | 646 // Generate two str instructions if strd is not available. |
| 650 if (CpuFeatures::IsSupported(ARMv7)) { | 647 if (Isolate::Current()->cpu_features()->IsSupported(ARMv7)) { |
| 651 CpuFeatures::Scope scope(ARMv7); | 648 CpuFeatures::Scope scope(ARMv7); |
| 652 strd(src1, src2, dst, cond); | 649 strd(src1, src2, dst, cond); |
| 653 } else { | 650 } else { |
| 654 MemOperand dst2(dst); | 651 MemOperand dst2(dst); |
| 655 dst2.set_offset(dst2.offset() + 4); | 652 dst2.set_offset(dst2.offset() + 4); |
| 656 str(src1, dst, cond); | 653 str(src1, dst, cond); |
| 657 str(src2, dst2, cond); | 654 str(src2, dst2, cond); |
| 658 } | 655 } |
| 659 } | 656 } |
| 660 | 657 |
| (...skipping 1134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1795 0, | 1792 0, |
| 1796 1); | 1793 1); |
| 1797 if (result->IsFailure()) { | 1794 if (result->IsFailure()) { |
| 1798 return result; | 1795 return result; |
| 1799 } | 1796 } |
| 1800 | 1797 |
| 1801 // HandleScope limit has changed. Delete allocated extensions. | 1798 // HandleScope limit has changed. Delete allocated extensions. |
| 1802 bind(&delete_allocated_handles); | 1799 bind(&delete_allocated_handles); |
| 1803 str(r5, MemOperand(r7, kLimitOffset)); | 1800 str(r5, MemOperand(r7, kLimitOffset)); |
| 1804 mov(r4, r0); | 1801 mov(r4, r0); |
| 1805 PrepareCallCFunction(1, r5); | 1802 PrepareCallCFunction(0, r5); |
| 1806 mov(r0, Operand(ExternalReference::isolate_address())); | |
| 1807 CallCFunction( | 1803 CallCFunction( |
| 1808 ExternalReference::delete_handle_scope_extensions(isolate()), 1); | 1804 ExternalReference::delete_handle_scope_extensions(isolate()), 0); |
| 1809 mov(r0, r4); | 1805 mov(r0, r4); |
| 1810 jmp(&leave_exit_frame); | 1806 jmp(&leave_exit_frame); |
| 1811 | 1807 |
| 1812 return result; | 1808 return result; |
| 1813 } | 1809 } |
| 1814 | 1810 |
| 1815 | 1811 |
| 1816 void MacroAssembler::IllegalOperation(int num_arguments) { | 1812 void MacroAssembler::IllegalOperation(int num_arguments) { |
| 1817 if (num_arguments > 0) { | 1813 if (num_arguments > 0) { |
| 1818 add(sp, sp, Operand(num_arguments * kPointerSize)); | 1814 add(sp, sp, Operand(num_arguments * kPointerSize)); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1899 | 1895 |
| 1900 // Tries to get a signed int32 out of a double precision floating point heap | 1896 // Tries to get a signed int32 out of a double precision floating point heap |
| 1901 // number. Rounds towards 0. Branch to 'not_int32' if the double is out of the | 1897 // number. Rounds towards 0. Branch to 'not_int32' if the double is out of the |
| 1902 // 32bits signed integer range. | 1898 // 32bits signed integer range. |
| 1903 void MacroAssembler::ConvertToInt32(Register source, | 1899 void MacroAssembler::ConvertToInt32(Register source, |
| 1904 Register dest, | 1900 Register dest, |
| 1905 Register scratch, | 1901 Register scratch, |
| 1906 Register scratch2, | 1902 Register scratch2, |
| 1907 DwVfpRegister double_scratch, | 1903 DwVfpRegister double_scratch, |
| 1908 Label *not_int32) { | 1904 Label *not_int32) { |
| 1909 if (CpuFeatures::IsSupported(VFP3)) { | 1905 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) { |
| 1910 CpuFeatures::Scope scope(VFP3); | 1906 CpuFeatures::Scope scope(VFP3); |
| 1911 sub(scratch, source, Operand(kHeapObjectTag)); | 1907 sub(scratch, source, Operand(kHeapObjectTag)); |
| 1912 vldr(double_scratch, scratch, HeapNumber::kValueOffset); | 1908 vldr(double_scratch, scratch, HeapNumber::kValueOffset); |
| 1913 vcvt_s32_f64(double_scratch.low(), double_scratch); | 1909 vcvt_s32_f64(double_scratch.low(), double_scratch); |
| 1914 vmov(dest, double_scratch.low()); | 1910 vmov(dest, double_scratch.low()); |
| 1915 // Signed vcvt instruction will saturate to the minimum (0x80000000) or | 1911 // Signed vcvt instruction will saturate to the minimum (0x80000000) or |
| 1916 // maximun (0x7fffffff) signed 32bits integer when the double is out of | 1912 // maximun (0x7fffffff) signed 32bits integer when the double is out of |
| 1917 // range. When substracting one, the minimum signed integer becomes the | 1913 // range. When substracting one, the minimum signed integer becomes the |
| 1918 // maximun signed integer. | 1914 // maximun signed integer. |
| 1919 sub(scratch, dest, Operand(1)); | 1915 sub(scratch, dest, Operand(1)); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1995 } | 1991 } |
| 1996 } | 1992 } |
| 1997 | 1993 |
| 1998 | 1994 |
| 1999 void MacroAssembler::EmitVFPTruncate(VFPRoundingMode rounding_mode, | 1995 void MacroAssembler::EmitVFPTruncate(VFPRoundingMode rounding_mode, |
| 2000 SwVfpRegister result, | 1996 SwVfpRegister result, |
| 2001 DwVfpRegister double_input, | 1997 DwVfpRegister double_input, |
| 2002 Register scratch1, | 1998 Register scratch1, |
| 2003 Register scratch2, | 1999 Register scratch2, |
| 2004 CheckForInexactConversion check_inexact) { | 2000 CheckForInexactConversion check_inexact) { |
| 2005 ASSERT(CpuFeatures::IsSupported(VFP3)); | 2001 ASSERT(Isolate::Current()->cpu_features()->IsSupported(VFP3)); |
| 2006 CpuFeatures::Scope scope(VFP3); | 2002 CpuFeatures::Scope scope(VFP3); |
| 2007 Register prev_fpscr = scratch1; | 2003 Register prev_fpscr = scratch1; |
| 2008 Register scratch = scratch2; | 2004 Register scratch = scratch2; |
| 2009 | 2005 |
| 2010 int32_t check_inexact_conversion = | 2006 int32_t check_inexact_conversion = |
| 2011 (check_inexact == kCheckForInexactConversion) ? kVFPInexactExceptionBit : 0; | 2007 (check_inexact == kCheckForInexactConversion) ? kVFPInexactExceptionBit : 0; |
| 2012 | 2008 |
| 2013 // Set custom FPCSR: | 2009 // Set custom FPCSR: |
| 2014 // - Set rounding mode. | 2010 // - Set rounding mode. |
| 2015 // - Clear vfp cumulative exception flags. | 2011 // - Clear vfp cumulative exception flags. |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2153 input_high, | 2149 input_high, |
| 2154 input_low, | 2150 input_low, |
| 2155 scratch); | 2151 scratch); |
| 2156 bind(&done); | 2152 bind(&done); |
| 2157 } | 2153 } |
| 2158 | 2154 |
| 2159 | 2155 |
| 2160 void MacroAssembler::GetLeastBitsFromSmi(Register dst, | 2156 void MacroAssembler::GetLeastBitsFromSmi(Register dst, |
| 2161 Register src, | 2157 Register src, |
| 2162 int num_least_bits) { | 2158 int num_least_bits) { |
| 2163 if (CpuFeatures::IsSupported(ARMv7)) { | 2159 if (Isolate::Current()->cpu_features()->IsSupported(ARMv7)) { |
| 2164 ubfx(dst, src, kSmiTagSize, num_least_bits); | 2160 ubfx(dst, src, kSmiTagSize, num_least_bits); |
| 2165 } else { | 2161 } else { |
| 2166 mov(dst, Operand(src, ASR, kSmiTagSize)); | 2162 mov(dst, Operand(src, ASR, kSmiTagSize)); |
| 2167 and_(dst, dst, Operand((1 << num_least_bits) - 1)); | 2163 and_(dst, dst, Operand((1 << num_least_bits) - 1)); |
| 2168 } | 2164 } |
| 2169 } | 2165 } |
| 2170 | 2166 |
| 2171 | 2167 |
| 2172 void MacroAssembler::GetLeastBitsFromInt32(Register dst, | 2168 void MacroAssembler::GetLeastBitsFromInt32(Register dst, |
| 2173 Register src, | 2169 Register src, |
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2794 and_(scratch, type, Operand(kFlatAsciiStringMask)); | 2790 and_(scratch, type, Operand(kFlatAsciiStringMask)); |
| 2795 cmp(scratch, Operand(kFlatAsciiStringTag)); | 2791 cmp(scratch, Operand(kFlatAsciiStringTag)); |
| 2796 b(ne, failure); | 2792 b(ne, failure); |
| 2797 } | 2793 } |
| 2798 | 2794 |
| 2799 static const int kRegisterPassedArguments = 4; | 2795 static const int kRegisterPassedArguments = 4; |
| 2800 | 2796 |
| 2801 void MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) { | 2797 void MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) { |
| 2802 int frame_alignment = ActivationFrameAlignment(); | 2798 int frame_alignment = ActivationFrameAlignment(); |
| 2803 | 2799 |
| 2800 // Reserve space for Isolate address which is always passed as last parameter |
| 2801 num_arguments += 1; |
| 2802 |
| 2804 // Up to four simple arguments are passed in registers r0..r3. | 2803 // Up to four simple arguments are passed in registers r0..r3. |
| 2805 int stack_passed_arguments = (num_arguments <= kRegisterPassedArguments) ? | 2804 int stack_passed_arguments = (num_arguments <= kRegisterPassedArguments) ? |
| 2806 0 : num_arguments - kRegisterPassedArguments; | 2805 0 : num_arguments - kRegisterPassedArguments; |
| 2807 if (frame_alignment > kPointerSize) { | 2806 if (frame_alignment > kPointerSize) { |
| 2808 // Make stack end at alignment and make room for num_arguments - 4 words | 2807 // Make stack end at alignment and make room for num_arguments - 4 words |
| 2809 // and the original value of sp. | 2808 // and the original value of sp. |
| 2810 mov(scratch, sp); | 2809 mov(scratch, sp); |
| 2811 sub(sp, sp, Operand((stack_passed_arguments + 1) * kPointerSize)); | 2810 sub(sp, sp, Operand((stack_passed_arguments + 1) * kPointerSize)); |
| 2812 ASSERT(IsPowerOf2(frame_alignment)); | 2811 ASSERT(IsPowerOf2(frame_alignment)); |
| 2813 and_(sp, sp, Operand(-frame_alignment)); | 2812 and_(sp, sp, Operand(-frame_alignment)); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2830 ExternalReference::the_hole_value_location(isolate()), | 2829 ExternalReference::the_hole_value_location(isolate()), |
| 2831 scratch, | 2830 scratch, |
| 2832 num_arguments); | 2831 num_arguments); |
| 2833 } | 2832 } |
| 2834 | 2833 |
| 2835 | 2834 |
| 2836 void MacroAssembler::CallCFunctionHelper(Register function, | 2835 void MacroAssembler::CallCFunctionHelper(Register function, |
| 2837 ExternalReference function_reference, | 2836 ExternalReference function_reference, |
| 2838 Register scratch, | 2837 Register scratch, |
| 2839 int num_arguments) { | 2838 int num_arguments) { |
| 2839 // Push Isolate address as the last argument. |
| 2840 if (num_arguments < kRegisterPassedArguments) { |
| 2841 Register arg_to_reg[] = {r0, r1, r2, r3}; |
| 2842 Register r = arg_to_reg[num_arguments]; |
| 2843 mov(r, Operand(ExternalReference::isolate_address())); |
| 2844 } else { |
| 2845 int stack_passed_arguments = num_arguments - kRegisterPassedArguments; |
| 2846 // Push Isolate address on the stack after the arguments. |
| 2847 mov(scratch, Operand(ExternalReference::isolate_address())); |
| 2848 str(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize)); |
| 2849 } |
| 2850 num_arguments += 1; |
| 2851 |
| 2840 // Make sure that the stack is aligned before calling a C function unless | 2852 // Make sure that the stack is aligned before calling a C function unless |
| 2841 // running in the simulator. The simulator has its own alignment check which | 2853 // running in the simulator. The simulator has its own alignment check which |
| 2842 // provides more information. | 2854 // provides more information. |
| 2843 #if defined(V8_HOST_ARCH_ARM) | 2855 #if defined(V8_HOST_ARCH_ARM) |
| 2844 if (emit_debug_code()) { | 2856 if (emit_debug_code()) { |
| 2845 int frame_alignment = OS::ActivationFrameAlignment(); | 2857 int frame_alignment = OS::ActivationFrameAlignment(); |
| 2846 int frame_alignment_mask = frame_alignment - 1; | 2858 int frame_alignment_mask = frame_alignment - 1; |
| 2847 if (frame_alignment > kPointerSize) { | 2859 if (frame_alignment > kPointerSize) { |
| 2848 ASSERT(IsPowerOf2(frame_alignment)); | 2860 ASSERT(IsPowerOf2(frame_alignment)); |
| 2849 Label alignment_as_expected; | 2861 Label alignment_as_expected; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2892 and_(result, result, Operand(kLdrOffsetMask)); | 2904 and_(result, result, Operand(kLdrOffsetMask)); |
| 2893 add(result, ldr_location, Operand(result)); | 2905 add(result, ldr_location, Operand(result)); |
| 2894 add(result, result, Operand(kPCRegOffset)); | 2906 add(result, result, Operand(kPCRegOffset)); |
| 2895 } | 2907 } |
| 2896 | 2908 |
| 2897 | 2909 |
| 2898 CodePatcher::CodePatcher(byte* address, int instructions) | 2910 CodePatcher::CodePatcher(byte* address, int instructions) |
| 2899 : address_(address), | 2911 : address_(address), |
| 2900 instructions_(instructions), | 2912 instructions_(instructions), |
| 2901 size_(instructions * Assembler::kInstrSize), | 2913 size_(instructions * Assembler::kInstrSize), |
| 2902 masm_(Isolate::Current(), address, size_ + Assembler::kGap) { | 2914 masm_(address, size_ + Assembler::kGap) { |
| 2903 // Create a new macro assembler pointing to the address of the code to patch. | 2915 // Create a new macro assembler pointing to the address of the code to patch. |
| 2904 // The size is adjusted with kGap on order for the assembler to generate size | 2916 // The size is adjusted with kGap on order for the assembler to generate size |
| 2905 // bytes of instructions without failing with buffer size constraints. | 2917 // bytes of instructions without failing with buffer size constraints. |
| 2906 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 2918 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
| 2907 } | 2919 } |
| 2908 | 2920 |
| 2909 | 2921 |
| 2910 CodePatcher::~CodePatcher() { | 2922 CodePatcher::~CodePatcher() { |
| 2911 // Indicate that code has changed. | 2923 // Indicate that code has changed. |
| 2912 CPU::FlushICache(address_, size_); | 2924 CPU::FlushICache(address_, size_); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2930 void CodePatcher::EmitCondition(Condition cond) { | 2942 void CodePatcher::EmitCondition(Condition cond) { |
| 2931 Instr instr = Assembler::instr_at(masm_.pc_); | 2943 Instr instr = Assembler::instr_at(masm_.pc_); |
| 2932 instr = (instr & ~kCondMask) | cond; | 2944 instr = (instr & ~kCondMask) | cond; |
| 2933 masm_.emit(instr); | 2945 masm_.emit(instr); |
| 2934 } | 2946 } |
| 2935 | 2947 |
| 2936 | 2948 |
| 2937 } } // namespace v8::internal | 2949 } } // namespace v8::internal |
| 2938 | 2950 |
| 2939 #endif // V8_TARGET_ARCH_ARM | 2951 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |