()
| 2666 | |
| 2667 | #[test] |
| 2668 | fn test_island() { |
| 2669 | let info = emit_info(); |
| 2670 | let mut buf = MachBuffer::new(); |
| 2671 | let mut state = <Inst as MachInstEmit>::State::default(); |
| 2672 | let constants = Default::default(); |
| 2673 | |
| 2674 | buf.reserve_labels_for_blocks(4); |
| 2675 | |
| 2676 | buf.bind_label(label(0), state.ctrl_plane_mut()); |
| 2677 | let inst = Inst::CondBr { |
| 2678 | kind: CondBrKind::NotZero(xreg(0), OperandSize::Size64), |
| 2679 | taken: target(2), |
| 2680 | not_taken: target(3), |
| 2681 | }; |
| 2682 | inst.emit(&mut buf, &info, &mut state); |
| 2683 | |
| 2684 | buf.bind_label(label(1), state.ctrl_plane_mut()); |
| 2685 | while buf.cur_offset() < 2000000 { |
| 2686 | if buf.island_needed(0) { |
| 2687 | buf.emit_island(0, state.ctrl_plane_mut()); |
| 2688 | } |
| 2689 | let inst = Inst::Nop4; |
| 2690 | inst.emit(&mut buf, &info, &mut state); |
| 2691 | } |
| 2692 | |
| 2693 | buf.bind_label(label(2), state.ctrl_plane_mut()); |
| 2694 | let inst = Inst::Nop4; |
| 2695 | inst.emit(&mut buf, &info, &mut state); |
| 2696 | |
| 2697 | buf.bind_label(label(3), state.ctrl_plane_mut()); |
| 2698 | let inst = Inst::Nop4; |
| 2699 | inst.emit(&mut buf, &info, &mut state); |
| 2700 | |
| 2701 | let buf = buf.finish(&constants, state.ctrl_plane_mut()); |
| 2702 | |
| 2703 | assert_eq!(2000000 + 8, buf.total_size()); |
| 2704 | |
| 2705 | let mut buf2 = MachBuffer::new(); |
| 2706 | let mut state = Default::default(); |
| 2707 | let inst = Inst::CondBr { |
| 2708 | kind: CondBrKind::NotZero(xreg(0), OperandSize::Size64), |
| 2709 | |
| 2710 | // This conditionally taken branch has a 19-bit constant, shifted |
| 2711 | // to the left by two, giving us a 21-bit range in total. Half of |
| 2712 | // this range positive so the we should be around 1 << 20 bytes |
| 2713 | // away for our jump target. |
| 2714 | // |
| 2715 | // There are two pending fixups by the time we reach this point, |
| 2716 | // one for this 19-bit jump and one for the unconditional 26-bit |
| 2717 | // jump below. A 19-bit veneer is 4 bytes large and the 26-bit |
| 2718 | // veneer is 20 bytes large, which means that pessimistically |
| 2719 | // assuming we'll need two veneers. Currently each veneer is |
| 2720 | // pessimistically assumed to be the maximal size which means we |
| 2721 | // need 40 bytes of extra space, meaning that the actual island |
| 2722 | // should come 40-bytes before the deadline. |
| 2723 | taken: BranchTarget::ResolvedOffset((1 << 20) - 20 - 20), |
| 2724 | |
| 2725 | // This branch is in-range so no veneers should be needed, it should |
nothing calls this directly
no test coverage detected