@@ -1580,6 +1580,59 @@ gen_branchunless(jitstate_t* jit, ctx_t* ctx)
1580
1580
return YJIT_END_BLOCK ;
1581
1581
}
1582
1582
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
10000
+ 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
+
1583
1636
static codegen_status_t
1584
1637
gen_jump (jitstate_t * jit , ctx_t * ctx )
1585
1638
{
@@ -2407,6 +2460,7 @@ yjit_init_codegen(void)
2407
2460
yjit_reg_op (BIN (opt_getinlinecache ), gen_opt_getinlinecache );
2408
2461
yjit_reg_op (BIN (branchif ), gen_branchif );
2409
2462
yjit_reg_op (BIN (branchunless ), gen_branchunless );
2463
+ yjit_reg_op (BIN (branchnil ), gen_branchnil );
2410
2464
yjit_reg_op (BIN (jump ), gen_jump );
2411
2465
yjit_reg_op (BIN (opt_send_without_block ), gen_opt_send_without_block );
2412
2466
yjit_reg_op (BIN (send ), gen_send );
0 commit comments