Line data Source code
1 : // Copyright 2014 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/compiler/instruction-codes.h"
6 : #include "src/compiler/instruction.h"
7 : #include "src/compiler/jump-threading.h"
8 : #include "src/source-position.h"
9 : #include "test/cctest/cctest.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 : namespace compiler {
14 :
15 1422 : class TestCode : public HandleAndZoneScope {
16 : public:
17 1422 : TestCode()
18 : : HandleAndZoneScope(),
19 : blocks_(main_zone()),
20 : sequence_(main_isolate(), main_zone(), &blocks_),
21 : rpo_number_(RpoNumber::FromInt(0)),
22 2844 : current_(nullptr) {}
23 :
24 : ZoneVector<InstructionBlock*> blocks_;
25 : InstructionSequence sequence_;
26 : RpoNumber rpo_number_;
27 : InstructionBlock* current_;
28 :
29 6696 : int Jump(int target) {
30 6696 : Start();
31 6696 : InstructionOperand ops[] = {UseRpo(target)};
32 : sequence_.AddInstruction(Instruction::New(main_zone(), kArchJmp, 0, nullptr,
33 6696 : 1, ops, 0, nullptr));
34 6696 : int pos = static_cast<int>(sequence_.instructions().size() - 1);
35 6696 : End();
36 6696 : return pos;
37 : }
38 : void Fallthru() {
39 156 : Start();
40 156 : End();
41 : }
42 432 : int Branch(int ttarget, int ftarget) {
43 432 : Start();
44 864 : InstructionOperand ops[] = {UseRpo(ttarget), UseRpo(ftarget)};
45 : InstructionCode code = 119 | FlagsModeField::encode(kFlags_branch) |
46 : FlagsConditionField::encode(kEqual);
47 : sequence_.AddInstruction(
48 432 : Instruction::New(main_zone(), code, 0, nullptr, 2, ops, 0, nullptr));
49 432 : int pos = static_cast<int>(sequence_.instructions().size() - 1);
50 432 : End();
51 432 : return pos;
52 : }
53 216 : void Nop() {
54 216 : Start();
55 216 : sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop));
56 216 : }
57 12 : void RedundantMoves() {
58 12 : Start();
59 12 : sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop));
60 12 : int index = static_cast<int>(sequence_.instructions().size()) - 1;
61 : AddGapMove(index, AllocatedOperand(LocationOperand::REGISTER,
62 : MachineRepresentation::kWord32, 13),
63 : AllocatedOperand(LocationOperand::REGISTER,
64 12 : MachineRepresentation::kWord32, 13));
65 12 : }
66 30 : void NonRedundantMoves() {
67 30 : Start();
68 30 : sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop));
69 30 : int index = static_cast<int>(sequence_.instructions().size()) - 1;
70 : AddGapMove(index, ConstantOperand(11),
71 : AllocatedOperand(LocationOperand::REGISTER,
72 30 : MachineRepresentation::kWord32, 11));
73 30 : }
74 276 : void Other() {
75 276 : Start();
76 276 : sequence_.AddInstruction(Instruction::New(main_zone(), 155));
77 276 : }
78 8640 : void End() {
79 8640 : Start();
80 8640 : sequence_.EndBlock(current_->rpo_number());
81 8640 : current_ = nullptr;
82 8640 : rpo_number_ = RpoNumber::FromInt(rpo_number_.ToInt() + 1);
83 8640 : }
84 : InstructionOperand UseRpo(int num) {
85 7560 : return sequence_.AddImmediate(Constant(RpoNumber::FromInt(num)));
86 : }
87 16476 : void Start(bool deferred = false) {
88 16476 : if (current_ == nullptr) {
89 : current_ = new (main_zone())
90 : InstructionBlock(main_zone(), rpo_number_, RpoNumber::Invalid(),
91 17280 : RpoNumber::Invalid(), deferred, false);
92 8640 : blocks_.push_back(current_);
93 8640 : sequence_.StartBlock(rpo_number_);
94 : }
95 16476 : }
96 18 : void Defer() {
97 18 : CHECK_NULL(current_);
98 18 : Start(true);
99 18 : }
100 42 : void AddGapMove(int index, const InstructionOperand& from,
101 : const InstructionOperand& to) {
102 : sequence_.InstructionAt(index)
103 : ->GetOrCreateParallelMove(Instruction::START, main_zone())
104 42 : ->AddMove(from, to);
105 42 : }
106 : };
107 :
108 :
109 1380 : void VerifyForwarding(TestCode& code, int count, int* expected) {
110 1380 : v8::internal::AccountingAllocator allocator;
111 2760 : Zone local_zone(&allocator, ZONE_NAME);
112 : ZoneVector<RpoNumber> result(&local_zone);
113 1380 : JumpThreading::ComputeForwarding(&local_zone, result, &code.sequence_, true);
114 :
115 2760 : CHECK(count == static_cast<int>(result.size()));
116 8454 : for (int i = 0; i < count; i++) {
117 16908 : CHECK(expected[i] == result[i].ToInt());
118 1380 : }
119 1380 : }
120 :
121 :
122 23724 : TEST(FwEmpty1) {
123 6 : TestCode code;
124 :
125 : // B0
126 6 : code.Jump(1);
127 : // B1
128 6 : code.Jump(2);
129 : // B2
130 6 : code.End();
131 :
132 : static int expected[] = {2, 2, 2};
133 6 : VerifyForwarding(code, 3, expected);
134 6 : }
135 :
136 :
137 23724 : TEST(FwEmptyN) {
138 60 : for (int i = 0; i < 9; i++) {
139 54 : TestCode code;
140 :
141 : // B0
142 54 : code.Jump(1);
143 : // B1
144 54 : for (int j = 0; j < i; j++) code.Nop();
145 54 : code.Jump(2);
146 : // B2
147 54 : code.End();
148 :
149 : static int expected[] = {2, 2, 2};
150 54 : VerifyForwarding(code, 3, expected);
151 : }
152 6 : }
153 :
154 :
155 23724 : TEST(FwNone1) {
156 6 : TestCode code;
157 :
158 : // B0
159 6 : code.End();
160 :
161 : static int expected[] = {0};
162 6 : VerifyForwarding(code, 1, expected);
163 6 : }
164 :
165 :
166 23724 : TEST(FwMoves1) {
167 6 : TestCode code;
168 :
169 : // B0
170 6 : code.RedundantMoves();
171 6 : code.End();
172 :
173 : static int expected[] = {0};
174 6 : VerifyForwarding(code, 1, expected);
175 6 : }
176 :
177 :
178 23724 : TEST(FwMoves2) {
179 6 : TestCode code;
180 :
181 : // B0
182 6 : code.RedundantMoves();
183 : code.Fallthru();
184 : // B1
185 6 : code.End();
186 :
187 : static int expected[] = {1, 1};
188 6 : VerifyForwarding(code, 2, expected);
189 6 : }
190 :
191 :
192 23724 : TEST(FwMoves2b) {
193 6 : TestCode code;
194 :
195 : // B0
196 6 : code.NonRedundantMoves();
197 : code.Fallthru();
198 : // B1
199 6 : code.End();
200 :
201 : static int expected[] = {0, 1};
202 6 : VerifyForwarding(code, 2, expected);
203 6 : }
204 :
205 :
206 23724 : TEST(FwOther2) {
207 6 : TestCode code;
208 :
209 : // B0
210 6 : code.Other();
211 : code.Fallthru();
212 : // B1
213 6 : code.End();
214 :
215 : static int expected[] = {0, 1};
216 6 : VerifyForwarding(code, 2, expected);
217 6 : }
218 :
219 :
220 23724 : TEST(FwNone2a) {
221 6 : TestCode code;
222 :
223 : // B0
224 : code.Fallthru();
225 : // B1
226 6 : code.End();
227 :
228 : static int expected[] = {1, 1};
229 6 : VerifyForwarding(code, 2, expected);
230 6 : }
231 :
232 :
233 23724 : TEST(FwNone2b) {
234 6 : TestCode code;
235 :
236 : // B0
237 6 : code.Jump(1);
238 : // B1
239 6 : code.End();
240 :
241 : static int expected[] = {1, 1};
242 6 : VerifyForwarding(code, 2, expected);
243 6 : }
244 :
245 :
246 23724 : TEST(FwLoop1) {
247 6 : TestCode code;
248 :
249 : // B0
250 6 : code.Jump(0);
251 :
252 : static int expected[] = {0};
253 6 : VerifyForwarding(code, 1, expected);
254 6 : }
255 :
256 :
257 23724 : TEST(FwLoop2) {
258 6 : TestCode code;
259 :
260 : // B0
261 : code.Fallthru();
262 : // B1
263 6 : code.Jump(0);
264 :
265 : static int expected[] = {0, 0};
266 6 : VerifyForwarding(code, 2, expected);
267 6 : }
268 :
269 :
270 23724 : TEST(FwLoop3) {
271 6 : TestCode code;
272 :
273 : // B0
274 : code.Fallthru();
275 : // B1
276 : code.Fallthru();
277 : // B2
278 6 : code.Jump(0);
279 :
280 : static int expected[] = {0, 0, 0};
281 6 : VerifyForwarding(code, 3, expected);
282 6 : }
283 :
284 :
285 23724 : TEST(FwLoop1b) {
286 6 : TestCode code;
287 :
288 : // B0
289 : code.Fallthru();
290 : // B1
291 6 : code.Jump(1);
292 :
293 : static int expected[] = {1, 1};
294 6 : VerifyForwarding(code, 2, expected);
295 6 : }
296 :
297 :
298 23724 : TEST(FwLoop2b) {
299 6 : TestCode code;
300 :
301 : // B0
302 : code.Fallthru();
303 : // B1
304 : code.Fallthru();
305 : // B2
306 6 : code.Jump(1);
307 :
308 : static int expected[] = {1, 1, 1};
309 6 : VerifyForwarding(code, 3, expected);
310 6 : }
311 :
312 :
313 23724 : TEST(FwLoop3b) {
314 6 : TestCode code;
315 :
316 : // B0
317 : code.Fallthru();
318 : // B1
319 : code.Fallthru();
320 : // B2
321 : code.Fallthru();
322 : // B3
323 6 : code.Jump(1);
324 :
325 : static int expected[] = {1, 1, 1, 1};
326 6 : VerifyForwarding(code, 4, expected);
327 6 : }
328 :
329 :
330 23724 : TEST(FwLoop2_1a) {
331 6 : TestCode code;
332 :
333 : // B0
334 : code.Fallthru();
335 : // B1
336 : code.Fallthru();
337 : // B2
338 : code.Fallthru();
339 : // B3
340 6 : code.Jump(1);
341 : // B4
342 6 : code.Jump(2);
343 :
344 : static int expected[] = {1, 1, 1, 1, 1};
345 6 : VerifyForwarding(code, 5, expected);
346 6 : }
347 :
348 :
349 23724 : TEST(FwLoop2_1b) {
350 6 : TestCode code;
351 :
352 : // B0
353 : code.Fallthru();
354 : // B1
355 : code.Fallthru();
356 : // B2
357 6 : code.Jump(4);
358 : // B3
359 6 : code.Jump(1);
360 : // B4
361 6 : code.Jump(2);
362 :
363 : static int expected[] = {2, 2, 2, 2, 2};
364 6 : VerifyForwarding(code, 5, expected);
365 6 : }
366 :
367 :
368 23724 : TEST(FwLoop2_1c) {
369 6 : TestCode code;
370 :
371 : // B0
372 : code.Fallthru();
373 : // B1
374 : code.Fallthru();
375 : // B2
376 6 : code.Jump(4);
377 : // B3
378 6 : code.Jump(2);
379 : // B4
380 6 : code.Jump(1);
381 :
382 : static int expected[] = {1, 1, 1, 1, 1};
383 6 : VerifyForwarding(code, 5, expected);
384 6 : }
385 :
386 :
387 23724 : TEST(FwLoop2_1d) {
388 6 : TestCode code;
389 :
390 : // B0
391 : code.Fallthru();
392 : // B1
393 : code.Fallthru();
394 : // B2
395 6 : code.Jump(1);
396 : // B3
397 6 : code.Jump(1);
398 : // B4
399 6 : code.Jump(1);
400 :
401 : static int expected[] = {1, 1, 1, 1, 1};
402 6 : VerifyForwarding(code, 5, expected);
403 6 : }
404 :
405 :
406 23724 : TEST(FwLoop3_1a) {
407 6 : TestCode code;
408 :
409 : // B0
410 : code.Fallthru();
411 : // B1
412 : code.Fallthru();
413 : // B2
414 : code.Fallthru();
415 : // B3
416 6 : code.Jump(2);
417 : // B4
418 6 : code.Jump(1);
419 : // B5
420 6 : code.Jump(0);
421 :
422 : static int expected[] = {2, 2, 2, 2, 2, 2};
423 6 : VerifyForwarding(code, 6, expected);
424 6 : }
425 :
426 :
427 23724 : TEST(FwDiamonds) {
428 18 : for (int i = 0; i < 2; i++) {
429 24 : for (int j = 0; j < 2; j++) {
430 24 : TestCode code;
431 : // B0
432 24 : code.Branch(1, 2);
433 : // B1
434 24 : if (i) code.Other();
435 24 : code.Jump(3);
436 : // B2
437 24 : if (j) code.Other();
438 24 : code.Jump(3);
439 : // B3
440 24 : code.End();
441 :
442 24 : int expected[] = {0, i ? 1 : 3, j ? 2 : 3, 3};
443 24 : VerifyForwarding(code, 4, expected);
444 : }
445 : }
446 6 : }
447 :
448 :
449 23724 : TEST(FwDiamonds2) {
450 18 : for (int i = 0; i < 2; i++) {
451 24 : for (int j = 0; j < 2; j++) {
452 48 : for (int k = 0; k < 2; k++) {
453 48 : TestCode code;
454 : // B0
455 48 : code.Branch(1, 2);
456 : // B1
457 48 : if (i) code.Other();
458 48 : code.Jump(3);
459 : // B2
460 48 : if (j) code.Other();
461 48 : code.Jump(3);
462 : // B3
463 48 : if (k) code.NonRedundantMoves();
464 48 : code.Jump(4);
465 : // B4
466 48 : code.End();
467 :
468 48 : int merge = k ? 3 : 4;
469 48 : int expected[] = {0, i ? 1 : merge, j ? 2 : merge, merge, 4};
470 48 : VerifyForwarding(code, 5, expected);
471 : }
472 : }
473 : }
474 6 : }
475 :
476 :
477 23724 : TEST(FwDoubleDiamonds) {
478 18 : for (int i = 0; i < 2; i++) {
479 24 : for (int j = 0; j < 2; j++) {
480 48 : for (int x = 0; x < 2; x++) {
481 96 : for (int y = 0; y < 2; y++) {
482 96 : TestCode code;
483 : // B0
484 96 : code.Branch(1, 2);
485 : // B1
486 96 : if (i) code.Other();
487 96 : code.Jump(3);
488 : // B2
489 96 : if (j) code.Other();
490 96 : code.Jump(3);
491 : // B3
492 96 : code.Branch(4, 5);
493 : // B4
494 96 : if (x) code.Other();
495 96 : code.Jump(6);
496 : // B5
497 96 : if (y) code.Other();
498 96 : code.Jump(6);
499 : // B6
500 96 : code.End();
501 :
502 : int expected[] = {0, i ? 1 : 3, j ? 2 : 3, 3,
503 96 : x ? 4 : 6, y ? 5 : 6, 6};
504 96 : VerifyForwarding(code, 7, expected);
505 : }
506 : }
507 : }
508 : }
509 6 : }
510 :
511 : template <int kSize>
512 2832 : void RunPermutationsRecursive(int outer[kSize], int start,
513 : void (*run)(int*, int)) {
514 : int permutation[kSize];
515 :
516 2832 : for (int i = 0; i < kSize; i++) permutation[i] = outer[i];
517 :
518 : int count = kSize - start;
519 5664 : if (count == 0) return run(permutation, kSize);
520 2808 : for (int i = start; i < kSize; i++) {
521 2808 : permutation[start] = outer[i];
522 2808 : permutation[i] = outer[start];
523 2808 : RunPermutationsRecursive<kSize>(permutation, start + 1, run);
524 2808 : permutation[i] = outer[i];
525 2808 : permutation[start] = outer[start];
526 : }
527 : }
528 :
529 :
530 : template <int kSize>
531 24 : void RunAllPermutations(void (*run)(int*, int)) {
532 : int permutation[kSize];
533 24 : for (int i = 0; i < kSize; i++) permutation[i] = i;
534 24 : RunPermutationsRecursive<kSize>(permutation, 0, run);
535 24 : }
536 :
537 :
538 0 : void PrintPermutation(int* permutation, int size) {
539 : printf("{ ");
540 0 : for (int i = 0; i < size; i++) {
541 0 : if (i > 0) printf(", ");
542 0 : printf("%d", permutation[i]);
543 : }
544 : printf(" }\n");
545 0 : }
546 :
547 :
548 0 : int find(int x, int* permutation, int size) {
549 13536 : for (int i = 0; i < size; i++) {
550 18540 : if (permutation[i] == x) return i;
551 : }
552 : return size;
553 : }
554 :
555 :
556 900 : void RunPermutedChain(int* permutation, int size) {
557 900 : TestCode code;
558 : int cur = -1;
559 5184 : for (int i = 0; i < size; i++) {
560 8568 : code.Jump(find(cur + 1, permutation, size) + 1);
561 4284 : cur = permutation[i];
562 : }
563 1800 : code.Jump(find(cur + 1, permutation, size) + 1);
564 900 : code.End();
565 :
566 900 : int expected[] = {size + 1, size + 1, size + 1, size + 1,
567 900 : size + 1, size + 1, size + 1};
568 900 : VerifyForwarding(code, size + 2, expected);
569 900 : }
570 :
571 :
572 23724 : TEST(FwPermuted_chain) {
573 6 : RunAllPermutations<3>(RunPermutedChain);
574 6 : RunAllPermutations<4>(RunPermutedChain);
575 6 : RunAllPermutations<5>(RunPermutedChain);
576 6 : }
577 :
578 :
579 144 : void RunPermutedDiamond(int* permutation, int size) {
580 144 : TestCode code;
581 144 : int br = 1 + find(0, permutation, size);
582 144 : code.Jump(br);
583 720 : for (int i = 0; i < size; i++) {
584 576 : switch (permutation[i]) {
585 : case 0:
586 : code.Branch(1 + find(1, permutation, size),
587 288 : 1 + find(2, permutation, size));
588 144 : break;
589 : case 1:
590 144 : code.Jump(1 + find(3, permutation, size));
591 144 : break;
592 : case 2:
593 144 : code.Jump(1 + find(3, permutation, size));
594 144 : break;
595 : case 3:
596 144 : code.Jump(5);
597 144 : break;
598 : }
599 : }
600 144 : code.End();
601 :
602 144 : int expected[] = {br, 5, 5, 5, 5, 5};
603 144 : expected[br] = br;
604 144 : VerifyForwarding(code, 6, expected);
605 144 : }
606 :
607 :
608 23724 : TEST(FwPermuted_diamond) { RunAllPermutations<4>(RunPermutedDiamond); }
609 :
610 :
611 42 : void ApplyForwarding(TestCode& code, int size, int* forward) {
612 : ZoneVector<RpoNumber> vector(code.main_zone());
613 228 : for (int i = 0; i < size; i++) {
614 372 : vector.push_back(RpoNumber::FromInt(forward[i]));
615 : }
616 42 : JumpThreading::ApplyForwarding(vector, &code.sequence_);
617 42 : }
618 :
619 :
620 72 : void CheckJump(TestCode& code, int pos, int target) {
621 72 : Instruction* instr = code.sequence_.InstructionAt(pos);
622 72 : CHECK_EQ(kArchJmp, instr->arch_opcode());
623 72 : CHECK_EQ(1, static_cast<int>(instr->InputCount()));
624 72 : CHECK_EQ(0, static_cast<int>(instr->OutputCount()));
625 72 : CHECK_EQ(0, static_cast<int>(instr->TempCount()));
626 144 : CHECK_EQ(target, code.sequence_.InputRpo(instr, 0).ToInt());
627 72 : }
628 :
629 :
630 42 : void CheckNop(TestCode& code, int pos) {
631 42 : Instruction* instr = code.sequence_.InstructionAt(pos);
632 42 : CHECK_EQ(kArchNop, instr->arch_opcode());
633 42 : CHECK_EQ(0, static_cast<int>(instr->InputCount()));
634 42 : CHECK_EQ(0, static_cast<int>(instr->OutputCount()));
635 42 : CHECK_EQ(0, static_cast<int>(instr->TempCount()));
636 42 : }
637 :
638 :
639 24 : void CheckBranch(TestCode& code, int pos, int t1, int t2) {
640 24 : Instruction* instr = code.sequence_.InstructionAt(pos);
641 24 : CHECK_EQ(2, static_cast<int>(instr->InputCount()));
642 24 : CHECK_EQ(0, static_cast<int>(instr->OutputCount()));
643 24 : CHECK_EQ(0, static_cast<int>(instr->TempCount()));
644 48 : CHECK_EQ(t1, code.sequence_.InputRpo(instr, 0).ToInt());
645 48 : CHECK_EQ(t2, code.sequence_.InputRpo(instr, 1).ToInt());
646 24 : }
647 :
648 :
649 42 : void CheckAssemblyOrder(TestCode& code, int size, int* expected) {
650 : int i = 0;
651 270 : for (auto const block : code.sequence_.instruction_blocks()) {
652 186 : CHECK_EQ(expected[i++], block->ao_number().ToInt());
653 : }
654 42 : }
655 :
656 :
657 23724 : TEST(Rewire1) {
658 6 : TestCode code;
659 :
660 : // B0
661 6 : int j1 = code.Jump(1);
662 : // B1
663 6 : int j2 = code.Jump(2);
664 : // B2
665 6 : code.End();
666 :
667 : static int forward[] = {2, 2, 2};
668 6 : ApplyForwarding(code, 3, forward);
669 6 : CheckJump(code, j1, 2);
670 6 : CheckNop(code, j2);
671 :
672 : static int assembly[] = {0, 1, 1};
673 6 : CheckAssemblyOrder(code, 3, assembly);
674 6 : }
675 :
676 :
677 23724 : TEST(Rewire1_deferred) {
678 6 : TestCode code;
679 :
680 : // B0
681 6 : int j1 = code.Jump(1);
682 : // B1
683 6 : int j2 = code.Jump(2);
684 : // B2
685 6 : code.Defer();
686 6 : int j3 = code.Jump(3);
687 : // B3
688 6 : code.End();
689 :
690 : static int forward[] = {3, 3, 3, 3};
691 6 : ApplyForwarding(code, 4, forward);
692 6 : CheckJump(code, j1, 3);
693 6 : CheckNop(code, j2);
694 6 : CheckNop(code, j3);
695 :
696 : static int assembly[] = {0, 1, 2, 1};
697 6 : CheckAssemblyOrder(code, 4, assembly);
698 6 : }
699 :
700 :
701 23724 : TEST(Rewire2_deferred) {
702 6 : TestCode code;
703 :
704 : // B0
705 6 : code.Other();
706 6 : int j1 = code.Jump(1);
707 : // B1
708 6 : code.Defer();
709 : code.Fallthru();
710 : // B2
711 6 : code.Defer();
712 6 : int j2 = code.Jump(3);
713 : // B3
714 6 : code.End();
715 :
716 : static int forward[] = {0, 1, 2, 3};
717 6 : ApplyForwarding(code, 4, forward);
718 6 : CheckJump(code, j1, 1);
719 6 : CheckJump(code, j2, 3);
720 :
721 : static int assembly[] = {0, 2, 3, 1};
722 6 : CheckAssemblyOrder(code, 4, assembly);
723 6 : }
724 :
725 :
726 23724 : TEST(Rewire_diamond) {
727 18 : for (int i = 0; i < 2; i++) {
728 24 : for (int j = 0; j < 2; j++) {
729 24 : TestCode code;
730 : // B0
731 24 : int j1 = code.Jump(1);
732 : // B1
733 24 : int b1 = code.Branch(2, 3);
734 : // B2
735 24 : int j2 = code.Jump(4);
736 : // B3
737 24 : int j3 = code.Jump(4);
738 : // B5
739 24 : code.End();
740 :
741 24 : int forward[] = {0, 1, i ? 4 : 2, j ? 4 : 3, 4};
742 24 : ApplyForwarding(code, 5, forward);
743 24 : CheckJump(code, j1, 1);
744 24 : CheckBranch(code, b1, i ? 4 : 2, j ? 4 : 3);
745 24 : if (i) {
746 12 : CheckNop(code, j2);
747 : } else {
748 12 : CheckJump(code, j2, 4);
749 : }
750 24 : if (j) {
751 12 : CheckNop(code, j3);
752 : } else {
753 12 : CheckJump(code, j3, 4);
754 : }
755 :
756 24 : int assembly[] = {0, 1, 2, 3, 4};
757 24 : if (i) {
758 24 : for (int k = 3; k < 5; k++) assembly[k]--;
759 : }
760 24 : if (j) {
761 12 : for (int k = 4; k < 5; k++) assembly[k]--;
762 : }
763 24 : CheckAssemblyOrder(code, 5, assembly);
764 : }
765 : }
766 6 : }
767 :
768 : } // namespace compiler
769 : } // namespace internal
770 71154 : } // namespace v8
|