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