Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
| 6 | 6 |
| 7 #include "src/compilation-info.h" | 7 #include "src/compilation-info.h" |
| 8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
| 9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| (...skipping 2242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2253 break; | 2253 break; |
| 2254 case kAtomicStoreWord8: | 2254 case kAtomicStoreWord8: |
| 2255 __ StoreByte(i.InputRegister(0), i.MemoryOperand(NULL, 1)); | 2255 __ StoreByte(i.InputRegister(0), i.MemoryOperand(NULL, 1)); |
| 2256 break; | 2256 break; |
| 2257 case kAtomicStoreWord16: | 2257 case kAtomicStoreWord16: |
| 2258 __ StoreHalfWord(i.InputRegister(0), i.MemoryOperand(NULL, 1)); | 2258 __ StoreHalfWord(i.InputRegister(0), i.MemoryOperand(NULL, 1)); |
| 2259 break; | 2259 break; |
| 2260 case kAtomicStoreWord32: | 2260 case kAtomicStoreWord32: |
| 2261 __ StoreW(i.InputRegister(0), i.MemoryOperand(NULL, 1)); | 2261 __ StoreW(i.InputRegister(0), i.MemoryOperand(NULL, 1)); |
| 2262 break; | 2262 break; |
| 2263 // 0x aa bb cc dd | |
| 2264 // index = 3..2..1..0 | |
| 2265 #define ATOMIC_EXCHANGE(start, end, shift_amount, offset) \ | |
| 2266 { \ | |
| 2267 Label do_cs; \ | |
| 2268 __ LoadlW(output, MemOperand(r1)); \ | |
|
JoranSiu
2017/03/10 04:50:58
Should this load be in the loop? i.e. if another
| |
| 2269 __ bind(&do_cs); \ | |
| 2270 __ llgfr(r0, output); \ | |
| 2271 __ risbg(r0, value, Operand(start), Operand(end), Operand(shift_amount), \ | |
| 2272 false); \ | |
| 2273 __ csy(output, r0, MemOperand(r1, offset)); \ | |
| 2274 __ bne(&do_cs, Label::kNear); \ | |
| 2275 __ srl(output, Operand(shift_amount)); \ | |
| 2276 } | |
| 2277 #ifdef V8_TARGET_BIG_ENDIAN | |
| 2278 #define ATOMIC_EXCHANGE_BYTE(i) \ | |
| 2279 { \ | |
| 2280 constexpr int idx = (i); \ | |
| 2281 static_assert(idx <= 3 && idx >= 0, "idx is out of range!"); \ | |
| 2282 constexpr int start = 32 + 8 * idx; \ | |
| 2283 constexpr int end = start + 7; \ | |
| 2284 constexpr int shift_amount = (3 - idx) * 8; \ | |
| 2285 ATOMIC_EXCHANGE(start, end, shift_amount, -idx); \ | |
| 2286 } | |
| 2287 #define ATOMIC_EXCHANGE_HALFWORD(i) \ | |
| 2288 { \ | |
| 2289 constexpr int idx = (i); \ | |
| 2290 static_assert(idx <= 1 && idx >= 0, "idx is out of range!"); \ | |
| 2291 constexpr int start = 32 + 16 * idx; \ | |
| 2292 constexpr int end = start + 15; \ | |
| 2293 constexpr int shift_amount = (1 - idx) * 16; \ | |
| 2294 ATOMIC_EXCHANGE(start, end, shift_amount, -idx * 2); \ | |
| 2295 } | |
| 2296 #else | |
| 2297 #define ATOMIC_EXCHANGE_BYTE(i) \ | |
| 2298 { \ | |
| 2299 constexpr int idx = (i); \ | |
| 2300 static_assert(idx <= 3 && idx >= 0, "idx is out of range!"); \ | |
| 2301 constexpr int start = 32 + 8 * (3 - idx); \ | |
| 2302 constexpr int end = start + 7; \ | |
| 2303 constexpr int shift_amount = idx * 8; \ | |
| 2304 ATOMIC_EXCHANGE(start, end, shift_amount, -idx); \ | |
| 2305 } | |
| 2306 #define ATOMIC_EXCHANGE_HALFWORD(i) \ | |
| 2307 { \ | |
| 2308 constexpr int idx = (i); \ | |
| 2309 static_assert(idx <= 1 && idx >= 0, "idx is out of range!"); \ | |
| 2310 constexpr int start = 32 + 16 * (1 - idx); \ | |
| 2311 constexpr int end = start + 15; \ | |
| 2312 constexpr int shift_amount = idx * 16; \ | |
| 2313 ATOMIC_EXCHANGE(start, end, shift_amount, -idx * 2); \ | |
| 2314 } | |
| 2315 #endif | |
| 2263 case kAtomicExchangeInt8: | 2316 case kAtomicExchangeInt8: |
| 2264 case kAtomicExchangeUint8: | 2317 case kAtomicExchangeUint8: { |
| 2318 Register base = i.InputRegister(0); | |
| 2319 Register index = i.InputRegister(1); | |
| 2320 Register value = i.InputRegister(2); | |
| 2321 Register output = i.OutputRegister(); | |
| 2322 Label three, two, one, done; | |
| 2323 __ lay(r1, MemOperand(base, index)); | |
| 2324 __ tmll(r1, Operand(3)); | |
| 2325 __ b(Condition(1), &three); | |
| 2326 __ b(Condition(2), &two); | |
| 2327 __ b(Condition(4), &one); | |
| 2328 | |
| 2329 // end with 0b00 | |
| 2330 ATOMIC_EXCHANGE_BYTE(0); | |
| 2331 __ b(&done); | |
| 2332 | |
| 2333 // ending with 0b01 | |
| 2334 __ bind(&one); | |
| 2335 ATOMIC_EXCHANGE_BYTE(1); | |
| 2336 __ b(&done); | |
| 2337 | |
| 2338 // ending with 0b10 | |
| 2339 __ bind(&two); | |
| 2340 ATOMIC_EXCHANGE_BYTE(2); | |
| 2341 __ b(&done); | |
| 2342 | |
| 2343 // ending with 0b11 | |
| 2344 __ bind(&three); | |
| 2345 ATOMIC_EXCHANGE_BYTE(3); | |
| 2346 | |
| 2347 __ bind(&done); | |
| 2348 if (opcode == kAtomicExchangeInt8) { | |
| 2349 __ lbr(output, output); | |
| 2350 } else { | |
| 2351 __ llcr(output, output); | |
| 2352 } | |
| 2353 break; | |
| 2354 } | |
| 2265 case kAtomicExchangeInt16: | 2355 case kAtomicExchangeInt16: |
| 2266 case kAtomicExchangeUint16: | 2356 case kAtomicExchangeUint16: { |
| 2267 case kAtomicExchangeWord32: | 2357 Register base = i.InputRegister(0); |
| 2268 UNREACHABLE(); | 2358 Register index = i.InputRegister(1); |
| 2359 Register value = i.InputRegister(2); | |
| 2360 Register output = i.OutputRegister(); | |
| 2361 Label three, two, one, done; | |
| 2362 __ lay(r1, MemOperand(base, index)); | |
| 2363 __ tmll(r1, Operand(3)); | |
| 2364 __ b(Condition(1), &three); | |
| 2365 __ b(Condition(2), &two); | |
| 2366 __ b(Condition(4), &one); | |
| 2367 | |
| 2368 // end with 0b00 | |
| 2369 ATOMIC_EXCHANGE_HALFWORD(0); | |
| 2370 __ b(&done); | |
| 2371 | |
| 2372 // ending with 0b10 | |
| 2373 __ bind(&two); | |
| 2374 ATOMIC_EXCHANGE_HALFWORD(1); | |
| 2375 __ b(&done); | |
| 2376 | |
| 2377 // ending with 0b01 or 0b11 | |
| 2378 __ bind(&one); | |
| 2379 __ bind(&three); | |
| 2380 // trigger Segmentation Fault | |
| 2381 __ lg(r0, MemOperand(r0)); | |
| 2382 | |
| 2383 __ bind(&done); | |
| 2384 if (opcode == kAtomicExchangeInt8) { | |
| 2385 __ lhr(output, output); | |
| 2386 } else { | |
| 2387 __ llhr(output, output); | |
| 2388 } | |
| 2269 break; | 2389 break; |
| 2390 } | |
| 2391 case kAtomicExchangeWord32: { | |
| 2392 Register base = i.InputRegister(0); | |
| 2393 Register index = i.InputRegister(1); | |
| 2394 Register value = i.InputRegister(2); | |
| 2395 Register output = i.OutputRegister(); | |
| 2396 Label do_cs; | |
| 2397 __ lay(r1, MemOperand(base, index)); | |
| 2398 __ LoadlW(output, MemOperand(r1)); | |
| 2399 __ bind(&do_cs); | |
| 2400 __ cs(output, value, MemOperand(r1)); | |
| 2401 __ bne(&do_cs, Label::kNear); | |
| 2402 break; | |
| 2403 } | |
| 2270 default: | 2404 default: |
| 2271 UNREACHABLE(); | 2405 UNREACHABLE(); |
| 2272 break; | 2406 break; |
| 2273 } | 2407 } |
| 2274 return kSuccess; | 2408 return kSuccess; |
| 2275 } // NOLINT(readability/fn_size) | 2409 } // NOLINT(readability/fn_size) |
| 2276 | 2410 |
| 2277 // Assembles branches after an instruction. | 2411 // Assembles branches after an instruction. |
| 2278 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { | 2412 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
| 2279 S390OperandConverter i(this, instr); | 2413 S390OperandConverter i(this, instr); |
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2805 padding_size -= 2; | 2939 padding_size -= 2; |
| 2806 } | 2940 } |
| 2807 } | 2941 } |
| 2808 } | 2942 } |
| 2809 | 2943 |
| 2810 #undef __ | 2944 #undef __ |
| 2811 | 2945 |
| 2812 } // namespace compiler | 2946 } // namespace compiler |
| 2813 } // namespace internal | 2947 } // namespace internal |
| 2814 } // namespace v8 | 2948 } // namespace v8 |
| OLD | NEW |