From 1f34acbd216a2775c46f2c46c38d657c4d9d0d79 Mon Sep 17 00:00:00 2001 From: pcpa Date: 2022年5月12日 13:52:10 -0300 Subject: Add basic infrastructure for conditional instructions This basic logic is for support for the patterns: cmovnr r0 r1 r2 that would mean in C: r0 = r2 ? r1 : r0 and cmovzr r0 r1 r3 that would mean in C: r0 = r2 ? r0 : r1 The fallback, where conditional moves are not available would be in the pattern: jit_mode_t b = jit_beqi(r2, 0); \ jit_movr(r0, r1); \ jit_patch(b); } while (0) jit_mode_t b = jit_bnei(r2, 0); \ jit_movr(r0, r1); \ jit_patch(b); } while (0) Note that the new jit_cc_a0_cnd flag must be used, so, an entry like this should be added for jit_classify: case jit_code_cmovnr: case jit_code_cmovzr: mask = jit_cc_a0_reg|jit_cc_a0_cnd|jit_cc_a1_reg; break; ***Must*** not set jit_cc_a0_chg, otherwise basically all places check is done for jit_cc_a0_chg must validate it is also does not have jit_cc_a0_cnd set. An explanation for this is, suppose this sequence: andi r0, r1, 1 (r2 not used) "" "" "" cmovnr r2, r1, r0 it would only set r2 to r1 if r0 is nonzero. What happens here is that we need lightning internals to understand r2 is live at least from on wards, but, we must also let the internals understand it is not dead from to , as it is not guaranteed it will be modified; thus, cannot be used as cheap temporary in the to range. Obviously, can still be used as a temporary if out of registers, but need a spill/reload. Note that calling it cmovnr of movnr or cmvnr is just cosmetic. In case a large pattern of conditional moves is added, the "c" prefix could be more self descriptive. --- lib/lightning.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/lightning.c b/lib/lightning.c index 22eca0c..0ed663d 100644 --- a/lib/lightning.c +++ b/lib/lightning.c @@ -3303,7 +3303,7 @@ _register_change_p(jit_state_t *_jit, jit_node_t *node, jit_node_t *link, default: value = jit_classify(node->code); /* lack of extra information */ - if (value & jit_cc_a0_jmp) + if (value & (jit_cc_a0_jmp|jit_cc_a0_cnd)) return (jit_reg_change); else if ((value & (jit_cc_a0_reg|jit_cc_a0_chg)) == (jit_cc_a0_reg|jit_cc_a0_chg) && -- cgit v1.2.3

AltStyle によって変換されたページ (->オリジナル) /