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)); \ |
| 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 __ la(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 two, unaligned, done; |
| 2362 __ la(r1, MemOperand(base, index)); |
| 2363 __ tmll(r1, Operand(3)); |
| 2364 __ b(Condition(2), &two); |
| 2365 |
| 2366 // end with 0b00 |
| 2367 ATOMIC_EXCHANGE_HALFWORD(0); |
| 2368 __ b(&done); |
| 2369 |
| 2370 // ending with 0b10 |
| 2371 __ bind(&two); |
| 2372 ATOMIC_EXCHANGE_HALFWORD(1); |
| 2373 |
| 2374 __ bind(&done); |
| 2375 if (opcode == kAtomicExchangeInt8) { |
| 2376 __ lhr(output, output); |
| 2377 } else { |
| 2378 __ llhr(output, output); |
| 2379 } |
2269 break; | 2380 break; |
| 2381 } |
| 2382 case kAtomicExchangeWord32: { |
| 2383 Register base = i.InputRegister(0); |
| 2384 Register index = i.InputRegister(1); |
| 2385 Register value = i.InputRegister(2); |
| 2386 Register output = i.OutputRegister(); |
| 2387 Label do_cs; |
| 2388 __ lay(r1, MemOperand(base, index)); |
| 2389 __ LoadlW(output, MemOperand(r1)); |
| 2390 __ bind(&do_cs); |
| 2391 __ cs(output, value, MemOperand(r1)); |
| 2392 __ bne(&do_cs, Label::kNear); |
| 2393 break; |
| 2394 } |
2270 default: | 2395 default: |
2271 UNREACHABLE(); | 2396 UNREACHABLE(); |
2272 break; | 2397 break; |
2273 } | 2398 } |
2274 return kSuccess; | 2399 return kSuccess; |
2275 } // NOLINT(readability/fn_size) | 2400 } // NOLINT(readability/fn_size) |
2276 | 2401 |
2277 // Assembles branches after an instruction. | 2402 // Assembles branches after an instruction. |
2278 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { | 2403 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
2279 S390OperandConverter i(this, instr); | 2404 S390OperandConverter i(this, instr); |
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2805 padding_size -= 2; | 2930 padding_size -= 2; |
2806 } | 2931 } |
2807 } | 2932 } |
2808 } | 2933 } |
2809 | 2934 |
2810 #undef __ | 2935 #undef __ |
2811 | 2936 |
2812 } // namespace compiler | 2937 } // namespace compiler |
2813 } // namespace internal | 2938 } // namespace internal |
2814 } // namespace v8 | 2939 } // namespace v8 |
OLD | NEW |