<commit_before>#
# %CopyrightBegin%
#
# Copyright Ericsson AB 1997-2010. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
#
# %CopyrightEnd%
#

#
# The instructions that follows are only known by the loader and the emulator.
# They can be changed without recompiling old Beam files.
#
# Instructions starting with a "i_" prefix are instructions produced by
# instruction transformations; thus, they never occur in BEAM files.
#

# Special instruction used to generate an error message when
# trying to load a module compiled by the V1 compiler (R5 & R6).
# (Specially treated in beam_load.c.)

too_old_compiler/0
too_old_compiler

#
# Obsolete instruction usage follow. (Nowdays we use f with
# a zero label instead of p.)
#

is_list p S => too_old_compiler
is_nonempty_list p R => too_old_compiler
is_nil p R => too_old_compiler

is_tuple p S => too_old_compiler
test_arity p S Arity => too_old_compiler

is_integer p R => too_old_compiler
is_float p R => too_old_compiler
is_atom p R => too_old_compiler

is_eq_exact p S1 S2 => too_old_compiler

# In R9C and earlier, the loader used to insert special instructions inside
# the module_info/0,1 functions. (In R10B and later, the compiler inserts
# an explicit call to an undocumented BIF, so that no loader trickery is
# necessary.) Since the instructions don't work correctly in R12B, simply
# refuse to load the module.

func_info M=a a==am_module_info A=u==0 | label L | move n r => too_old_compiler
func_info M=a a==am_module_info A=u==1 | label L | move n r => too_old_compiler

# The undocumented and unsupported guard BIF is_constant/1 was removed
# in R13. The is_constant/2 operation is marked as obsolete in genop.tab,
# so the loader will automatically generate a too_old_compiler message
# it is used, but we need to handle the is_constant/1 BIF specially here.

bif1 Fail u$func:erlang:is_constant/1 Src Dst => too_old_compiler

# Since the constant pool was introduced in R12B, empty tuples ({})
# are literals. Therefore we no longer need to allow put_tuple/2
# with a tuple size of zero.

put_tuple u==0 d => too_old_compiler

#
# All the other instructions.
#

label L
i_func_info I a a I
int_code_end

i_trace_breakpoint
i_mtrace_breakpoint
i_debug_breakpoint
i_count_breakpoint
i_time_breakpoint
i_return_time_trace
i_return_to_trace
i_yield
i_global_cons
i_global_tuple
i_global_copy

return

%macro: allocate Allocate -pack
%macro: allocate_zero AllocateZero -pack
%macro: allocate_heap AllocateHeap -pack
%macro: allocate_heap_zero AllocateHeapZero -pack
%macro: test_heap TestHeap -pack

allocate t t
allocate_heap t I t
deallocate I
init y
allocate_zero t t
allocate_heap_zero t I t

trim N Remaining => i_trim N
i_trim I

test_heap I t

allocate_heap S u==0 R => allocate S R
allocate_heap_zero S u==0 R => allocate_zero S R

init2 y y
init3 y y y
init Y1 | init Y2 | init Y3 => init3 Y1 Y2 Y3
init Y1 | init Y2 => init2 Y1 Y2
%macro: init2 Init2 -pack
%macro: init3 Init3 -pack

# Selecting values

select_val S=aiq Fail=f Size=u Rest=* => const_select_val(S, Fail, Size, Rest)

select_val S=s Fail=f Size=u Rest=* | use_jump_tab(Size, Rest) => \
  gen_jump_tab(S, Fail, Size, Rest)

is_integer Fail=f S | select_val S=s Fail=f Size=u Rest=* | use_jump_tab(Size, Rest) => \
  gen_jump_tab(S, Fail, Size, Rest)

is_integer TypeFail=f S | select_val S=s Fail=f Size=u Rest=* | \
	   mixed_types(Size, Rest) => \
  gen_split_values(S, TypeFail, Fail, Size, Rest)

select_val S=s Fail=f Size=u Rest=* | mixed_types(Size, Rest) => \
  gen_split_values(S, Fail, Fail, Size, Rest)

is_integer Fail=f S | select_val S=d Fail=f Size=u Rest=* | \
  fixed_size_values(Size, Rest) => gen_select_val(S, Fail, Size, Rest)

is_atom Fail=f S | select_val S=d Fail=f Size=u Rest=* | \
  fixed_size_values(Size, Rest) => gen_select_val(S, Fail, Size, Rest)

select_val S=s Fail=f Size=u Rest=* | floats_or_bignums(Size, Rest) => \
  gen_select_literals(S, Fail, Size, Rest)

select_val S=d Fail=f Size=u Rest=* | fixed_size_values(Size, Rest) => \
  gen_select_val(S, Fail, Size, Rest)

is_tuple Fail=f S | select_tuple_arity S=d Fail=f Size=u Rest=* => \
  gen_select_tuple_arity(S, Fail, Size, Rest)

select_tuple_arity S=d Fail=f Size=u Rest=* => \
  gen_select_tuple_arity(S, Fail, Size, Rest)

i_select_val r f I
i_select_val x f I
i_select_val y f I
i_select_tuple_arity r f I
i_select_tuple_arity x f I
i_select_tuple_arity y f I

i_jump_on_val_zero r f I
i_jump_on_val_zero x f I
i_jump_on_val_zero y f I

i_jump_on_val r f I I
i_jump_on_val x f I I
i_jump_on_val y f I I

jump Target | label Lbl | same_label(Target, Lbl) => label Lbl

is_ne_exact L1 S1 S2 | jump Fail | label L2 | same_label(L1, L2) => \
  is_eq_exact Fail S1 S2 | label L2

%macro: get_list GetList -pack
get_list x x x
get_list x x y
get_list x x r
get_list x y x
get_list x y y
get_list x y r
get_list x r x
get_list x r y

get_list y x x
get_list y x y
get_list y x r
get_list y y x
get_list y y y
get_list y y r
get_list y r x
get_list y r y

get_list r x x
get_list r x y
get_list r x r
get_list r y x
get_list r y y
get_list r y r
get_list r r x
get_list r r y

# Old-style catch.
catch y f
catch_end y

# Try/catch.
try Y F => catch Y F
try_case Y => try_end Y
try_end y

try_case_end Literal=q => move Literal x | try_case_end x
try_case_end s

# Destructive set tuple element

set_tuple_element Lit=q Tuple Pos => move Lit x | set_tuple_element x Tuple Pos
set_tuple_element s d P

# Get tuple element

%macro: i_get_tuple_element GetTupleElement -pack
i_get_tuple_element x P x
i_get_tuple_element r P x
i_get_tuple_element y P x
i_get_tuple_element x P r
i_get_tuple_element y P r

%cold
i_get_tuple_element r P r
i_get_tuple_element x P y
i_get_tuple_element r P y
i_get_tuple_element y P y
%hot

%macro: is_number IsNumber -fail_action
%cold
is_number f r
is_number f x
is_number f y
%hot
is_number Fail=f i =>
is_number Fail=f na => jump Fail
is_number Fail Literal=q => move Literal x | is_number Fail x

jump f

case_end Literal=cq => move Literal x | case_end x
badmatch Literal=cq => move Literal x | badmatch x

case_end r
case_end x
case_end y

badmatch r
badmatch x
badmatch y

if_end
raise s s

# Internal now, but could be useful to make known to the compiler.
badarg j
system_limit j

move R R =>

move X1=x Y1=y | move X2=x Y2=y => move2 X1 Y1 X2 Y2
move Y1=y X1=x | move Y2=y X2=x => move2 Y1 X1 Y2 X2
move X1=x X2=x | move X3=x X4=x => move2 X1 X2 X3 X4

%macro: move2 Move2 -pack
move2 x y x y
move2 y x y x
move2 x x x x

%macro:move Move -pack -gen_dest
move x x
move x y
move x r
move y x
move y r
move r x
move r y
move c r
move c x
move c y
move n x
move n r
move y y

%cold
move s d
%hot

# Receive operations.

loop_rec Fail Src | smp_mark_target_label(Fail) => i_loop_rec Fail Src

label L | wait_timeout Fail Src | smp_already_locked(L) => label L | i_wait_timeout_locked Fail Src
wait_timeout Fail Src => i_wait_timeout Fail Src
i_wait_timeout Fail Src=aiq => gen_literal_timeout(Fail, Src)
i_wait_timeout_locked Fail Src=aiq => gen_literal_timeout_locked(Fail, Src)<commit_msg>Eliminate the specific move_sd instruction<commit_after>#
# %CopyrightBegin%
#
# Copyright Ericsson AB 1997-2010. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
#
# %CopyrightEnd%
#

#
# The instructions that follows are only known by the loader and the emulator.
# They can be changed without recompiling old Beam files.
#
# Instructions starting with a "i_" prefix are instructions produced by
# instruction transformations; thus, they never occur in BEAM files.
#

# Special instruction used to generate an error message when
# trying to load a module compiled by the V1 compiler (R5 & R6).
# (Specially treated in beam_load.c.)

too_old_compiler/0
too_old_compiler

#
# Obsolete instruction usage follow. (Nowdays we use f with
# a zero label instead of p.)
#

is_list p S => too_old_compiler
is_nonempty_list p R => too_old_compiler
is_nil p R => too_old_compiler

is_tuple p S => too_old_compiler
test_arity p S Arity => too_old_compiler

is_integer p R => too_old_compiler
is_float p R => too_old_compiler
is_atom p R => too_old_compiler

is_eq_exact p S1 S2 => too_old_compiler

# In R9C and earlier, the loader used to insert special instructions inside
# the module_info/0,1 functions. (In R10B and later, the compiler inserts
# an explicit call to an undocumented BIF, so that no loader trickery is
# necessary.) Since the instructions don't work correctly in R12B, simply
# refuse to load the module.

func_info M=a a==am_module_info A=u==0 | label L | move n r => too_old_compiler
func_info M=a a==am_module_info A=u==1 | label L | move n r => too_old_compiler

# The undocumented and unsupported guard BIF is_constant/1 was removed
# in R13. The is_constant/2 operation is marked as obsolete in genop.tab,
# so the loader will automatically generate a too_old_compiler message
# it is used, but we need to handle the is_constant/1 BIF specially here.

bif1 Fail u$func:erlang:is_constant/1 Src Dst => too_old_compiler

# Since the constant pool was introduced in R12B, empty tuples ({})
# are literals. Therefore we no longer need to allow put_tuple/2
# with a tuple size of zero.

put_tuple u==0 d => too_old_compiler

#
# All the other instructions.
#

label L
i_func_info I a a I
int_code_end

i_trace_breakpoint
i_mtrace_breakpoint
i_debug_breakpoint
i_count_breakpoint
i_time_breakpoint
i_return_time_trace
i_return_to_trace
i_yield
i_global_cons
i_global_tuple
i_global_copy

return

%macro: allocate Allocate -pack
%macro: allocate_zero AllocateZero -pack
%macro: allocate_heap AllocateHeap -pack
%macro: allocate_heap_zero AllocateHeapZero -pack
%macro: test_heap TestHeap -pack

allocate t t
allocate_heap t I t
deallocate I
init y
allocate_zero t t
allocate_heap_zero t I t

trim N Remaining => i_trim N
i_trim I

test_heap I t

allocate_heap S u==0 R => allocate S R
allocate_heap_zero S u==0 R => allocate_zero S R

init2 y y
init3 y y y
init Y1 | init Y2 | init Y3 => init3 Y1 Y2 Y3
init Y1 | init Y2 => init2 Y1 Y2
%macro: init2 Init2 -pack
%macro: init3 Init3 -pack

# Selecting values

select_val S=aiq Fail=f Size=u Rest=* => const_select_val(S, Fail, Size, Rest)

select_val S=s Fail=f Size=u Rest=* | use_jump_tab(Size, Rest) => \
  gen_jump_tab(S, Fail, Size, Rest)

is_integer Fail=f S | select_val S=s Fail=f Size=u Rest=* | use_jump_tab(Size, Rest) => \
  gen_jump_tab(S, Fail, Size, Rest)

is_integer TypeFail=f S | select_val S=s Fail=f Size=u Rest=* | \
	   mixed_types(Size, Rest) => \
  gen_split_values(S, TypeFail, Fail, Size, Rest)

select_val S=s Fail=f Size=u Rest=* | mixed_types(Size, Rest) => \
  gen_split_values(S, Fail, Fail, Size, Rest)

is_integer Fail=f S | select_val S=d Fail=f Size=u Rest=* | \
  fixed_size_values(Size, Rest) => gen_select_val(S, Fail, Size, Rest)

is_atom Fail=f S | select_val S=d Fail=f Size=u Rest=* | \
  fixed_size_values(Size, Rest) => gen_select_val(S, Fail, Size, Rest)

select_val S=s Fail=f Size=u Rest=* | floats_or_bignums(Size, Rest) => \
  gen_select_literals(S, Fail, Size, Rest)

select_val S=d Fail=f Size=u Rest=* | fixed_size_values(Size, Rest) => \
  gen_select_val(S, Fail, Size, Rest)

is_tuple Fail=f S | select_tuple_arity S=d Fail=f Size=u Rest=* => \
  gen_select_tuple_arity(S, Fail, Size, Rest)

select_tuple_arity S=d Fail=f Size=u Rest=* => \
  gen_select_tuple_arity(S, Fail, Size, Rest)

i_select_val r f I
i_select_val x f I
i_select_val y f I
i_select_tuple_arity r f I
i_select_tuple_arity x f I
i_select_tuple_arity y f I

i_jump_on_val_zero r f I
i_jump_on_val_zero x f I
i_jump_on_val_zero y f I

i_jump_on_val r f I I
i_jump_on_val x f I I
i_jump_on_val y f I I

jump Target | label Lbl | same_label(Target, Lbl) => label Lbl

is_ne_exact L1 S1 S2 | jump Fail | label L2 | same_label(L1, L2) => \
  is_eq_exact Fail S1 S2 | label L2

%macro: get_list GetList -pack
get_list x x x
get_list x x y
get_list x x r
get_list x y x
get_list x y y
get_list x y r
get_list x r x
get_list x r y

get_list y x x
get_list y x y
get_list y x r
get_list y y x
get_list y y y
get_list y y r
get_list y r x
get_list y r y

get_list r x x
get_list r x y
get_list r x r
get_list r y x
get_list r y y
get_list r y r
get_list r r x
get_list r r y

# Old-style catch.
catch y f
catch_end y

# Try/catch.
try Y F => catch Y F
try_case Y => try_end Y
try_end y

try_case_end Literal=q => move Literal x | try_case_end x
try_case_end s

# Destructive set tuple element

set_tuple_element Lit=q Tuple Pos => move Lit x | set_tuple_element x Tuple Pos
set_tuple_element s d P

# Get tuple element

%macro: i_get_tuple_element GetTupleElement -pack
i_get_tuple_element x P x
i_get_tuple_element r P x
i_get_tuple_element y P x
i_get_tuple_element x P r
i_get_tuple_element y P r

%cold
i_get_tuple_element r P r
i_get_tuple_element x P y
i_get_tuple_element r P y
i_get_tuple_element y P y
%hot

%macro: is_number IsNumber -fail_action
%cold
is_number f r
is_number f x
is_number f y
%hot
is_number Fail=f i =>
is_number Fail=f na => jump Fail
is_number Fail Literal=q => move Literal x | is_number Fail x

jump f

case_end Literal=cq => move Literal x | case_end x
badmatch Literal=cq => move Literal x | badmatch x

case_end r
case_end x
case_end y

badmatch r
badmatch x
badmatch y

if_end
raise s s

# Internal now, but could be useful to make known to the compiler.
badarg j
system_limit j

move R R =>

move X1=x Y1=y | move X2=x Y2=y => move2 X1 Y1 X2 Y2
move Y1=y X1=x | move Y2=y X2=x => move2 Y1 X1 Y2 X2
move X1=x X2=x | move X3=x X4=x => move2 X1 X2 X3 X4

%macro: move2 Move2 -pack
move2 x y x y
move2 y x y x
move2 x x x x

# The compiler almost never generates a "move Literal y(Y)" instruction,
# so let's cheat if we encounter one.
move S=n D=y => init D
move S=c D=y => move S x | move x D

%macro:move Move -pack -gen_dest
move x x
move x y
move x r
move y x
move y r
move r x
move r y
move c r
move c x
move n x
move n r
move y y

# Receive operations.

loop_rec Fail Src | smp_mark_target_label(Fail) => i_loop_rec Fail Src

label L | wait_timeout Fail Src | smp_already_locked(L) => label L | i_wait_timeout_locked Fail Src
wait_timeout Fail Src => i_wait_timeout Fail Src
i_wait_timeout Fail Src=aiq => gen_literal_timeout(Fail, Src)
i_wait_timeout_locked Fail Src=aiq => gen_literal_timeout_locked(Fail, Src)
{'fraction_non_alphanumeric': 0.07078607743449354, 'fraction_numerical': 0.012645026724025552, 'mean_word_length': 4.338552540013918, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 103, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7456087', 'n_tokens_mistral': 5782, 'n_tokens_neox': 5745, 'n_words': 2236}