Refactor String.concat to not shift 256 bits #506
@ -38,7 +38,7 @@ builtin_deps1({map_upd, Type}) -> [{map_get, Type}, map_put];
|
|||||||
builtin_deps1({map_upd_default, Type}) -> [{map_lookup_default, Type}, map_put];
|
builtin_deps1({map_upd_default, Type}) -> [{map_lookup_default, Type}, map_put];
|
||||||
builtin_deps1(map_from_list) -> [map_put];
|
builtin_deps1(map_from_list) -> [map_put];
|
||||||
builtin_deps1(str_equal) -> [str_equal_p];
|
builtin_deps1(str_equal) -> [str_equal_p];
|
||||||
builtin_deps1(string_concat) -> [string_concat_inner1, string_concat_inner2];
|
builtin_deps1(string_concat) -> [string_concat_inner1, string_copy, string_shift_copy];
|
||||||
builtin_deps1(int_to_str) -> [{baseX_int, 10}];
|
builtin_deps1(int_to_str) -> [{baseX_int, 10}];
|
||||||
builtin_deps1(addr_to_str) -> [{baseX_int, 58}];
|
builtin_deps1(addr_to_str) -> [{baseX_int, 58}];
|
||||||
builtin_deps1({baseX_int, X}) -> [{baseX_int_pad, X}];
|
builtin_deps1({baseX_int, X}) -> [{baseX_int_pad, X}];
|
||||||
@ -144,7 +144,8 @@ builtin_function(BF) ->
|
|||||||
string_length -> bfun(BF, builtin_string_length());
|
string_length -> bfun(BF, builtin_string_length());
|
||||||
string_concat -> bfun(BF, builtin_string_concat());
|
string_concat -> bfun(BF, builtin_string_concat());
|
||||||
string_concat_inner1 -> bfun(BF, builtin_string_concat_inner1());
|
string_concat_inner1 -> bfun(BF, builtin_string_concat_inner1());
|
||||||
string_concat_inner2 -> bfun(BF, builtin_string_concat_inner2());
|
string_copy -> bfun(BF, builtin_string_copy());
|
||||||
|
string_shift_copy -> bfun(BF, builtin_string_shift_copy());
|
||||||
str_equal_p -> bfun(BF, builtin_str_equal_p());
|
str_equal_p -> bfun(BF, builtin_str_equal_p());
|
||||||
str_equal -> bfun(BF, builtin_str_equal());
|
str_equal -> bfun(BF, builtin_str_equal());
|
||||||
int_to_str -> bfun(BF, builtin_int_to_str());
|
int_to_str -> bfun(BF, builtin_int_to_str());
|
||||||
@ -154,7 +155,6 @@ builtin_function(BF) ->
|
|||||||
{baseX_tab, X} -> bfun(BF, builtin_baseX_tab(X));
|
{baseX_tab, X} -> bfun(BF, builtin_baseX_tab(X));
|
||||||
{baseX_int_pad, X} -> bfun(BF, builtin_baseX_int_pad(X));
|
{baseX_int_pad, X} -> bfun(BF, builtin_baseX_int_pad(X));
|
||||||
{baseX_int_encode, X} -> bfun(BF, builtin_baseX_int_encode(X));
|
{baseX_int_encode, X} -> bfun(BF, builtin_baseX_int_encode(X));
|
||||||
{baseX_int_encode_, X} -> bfun(BF, builtin_baseX_int_encode_(X));
|
|
||||||
string_reverse -> bfun(BF, builtin_string_reverse());
|
string_reverse -> bfun(BF, builtin_string_reverse());
|
||||||
string_reverse_ -> bfun(BF, builtin_string_reverse_())
|
string_reverse_ -> bfun(BF, builtin_string_reverse_())
|
||||||
end.
|
end.
|
||||||
@ -322,14 +322,17 @@ builtin_string_concat() ->
|
|||||||
{[{"s1", string}, {"s2", string}],
|
{[{"s1", string}, {"s2", string}],
|
||||||
?DEREF(n1, s1,
|
?DEREF(n1, s1,
|
||||||
?DEREF(n2, s2,
|
?DEREF(n2, s2,
|
||||||
{ifte, ?EQ(n2, 0),
|
{ifte, ?EQ(n1, 0),
|
||||||
?V(s1), %% Second string is empty return first string
|
?V(s2), %% First string is empty return second string
|
||||||
?LET(ret, {inline_asm, [?A(?MSIZE)]},
|
{ifte, ?EQ(n2, 0),
|
||||||
{seq, [?ADD(n1, n2), {inline_asm, [?A(?MSIZE), ?A(?MSTORE)]}, %% Store total len
|
?V(s1), %% Second string is empty return first string
|
||||||
?call(string_concat_inner1, [?V(n1), ?NXT(s1), ?V(n2), ?NXT(s2)]),
|
?LET(ret, {inline_asm, [?A(?MSIZE)]},
|
||||||
{inline_asm, [?A(?POP)]}, %% Discard fun ret val
|
{seq, [?ADD(n1, n2), {inline_asm, [?A(?MSIZE), ?A(?MSTORE)]}, %% Store total len
|
||||||
?V(ret) %% Put the actual return value
|
?call(string_concat_inner1, [?V(n1), ?NXT(s1), ?V(n2), ?NXT(s2)]),
|
||||||
]})}
|
{inline_asm, [?A(?POP)]}, %% Discard fun ret val
|
||||||
|
?V(ret) %% Put the actual return value
|
||||||
|
]})}
|
||||||
|
}
|
||||||
)),
|
)),
|
||||||
word}.
|
word}.
|
||||||
|
|
||||||
@ -337,33 +340,33 @@ builtin_string_concat_inner1() ->
|
|||||||
%% Copy all whole words from the first string, and set up for word fusion
|
%% Copy all whole words from the first string, and set up for word fusion
|
||||||
%% Special case when the length of the first string is divisible by 32.
|
%% Special case when the length of the first string is divisible by 32.
|
||||||
{[{"n1", word}, {"p1", pointer}, {"n2", word}, {"p2", pointer}],
|
{[{"n1", word}, {"p1", pointer}, {"n2", word}, {"p2", pointer}],
|
||||||
?DEREF(w1, p1,
|
?LET(w1, ?call(string_copy, [?V(n1), ?V(p1)]),
|
||||||
{ifte, ?GT(n1, 32),
|
?LET(nx, ?MOD(n1, 32),
|
||||||
{seq, [?V(w1), {inline_asm, [?A(?MSIZE), ?A(?MSTORE)]},
|
{ifte, ?EQ(nx, 0),
|
||||||
?call(string_concat_inner1, [?SUB(n1, 32), ?NXT(p1), ?V(n2), ?V(p2)])]},
|
?LET(w2, ?call(string_copy, [?V(n2), ?V(p2)]),
|
||||||
{ifte, ?EQ(n1, 0),
|
{seq, [?V(w2), {inline_asm, [?A(?MSIZE), ?A(?MSTORE), ?A(?MSIZE)]}]}),
|
||||||
?call(string_concat_inner2, [?I(32), ?I(0), ?V(n2), ?V(p2)]),
|
?call(string_shift_copy, [?V(nx), ?V(w1), ?V(n2), ?V(p2)])
|
||||||
?call(string_concat_inner2, [?SUB(32, n1), ?V(w1), ?V(n2), ?V(p2)])}
|
})),
|
||||||
|
word}.
|
||||||
|
|
||||||
|
builtin_string_copy() ->
|
||||||
|
{[{"n", word}, {"p", pointer}],
|
||||||
|
?DEREF(w, p,
|
||||||
|
{ifte, ?GT(n, 31),
|
||||||
|
{seq, [?V(w), {inline_asm, [?A(?MSIZE), ?A(?MSTORE)]},
|
||||||
|
?call(string_copy, [?SUB(n, 32), ?NXT(p)])]},
|
||||||
|
?V(w)
|
||||||
}),
|
}),
|
||||||
word}.
|
word}.
|
||||||
|
|
||||||
builtin_string_concat_inner2() ->
|
builtin_string_shift_copy() ->
|
||||||
%% Current "work in progess" word 'x', has 'o' bytes that are "free" - fill them from
|
{[{"off", word}, {"dst", word}, {"n", word}, {"p", pointer}],
|
||||||
%% words of the second string.
|
?DEREF(w, p,
|
||||||
{[{"o", word}, {"x", word}, {"n2", word}, {"p2", pointer}],
|
{seq, [?ADD(dst, ?BSR(w, off)), {inline_asm, [?A(?MSIZE), ?A(?MSTORE)]},
|
||||||
{ifte, ?LT(n2, 1),
|
{ifte, ?GT(n, ?SUB(32, off)),
|
||||||
{seq, [?V(x), {inline_asm, [?A(?MSIZE), ?A(?MSTORE), ?A(?MSIZE)]}]}, %% Use MSIZE as dummy return value
|
?call(string_shift_copy, [?V(off), ?BSL(w, ?SUB(32, off)), ?SUB(n, 32), ?NXT(p)]),
|
||||||
?DEREF(w2, p2,
|
{inline_asm, [?A(?MSIZE)]}}]
|
||||||
{ifte, ?GT(n2, o),
|
}),
|
||||||
{seq, [?ADD(x, ?BSR(w2, ?SUB(32, o))),
|
|
||||||
{inline_asm, [?A(?MSIZE), ?A(?MSTORE)]},
|
|
||||||
?call(string_concat_inner2,
|
|
||||||
[?V(o), ?BSL(w2, o), ?SUB(n2, 32), ?NXT(p2)])
|
|
||||||
]},
|
|
||||||
{seq, [?ADD(x, ?BSR(w2, ?SUB(32, o))),
|
|
||||||
{inline_asm, [?A(?MSIZE), ?A(?MSTORE), ?A(?MSIZE)]}]} %% Use MSIZE as dummy return value
|
|
||||||
})
|
|
||||||
},
|
|
||||||
word}.
|
word}.
|
||||||
|
|
||||||
builtin_str_equal_p() ->
|
builtin_str_equal_p() ->
|
||||||
|
Loading…
x
Reference in New Issue
Block a user