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

Side by Side Diff: src/mips/macro-assembler-mips.cc

Issue 7778013: NewGC: Merge bleeding edge up to 9009. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 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/mips/macro-assembler-mips.h ('k') | src/mips/stub-cache-mips.cc » ('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 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 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 } 750 }
751 addiu(sp, sp, 4 * NumSaved); 751 addiu(sp, sp, 4 * NumSaved);
752 } 752 }
753 753
754 754
755 void MacroAssembler::Ext(Register rt, 755 void MacroAssembler::Ext(Register rt,
756 Register rs, 756 Register rs,
757 uint16_t pos, 757 uint16_t pos,
758 uint16_t size) { 758 uint16_t size) {
759 ASSERT(pos < 32); 759 ASSERT(pos < 32);
760 ASSERT(pos + size < 32); 760 ASSERT(pos + size < 33);
761 761
762 if (mips32r2) { 762 if (mips32r2) {
763 ext_(rt, rs, pos, size); 763 ext_(rt, rs, pos, size);
764 } else { 764 } else {
765 // Move rs to rt and shift it left then right to get the 765 // Move rs to rt and shift it left then right to get the
766 // desired bitfield on the right side and zeroes on the left. 766 // desired bitfield on the right side and zeroes on the left.
767 sll(rt, rs, 32 - (pos + size)); 767 int shift_left = 32 - (pos + size);
768 srl(rt, rt, 32 - size); 768 if (shift_left > 0) {
769 sll(rt, rs, shift_left);
770 }
771
772 int shift_right = 32 - size;
773 if (shift_right > 0) {
774 srl(rt, rt, shift_right);
775 }
769 } 776 }
770 } 777 }
771 778
772 779
773 void MacroAssembler::Ins(Register rt, 780 void MacroAssembler::Ins(Register rt,
774 Register rs, 781 Register rs,
775 uint16_t pos, 782 uint16_t pos,
776 uint16_t size) { 783 uint16_t size) {
777 ASSERT(pos < 32); 784 ASSERT(pos < 32);
778 ASSERT(pos + size < 32); 785 ASSERT(pos + size < 32);
(...skipping 21 matching lines...) Expand all
800 // t8 now contains the chunk from rs on the left and zeroes. 807 // t8 now contains the chunk from rs on the left and zeroes.
801 srl(t8, t8, 32 - size - pos); 808 srl(t8, t8, 32 - size - pos);
802 // t8 now contains the original chunk from rs in 809 // t8 now contains the original chunk from rs in
803 // the middle (proper position). 810 // the middle (proper position).
804 or_(rt, rt, t8); 811 or_(rt, rt, t8);
805 // rt now contains the result of the ins instruction in R2 mode. 812 // rt now contains the result of the ins instruction in R2 mode.
806 } 813 }
807 } 814 }
808 815
809 816
810 void MacroAssembler::Cvt_d_uw(FPURegister fd, FPURegister fs) { 817 void MacroAssembler::Cvt_d_uw(FPURegister fd,
811 // Move the data from fs to t4. 818 FPURegister fs,
812 mfc1(t4, fs); 819 FPURegister scratch) {
813 return Cvt_d_uw(fd, t4); 820 // Move the data from fs to t8.
821 mfc1(t8, fs);
822 Cvt_d_uw(fd, t8, scratch);
814 } 823 }
815 824
816 825
817 void MacroAssembler::Cvt_d_uw(FPURegister fd, Register rs) { 826 void MacroAssembler::Cvt_d_uw(FPURegister fd,
827 Register rs,
828 FPURegister scratch) {
818 // Convert rs to a FP value in fd (and fd + 1). 829 // Convert rs to a FP value in fd (and fd + 1).
819 // We do this by converting rs minus the MSB to avoid sign conversion, 830 // We do this by converting rs minus the MSB to avoid sign conversion,
820 // then adding 2^31-1 and 1 to the result. 831 // then adding 2^31 to the result (if needed).
821 832
822 ASSERT(!fd.is(f20)); 833 ASSERT(!fd.is(scratch));
823 ASSERT(!rs.is(t9)); 834 ASSERT(!rs.is(t9));
824 ASSERT(!rs.is(t8)); 835 ASSERT(!rs.is(at));
825 836
826 // Save rs's MSB to t8. 837 // Save rs's MSB to t9.
827 And(t8, rs, 0x80000000); 838 Ext(t9, rs, 31, 1);
828 // Remove rs's MSB. 839 // Remove rs's MSB.
829 And(t9, rs, 0x7FFFFFFF); 840 Ext(at, rs, 0, 31);
830 // Move t9 to fd. 841 // Move the result to fd.
831 mtc1(t9, fd); 842 mtc1(at, fd);
832 843
833 // Convert fd to a real FP value. 844 // Convert fd to a real FP value.
834 cvt_d_w(fd, fd); 845 cvt_d_w(fd, fd);
835 846
836 Label conversion_done; 847 Label conversion_done;
837 848
838 // If rs's MSB was 0, it's done. 849 // If rs's MSB was 0, it's done.
839 // Otherwise we need to add that to the FP register. 850 // Otherwise we need to add that to the FP register.
840 Branch(&conversion_done, eq, t8, Operand(zero_reg)); 851 Branch(&conversion_done, eq, t9, Operand(zero_reg));
841 852
842 // First load 2^31 - 1 into f20. 853 // Load 2^31 into f20 as its float representation.
843 Or(t9, zero_reg, 0x7FFFFFFF); 854 li(at, 0x41E00000);
844 mtc1(t9, f20); 855 mtc1(at, FPURegister::from_code(scratch.code() + 1));
856 mtc1(zero_reg, scratch);
857 // Add it to fd.
858 add_d(fd, fd, scratch);
845 859
846 // Convert it to FP and add it to fd.
847 cvt_d_w(f20, f20);
848 add_d(fd, fd, f20);
849 // Now add 1.
850 Or(t9, zero_reg, 1);
851 mtc1(t9, f20);
852
853 cvt_d_w(f20, f20);
854 add_d(fd, fd, f20);
855 bind(&conversion_done); 860 bind(&conversion_done);
856 } 861 }
857 862
858 863
859 void MacroAssembler::Trunc_uw_d(FPURegister fd, FPURegister fs) { 864 void MacroAssembler::Trunc_uw_d(FPURegister fd,
860 Trunc_uw_d(fs, t4); 865 FPURegister fs,
861 mtc1(t4, fd); 866 FPURegister scratch) {
867 Trunc_uw_d(fs, t8, scratch);
868 mtc1(t8, fd);
862 } 869 }
863 870
864 871
865 void MacroAssembler::Trunc_uw_d(FPURegister fd, Register rs) { 872 void MacroAssembler::Trunc_uw_d(FPURegister fd,
866 ASSERT(!fd.is(f22)); 873 Register rs,
867 ASSERT(!rs.is(t8)); 874 FPURegister scratch) {
875 ASSERT(!fd.is(scratch));
876 ASSERT(!rs.is(at));
868 877
869 // Load 2^31 into f22. 878 // Load 2^31 into scratch as its float representation.
870 Or(t8, zero_reg, 0x80000000); 879 li(at, 0x41E00000);
871 Cvt_d_uw(f22, t8); 880 mtc1(at, FPURegister::from_code(scratch.code() + 1));
872 881 mtc1(zero_reg, scratch);
873 // Test if f22 > fd. 882 // Test if scratch > fd.
874 c(OLT, D, fd, f22); 883 c(OLT, D, fd, scratch);
875 884
876 Label simple_convert; 885 Label simple_convert;
877 // If fd < 2^31 we can convert it normally. 886 // If fd < 2^31 we can convert it normally.
878 bc1t(&simple_convert); 887 bc1t(&simple_convert);
879 888
880 // First we subtract 2^31 from fd, then trunc it to rs 889 // First we subtract 2^31 from fd, then trunc it to rs
881 // and add 2^31 to rs. 890 // and add 2^31 to rs.
882 891 sub_d(scratch, fd, scratch);
883 sub_d(f22, fd, f22); 892 trunc_w_d(scratch, scratch);
884 trunc_w_d(f22, f22); 893 mfc1(rs, scratch);
885 mfc1(rs, f22); 894 Or(rs, rs, 1 << 31);
886 or_(rs, rs, t8);
887 895
888 Label done; 896 Label done;
889 Branch(&done); 897 Branch(&done);
890 // Simple conversion. 898 // Simple conversion.
891 bind(&simple_convert); 899 bind(&simple_convert);
892 trunc_w_d(f22, fd); 900 trunc_w_d(scratch, fd);
893 mfc1(rs, f22); 901 mfc1(rs, scratch);
894 902
895 bind(&done); 903 bind(&done);
896 } 904 }
897 905
898 906
899 // Tries to get a signed int32 out of a double precision floating point heap 907 // Tries to get a signed int32 out of a double precision floating point heap
900 // number. Rounds towards 0. Branch to 'not_int32' if the double is out of the 908 // number. Rounds towards 0. Branch to 'not_int32' if the double is out of the
901 // 32bits signed integer range. 909 // 32bits signed integer range.
902 // This method implementation differs from the ARM version for performance 910 // This method implementation differs from the ARM version for performance
903 // reasons. 911 // reasons.
(...skipping 1333 matching lines...) Expand 10 before | Expand all | Expand 10 after
2237 2245
2238 #endif // ENABLE_DEBUGGER_SUPPORT 2246 #endif // ENABLE_DEBUGGER_SUPPORT
2239 2247
2240 2248
2241 // --------------------------------------------------------------------------- 2249 // ---------------------------------------------------------------------------
2242 // Exception handling. 2250 // Exception handling.
2243 2251
2244 void MacroAssembler::PushTryHandler(CodeLocation try_location, 2252 void MacroAssembler::PushTryHandler(CodeLocation try_location,
2245 HandlerType type) { 2253 HandlerType type) {
2246 // Adjust this code if not the case. 2254 // Adjust this code if not the case.
2247 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); 2255 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
2256 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
2257 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize);
2258 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 2 * kPointerSize);
2259 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 3 * kPointerSize);
2260 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize);
2261
2248 // The return address is passed in register ra. 2262 // The return address is passed in register ra.
2249 if (try_location == IN_JAVASCRIPT) { 2263 if (try_location == IN_JAVASCRIPT) {
2250 if (type == TRY_CATCH_HANDLER) { 2264 if (type == TRY_CATCH_HANDLER) {
2251 li(t0, Operand(StackHandler::TRY_CATCH)); 2265 li(t0, Operand(StackHandler::TRY_CATCH));
2252 } else { 2266 } else {
2253 li(t0, Operand(StackHandler::TRY_FINALLY)); 2267 li(t0, Operand(StackHandler::TRY_FINALLY));
2254 } 2268 }
2255 ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize
2256 && StackHandlerConstants::kFPOffset == 2 * kPointerSize
2257 && StackHandlerConstants::kPCOffset == 3 * kPointerSize
2258 && StackHandlerConstants::kNextOffset == 0 * kPointerSize);
2259 // Save the current handler as the next handler. 2269 // Save the current handler as the next handler.
2260 li(t2, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); 2270 li(t2, Operand(ExternalReference(Isolate::k_handler_address, isolate())));
2261 lw(t1, MemOperand(t2)); 2271 lw(t1, MemOperand(t2));
2262 2272
2263 addiu(sp, sp, -StackHandlerConstants::kSize); 2273 addiu(sp, sp, -StackHandlerConstants::kSize);
2264 sw(ra, MemOperand(sp, 12)); 2274 sw(ra, MemOperand(sp, StackHandlerConstants::kPCOffset));
2265 sw(fp, MemOperand(sp, 8)); 2275 sw(fp, MemOperand(sp, StackHandlerConstants::kFPOffset));
2266 sw(t0, MemOperand(sp, 4)); 2276 sw(cp, MemOperand(sp, StackHandlerConstants::kContextOffset));
2267 sw(t1, MemOperand(sp, 0)); 2277 sw(t0, MemOperand(sp, StackHandlerConstants::kStateOffset));
2278 sw(t1, MemOperand(sp, StackHandlerConstants::kNextOffset));
2268 2279
2269 // Link this handler as the new current one. 2280 // Link this handler as the new current one.
2270 sw(sp, MemOperand(t2)); 2281 sw(sp, MemOperand(t2));
2271 2282
2272 } else { 2283 } else {
2273 // Must preserve a0-a3, and s0 (argv). 2284 // Must preserve a0-a3, and s0 (argv).
2274 ASSERT(try_location == IN_JS_ENTRY); 2285 ASSERT(try_location == IN_JS_ENTRY);
2275 ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize
2276 && StackHandlerConstants::kFPOffset == 2 * kPointerSize
2277 && StackHandlerConstants::kPCOffset == 3 * kPointerSize
2278 && StackHandlerConstants::kNextOffset == 0 * kPointerSize);
2279
2280 // The frame pointer does not point to a JS frame so we save NULL 2286 // The frame pointer does not point to a JS frame so we save NULL
2281 // for fp. We expect the code throwing an exception to check fp 2287 // for fp. We expect the code throwing an exception to check fp
2282 // before dereferencing it to restore the context. 2288 // before dereferencing it to restore the context.
2283 li(t0, Operand(StackHandler::ENTRY)); 2289 li(t0, Operand(StackHandler::ENTRY));
2284 2290
2285 // Save the current handler as the next handler. 2291 // Save the current handler as the next handler.
2286 li(t2, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); 2292 li(t2, Operand(ExternalReference(Isolate::k_handler_address, isolate())));
2287 lw(t1, MemOperand(t2)); 2293 lw(t1, MemOperand(t2));
2288 2294
2295 ASSERT(Smi::FromInt(0) == 0); // Used for no context.
2296
2289 addiu(sp, sp, -StackHandlerConstants::kSize); 2297 addiu(sp, sp, -StackHandlerConstants::kSize);
2290 sw(ra, MemOperand(sp, 12)); 2298 sw(ra, MemOperand(sp, StackHandlerConstants::kPCOffset));
2291 sw(zero_reg, MemOperand(sp, 8)); 2299 sw(zero_reg, MemOperand(sp, StackHandlerConstants::kFPOffset));
2292 sw(t0, MemOperand(sp, 4)); 2300 sw(zero_reg, MemOperand(sp, StackHandlerConstants::kContextOffset));
2293 sw(t1, MemOperand(sp, 0)); 2301 sw(t0, MemOperand(sp, StackHandlerConstants::kStateOffset));
2302 sw(t1, MemOperand(sp, StackHandlerConstants::kNextOffset));
2294 2303
2295 // Link this handler as the new current one. 2304 // Link this handler as the new current one.
2296 sw(sp, MemOperand(t2)); 2305 sw(sp, MemOperand(t2));
2297 } 2306 }
2298 } 2307 }
2299 2308
2300 2309
2301 void MacroAssembler::PopTryHandler() { 2310 void MacroAssembler::PopTryHandler() {
2302 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); 2311 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
2303 pop(a1); 2312 pop(a1);
2304 Addu(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); 2313 Addu(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize));
2305 li(at, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); 2314 li(at, Operand(ExternalReference(Isolate::k_handler_address, isolate())));
2306 sw(a1, MemOperand(at)); 2315 sw(a1, MemOperand(at));
2307 } 2316 }
2308 2317
2309 2318
2310 void MacroAssembler::Throw(Register value) { 2319 void MacroAssembler::Throw(Register value) {
2311 // v0 is expected to hold the exception. 2320 // v0 is expected to hold the exception.
2312 Move(v0, value); 2321 Move(v0, value);
2313 2322
2314 // Adjust this code if not the case. 2323 // Adjust this code if not the case.
2315 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); 2324 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
2325 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
2326 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize);
2327 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 2 * kPointerSize);
2328 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 3 * kPointerSize);
2329 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize);
2316 2330
2317 // Drop the sp to the top of the handler. 2331 // Drop the sp to the top of the handler.
2318 li(a3, Operand(ExternalReference(Isolate::k_handler_address, 2332 li(a3, Operand(ExternalReference(Isolate::k_handler_address,
2319 isolate()))); 2333 isolate())));
2320 lw(sp, MemOperand(a3)); 2334 lw(sp, MemOperand(a3));
2321 2335
2322 // Restore the next handler and frame pointer, discard handler state. 2336 // Restore the next handler.
2323 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
2324 pop(a2); 2337 pop(a2);
2325 sw(a2, MemOperand(a3)); 2338 sw(a2, MemOperand(a3));
2326 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
2327 MultiPop(a3.bit() | fp.bit());
2328 2339
2329 // Before returning we restore the context from the frame pointer if 2340 // Restore context and frame pointer, discard state (a3).
2330 // not NULL. The frame pointer is NULL in the exception handler of a 2341 MultiPop(a3.bit() | cp.bit() | fp.bit());
2331 // JS entry frame. 2342
2332 // Set cp to NULL if fp is NULL. 2343 // If the handler is a JS frame, restore the context to the frame.
2344 // (a3 == ENTRY) == (fp == 0) == (cp == 0), so we could test any
2345 // of them.
2333 Label done; 2346 Label done;
2334 Branch(USE_DELAY_SLOT, &done, eq, fp, Operand(zero_reg)); 2347 Branch(&done, eq, fp, Operand(zero_reg));
2335 mov(cp, zero_reg); // In branch delay slot. 2348 sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2336 lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2337 bind(&done); 2349 bind(&done);
2338 2350
2339 #ifdef DEBUG 2351 #ifdef DEBUG
2340 // When emitting debug_code, set ra as return address for the jump. 2352 // When emitting debug_code, set ra as return address for the jump.
2341 // 5 instructions: add: 1, pop: 2, jump: 2. 2353 // 5 instructions: add: 1, pop: 2, jump: 2.
2342 const int kOffsetRaInstructions = 5; 2354 const int kOffsetRaInstructions = 5;
2343 Label find_ra; 2355 Label find_ra;
2344 2356
2345 if (emit_debug_code()) { 2357 if (emit_debug_code()) {
2346 // Compute ra for the Jump(t9). 2358 // Compute ra for the Jump(t9).
2347 const int kOffsetRaBytes = kOffsetRaInstructions * Assembler::kInstrSize; 2359 const int kOffsetRaBytes = kOffsetRaInstructions * Assembler::kInstrSize;
2348 2360
2349 // This branch-and-link sequence is needed to get the current PC on mips, 2361 // This branch-and-link sequence is needed to get the current PC on mips,
2350 // saved to the ra register. Then adjusted for instruction count. 2362 // saved to the ra register. Then adjusted for instruction count.
2351 bal(&find_ra); // bal exposes branch-delay. 2363 bal(&find_ra); // bal exposes branch-delay.
2352 nop(); // Branch delay slot nop. 2364 nop(); // Branch delay slot nop.
2353 bind(&find_ra); 2365 bind(&find_ra);
2354 addiu(ra, ra, kOffsetRaBytes); 2366 addiu(ra, ra, kOffsetRaBytes);
2355 } 2367 }
2356 #endif 2368 #endif
2357 2369
2358 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
2359 pop(t9); // 2 instructions: lw, add sp. 2370 pop(t9); // 2 instructions: lw, add sp.
2360 Jump(t9); // 2 instructions: jr, nop (in delay slot). 2371 Jump(t9); // 2 instructions: jr, nop (in delay slot).
2361 2372
2362 if (emit_debug_code()) { 2373 if (emit_debug_code()) {
2363 // Make sure that the expected number of instructions were generated. 2374 // Make sure that the expected number of instructions were generated.
2364 ASSERT_EQ(kOffsetRaInstructions, 2375 ASSERT_EQ(kOffsetRaInstructions,
2365 InstructionsGeneratedSince(&find_ra)); 2376 InstructionsGeneratedSince(&find_ra));
2366 } 2377 }
2367 } 2378 }
2368 2379
2369 2380
2370 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, 2381 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
2371 Register value) { 2382 Register value) {
2372 // Adjust this code if not the case. 2383 // Adjust this code if not the case.
2373 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); 2384 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
2385 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
2386 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize);
2387 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 2 * kPointerSize);
2388 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 3 * kPointerSize);
2389 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize);
2374 2390
2375 // v0 is expected to hold the exception. 2391 // v0 is expected to hold the exception.
2376 Move(v0, value); 2392 Move(v0, value);
2377 2393
2378 // Drop sp to the top stack handler. 2394 // Drop sp to the top stack handler.
2379 li(a3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); 2395 li(a3, Operand(ExternalReference(Isolate::k_handler_address, isolate())));
2380 lw(sp, MemOperand(a3)); 2396 lw(sp, MemOperand(a3));
2381 2397
2382 // Unwind the handlers until the ENTRY handler is found. 2398 // Unwind the handlers until the ENTRY handler is found.
2383 Label loop, done; 2399 Label loop, done;
2384 bind(&loop); 2400 bind(&loop);
2385 // Load the type of the current stack handler. 2401 // Load the type of the current stack handler.
2386 const int kStateOffset = StackHandlerConstants::kStateOffset; 2402 const int kStateOffset = StackHandlerConstants::kStateOffset;
2387 lw(a2, MemOperand(sp, kStateOffset)); 2403 lw(a2, MemOperand(sp, kStateOffset));
2388 Branch(&done, eq, a2, Operand(StackHandler::ENTRY)); 2404 Branch(&done, eq, a2, Operand(StackHandler::ENTRY));
2389 // Fetch the next handler in the list. 2405 // Fetch the next handler in the list.
2390 const int kNextOffset = StackHandlerConstants::kNextOffset; 2406 const int kNextOffset = StackHandlerConstants::kNextOffset;
2391 lw(sp, MemOperand(sp, kNextOffset)); 2407 lw(sp, MemOperand(sp, kNextOffset));
2392 jmp(&loop); 2408 jmp(&loop);
2393 bind(&done); 2409 bind(&done);
2394 2410
2395 // Set the top handler address to next handler past the current ENTRY handler. 2411 // Set the top handler address to next handler past the current ENTRY handler.
2396 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
2397 pop(a2); 2412 pop(a2);
2398 sw(a2, MemOperand(a3)); 2413 sw(a2, MemOperand(a3));
2399 2414
2400 if (type == OUT_OF_MEMORY) { 2415 if (type == OUT_OF_MEMORY) {
2401 // Set external caught exception to false. 2416 // Set external caught exception to false.
2402 ExternalReference external_caught( 2417 ExternalReference external_caught(
2403 Isolate::k_external_caught_exception_address, isolate()); 2418 Isolate::k_external_caught_exception_address, isolate());
2404 li(a0, Operand(false, RelocInfo::NONE)); 2419 li(a0, Operand(false, RelocInfo::NONE));
2405 li(a2, Operand(external_caught)); 2420 li(a2, Operand(external_caught));
2406 sw(a0, MemOperand(a2)); 2421 sw(a0, MemOperand(a2));
2407 2422
2408 // Set pending exception and v0 to out of memory exception. 2423 // Set pending exception and v0 to out of memory exception.
2409 Failure* out_of_memory = Failure::OutOfMemoryException(); 2424 Failure* out_of_memory = Failure::OutOfMemoryException();
2410 li(v0, Operand(reinterpret_cast<int32_t>(out_of_memory))); 2425 li(v0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
2411 li(a2, Operand(ExternalReference(Isolate::k_pending_exception_address, 2426 li(a2, Operand(ExternalReference(Isolate::k_pending_exception_address,
2412 isolate()))); 2427 isolate())));
2413 sw(v0, MemOperand(a2)); 2428 sw(v0, MemOperand(a2));
2414 } 2429 }
2415 2430
2416 // Stack layout at this point. See also StackHandlerConstants. 2431 // Stack layout at this point. See also StackHandlerConstants.
2417 // sp -> state (ENTRY) 2432 // sp -> state (ENTRY)
2433 // cp
2418 // fp 2434 // fp
2419 // ra 2435 // ra
2420 2436
2421 // Discard handler state (a2 is not used) and restore frame pointer. 2437 // Restore context and frame pointer, discard state (r2).
2422 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); 2438 MultiPop(a2.bit() | cp.bit() | fp.bit());
2423 MultiPop(a2.bit() | fp.bit()); // a2: discarded state.
2424 // Before returning we restore the context from the frame pointer if
2425 // not NULL. The frame pointer is NULL in the exception handler of a
2426 // JS entry frame.
2427 Label cp_null;
2428 Branch(USE_DELAY_SLOT, &cp_null, eq, fp, Operand(zero_reg));
2429 mov(cp, zero_reg); // In the branch delay slot.
2430 lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2431 bind(&cp_null);
2432 2439
2433 #ifdef DEBUG 2440 #ifdef DEBUG
2434 // When emitting debug_code, set ra as return address for the jump. 2441 // When emitting debug_code, set ra as return address for the jump.
2435 // 5 instructions: add: 1, pop: 2, jump: 2. 2442 // 5 instructions: add: 1, pop: 2, jump: 2.
2436 const int kOffsetRaInstructions = 5; 2443 const int kOffsetRaInstructions = 5;
2437 Label find_ra; 2444 Label find_ra;
2438 2445
2439 if (emit_debug_code()) { 2446 if (emit_debug_code()) {
2440 // Compute ra for the Jump(t9). 2447 // Compute ra for the Jump(t9).
2441 const int kOffsetRaBytes = kOffsetRaInstructions * Assembler::kInstrSize; 2448 const int kOffsetRaBytes = kOffsetRaInstructions * Assembler::kInstrSize;
2442 2449
2443 // This branch-and-link sequence is needed to get the current PC on mips, 2450 // This branch-and-link sequence is needed to get the current PC on mips,
2444 // saved to the ra register. Then adjusted for instruction count. 2451 // saved to the ra register. Then adjusted for instruction count.
2445 bal(&find_ra); // bal exposes branch-delay slot. 2452 bal(&find_ra); // bal exposes branch-delay slot.
2446 nop(); // Branch delay slot nop. 2453 nop(); // Branch delay slot nop.
2447 bind(&find_ra); 2454 bind(&find_ra);
2448 addiu(ra, ra, kOffsetRaBytes); 2455 addiu(ra, ra, kOffsetRaBytes);
2449 } 2456 }
2450 #endif 2457 #endif
2451 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
2452 pop(t9); // 2 instructions: lw, add sp. 2458 pop(t9); // 2 instructions: lw, add sp.
2453 Jump(t9); // 2 instructions: jr, nop (in delay slot). 2459 Jump(t9); // 2 instructions: jr, nop (in delay slot).
2454 2460
2455 if (emit_debug_code()) { 2461 if (emit_debug_code()) {
2456 // Make sure that the expected number of instructions were generated. 2462 // Make sure that the expected number of instructions were generated.
2457 ASSERT_EQ(kOffsetRaInstructions, 2463 ASSERT_EQ(kOffsetRaInstructions,
2458 InstructionsGeneratedSince(&find_ra)); 2464 InstructionsGeneratedSince(&find_ra));
2459 } 2465 }
2460 } 2466 }
2461 2467
(...skipping 1829 matching lines...) Expand 10 before | Expand all | Expand 10 after
4291 opcode == BGTZL); 4297 opcode == BGTZL);
4292 opcode = (cond == eq) ? BEQ : BNE; 4298 opcode = (cond == eq) ? BEQ : BNE;
4293 instr = (instr & ~kOpcodeMask) | opcode; 4299 instr = (instr & ~kOpcodeMask) | opcode;
4294 masm_.emit(instr); 4300 masm_.emit(instr);
4295 } 4301 }
4296 4302
4297 4303
4298 } } // namespace v8::internal 4304 } } // namespace v8::internal
4299 4305
4300 #endif // V8_TARGET_ARCH_MIPS 4306 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/macro-assembler-mips.h ('k') | src/mips/stub-cache-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698