@@ -1580,6 +1580,59 @@ gen_branchunless(jitstate_t* jit, ctx_t* ctx)
15801580 return YJIT_END_BLOCK ;
15811581}
15821582
1583+ void
1584+ gen_branchnil_branch (codeblock_t * cb , uint8_t * target0 , uint8_t * target1 , uint8_t shape )
1585+ {
1586+ switch (shape )
1587+ {
1588+ case SHAPE_NEXT0 :
1589+ jne_ptr (cb , target1 );
1590+ break ;
1591+
1592+ case SHAPE_NEXT1 :
1593+ je_ptr (cb , target0 );
1594+ break ;
1595+
1596+ case SHAPE_DEFAULT :
1597+ je_ptr (cb , target0 );
1598+ jmp_ptr (cb , target1 );
1599+ break ;
1600+ }
1601+ }
1602+
1603+ static codegen_status_t
1604+ gen_branchnil (jitstate_t * jit , ctx_t * ctx )
1605+ {
1606+ // FIXME: eventually, put VM_CHECK_INTS() only on backward branch targets
1607+ // Check for interrupts
1608+ uint8_t * side_exit = yjit_side_exit (jit , ctx );
1609+ yjit_check_ints (cb , side_exit );
1610+
1611+ // Test if the value is Qnil
1612+ // RUBY_Qnil /* ...0000 1000 */
1613+ x86opnd_t val_opnd = ctx_stack_pop (ctx , 1 );
1614+ cmp (cb , val_opnd , imm_opnd (Qnil ));
1615+
1616+ // Get the branch target instruction offsets
1617+ uint32_t next_idx = jit_next_insn_idx (jit );
1618+ uint32_t jump_idx = next_idx + (uint32_t )jit_get_arg (jit , 0 );
1619+ blockid_t next_block = { jit -> iseq , next_idx };
1620+ blockid_t jump_block = { jit -> iseq , jump_idx };
1621+
1622+ // Generate the branch instructions
1623+ gen_branch (
1624+ jit -> block ,
1625+ ctx ,
1626+ jump_block ,
1627+ ctx ,
1628+ next_block ,
1629+ ctx ,
1630+ gen_branchnil_branch
1631+ );
1632+
1633+ return YJIT_END_BLOCK ;
1634+ }
1635+
15831636static codegen_status_t
15841637gen_jump (jitstate_t * jit , ctx_t * ctx )
15851638{
@@ -2407,6 +2460,7 @@ yjit_init_codegen(void)
24072460 yjit_reg_op (BIN (opt_getinlinecache ), gen_opt_getinlinecache );
24082461 yjit_reg_op (BIN (branchif ), gen_branchif );
24092462 yjit_reg_op (BIN (branchunless ), gen_branchunless );
2463+ yjit_reg_op (BIN (branchnil ), gen_branchnil );
24102464 yjit_reg_op (BIN (jump ), gen_jump );
24112465 yjit_reg_op (BIN (opt_send_without_block ), gen_opt_send_without_block );
24122466 yjit_reg_op (BIN (send ), gen_send );
0 commit comments