finish_assembler_test();
END_TEST
+
+BEGIN_TEST(assembler.long_jump.unconditional_forwards)
+ if (!setup_cs(NULL, (chip_class)GFX10))
+ return;
+
+ //!BB0:
+ //! s_getpc_b64 s[0:1] ; be801f00
+ //! s_addc_u32 s0, s0, 0x20018 ; 8200ff00 00020018
+ //! s_addc_u32 s1, s1, 0 ; 82018001
+ //! s_bitcmp1_b32 s0, 0 ; bf0d8000
+ //! s_bitset0_b32 s0, 0 ; be801b80
+ //! s_setpc_b64 s[0:1] ; be802000
+ bld.sopp(aco_opcode::s_branch, Definition(PhysReg(0), s2), 2);
+
+ bld.reset(program->create_and_insert_block());
+
+ //! s_nop 0 ; bf800000
+ //!(then repeated 32767 times)
+ for (unsigned i = 0; i < INT16_MAX + 1; i++)
+ bld.sopp(aco_opcode::s_nop, -1, 0);
+
+ //! BB2:
+ //! s_endpgm ; bf810000
+ bld.reset(program->create_and_insert_block());
+
+ program->blocks[2].linear_preds.push_back(0u);
+ program->blocks[2].linear_preds.push_back(1u);
+
+ finish_assembler_test();
+END_TEST
+
+BEGIN_TEST(assembler.long_jump.conditional_forwards)
+ if (!setup_cs(NULL, (chip_class)GFX10))
+ return;
+
+ //! BB0:
+ //! s_cbranch_scc1 BB1 ; bf850007
+ //! s_getpc_b64 s[0:1] ; be801f00
+ //! s_addc_u32 s0, s0, 0x20018 ; 8200ff00 00020018
+ //! s_addc_u32 s1, s1, 0 ; 82018001
+ //! s_bitcmp1_b32 s0, 0 ; bf0d8000
+ //! s_bitset0_b32 s0, 0 ; be801b80
+ //! s_setpc_b64 s[0:1] ; be802000
+ bld.sopp(aco_opcode::s_cbranch_scc0, Definition(PhysReg(0), s2), 2);
+
+ bld.reset(program->create_and_insert_block());
+
+ //! BB1:
+ //! s_nop 0 ; bf800000
+ //!(then repeated 32767 times)
+ for (unsigned i = 0; i < INT16_MAX + 1; i++)
+ bld.sopp(aco_opcode::s_nop, -1, 0);
+
+ //! BB2:
+ //! s_endpgm ; bf810000
+ bld.reset(program->create_and_insert_block());
+
+ program->blocks[1].linear_preds.push_back(0u);
+ program->blocks[2].linear_preds.push_back(0u);
+ program->blocks[2].linear_preds.push_back(1u);
+
+ finish_assembler_test();
+END_TEST
+
+BEGIN_TEST(assembler.long_jump.unconditional_backwards)
+ if (!setup_cs(NULL, (chip_class)GFX10))
+ return;
+
+ //!BB0:
+ //! s_nop 0 ; bf800000
+ //!(then repeated 32767 times)
+ for (unsigned i = 0; i < INT16_MAX + 1; i++)
+ bld.sopp(aco_opcode::s_nop, -1, 0);
+
+ //! s_getpc_b64 s[0:1] ; be801f00
+ //! s_addc_u32 s0, s0, 0xfffdfffc ; 8200ff00 fffdfffc
+ //! s_addc_u32 s1, s1, -1 ; 8201c101
+ //! s_bitcmp1_b32 s0, 0 ; bf0d8000
+ //! s_bitset0_b32 s0, 0 ; be801b80
+ //! s_setpc_b64 s[0:1] ; be802000
+ bld.sopp(aco_opcode::s_branch, Definition(PhysReg(0), s2), 0);
+
+ //! BB1:
+ //! s_endpgm ; bf810000
+ bld.reset(program->create_and_insert_block());
+
+ program->blocks[0].linear_preds.push_back(0u);
+ program->blocks[1].linear_preds.push_back(0u);
+
+ finish_assembler_test();
+END_TEST
+
+BEGIN_TEST(assembler.long_jump.conditional_backwards)
+ if (!setup_cs(NULL, (chip_class)GFX10))
+ return;
+
+ //!BB0:
+ //! s_nop 0 ; bf800000
+ //!(then repeated 32767 times)
+ for (unsigned i = 0; i < INT16_MAX + 1; i++)
+ bld.sopp(aco_opcode::s_nop, -1, 0);
+
+ //! s_cbranch_execz BB1 ; bf880007
+ //! s_getpc_b64 s[0:1] ; be801f00
+ //! s_addc_u32 s0, s0, 0xfffdfff8 ; 8200ff00 fffdfff8
+ //! s_addc_u32 s1, s1, -1 ; 8201c101
+ //! s_bitcmp1_b32 s0, 0 ; bf0d8000
+ //! s_bitset0_b32 s0, 0 ; be801b80
+ //! s_setpc_b64 s[0:1] ; be802000
+ bld.sopp(aco_opcode::s_cbranch_execnz, Definition(PhysReg(0), s2), 0);
+
+ //! BB1:
+ //! s_endpgm ; bf810000
+ bld.reset(program->create_and_insert_block());
+
+ program->blocks[0].linear_preds.push_back(0u);
+ program->blocks[1].linear_preds.push_back(0u);
+
+ finish_assembler_test();
+END_TEST
+
+BEGIN_TEST(assembler.long_jump.3f)
+ if (!setup_cs(NULL, (chip_class)GFX10))
+ return;
+
+ //! BB0:
+ //! s_branch BB1 ; bf820040
+ //! s_nop 0 ; bf800000
+ bld.sopp(aco_opcode::s_branch, Definition(PhysReg(0), s2), 1);
+
+ for (unsigned i = 0; i < 0x3f - 7; i++) // a unconditional long jump is 7 dwords
+ bld.vop1(aco_opcode::v_nop);
+ bld.sopp(aco_opcode::s_branch, Definition(PhysReg(0), s2), 2);
+
+ bld.reset(program->create_and_insert_block());
+ for (unsigned i = 0; i < INT16_MAX + 1; i++)
+ bld.vop1(aco_opcode::v_nop);
+ bld.reset(program->create_and_insert_block());
+
+ program->blocks[1].linear_preds.push_back(0u);
+ program->blocks[2].linear_preds.push_back(0u);
+ program->blocks[2].linear_preds.push_back(1u);
+
+ finish_assembler_test();
+END_TEST
+
+BEGIN_TEST(assembler.long_jump.constaddr)
+ if (!setup_cs(NULL, (chip_class)GFX10))
+ return;
+
+ //>> s_getpc_b64 s[0:1] ; be801f00
+ bld.sopp(aco_opcode::s_branch, Definition(PhysReg(0), s2), 2);
+
+ bld.reset(program->create_and_insert_block());
+
+ for (unsigned i = 0; i < INT16_MAX + 1; i++)
+ bld.sopp(aco_opcode::s_nop, -1, 0);
+
+ bld.reset(program->create_and_insert_block());
+
+ //>> s_getpc_b64 s[0:1] ; be801f00
+ //! s_add_u32 s0, s0, 0xe0 ; 8000ff00 000000e0
+ bld.sop1(aco_opcode::p_constaddr, Definition(PhysReg(0), s2), Operand(0u));
+
+ program->blocks[2].linear_preds.push_back(0u);
+ program->blocks[2].linear_preds.push_back(1u);
+
+ finish_assembler_test();
+END_TEST