Handle 5 to 8 args. Generate a test file with all instructions for as… (#14)
* Handle 5 to 8 args. Generate a test file with all instructions for asm/disasm. * Add ops to test 7 and 8 arguments.
This commit is contained in:
parent
6f67da1292
commit
43652e0843
@ -341,14 +341,13 @@ deserialize_op(?SWITCH_VN, Rest, Code) ->
|
|||||||
<<ArgType:8, Rest2/binary>> = Rest,
|
<<ArgType:8, Rest2/binary>> = Rest,
|
||||||
{Arg0, Rest3} = aeb_fate_encoding:deserialize_one(Rest2),
|
{Arg0, Rest3} = aeb_fate_encoding:deserialize_one(Rest2),
|
||||||
case aeb_fate_encoding:deserialize_one(Rest3) of
|
case aeb_fate_encoding:deserialize_one(Rest3) of
|
||||||
{N, Rest4} when is_integer(N), N >= 0 ->
|
{L, Rest4} when is_list(L) ->
|
||||||
Modifier0 = bits_to_modifier(ArgType band 2#11),
|
Modifier0 = bits_to_modifier(ArgType band 2#11),
|
||||||
immediate = bits_to_modifier((ArgType bsr 2) band 2#11),
|
immediate = bits_to_modifier((ArgType bsr 2) band 2#11),
|
||||||
{BBs, Rest5} = deserialize_n(N, Rest4),
|
{Rest4, [{aeb_fate_opcodes:mnemonic(?SWITCH_VN)
|
||||||
{Rest5, [{aeb_fate_opcodes:mnemonic(?SWITCH_VN)
|
|
||||||
, {Modifier0, Arg0}
|
, {Modifier0, Arg0}
|
||||||
, {immediate, N}
|
, {immediate, L}
|
||||||
, list_to_tuple(BBs)}
|
}
|
||||||
| Code]};
|
| Code]};
|
||||||
_ -> exit(bad_argument_to_switch_vn)
|
_ -> exit(bad_argument_to_switch_vn)
|
||||||
end;
|
end;
|
||||||
@ -397,17 +396,107 @@ deserialize_op(Op, Rest, Code) ->
|
|||||||
, {Modifier1, Arg1}
|
, {Modifier1, Arg1}
|
||||||
, {Modifier2, Arg2}
|
, {Modifier2, Arg2}
|
||||||
, {Modifier3, Arg3}}
|
, {Modifier3, Arg3}}
|
||||||
|
| Code]};
|
||||||
|
5 ->
|
||||||
|
<<ArgType:8, ArgType2:8, Rest2/binary>> = Rest,
|
||||||
|
{Arg0, Rest3} = aeb_fate_encoding:deserialize_one(Rest2),
|
||||||
|
{Arg1, Rest4} = aeb_fate_encoding:deserialize_one(Rest3),
|
||||||
|
{Arg2, Rest5} = aeb_fate_encoding:deserialize_one(Rest4),
|
||||||
|
{Arg3, Rest6} = aeb_fate_encoding:deserialize_one(Rest5),
|
||||||
|
{Arg4, Rest7} = aeb_fate_encoding:deserialize_one(Rest6),
|
||||||
|
Modifier0 = bits_to_modifier(ArgType band 2#11),
|
||||||
|
Modifier1 = bits_to_modifier((ArgType bsr 2) band 2#11),
|
||||||
|
Modifier2 = bits_to_modifier((ArgType bsr 4) band 2#11),
|
||||||
|
Modifier3 = bits_to_modifier((ArgType bsr 6) band 2#11),
|
||||||
|
Modifier4 = bits_to_modifier(ArgType2 band 2#11),
|
||||||
|
{Rest7, [{ OpName
|
||||||
|
, {Modifier0, Arg0}
|
||||||
|
, {Modifier1, Arg1}
|
||||||
|
, {Modifier2, Arg2}
|
||||||
|
, {Modifier3, Arg3}
|
||||||
|
, {Modifier4, Arg4}
|
||||||
|
}
|
||||||
|
| Code]};
|
||||||
|
6 ->
|
||||||
|
<<ArgType:8, ArgType2:8, Rest2/binary>> = Rest,
|
||||||
|
{Arg0, Rest3} = aeb_fate_encoding:deserialize_one(Rest2),
|
||||||
|
{Arg1, Rest4} = aeb_fate_encoding:deserialize_one(Rest3),
|
||||||
|
{Arg2, Rest5} = aeb_fate_encoding:deserialize_one(Rest4),
|
||||||
|
{Arg3, Rest6} = aeb_fate_encoding:deserialize_one(Rest5),
|
||||||
|
{Arg4, Rest7} = aeb_fate_encoding:deserialize_one(Rest6),
|
||||||
|
{Arg5, Rest8} = aeb_fate_encoding:deserialize_one(Rest7),
|
||||||
|
Modifier0 = bits_to_modifier(ArgType band 2#11),
|
||||||
|
Modifier1 = bits_to_modifier((ArgType bsr 2) band 2#11),
|
||||||
|
Modifier2 = bits_to_modifier((ArgType bsr 4) band 2#11),
|
||||||
|
Modifier3 = bits_to_modifier((ArgType bsr 6) band 2#11),
|
||||||
|
Modifier4 = bits_to_modifier(ArgType2 band 2#11),
|
||||||
|
Modifier5 = bits_to_modifier((ArgType2 bsr 2) band 2#11),
|
||||||
|
{Rest8, [{ OpName
|
||||||
|
, {Modifier0, Arg0}
|
||||||
|
, {Modifier1, Arg1}
|
||||||
|
, {Modifier2, Arg2}
|
||||||
|
, {Modifier3, Arg3}
|
||||||
|
, {Modifier4, Arg4}
|
||||||
|
, {Modifier5, Arg5}
|
||||||
|
}
|
||||||
|
| Code]};
|
||||||
|
7 ->
|
||||||
|
<<ArgType:8, ArgType2:8, Rest2/binary>> = Rest,
|
||||||
|
{Arg0, Rest3} = aeb_fate_encoding:deserialize_one(Rest2),
|
||||||
|
{Arg1, Rest4} = aeb_fate_encoding:deserialize_one(Rest3),
|
||||||
|
{Arg2, Rest5} = aeb_fate_encoding:deserialize_one(Rest4),
|
||||||
|
{Arg3, Rest6} = aeb_fate_encoding:deserialize_one(Rest5),
|
||||||
|
{Arg4, Rest7} = aeb_fate_encoding:deserialize_one(Rest6),
|
||||||
|
{Arg5, Rest8} = aeb_fate_encoding:deserialize_one(Rest7),
|
||||||
|
{Arg6, Rest9} = aeb_fate_encoding:deserialize_one(Rest8),
|
||||||
|
Modifier0 = bits_to_modifier(ArgType band 2#11),
|
||||||
|
Modifier1 = bits_to_modifier((ArgType bsr 2) band 2#11),
|
||||||
|
Modifier2 = bits_to_modifier((ArgType bsr 4) band 2#11),
|
||||||
|
Modifier3 = bits_to_modifier((ArgType bsr 6) band 2#11),
|
||||||
|
Modifier4 = bits_to_modifier(ArgType2 band 2#11),
|
||||||
|
Modifier5 = bits_to_modifier((ArgType2 bsr 2) band 2#11),
|
||||||
|
Modifier6 = bits_to_modifier((ArgType2 bsr 4) band 2#11),
|
||||||
|
{Rest9, [{ OpName
|
||||||
|
, {Modifier0, Arg0}
|
||||||
|
, {Modifier1, Arg1}
|
||||||
|
, {Modifier2, Arg2}
|
||||||
|
, {Modifier3, Arg3}
|
||||||
|
, {Modifier4, Arg4}
|
||||||
|
, {Modifier5, Arg5}
|
||||||
|
, {Modifier6, Arg6}
|
||||||
|
}
|
||||||
|
| Code]};
|
||||||
|
8 ->
|
||||||
|
<<ArgType:8, ArgType2:8, Rest2/binary>> = Rest,
|
||||||
|
{Arg0, Rest3} = aeb_fate_encoding:deserialize_one(Rest2),
|
||||||
|
{Arg1, Rest4} = aeb_fate_encoding:deserialize_one(Rest3),
|
||||||
|
{Arg2, Rest5} = aeb_fate_encoding:deserialize_one(Rest4),
|
||||||
|
{Arg3, Rest6} = aeb_fate_encoding:deserialize_one(Rest5),
|
||||||
|
{Arg4, Rest7} = aeb_fate_encoding:deserialize_one(Rest6),
|
||||||
|
{Arg5, Rest8} = aeb_fate_encoding:deserialize_one(Rest7),
|
||||||
|
{Arg6, Rest9} = aeb_fate_encoding:deserialize_one(Rest8),
|
||||||
|
{Arg7, Rest10} = aeb_fate_encoding:deserialize_one(Rest9),
|
||||||
|
Modifier0 = bits_to_modifier(ArgType band 2#11),
|
||||||
|
Modifier1 = bits_to_modifier((ArgType bsr 2) band 2#11),
|
||||||
|
Modifier2 = bits_to_modifier((ArgType bsr 4) band 2#11),
|
||||||
|
Modifier3 = bits_to_modifier((ArgType bsr 6) band 2#11),
|
||||||
|
Modifier4 = bits_to_modifier(ArgType2 band 2#11),
|
||||||
|
Modifier5 = bits_to_modifier((ArgType2 bsr 2) band 2#11),
|
||||||
|
Modifier6 = bits_to_modifier((ArgType2 bsr 4) band 2#11),
|
||||||
|
Modifier7 = bits_to_modifier((ArgType2 bsr 6) band 2#11),
|
||||||
|
{Rest10, [{ OpName
|
||||||
|
, {Modifier0, Arg0}
|
||||||
|
, {Modifier1, Arg1}
|
||||||
|
, {Modifier2, Arg2}
|
||||||
|
, {Modifier3, Arg3}
|
||||||
|
, {Modifier4, Arg4}
|
||||||
|
, {Modifier5, Arg5}
|
||||||
|
, {Modifier6, Arg6}
|
||||||
|
, {Modifier7, Arg7}
|
||||||
|
}
|
||||||
| Code]}
|
| Code]}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
deserialize_n(N, Binary) ->
|
|
||||||
deserialize_n(N, Binary, []).
|
|
||||||
|
|
||||||
deserialize_n(0, Binary, Acc) ->
|
|
||||||
{lists:reverse(Acc), Binary};
|
|
||||||
deserialize_n(N, Binary, Acc) ->
|
|
||||||
{Value, Rest} = aeb_fate_encoding:deserialize_one(Binary),
|
|
||||||
deserialize_n(N-1, Rest, [Value|Acc]).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -447,11 +536,114 @@ serialize(#{functions := Functions} =_Env) ->
|
|||||||
%% bitpos: 6 4 2 0
|
%% bitpos: 6 4 2 0
|
||||||
%% xx xx xx xx
|
%% xx xx xx xx
|
||||||
%% Arg3 Arg2 Arg1 Arg0
|
%% Arg3 Arg2 Arg1 Arg0
|
||||||
|
%% For 5-8 args another Argument Spec Byte is used
|
||||||
%% Bit pattern
|
%% Bit pattern
|
||||||
%% 00 : stack/unused (depending on instruction)
|
%% 00 : stack/unused (depending on instruction)
|
||||||
%% 01 : argN
|
%% 01 : argN
|
||||||
%% 10 : varN
|
%% 10 : varN
|
||||||
%% 11 : immediate
|
%% 11 : immediate
|
||||||
|
serialize_code([ {Arg0Type, Arg0}
|
||||||
|
, {Arg1Type, Arg1}
|
||||||
|
, {Arg2Type, Arg2}
|
||||||
|
, {Arg3Type, Arg3}
|
||||||
|
, {Arg4Type, Arg4}
|
||||||
|
, {Arg5Type, Arg5}
|
||||||
|
, {Arg6Type, Arg6}
|
||||||
|
, {Arg7Type, Arg7}
|
||||||
|
| Rest]) ->
|
||||||
|
ArgSpec1 =
|
||||||
|
modifier_bits(Arg0Type) bor
|
||||||
|
(modifier_bits(Arg1Type) bsl 2) bor
|
||||||
|
(modifier_bits(Arg2Type) bsl 4) bor
|
||||||
|
(modifier_bits(Arg3Type) bsl 6),
|
||||||
|
ArgSpec2 =
|
||||||
|
modifier_bits(Arg4Type) bor
|
||||||
|
(modifier_bits(Arg5Type) bsl 2) bor
|
||||||
|
(modifier_bits(Arg6Type) bsl 4) bor
|
||||||
|
(modifier_bits(Arg7Type) bsl 6),
|
||||||
|
[ ArgSpec1
|
||||||
|
, ArgSpec2
|
||||||
|
, serialize_data(Arg0Type, Arg0)
|
||||||
|
, serialize_data(Arg1Type, Arg1)
|
||||||
|
, serialize_data(Arg2Type, Arg2)
|
||||||
|
, serialize_data(Arg3Type, Arg3)
|
||||||
|
, serialize_data(Arg4Type, Arg4)
|
||||||
|
, serialize_data(Arg5Type, Arg5)
|
||||||
|
, serialize_data(Arg6Type, Arg6)
|
||||||
|
, serialize_data(Arg7Type, Arg7)
|
||||||
|
| serialize_code(Rest)];
|
||||||
|
serialize_code([ {Arg0Type, Arg0}
|
||||||
|
, {Arg1Type, Arg1}
|
||||||
|
, {Arg2Type, Arg2}
|
||||||
|
, {Arg3Type, Arg3}
|
||||||
|
, {Arg4Type, Arg4}
|
||||||
|
, {Arg5Type, Arg5}
|
||||||
|
, {Arg6Type, Arg6}
|
||||||
|
| Rest]) ->
|
||||||
|
ArgSpec1 =
|
||||||
|
modifier_bits(Arg0Type) bor
|
||||||
|
(modifier_bits(Arg1Type) bsl 2) bor
|
||||||
|
(modifier_bits(Arg2Type) bsl 4) bor
|
||||||
|
(modifier_bits(Arg3Type) bsl 6),
|
||||||
|
ArgSpec2 =
|
||||||
|
modifier_bits(Arg4Type) bor
|
||||||
|
(modifier_bits(Arg5Type) bsl 2) bor
|
||||||
|
(modifier_bits(Arg6Type) bsl 4),
|
||||||
|
[ ArgSpec1
|
||||||
|
, ArgSpec2
|
||||||
|
, serialize_data(Arg0Type, Arg0)
|
||||||
|
, serialize_data(Arg1Type, Arg1)
|
||||||
|
, serialize_data(Arg2Type, Arg2)
|
||||||
|
, serialize_data(Arg3Type, Arg3)
|
||||||
|
, serialize_data(Arg4Type, Arg4)
|
||||||
|
, serialize_data(Arg5Type, Arg5)
|
||||||
|
, serialize_data(Arg6Type, Arg6)
|
||||||
|
| serialize_code(Rest)];
|
||||||
|
serialize_code([ {Arg0Type, Arg0}
|
||||||
|
, {Arg1Type, Arg1}
|
||||||
|
, {Arg2Type, Arg2}
|
||||||
|
, {Arg3Type, Arg3}
|
||||||
|
, {Arg4Type, Arg4}
|
||||||
|
, {Arg5Type, Arg5}
|
||||||
|
| Rest]) ->
|
||||||
|
ArgSpec1 =
|
||||||
|
modifier_bits(Arg0Type) bor
|
||||||
|
(modifier_bits(Arg1Type) bsl 2) bor
|
||||||
|
(modifier_bits(Arg2Type) bsl 4) bor
|
||||||
|
(modifier_bits(Arg3Type) bsl 6),
|
||||||
|
ArgSpec2 =
|
||||||
|
modifier_bits(Arg4Type) bor
|
||||||
|
(modifier_bits(Arg5Type) bsl 2),
|
||||||
|
[ ArgSpec1
|
||||||
|
, ArgSpec2
|
||||||
|
, serialize_data(Arg0Type, Arg0)
|
||||||
|
, serialize_data(Arg1Type, Arg1)
|
||||||
|
, serialize_data(Arg2Type, Arg2)
|
||||||
|
, serialize_data(Arg3Type, Arg3)
|
||||||
|
, serialize_data(Arg4Type, Arg4)
|
||||||
|
, serialize_data(Arg5Type, Arg5)
|
||||||
|
| serialize_code(Rest)];
|
||||||
|
serialize_code([ {Arg0Type, Arg0}
|
||||||
|
, {Arg1Type, Arg1}
|
||||||
|
, {Arg2Type, Arg2}
|
||||||
|
, {Arg3Type, Arg3}
|
||||||
|
, {Arg4Type, Arg4}
|
||||||
|
| Rest]) ->
|
||||||
|
ArgSpec1 =
|
||||||
|
modifier_bits(Arg0Type) bor
|
||||||
|
(modifier_bits(Arg1Type) bsl 2) bor
|
||||||
|
(modifier_bits(Arg2Type) bsl 4) bor
|
||||||
|
(modifier_bits(Arg3Type) bsl 6),
|
||||||
|
ArgSpec2 =
|
||||||
|
modifier_bits(Arg4Type),
|
||||||
|
[ ArgSpec1
|
||||||
|
, ArgSpec2
|
||||||
|
, serialize_data(Arg0Type, Arg0)
|
||||||
|
, serialize_data(Arg1Type, Arg1)
|
||||||
|
, serialize_data(Arg2Type, Arg2)
|
||||||
|
, serialize_data(Arg3Type, Arg3)
|
||||||
|
, serialize_data(Arg4Type, Arg4)
|
||||||
|
| serialize_code(Rest)];
|
||||||
|
|
||||||
serialize_code([ {Arg0Type, Arg0}
|
serialize_code([ {Arg0Type, Arg0}
|
||||||
, {Arg1Type, Arg1}
|
, {Arg1Type, Arg1}
|
||||||
@ -505,35 +697,19 @@ serialize_code([ ?ELEMENT
|
|||||||
| serialize_code(Rest)];
|
| serialize_code(Rest)];
|
||||||
serialize_code([ ?SWITCH_VN
|
serialize_code([ ?SWITCH_VN
|
||||||
, {Arg0Type, Arg0}
|
, {Arg0Type, Arg0}
|
||||||
, {immediate, N}
|
, {immediate, L}
|
||||||
| Rest]) when is_integer(N), N >= 0 ->
|
| Rest]) ->
|
||||||
ArgSpec =
|
ArgSpec =
|
||||||
modifier_bits(Arg0Type) bor
|
modifier_bits(Arg0Type) bor
|
||||||
(modifier_bits(immediate) bsl 2),
|
(modifier_bits(immediate) bsl 2),
|
||||||
{Serialization, Rest2} = serialize_n_ints(N, Rest),
|
|
||||||
[?SWITCH_VN
|
[?SWITCH_VN
|
||||||
, ArgSpec
|
, ArgSpec
|
||||||
, serialize_data(Arg0Type, Arg0)
|
, serialize_data(Arg0Type, Arg0)
|
||||||
, serialize_data(immediate, N)
|
, serialize_data(immediate, L)] ++ serialize_code(Rest);
|
||||||
| Serialization] ++ serialize_code(Rest2);
|
|
||||||
serialize_code([B|Rest]) ->
|
serialize_code([B|Rest]) ->
|
||||||
[B | serialize_code(Rest)];
|
[B | serialize_code(Rest)];
|
||||||
serialize_code([]) -> [].
|
serialize_code([]) -> [].
|
||||||
|
|
||||||
serialize_n_ints(N, Rest) ->
|
|
||||||
serialize_n_ints(N, Rest, []).
|
|
||||||
|
|
||||||
serialize_n_ints(0, Rest, Acc) ->
|
|
||||||
%% Acc is a list of binaries.
|
|
||||||
{lists:reverse(Acc), Rest};
|
|
||||||
serialize_n_ints(N, [Int|Rest], Acc) when is_integer(Int), Int >= 0 ->
|
|
||||||
serialize_n_ints(N - 1, Rest, [aeb_fate_encoding:serialize(Int)|Acc]);
|
|
||||||
serialize_n_ints(_, [], _) ->
|
|
||||||
exit(not_enough_bbs_for_switch_vn);
|
|
||||||
serialize_n_ints(_, _, _) ->
|
|
||||||
exit(bad_bbs_value_for_switch_vn).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%% 00 : stack/unused (depending on instruction)
|
%% 00 : stack/unused (depending on instruction)
|
||||||
%% 01 : argN
|
%% 01 : argN
|
||||||
|
@ -55,8 +55,8 @@ FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}.
|
|||||||
\: : {token, {to, TokenLine}}.
|
\: : {token, {to, TokenLine}}.
|
||||||
|
|
||||||
\=\> : {token, {arrow, TokenLine}}.
|
\=\> : {token, {arrow, TokenLine}}.
|
||||||
\(\| : {token, {start_varaint, TokenLine}}.
|
\(\| : {token, {start_variant, TokenLine}}.
|
||||||
\|\) : {token, {end_varaint, TokenLine}}.
|
\|\) : {token, {end_variant, TokenLine}}.
|
||||||
|
|
||||||
, : {token, {',', TokenLine}}.
|
, : {token, {',', TokenLine}}.
|
||||||
\( : {token, {'(', TokenLine}}.
|
\( : {token, {'(', TokenLine}}.
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
-module(aeb_fate_generate_ops).
|
-module(aeb_fate_generate_ops).
|
||||||
|
|
||||||
-export([ gen_and_halt/1
|
-export([ gen_and_halt/1
|
||||||
, generate/0]).
|
, generate/0
|
||||||
|
, test_asm_generator/1]).
|
||||||
|
|
||||||
gen_and_halt([SrcDirArg, IncludeDirArg]) ->
|
gen_and_halt([SrcDirArg, IncludeDirArg]) ->
|
||||||
generate(atom_to_list(SrcDirArg),
|
generate(atom_to_list(SrcDirArg),
|
||||||
@ -34,7 +35,7 @@ ops_defs() ->
|
|||||||
, { 'JUMPIF', 16#07, 2, true, 4, [a,ii], jumpif, "Conditional jump to a basic block. If Arg0 then jump to Arg1."}
|
, { 'JUMPIF', 16#07, 2, true, 4, [a,ii], jumpif, "Conditional jump to a basic block. If Arg0 then jump to Arg1."}
|
||||||
, { 'SWITCH_V2', 16#08, 3, true, 4, [a,ii,ii], switch, "Conditional jump to a basic block on variant tag."}
|
, { 'SWITCH_V2', 16#08, 3, true, 4, [a,ii,ii], switch, "Conditional jump to a basic block on variant tag."}
|
||||||
, { 'SWITCH_V3', 16#09, 4, true, 4, [a,ii,ii,ii], switch, "Conditional jump to a basic block on variant tag."}
|
, { 'SWITCH_V3', 16#09, 4, true, 4, [a,ii,ii,ii], switch, "Conditional jump to a basic block on variant tag."}
|
||||||
, { 'SWITCH_VN', 16#0a, 2, true, 4, [a,li], switch, "Conditional jump to a basic block on variant tag."}
|
, { 'SWITCH_VN', 16#0a, 2, true, 4, [a, li], switch, "Conditional jump to a basic block on variant tag."}
|
||||||
, { 'PUSH', 16#0b, 1, false, 2, [a], push, "Push argument to stack."}
|
, { 'PUSH', 16#0b, 1, false, 2, [a], push, "Push argument to stack."}
|
||||||
, { 'DUPA', 16#0c, 0, false, 3, atomic, dup, "push copy of accumulator on stack."}
|
, { 'DUPA', 16#0c, 0, false, 3, atomic, dup, "push copy of accumulator on stack."}
|
||||||
, { 'DUP', 16#0d, 1, false, 3, [a], dup, "push Arg0 stack pos on top of stack."}
|
, { 'DUP', 16#0d, 1, false, 3, [a], dup, "push Arg0 stack pos on top of stack."}
|
||||||
@ -136,8 +137,11 @@ ops_defs() ->
|
|||||||
, { 'SHA256', 16#7c, 0, false,3, atomic, sha256, ""}
|
, { 'SHA256', 16#7c, 0, false,3, atomic, sha256, ""}
|
||||||
, { 'BLAKE2B', 16#7d, 0, false,3, atomic, blake2b, ""}
|
, { 'BLAKE2B', 16#7d, 0, false,3, atomic, blake2b, ""}
|
||||||
|
|
||||||
, {'ABORT', 16#fb, 1, false, 3, [a], abort, "Abort execution (dont use all gas) with error message in Arg0."}
|
|
||||||
, {'EXIT', 16#fc, 1, false, 3, [a], exit, "Abort execution (use upp all gas) with error message in Arg0."}
|
, { 'DUMMY7ARG', 16#f9, 7, false,3, [a,a,a,a,a,a,a], dummyarg, "Temporary dummy instruction to test 7 args."}
|
||||||
|
, { 'DUMMY8ARG', 16#fa, 8, false,3, [a,a,a,a,a,a,a,a],dummyarg, "Temporary dummy instruction to test 8 args."}
|
||||||
|
, { 'ABORT', 16#fb, 1, false, 3, [a], abort, "Abort execution (dont use all gas) with error message in Arg0."}
|
||||||
|
, { 'EXIT', 16#fc, 1, false, 3, [a], exit, "Abort execution (use upp all gas) with error message in Arg0."}
|
||||||
, { 'NOP', 16#fd, 0, false, 1, atomic, nop, "The no op. does nothing."}
|
, { 'NOP', 16#fd, 0, false, 1, atomic, nop, "The no op. does nothing."}
|
||||||
%% FUNCTION 16#fe "Function declaration and entrypoint."
|
%% FUNCTION 16#fe "Function declaration and entrypoint."
|
||||||
%% EXTEND 16#ff "Reserved for future extensions beyond one byte opcodes."
|
%% EXTEND 16#ff "Reserved for future extensions beyond one byte opcodes."
|
||||||
@ -411,8 +415,8 @@ gen_asm_pp(Module, Path, Ops) ->
|
|||||||
"-export([format_op/2]).\n\n"
|
"-export([format_op/2]).\n\n"
|
||||||
"format_arg(t, T) ->\n"
|
"format_arg(t, T) ->\n"
|
||||||
" io_lib:format(\"~~p \", [T]);\n"
|
" io_lib:format(\"~~p \", [T]);\n"
|
||||||
"format_arg(li, List) ->\n"
|
"format_arg(li, {immediate, LI}) ->\n"
|
||||||
" [[\" \", E] || {immedate, E} <- List];\n"
|
" aeb_fate_data:format(LI);\n"
|
||||||
"format_arg(_, {immediate, I}) ->\n"
|
"format_arg(_, {immediate, I}) ->\n"
|
||||||
" aeb_fate_data:format(I);\n"
|
" aeb_fate_data:format(I);\n"
|
||||||
"format_arg(a, {arg, N}) -> io_lib:format(\"arg~~p\", [N]);\n"
|
"format_arg(a, {arg, N}) -> io_lib:format(\"arg~~p\", [N]);\n"
|
||||||
@ -420,7 +424,7 @@ gen_asm_pp(Module, Path, Ops) ->
|
|||||||
"format_arg(a, {stack, 0}) -> \"a\";\n"
|
"format_arg(a, {stack, 0}) -> \"a\";\n"
|
||||||
"format_arg(a, {stack, N}) -> io_lib:format(\"a~~p\", [N]).\n\n"
|
"format_arg(a, {stack, N}) -> io_lib:format(\"a~~p\", [N]).\n\n"
|
||||||
"lookup(Name, Symbols) ->\n"
|
"lookup(Name, Symbols) ->\n"
|
||||||
" maps:get(Name, Symbols, Name).\n\n"
|
" maps:get(Name, Symbols, io_lib:format(\"~~w\",[Name])).\n\n"
|
||||||
"~s"
|
"~s"
|
||||||
, [Formats]),
|
, [Formats]),
|
||||||
|
|
||||||
@ -497,5 +501,137 @@ gen_format(#{opname := Name, format := Args}) ->
|
|||||||
"\" \", format_arg(~w, Arg4),"
|
"\" \", format_arg(~w, Arg4),"
|
||||||
"\" \", format_arg(~w, Arg5),"
|
"\" \", format_arg(~w, Arg5),"
|
||||||
"\" \", format_arg(~w, Arg6)];",
|
"\" \", format_arg(~w, Arg6)];",
|
||||||
[Name, NameAsString, T0, T1, T2, T3, T4, T5, T6])
|
[Name, NameAsString, T0, T1, T2, T3, T4, T5, T6]);
|
||||||
|
[T0, T1, T2, T3, T4, T5, T6, T7] ->
|
||||||
|
io_lib:format(
|
||||||
|
"format_op({~w, Arg0, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7}, _) ->\n"
|
||||||
|
" [\"~s \", format_arg(~w, Arg0), "
|
||||||
|
"\" \", format_arg(~w, Arg1),"
|
||||||
|
"\" \", format_arg(~w, Arg2),"
|
||||||
|
"\" \", format_arg(~w, Arg3),"
|
||||||
|
"\" \", format_arg(~w, Arg4),"
|
||||||
|
"\" \", format_arg(~w, Arg5),"
|
||||||
|
"\" \", format_arg(~w, Arg6),"
|
||||||
|
"\" \", format_arg(~w, Arg7)];",
|
||||||
|
[Name, NameAsString, T0, T1, T2, T3, T4, T5, T6, T7])
|
||||||
|
end.
|
||||||
|
|
||||||
|
test_asm_generator(Filename) ->
|
||||||
|
{ok, File} = file:open(Filename, [write]),
|
||||||
|
Instructions = lists:flatten([gen_instruction(Op)++"\n" || Op <- gen(ops_defs())]),
|
||||||
|
io:format(File,
|
||||||
|
";; CONTRACT all_instructions\n\n"
|
||||||
|
";; Dont expect this contract to typecheck or run.\n"
|
||||||
|
";; Just used to check assembler rountrip of all instruction.\n\n"
|
||||||
|
"FUNCTION foo () : {tuple, []}\n"
|
||||||
|
"~s"
|
||||||
|
, [Instructions]),
|
||||||
|
io:format(File, " RETURNR ()\n", []),
|
||||||
|
file:close(File).
|
||||||
|
|
||||||
|
|
||||||
|
gen_instruction(#{opname := Name, format := atomic}) ->
|
||||||
|
io_lib:format(" ~s\n", [Name]);
|
||||||
|
gen_instruction(#{opname := Name, format := ArgTypes}) ->
|
||||||
|
Args = lists:flatten(lists:join(" ", [gen_arg(A) || A <- ArgTypes])),
|
||||||
|
I = io_lib:format(" ~s ~s\n", [Name, Args]),
|
||||||
|
I.
|
||||||
|
|
||||||
|
%% This should be done with a Quick Check generator...
|
||||||
|
gen_arg(a) -> any_arg();
|
||||||
|
gen_arg(is) -> "foo";
|
||||||
|
gen_arg(ii) -> gen_int();
|
||||||
|
gen_arg(li) -> "[1, 2, 3]";
|
||||||
|
gen_arg(t) -> "integer".
|
||||||
|
|
||||||
|
any_arg() ->
|
||||||
|
element(rand:uniform(5), {"a", stack_arg(), var_arg(), arg_arg(), imm_arg()}).
|
||||||
|
stack_arg() -> "a" ++ integer_to_list(rand:uniform(255)-1).
|
||||||
|
arg_arg() -> "arg" ++ integer_to_list(rand:uniform(256)-1).
|
||||||
|
var_arg() -> "var" ++ integer_to_list(rand:uniform(256)-1).
|
||||||
|
imm_arg() ->
|
||||||
|
case rand:uniform(15) of
|
||||||
|
1 -> gen_int();
|
||||||
|
2 -> gen_int();
|
||||||
|
3 -> gen_int();
|
||||||
|
4 -> gen_int();
|
||||||
|
5 -> gen_int();
|
||||||
|
6 -> gen_int();
|
||||||
|
7 -> gen_int();
|
||||||
|
8 -> gen_address();
|
||||||
|
9 -> gen_boolean();
|
||||||
|
10 -> gen_string();
|
||||||
|
11 -> gen_map();
|
||||||
|
12 -> gen_list();
|
||||||
|
13 -> gen_bits();
|
||||||
|
14 -> gen_tuple();
|
||||||
|
15 -> gen_variant()
|
||||||
|
end.
|
||||||
|
|
||||||
|
gen_key() ->
|
||||||
|
case rand:uniform(15) of
|
||||||
|
1 -> gen_int();
|
||||||
|
2 -> gen_int();
|
||||||
|
3 -> gen_int();
|
||||||
|
4 -> gen_int();
|
||||||
|
5 -> gen_int();
|
||||||
|
6 -> gen_int();
|
||||||
|
7 -> gen_int();
|
||||||
|
8 -> gen_address();
|
||||||
|
9 -> gen_boolean();
|
||||||
|
10 -> gen_string();
|
||||||
|
11 -> gen_string();
|
||||||
|
12 -> gen_list();
|
||||||
|
13 -> gen_bits();
|
||||||
|
14 -> gen_tuple();
|
||||||
|
15 -> gen_variant()
|
||||||
|
end.
|
||||||
|
|
||||||
|
gen_boolean() ->
|
||||||
|
element(rand:uniform(2), {"true", "false"}).
|
||||||
|
|
||||||
|
gen_int() ->
|
||||||
|
element(rand:uniform(4),
|
||||||
|
{ integer_to_list(rand:uniform(round(math:pow(10,40))))
|
||||||
|
, integer_to_list(rand:uniform(10))
|
||||||
|
, integer_to_list(rand:uniform(100))
|
||||||
|
, io_lib:format("0x~.16b",[rand:uniform(round(math:pow(10,10)))])}).
|
||||||
|
|
||||||
|
gen_address() -> "#nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv".
|
||||||
|
gen_string() -> "\"foo\"".
|
||||||
|
gen_map() -> "{ " ++ gen_key() ++ " => " ++ imm_arg() ++ "}".
|
||||||
|
gen_list() ->
|
||||||
|
case rand:uniform(4) of
|
||||||
|
1 -> "[]";
|
||||||
|
2 -> "[" ++ lists:join(", ", gen_list_elements()) ++ " ]";
|
||||||
|
3 -> "[ " ++ imm_arg() ++ " ]";
|
||||||
|
4 -> "[ " ++ imm_arg() ++ ", " ++ imm_arg() ++ " ]"
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% Not type correct.
|
||||||
|
gen_list_elements() ->
|
||||||
|
case rand:uniform(3) of
|
||||||
|
1 -> [imm_arg() | gen_list_elements()];
|
||||||
|
2 -> [];
|
||||||
|
3 -> [imm_arg()]
|
||||||
|
end.
|
||||||
|
|
||||||
|
gen_bits() ->
|
||||||
|
element(rand:uniform(3),
|
||||||
|
{"<>"
|
||||||
|
,"!<>"
|
||||||
|
, "101010"}).
|
||||||
|
|
||||||
|
gen_tuple() ->
|
||||||
|
case rand:uniform(3) of
|
||||||
|
1 -> "()";
|
||||||
|
2 -> "(42)";
|
||||||
|
3 -> "(" ++ imm_arg() ++ ")"
|
||||||
|
end.
|
||||||
|
|
||||||
|
gen_variant() ->
|
||||||
|
case rand:uniform(3) of
|
||||||
|
1 -> "(| 5 | 2 | (1, \"foo\", ()) |)";
|
||||||
|
2 -> "(| 2 | 1 | ( " ++ imm_arg() ++ " ) |)";
|
||||||
|
3 -> "(| 2 | 0 | ( " ++ imm_arg() ++ ", " ++ imm_arg() ++ " ) |)"
|
||||||
end.
|
end.
|
||||||
|
@ -52,6 +52,7 @@ sources() ->
|
|||||||
, "tuple"
|
, "tuple"
|
||||||
, "mapofmap"
|
, "mapofmap"
|
||||||
, "immediates"
|
, "immediates"
|
||||||
|
, "all_instructions"
|
||||||
].
|
].
|
||||||
|
|
||||||
check_roundtrip(File) ->
|
check_roundtrip(File) ->
|
||||||
|
233
test/asm_code/all_instructions.fate
Normal file
233
test/asm_code/all_instructions.fate
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
;; CONTRACT all_instructions
|
||||||
|
|
||||||
|
;; Dont expect this contract to typecheck or run.
|
||||||
|
;; Just used to check assembler rountrip of all instruction.
|
||||||
|
|
||||||
|
FUNCTION foo () : {tuple, []}
|
||||||
|
RETURN
|
||||||
|
|
||||||
|
RETURNR a13
|
||||||
|
|
||||||
|
CALL foo
|
||||||
|
|
||||||
|
CALL_R arg125 foo
|
||||||
|
|
||||||
|
CALL_T foo
|
||||||
|
|
||||||
|
CALL_TR arg245 foo
|
||||||
|
|
||||||
|
JUMP 5514251025295783441695716053282666408426
|
||||||
|
|
||||||
|
JUMPIF arg196 0x12c651665
|
||||||
|
|
||||||
|
SWITCH_V2 a27 63 33
|
||||||
|
|
||||||
|
SWITCH_V3 var4 0x1d61723dd 79 7
|
||||||
|
|
||||||
|
SWITCH_VN #nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv [1, 2, 3]
|
||||||
|
|
||||||
|
PUSH var80
|
||||||
|
|
||||||
|
DUPA
|
||||||
|
|
||||||
|
DUP a
|
||||||
|
|
||||||
|
POP a107
|
||||||
|
|
||||||
|
STORE arg183 var225
|
||||||
|
|
||||||
|
INCA
|
||||||
|
|
||||||
|
INC a25
|
||||||
|
|
||||||
|
DECA
|
||||||
|
|
||||||
|
DEC a
|
||||||
|
|
||||||
|
ADD a217 a a
|
||||||
|
|
||||||
|
SUB arg35 arg165 var74
|
||||||
|
|
||||||
|
MUL 44 35 "foo"
|
||||||
|
|
||||||
|
DIV 263838340369912686645632650718169038811 a24 a
|
||||||
|
|
||||||
|
MOD var113 arg80 arg207
|
||||||
|
|
||||||
|
POW a176 a a123
|
||||||
|
|
||||||
|
LT a 78 var81
|
||||||
|
|
||||||
|
GT arg19 4729414120208894485838100532547810615352 var175
|
||||||
|
|
||||||
|
EQ 85 a arg164
|
||||||
|
|
||||||
|
ELT a161 arg226 a168
|
||||||
|
|
||||||
|
EGT a131 1 var250
|
||||||
|
|
||||||
|
NEQ a85 a a83
|
||||||
|
|
||||||
|
AND var255 0x294a24f6 var189
|
||||||
|
|
||||||
|
OR (| 2 | 0 | ( (), (42) ) |) arg168 var107
|
||||||
|
|
||||||
|
NOT arg124 a
|
||||||
|
|
||||||
|
TUPLE 5019186157739257888756115213149493826410
|
||||||
|
|
||||||
|
ELEMENT integer arg148 var25 a219
|
||||||
|
|
||||||
|
MAP_EMPTY a135
|
||||||
|
|
||||||
|
MAP_LOOKUP a82 a a143
|
||||||
|
|
||||||
|
MAP_LOOKUPD var112 arg35 a163 var112
|
||||||
|
|
||||||
|
MAP_UPDATE false a0 a56 a
|
||||||
|
|
||||||
|
MAP_DELETE arg180 a var1
|
||||||
|
|
||||||
|
MAP_MEMBER a { true => 4} 94
|
||||||
|
|
||||||
|
MAP_FROM_LIST () a159
|
||||||
|
|
||||||
|
NIL arg91
|
||||||
|
|
||||||
|
IS_NIL a121 var6
|
||||||
|
|
||||||
|
CONS arg185 "foo" a114
|
||||||
|
|
||||||
|
HD a150 var124
|
||||||
|
|
||||||
|
TL arg223 a
|
||||||
|
|
||||||
|
LENGTH var216 a143
|
||||||
|
|
||||||
|
STR_EQ { 203961992615221001243597889146034217896 => 0x1f53a1843} 281217554184165828643225535776787296845 a177
|
||||||
|
|
||||||
|
STR_JOIN a a 7144184027126178769820155907121270843348
|
||||||
|
|
||||||
|
INT_TO_STR var238 a
|
||||||
|
|
||||||
|
ADDR_TO_STR a arg216
|
||||||
|
|
||||||
|
STR_REVERSE a174 #nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv
|
||||||
|
|
||||||
|
INT_TO_ADDR arg127 var207
|
||||||
|
|
||||||
|
VARIANT a a 0x1f7b72200 a
|
||||||
|
|
||||||
|
VARIANT_TEST a26 arg217 a
|
||||||
|
|
||||||
|
VARIANT_ELEMENT a86 arg103 arg108
|
||||||
|
|
||||||
|
BITS_NONEA
|
||||||
|
|
||||||
|
BITS_NONE a
|
||||||
|
|
||||||
|
BITS_ALLA
|
||||||
|
|
||||||
|
BITS_ALL a164
|
||||||
|
|
||||||
|
BITS_ALL_N a221 arg135
|
||||||
|
|
||||||
|
BITS_SET arg150 a48 { 0x1a715e2a6 => 3}
|
||||||
|
|
||||||
|
BITS_CLEAR arg98 a arg164
|
||||||
|
|
||||||
|
BITS_TEST a a242 (| 5 | 2 | (1, "foo", ()) |)
|
||||||
|
|
||||||
|
BITS_SUM a244 a71
|
||||||
|
|
||||||
|
BITS_OR var20 var186 a
|
||||||
|
|
||||||
|
BITS_AND a187 4 arg203
|
||||||
|
|
||||||
|
BITS_DIFF var200 arg247 var20
|
||||||
|
|
||||||
|
ADDRESS a237
|
||||||
|
|
||||||
|
BALANCE a231
|
||||||
|
|
||||||
|
ORIGIN arg216
|
||||||
|
|
||||||
|
CALLER a27
|
||||||
|
|
||||||
|
GASPRICE arg119
|
||||||
|
|
||||||
|
BLOCKHASH arg110
|
||||||
|
|
||||||
|
BENEFICIARY var163
|
||||||
|
|
||||||
|
TIMESTAMP a
|
||||||
|
|
||||||
|
GENERATION 242795038229506961431398379342231049652
|
||||||
|
|
||||||
|
MICROBLOCK arg43
|
||||||
|
|
||||||
|
DIFFICULTY var24
|
||||||
|
|
||||||
|
GASLIMIT arg220
|
||||||
|
|
||||||
|
GAS var35
|
||||||
|
|
||||||
|
LOG0 a a85
|
||||||
|
|
||||||
|
LOG1 arg94 arg86 arg208
|
||||||
|
|
||||||
|
LOG2 a113 (| 5 | 2 | (1, "foo", ()) |) arg238 var108
|
||||||
|
|
||||||
|
LOG3 arg255 arg15 arg211 var139 arg44
|
||||||
|
|
||||||
|
LOG4 #nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv a247 a 9 a38 a
|
||||||
|
|
||||||
|
DEACTIVATE
|
||||||
|
|
||||||
|
SPEND #nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv var136
|
||||||
|
|
||||||
|
ORACLE_REGISTER arg29 48 ((| 5 | 2 | (1, "foo", ()) |)) arg65 { <> => false} <>
|
||||||
|
|
||||||
|
ORACLE_QUERY
|
||||||
|
|
||||||
|
ORACLE_RESPOND
|
||||||
|
|
||||||
|
ORACLE_EXTEND
|
||||||
|
|
||||||
|
ORACLE_GET_ANSWER
|
||||||
|
|
||||||
|
ORACLE_GET_QUESTION
|
||||||
|
|
||||||
|
ORACLE_QUERY_FEE
|
||||||
|
|
||||||
|
AENS_RESOLVE
|
||||||
|
|
||||||
|
AENS_PRECLAIM
|
||||||
|
|
||||||
|
AENS_CLAIM
|
||||||
|
|
||||||
|
AENS_UPDATE
|
||||||
|
|
||||||
|
AENS_TRANSFER
|
||||||
|
|
||||||
|
AENS_REVOKE
|
||||||
|
|
||||||
|
ECVERIFY
|
||||||
|
|
||||||
|
SHA3
|
||||||
|
|
||||||
|
SHA256
|
||||||
|
|
||||||
|
BLAKE2B
|
||||||
|
|
||||||
|
DUMMY7ARG a a 7607708484837907159893701471377343595877 (| 2 | 0 | ( [], [ 45, { 1 => 3441201581501946066216994494994943246334} ] ) |) a0 var56 "foo"
|
||||||
|
|
||||||
|
DUMMY8ARG 3673679924816289365509492271980889822579 a69 arg242 var237 a175 arg106 () var255
|
||||||
|
|
||||||
|
ABORT a
|
||||||
|
|
||||||
|
EXIT var120
|
||||||
|
|
||||||
|
NOP
|
||||||
|
|
||||||
|
RETURNR ()
|
@ -69,5 +69,9 @@ FUNCTION address() : address
|
|||||||
RETURNR #deadbeef
|
RETURNR #deadbeef
|
||||||
|
|
||||||
;; Option(integer) = NONE | SOME(integer)
|
;; Option(integer) = NONE | SOME(integer)
|
||||||
FUNCTION varaint() : {variant, [{tuple, []}, {tuple, [integer]}]}
|
FUNCTION variant_none() : {variant, [{tuple, []}, {tuple, [integer]}]}
|
||||||
RETURNR #deadbeef
|
RETURNR (| 2 | 0 | () |)
|
||||||
|
|
||||||
|
;; Option(integer) = NONE | SOME(integer)
|
||||||
|
FUNCTION variant_some() : {variant, [{tuple, []}, {tuple, [integer]}]}
|
||||||
|
RETURNR (| 2 | 1 | (42) |)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user