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 |