OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1101 bind(&done); | 1101 bind(&done); |
1102 } | 1102 } |
1103 | 1103 |
1104 | 1104 |
1105 void MacroAssembler::BranchF(Label* target, | 1105 void MacroAssembler::BranchF(Label* target, |
1106 Label* nan, | 1106 Label* nan, |
1107 Condition cc, | 1107 Condition cc, |
1108 FPURegister cmp1, | 1108 FPURegister cmp1, |
1109 FPURegister cmp2, | 1109 FPURegister cmp2, |
1110 BranchDelaySlot bd) { | 1110 BranchDelaySlot bd) { |
| 1111 BlockTrampolinePoolScope block_trampoline_pool(this); |
1111 if (cc == al) { | 1112 if (cc == al) { |
1112 Branch(bd, target); | 1113 Branch(bd, target); |
1113 return; | 1114 return; |
1114 } | 1115 } |
1115 | 1116 |
1116 ASSERT(nan || target); | 1117 ASSERT(nan || target); |
1117 // Check for unordered (NaN) cases. | 1118 // Check for unordered (NaN) cases. |
1118 if (nan) { | 1119 if (nan) { |
1119 c(UN, D, cmp1, cmp2); | 1120 c(UN, D, cmp1, cmp2); |
1120 bc1t(nan); | 1121 bc1t(nan); |
1121 } | 1122 } |
1122 | 1123 |
1123 if (target) { | 1124 if (target) { |
1124 // Here NaN cases were either handled by this function or are assumed to | 1125 // Here NaN cases were either handled by this function or are assumed to |
1125 // have been handled by the caller. | 1126 // have been handled by the caller. |
1126 // Unsigned conditions are treated as their signed counterpart. | 1127 // Unsigned conditions are treated as their signed counterpart. |
1127 switch (cc) { | 1128 switch (cc) { |
1128 case Uless: | 1129 case lt: |
1129 case less: | |
1130 c(OLT, D, cmp1, cmp2); | 1130 c(OLT, D, cmp1, cmp2); |
1131 bc1t(target); | 1131 bc1t(target); |
1132 break; | 1132 break; |
1133 case Ugreater: | 1133 case gt: |
1134 case greater: | |
1135 c(ULE, D, cmp1, cmp2); | 1134 c(ULE, D, cmp1, cmp2); |
1136 bc1f(target); | 1135 bc1f(target); |
1137 break; | 1136 break; |
1138 case Ugreater_equal: | 1137 case ge: |
1139 case greater_equal: | |
1140 c(ULT, D, cmp1, cmp2); | 1138 c(ULT, D, cmp1, cmp2); |
1141 bc1f(target); | 1139 bc1f(target); |
1142 break; | 1140 break; |
1143 case Uless_equal: | 1141 case le: |
1144 case less_equal: | |
1145 c(OLE, D, cmp1, cmp2); | 1142 c(OLE, D, cmp1, cmp2); |
1146 bc1t(target); | 1143 bc1t(target); |
1147 break; | 1144 break; |
1148 case eq: | 1145 case eq: |
1149 c(EQ, D, cmp1, cmp2); | 1146 c(EQ, D, cmp1, cmp2); |
1150 bc1t(target); | 1147 bc1t(target); |
1151 break; | 1148 break; |
| 1149 case ueq: |
| 1150 c(UEQ, D, cmp1, cmp2); |
| 1151 bc1t(target); |
| 1152 break; |
1152 case ne: | 1153 case ne: |
1153 c(EQ, D, cmp1, cmp2); | 1154 c(EQ, D, cmp1, cmp2); |
1154 bc1f(target); | 1155 bc1f(target); |
1155 break; | 1156 break; |
| 1157 case nue: |
| 1158 c(UEQ, D, cmp1, cmp2); |
| 1159 bc1f(target); |
| 1160 break; |
1156 default: | 1161 default: |
1157 CHECK(0); | 1162 CHECK(0); |
1158 }; | 1163 }; |
1159 } | 1164 } |
1160 | 1165 |
1161 if (bd == PROTECT) { | 1166 if (bd == PROTECT) { |
1162 nop(); | 1167 nop(); |
1163 } | 1168 } |
1164 } | 1169 } |
1165 | 1170 |
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1689 const Operand& rt, | 1694 const Operand& rt, |
1690 BranchDelaySlot bdslot) { | 1695 BranchDelaySlot bdslot) { |
1691 BRANCH_ARGS_CHECK(cond, rs, rt); | 1696 BRANCH_ARGS_CHECK(cond, rs, rt); |
1692 ASSERT(!rs.is(zero_reg)); | 1697 ASSERT(!rs.is(zero_reg)); |
1693 Register r2 = no_reg; | 1698 Register r2 = no_reg; |
1694 Register scratch = at; | 1699 Register scratch = at; |
1695 | 1700 |
1696 if (rt.is_reg()) { | 1701 if (rt.is_reg()) { |
1697 // NOTE: 'at' can be clobbered by Branch but it is legal to use it as rs or | 1702 // NOTE: 'at' can be clobbered by Branch but it is legal to use it as rs or |
1698 // rt. | 1703 // rt. |
| 1704 BlockTrampolinePoolScope block_trampoline_pool(this); |
1699 r2 = rt.rm_; | 1705 r2 = rt.rm_; |
1700 switch (cond) { | 1706 switch (cond) { |
1701 case cc_always: | 1707 case cc_always: |
1702 b(offset); | 1708 b(offset); |
1703 break; | 1709 break; |
1704 case eq: | 1710 case eq: |
1705 beq(rs, r2, offset); | 1711 beq(rs, r2, offset); |
1706 break; | 1712 break; |
1707 case ne: | 1713 case ne: |
1708 bne(rs, r2, offset); | 1714 bne(rs, r2, offset); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1774 beq(scratch, zero_reg, offset); | 1780 beq(scratch, zero_reg, offset); |
1775 } | 1781 } |
1776 break; | 1782 break; |
1777 default: | 1783 default: |
1778 UNREACHABLE(); | 1784 UNREACHABLE(); |
1779 } | 1785 } |
1780 } else { | 1786 } else { |
1781 // Be careful to always use shifted_branch_offset only just before the | 1787 // Be careful to always use shifted_branch_offset only just before the |
1782 // branch instruction, as the location will be remember for patching the | 1788 // branch instruction, as the location will be remember for patching the |
1783 // target. | 1789 // target. |
| 1790 BlockTrampolinePoolScope block_trampoline_pool(this); |
1784 switch (cond) { | 1791 switch (cond) { |
1785 case cc_always: | 1792 case cc_always: |
1786 b(offset); | 1793 b(offset); |
1787 break; | 1794 break; |
1788 case eq: | 1795 case eq: |
1789 // We don't want any other register but scratch clobbered. | 1796 // We don't want any other register but scratch clobbered. |
1790 ASSERT(!scratch.is(rs)); | 1797 ASSERT(!scratch.is(rs)); |
1791 r2 = scratch; | 1798 r2 = scratch; |
1792 li(r2, rt); | 1799 li(r2, rt); |
1793 beq(rs, r2, offset); | 1800 beq(rs, r2, offset); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1918 | 1925 |
1919 void MacroAssembler::BranchShort(Label* L, Condition cond, Register rs, | 1926 void MacroAssembler::BranchShort(Label* L, Condition cond, Register rs, |
1920 const Operand& rt, | 1927 const Operand& rt, |
1921 BranchDelaySlot bdslot) { | 1928 BranchDelaySlot bdslot) { |
1922 BRANCH_ARGS_CHECK(cond, rs, rt); | 1929 BRANCH_ARGS_CHECK(cond, rs, rt); |
1923 | 1930 |
1924 int32_t offset = 0; | 1931 int32_t offset = 0; |
1925 Register r2 = no_reg; | 1932 Register r2 = no_reg; |
1926 Register scratch = at; | 1933 Register scratch = at; |
1927 if (rt.is_reg()) { | 1934 if (rt.is_reg()) { |
| 1935 BlockTrampolinePoolScope block_trampoline_pool(this); |
1928 r2 = rt.rm_; | 1936 r2 = rt.rm_; |
1929 // Be careful to always use shifted_branch_offset only just before the | 1937 // Be careful to always use shifted_branch_offset only just before the |
1930 // branch instruction, as the location will be remember for patching the | 1938 // branch instruction, as the location will be remember for patching the |
1931 // target. | 1939 // target. |
1932 switch (cond) { | 1940 switch (cond) { |
1933 case cc_always: | 1941 case cc_always: |
1934 offset = shifted_branch_offset(L, false); | 1942 offset = shifted_branch_offset(L, false); |
1935 b(offset); | 1943 b(offset); |
1936 break; | 1944 break; |
1937 case eq: | 1945 case eq: |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2024 beq(scratch, zero_reg, offset); | 2032 beq(scratch, zero_reg, offset); |
2025 } | 2033 } |
2026 break; | 2034 break; |
2027 default: | 2035 default: |
2028 UNREACHABLE(); | 2036 UNREACHABLE(); |
2029 } | 2037 } |
2030 } else { | 2038 } else { |
2031 // Be careful to always use shifted_branch_offset only just before the | 2039 // Be careful to always use shifted_branch_offset only just before the |
2032 // branch instruction, as the location will be remember for patching the | 2040 // branch instruction, as the location will be remember for patching the |
2033 // target. | 2041 // target. |
| 2042 BlockTrampolinePoolScope block_trampoline_pool(this); |
2034 switch (cond) { | 2043 switch (cond) { |
2035 case cc_always: | 2044 case cc_always: |
2036 offset = shifted_branch_offset(L, false); | 2045 offset = shifted_branch_offset(L, false); |
2037 b(offset); | 2046 b(offset); |
2038 break; | 2047 break; |
2039 case eq: | 2048 case eq: |
2040 ASSERT(!scratch.is(rs)); | 2049 ASSERT(!scratch.is(rs)); |
2041 r2 = scratch; | 2050 r2 = scratch; |
2042 li(r2, rt); | 2051 li(r2, rt); |
2043 offset = shifted_branch_offset(L, false); | 2052 offset = shifted_branch_offset(L, false); |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2260 Register r2 = no_reg; | 2269 Register r2 = no_reg; |
2261 Register scratch = at; | 2270 Register scratch = at; |
2262 | 2271 |
2263 if (rt.is_reg()) { | 2272 if (rt.is_reg()) { |
2264 r2 = rt.rm_; | 2273 r2 = rt.rm_; |
2265 } else if (cond != cc_always) { | 2274 } else if (cond != cc_always) { |
2266 r2 = scratch; | 2275 r2 = scratch; |
2267 li(r2, rt); | 2276 li(r2, rt); |
2268 } | 2277 } |
2269 | 2278 |
2270 switch (cond) { | 2279 { |
2271 case cc_always: | 2280 BlockTrampolinePoolScope block_trampoline_pool(this); |
2272 bal(offset); | 2281 switch (cond) { |
2273 break; | 2282 case cc_always: |
2274 case eq: | 2283 bal(offset); |
2275 bne(rs, r2, 2); | 2284 break; |
2276 nop(); | 2285 case eq: |
2277 bal(offset); | 2286 bne(rs, r2, 2); |
2278 break; | 2287 nop(); |
2279 case ne: | 2288 bal(offset); |
2280 beq(rs, r2, 2); | 2289 break; |
2281 nop(); | 2290 case ne: |
2282 bal(offset); | 2291 beq(rs, r2, 2); |
2283 break; | 2292 nop(); |
| 2293 bal(offset); |
| 2294 break; |
2284 | 2295 |
2285 // Signed comparison. | 2296 // Signed comparison. |
2286 case greater: | 2297 case greater: |
2287 slt(scratch, r2, rs); | 2298 slt(scratch, r2, rs); |
2288 addiu(scratch, scratch, -1); | 2299 addiu(scratch, scratch, -1); |
2289 bgezal(scratch, offset); | 2300 bgezal(scratch, offset); |
2290 break; | 2301 break; |
2291 case greater_equal: | 2302 case greater_equal: |
2292 slt(scratch, rs, r2); | 2303 slt(scratch, rs, r2); |
2293 addiu(scratch, scratch, -1); | 2304 addiu(scratch, scratch, -1); |
2294 bltzal(scratch, offset); | 2305 bltzal(scratch, offset); |
2295 break; | 2306 break; |
2296 case less: | 2307 case less: |
2297 slt(scratch, rs, r2); | 2308 slt(scratch, rs, r2); |
2298 addiu(scratch, scratch, -1); | 2309 addiu(scratch, scratch, -1); |
2299 bgezal(scratch, offset); | 2310 bgezal(scratch, offset); |
2300 break; | 2311 break; |
2301 case less_equal: | 2312 case less_equal: |
2302 slt(scratch, r2, rs); | 2313 slt(scratch, r2, rs); |
2303 addiu(scratch, scratch, -1); | 2314 addiu(scratch, scratch, -1); |
2304 bltzal(scratch, offset); | 2315 bltzal(scratch, offset); |
2305 break; | 2316 break; |
2306 | 2317 |
2307 // Unsigned comparison. | 2318 // Unsigned comparison. |
2308 case Ugreater: | 2319 case Ugreater: |
2309 sltu(scratch, r2, rs); | 2320 sltu(scratch, r2, rs); |
2310 addiu(scratch, scratch, -1); | 2321 addiu(scratch, scratch, -1); |
2311 bgezal(scratch, offset); | 2322 bgezal(scratch, offset); |
2312 break; | 2323 break; |
2313 case Ugreater_equal: | 2324 case Ugreater_equal: |
2314 sltu(scratch, rs, r2); | 2325 sltu(scratch, rs, r2); |
2315 addiu(scratch, scratch, -1); | 2326 addiu(scratch, scratch, -1); |
2316 bltzal(scratch, offset); | 2327 bltzal(scratch, offset); |
2317 break; | 2328 break; |
2318 case Uless: | 2329 case Uless: |
2319 sltu(scratch, rs, r2); | 2330 sltu(scratch, rs, r2); |
2320 addiu(scratch, scratch, -1); | 2331 addiu(scratch, scratch, -1); |
2321 bgezal(scratch, offset); | 2332 bgezal(scratch, offset); |
2322 break; | 2333 break; |
2323 case Uless_equal: | 2334 case Uless_equal: |
2324 sltu(scratch, r2, rs); | 2335 sltu(scratch, r2, rs); |
2325 addiu(scratch, scratch, -1); | 2336 addiu(scratch, scratch, -1); |
2326 bltzal(scratch, offset); | 2337 bltzal(scratch, offset); |
2327 break; | 2338 break; |
2328 | 2339 |
2329 default: | 2340 default: |
2330 UNREACHABLE(); | 2341 UNREACHABLE(); |
| 2342 } |
2331 } | 2343 } |
2332 // Emit a nop in the branch delay slot if required. | 2344 // Emit a nop in the branch delay slot if required. |
2333 if (bdslot == PROTECT) | 2345 if (bdslot == PROTECT) |
2334 nop(); | 2346 nop(); |
2335 } | 2347 } |
2336 | 2348 |
2337 | 2349 |
2338 void MacroAssembler::BranchAndLinkShort(Label* L, BranchDelaySlot bdslot) { | 2350 void MacroAssembler::BranchAndLinkShort(Label* L, BranchDelaySlot bdslot) { |
2339 bal(shifted_branch_offset(L, false)); | 2351 bal(shifted_branch_offset(L, false)); |
2340 | 2352 |
(...skipping 11 matching lines...) Expand all Loading... |
2352 int32_t offset = 0; | 2364 int32_t offset = 0; |
2353 Register r2 = no_reg; | 2365 Register r2 = no_reg; |
2354 Register scratch = at; | 2366 Register scratch = at; |
2355 if (rt.is_reg()) { | 2367 if (rt.is_reg()) { |
2356 r2 = rt.rm_; | 2368 r2 = rt.rm_; |
2357 } else if (cond != cc_always) { | 2369 } else if (cond != cc_always) { |
2358 r2 = scratch; | 2370 r2 = scratch; |
2359 li(r2, rt); | 2371 li(r2, rt); |
2360 } | 2372 } |
2361 | 2373 |
2362 switch (cond) { | 2374 { |
2363 case cc_always: | 2375 BlockTrampolinePoolScope block_trampoline_pool(this); |
2364 offset = shifted_branch_offset(L, false); | 2376 switch (cond) { |
2365 bal(offset); | 2377 case cc_always: |
2366 break; | 2378 offset = shifted_branch_offset(L, false); |
2367 case eq: | 2379 bal(offset); |
2368 bne(rs, r2, 2); | 2380 break; |
2369 nop(); | 2381 case eq: |
2370 offset = shifted_branch_offset(L, false); | 2382 bne(rs, r2, 2); |
2371 bal(offset); | 2383 nop(); |
2372 break; | 2384 offset = shifted_branch_offset(L, false); |
2373 case ne: | 2385 bal(offset); |
2374 beq(rs, r2, 2); | 2386 break; |
2375 nop(); | 2387 case ne: |
2376 offset = shifted_branch_offset(L, false); | 2388 beq(rs, r2, 2); |
2377 bal(offset); | 2389 nop(); |
2378 break; | 2390 offset = shifted_branch_offset(L, false); |
| 2391 bal(offset); |
| 2392 break; |
2379 | 2393 |
2380 // Signed comparison. | 2394 // Signed comparison. |
2381 case greater: | 2395 case greater: |
2382 slt(scratch, r2, rs); | 2396 slt(scratch, r2, rs); |
2383 addiu(scratch, scratch, -1); | 2397 addiu(scratch, scratch, -1); |
2384 offset = shifted_branch_offset(L, false); | 2398 offset = shifted_branch_offset(L, false); |
2385 bgezal(scratch, offset); | 2399 bgezal(scratch, offset); |
2386 break; | 2400 break; |
2387 case greater_equal: | 2401 case greater_equal: |
2388 slt(scratch, rs, r2); | 2402 slt(scratch, rs, r2); |
2389 addiu(scratch, scratch, -1); | 2403 addiu(scratch, scratch, -1); |
2390 offset = shifted_branch_offset(L, false); | 2404 offset = shifted_branch_offset(L, false); |
2391 bltzal(scratch, offset); | 2405 bltzal(scratch, offset); |
2392 break; | 2406 break; |
2393 case less: | 2407 case less: |
2394 slt(scratch, rs, r2); | 2408 slt(scratch, rs, r2); |
2395 addiu(scratch, scratch, -1); | 2409 addiu(scratch, scratch, -1); |
2396 offset = shifted_branch_offset(L, false); | 2410 offset = shifted_branch_offset(L, false); |
2397 bgezal(scratch, offset); | 2411 bgezal(scratch, offset); |
2398 break; | 2412 break; |
2399 case less_equal: | 2413 case less_equal: |
2400 slt(scratch, r2, rs); | 2414 slt(scratch, r2, rs); |
2401 addiu(scratch, scratch, -1); | 2415 addiu(scratch, scratch, -1); |
2402 offset = shifted_branch_offset(L, false); | 2416 offset = shifted_branch_offset(L, false); |
2403 bltzal(scratch, offset); | 2417 bltzal(scratch, offset); |
2404 break; | 2418 break; |
2405 | 2419 |
2406 // Unsigned comparison. | 2420 // Unsigned comparison. |
2407 case Ugreater: | 2421 case Ugreater: |
2408 sltu(scratch, r2, rs); | 2422 sltu(scratch, r2, rs); |
2409 addiu(scratch, scratch, -1); | 2423 addiu(scratch, scratch, -1); |
2410 offset = shifted_branch_offset(L, false); | 2424 offset = shifted_branch_offset(L, false); |
2411 bgezal(scratch, offset); | 2425 bgezal(scratch, offset); |
2412 break; | 2426 break; |
2413 case Ugreater_equal: | 2427 case Ugreater_equal: |
2414 sltu(scratch, rs, r2); | 2428 sltu(scratch, rs, r2); |
2415 addiu(scratch, scratch, -1); | 2429 addiu(scratch, scratch, -1); |
2416 offset = shifted_branch_offset(L, false); | 2430 offset = shifted_branch_offset(L, false); |
2417 bltzal(scratch, offset); | 2431 bltzal(scratch, offset); |
2418 break; | 2432 break; |
2419 case Uless: | 2433 case Uless: |
2420 sltu(scratch, rs, r2); | 2434 sltu(scratch, rs, r2); |
2421 addiu(scratch, scratch, -1); | 2435 addiu(scratch, scratch, -1); |
2422 offset = shifted_branch_offset(L, false); | 2436 offset = shifted_branch_offset(L, false); |
2423 bgezal(scratch, offset); | 2437 bgezal(scratch, offset); |
2424 break; | 2438 break; |
2425 case Uless_equal: | 2439 case Uless_equal: |
2426 sltu(scratch, r2, rs); | 2440 sltu(scratch, r2, rs); |
2427 addiu(scratch, scratch, -1); | 2441 addiu(scratch, scratch, -1); |
2428 offset = shifted_branch_offset(L, false); | 2442 offset = shifted_branch_offset(L, false); |
2429 bltzal(scratch, offset); | 2443 bltzal(scratch, offset); |
2430 break; | 2444 break; |
2431 | 2445 |
2432 default: | 2446 default: |
2433 UNREACHABLE(); | 2447 UNREACHABLE(); |
| 2448 } |
2434 } | 2449 } |
2435 | |
2436 // Check that offset could actually hold on an int16_t. | 2450 // Check that offset could actually hold on an int16_t. |
2437 ASSERT(is_int16(offset)); | 2451 ASSERT(is_int16(offset)); |
2438 | 2452 |
2439 // Emit a nop in the branch delay slot if required. | 2453 // Emit a nop in the branch delay slot if required. |
2440 if (bdslot == PROTECT) | 2454 if (bdslot == PROTECT) |
2441 nop(); | 2455 nop(); |
2442 } | 2456 } |
2443 | 2457 |
2444 | 2458 |
2445 void MacroAssembler::Jump(Register target, | 2459 void MacroAssembler::Jump(Register target, |
(...skipping 3084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5530 opcode == BGTZL); | 5544 opcode == BGTZL); |
5531 opcode = (cond == eq) ? BEQ : BNE; | 5545 opcode = (cond == eq) ? BEQ : BNE; |
5532 instr = (instr & ~kOpcodeMask) | opcode; | 5546 instr = (instr & ~kOpcodeMask) | opcode; |
5533 masm_.emit(instr); | 5547 masm_.emit(instr); |
5534 } | 5548 } |
5535 | 5549 |
5536 | 5550 |
5537 } } // namespace v8::internal | 5551 } } // namespace v8::internal |
5538 | 5552 |
5539 #endif // V8_TARGET_ARCH_MIPS | 5553 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |