diff options
Diffstat (limited to 'erts/emulator/beam/jit/x86/ops.tab')
-rw-r--r-- | erts/emulator/beam/jit/x86/ops.tab | 153 |
1 files changed, 113 insertions, 40 deletions
diff --git a/erts/emulator/beam/jit/x86/ops.tab b/erts/emulator/beam/jit/x86/ops.tab index 99cd96ac8b..ef57021d83 100644 --- a/erts/emulator/beam/jit/x86/ops.tab +++ b/erts/emulator/beam/jit/x86/ops.tab @@ -81,7 +81,7 @@ nif_start i_generic_breakpoint i_debug_breakpoint -i_return_time_trace +i_call_trace_return i_return_to_trace trace_jump W i_yield @@ -314,6 +314,14 @@ current_tuple Tuple Dst => current_tuple Tuple i_get_tuple_element s P S get_two_tuple_elements s P S S +i_get_tuple_element Tuple Pos Dst | swap Reg1 Reg2 | equal(Dst, Reg1) => + get_tuple_element_swap Tuple Pos Dst Reg2 + +i_get_tuple_element Tuple Pos Dst | swap Reg2 Reg1 | equal(Dst, Reg1) => + get_tuple_element_swap Tuple Pos Dst Reg2 + +get_tuple_element_swap s P d d + # # Exception raising instructions. Infrequently executed. # @@ -427,21 +435,48 @@ is_eq_exact Lbl LHS RHS | equal(LHS, RHS) => _ is_eq_exact Lbl C=c R=xy => is_eq_exact Lbl R C is_eq_exact Lbl R=xy n => is_nil Lbl R -is_eq_exact Lbl R=xy C=q => is_eq_exact_literal(Lbl, R, C) is_ne_exact Lbl LHS RHS | equal(LHS, RHS) => jump Lbl is_ne_exact Lbl C=c R=xy => is_ne_exact Lbl R C -is_ne_exact Lbl R=xy C=q => i_is_ne_exact_literal Lbl R C +is_eq_exact f s s -i_is_eq_exact_literal/4 -i_is_eq_exact_literal f s c I +is_ne_exact f s s -i_is_ne_exact_literal f s c +is_integer NotInt N0 | is_ge Small N1=xy Min=i | is_ge Large Max=i N2=xy | + equal(N0, N1) | equal(N1, N2) | + equal(NotInt, Small) | equal(Small, Large) => + is_int_in_range NotInt N0 Min Max -is_eq_exact f s s +is_integer NotInt N0 | is_ge Large Max=i N2=xy | is_ge Small N1=xy Min=i | + equal(N0, N1) | equal(N1, N2) | + equal(NotInt, Small) | equal(Small, Large) => + is_int_in_range NotInt N0 Min Max -is_ne_exact f s s +is_integer NotInt N0 | is_ge Fail N1=xy Min=i | + equal(N0, N1) | equal(NotInt, Fail) => + is_int_ge NotInt N0 Min + +is_int_in_range f S c c +is_int_ge f S c + +is_ge Small N1=xy Min=i | is_ge Large Max=i N2=xy | equal(N1, N2) => + is_in_range Small Large N1 Min Max + +is_ge Large Max=i N2=xy | is_ge Small N1=xy Min=i | equal(N1, N2) => + is_in_range Small Large N2 Min Max + +is_in_range f f S c c + +is_ge Small N1=xy A=i | is_lt Large B=i N2=xy | equal(N1, N2) => + is_ge_lt Small Large N1 A B + +is_ge_lt f f S c c + +is_ge Fail1 N1=xy A=i | is_ge Fail2 N2=xy B=i | equal(N1, N2) => + is_ge_ge Fail1 Fail2 N1 A B + +is_ge_ge f f S c c is_lt f s s is_ge f s s @@ -675,6 +710,36 @@ bif1 Fail Bif=u$bif:erlang:get/1 Src=s Dst=d => get(Src, Dst) bif2 Fail u$bif:erlang:element/2 S1=ixy S2 Dst => bif_element Fail S1 S2 Dst bif_element j s s d +bif1 Fail Bif=u$bif:erlang:node/1 Src=d Dst=d => bif_node Fail Src Dst +bif_node j S d + +gc_bif1 Fail Live Bif=u$bif:erlang:bit_size/1 Src Dst=d => + bif_bit_size Bif Fail Src Dst +bif_bit_size b j s d + +gc_bif1 Fail Live Bif=u$bif:erlang:byte_size/1 Src Dst=d => + bif_byte_size Bif Fail Src Dst +bif_byte_size b j s d + +bif1 Fail Bif=u$bif:erlang:tuple_size/1 Src=d Dst=d => + bif_tuple_size Bif Fail Src Dst +bif_tuple_size b j S d + +bif2 Fail Bif=u$bif:erlang:map_get/2 Src1 Src2=xy Dst=d => + bif_map_get Fail Src1 Src2 Dst +bif_map_get j s s d + +bif2 Fail Bif=u$bif:erlang:is_map_key/2 Key Map=xy Dst=d => + bif_is_map_key Bif Fail Key Map Dst +bif_is_map_key b j s s d + +bif2 Fail Bif=u$bif:erlang:max/2 Src1 Src2 Dst => + bif_max Src1 Src2 Dst +bif2 Fail Bif=u$bif:erlang:min/2 Src1 Src2 Dst => + bif_min Src1 Src2 Dst +bif_max s s d +bif_min s s d + bif1 Fail Bif S1 Dst | never_fails(Bif) => nofail_bif1 S1 Bif Dst bif2 Fail Bif S1 S2 Dst | never_fails(Bif) => nofail_bif2 S1 S2 Bif Dst @@ -683,6 +748,8 @@ bif2 Fail Bif S1 S2 Dst => i_bif2 S1 S2 Fail Bif Dst nofail_bif2 S1=d S2 Bif Dst | is_eq_exact_bif(Bif) => bif_is_eq_exact S1 S2 Dst nofail_bif2 S1=d S2 Bif Dst | is_ne_exact_bif(Bif) => bif_is_ne_exact S1 S2 Dst +nofail_bif2 S1 S2 Bif Dst | is_ge_bif(Bif) => bif_is_ge S1 S2 Dst +nofail_bif2 S1 S2 Bif Dst | is_lt_bif(Bif) => bif_is_lt S1 S2 Dst i_get_hash c I d i_get s d @@ -700,6 +767,8 @@ i_bif3 s s s j b d bif_is_eq_exact S s d bif_is_ne_exact S s d +bif_is_ge s s d +bif_is_lt s s d # # Internal calls. @@ -810,26 +879,38 @@ i_lambda_trampoline F f W W i_breakpoint_trampoline # ================================================================ -# New bit syntax matching (R11B). +# New bit syntax matching for fixed sizes (from OTP 26). +# ================================================================ + +bs_match Fail Ctx Size Rest=* => bs_match(Fail, Ctx, Size, Rest) + +i_bs_match Fail Ctx Rest=* | test_heap Need Live => + i_bs_match_test_heap Fail Ctx Need Live Rest + +i_bs_match f S * +i_bs_match_test_heap f S I t * + +# +# The following instruction is specially handled in beam_load.c +# to produce a user-friendly message if a bad bs_match instruction +# is encountered. +# +bad_bs_match/1 +bad_bs_match A | never() => _ + +# ================================================================ +# Bit syntax matching (from R11B). # ================================================================ %warm -# Matching integers +# Matching integers. bs_match_string Fail Ms Bits Val => i_bs_match_string Ms Fail Bits Val i_bs_match_string S f W M # Fetching integers from binaries. -bs_get_integer2 Fail=f Ms=xy Live=u Sz=sq Unit=u Flags=u Dst=d => - get_integer2(Fail, Ms, Live, Sz, Unit, Flags, Dst) - -i_bs_get_integer S f t t s d - -i_bs_get_integer_8 S t f d -i_bs_get_integer_16 S t f d -i_bs_get_integer_32 S t f d -i_bs_get_integer_64 S t f t d +bs_get_integer2 f S t s t t d # Fetching binaries from binaries. bs_get_binary2 Fail=f Ms=xy Live=u Sz=sq Unit=u Flags=u Dst=d => @@ -1186,28 +1267,9 @@ gc_bif2 Fail Live u$bif:erlang:sminus/2 S1 S2 Dst => gen_minus Fail Live S1 S2 Dst # -# Optimize addition and subtraction of small literals using -# the i_increment/3 instruction (in bodies, not in guards). -# - -gen_plus p Live Int=i Reg=d Dst => - increment(Reg, Int, Dst) -gen_plus p Live Reg=d Int=i Dst => - increment(Reg, Int, Dst) - -gen_minus p Live Reg=d Int=i Dst | negation_is_small(Int) => - increment_from_minus(Reg, Int, Dst) - -# # Arithmetic instructions. # -# It is OK to swap arguments for '+' in a guard. It is also -# OK to turn minus into plus in a guard. -gen_plus Fail=f Live S1=c S2 Dst => i_plus S2 S1 Fail Dst -gen_minus Fail=f Live S1 S2=i Dst | negation_is_small(S2) => - plus_from_minus(Fail, Live, S1, S2, Dst) - gen_plus Fail Live S1 S2 Dst => i_plus S1 S2 Fail Dst gen_minus Fail Live S1 S2 Dst => i_minus S1 S2 Fail Dst @@ -1278,8 +1340,6 @@ gc_bif2 Fail Live u$bif:erlang:bxor/2 S1 S2 Dst => gc_bif1 Fail Live u$bif:erlang:bnot/1 Src Dst => i_bnot Fail Src Dst -i_increment S W d - i_plus s s j d i_minus s s j d @@ -1324,6 +1384,13 @@ i_length_setup j t s i_length j t d # +# Specialized guard BIFs. +# + +gc_bif1 Fail Live Bif=u$bif:erlang:map_size/1 Src Dst=d => bif_map_size Fail Src Dst +bif_map_size j s d + +# # Guard BIFs. # gc_bif1 Fail Live Bif Src Dst => i_bif1 Src Fail Bif Dst @@ -1380,3 +1447,9 @@ recv_marker_reserve S recv_marker_bind S S recv_marker_clear S recv_marker_use S + +# +# OTP 26 +# + +update_record a I s d I * |