From 5eb3689458dceb40d27dd02e1581c026b8db2b56 Mon Sep 17 00:00:00 2001 From: Erik Stenman Date: Fri, 1 Mar 2019 16:06:03 +0100 Subject: [PATCH 1/2] Handle 5 to 8 args. Generate a test file with all instructions for asm/disasm. --- src/aeb_fate_asm.erl | 228 ++++++++++++++++++++++++--- src/aeb_fate_asm_scan.template | 4 +- src/aeb_fate_generate_ops.erl | 131 +++++++++++++++- test/aeb_fate_asm_test.erl | 1 + test/asm_code/all_instructions.fate | 229 ++++++++++++++++++++++++++++ test/asm_code/immediates.fate | 8 +- 6 files changed, 573 insertions(+), 28 deletions(-) create mode 100644 test/asm_code/all_instructions.fate diff --git a/src/aeb_fate_asm.erl b/src/aeb_fate_asm.erl index 024b5ba..7a91981 100644 --- a/src/aeb_fate_asm.erl +++ b/src/aeb_fate_asm.erl @@ -341,14 +341,13 @@ deserialize_op(?SWITCH_VN, Rest, Code) -> <> = Rest, {Arg0, Rest3} = aeb_fate_encoding:deserialize_one(Rest2), 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), immediate = bits_to_modifier((ArgType bsr 2) band 2#11), - {BBs, Rest5} = deserialize_n(N, Rest4), - {Rest5, [{aeb_fate_opcodes:mnemonic(?SWITCH_VN) + {Rest4, [{aeb_fate_opcodes:mnemonic(?SWITCH_VN) , {Modifier0, Arg0} - , {immediate, N} - , list_to_tuple(BBs)} + , {immediate, L} + } | Code]}; _ -> exit(bad_argument_to_switch_vn) end; @@ -397,17 +396,107 @@ deserialize_op(Op, Rest, Code) -> , {Modifier1, Arg1} , {Modifier2, Arg2} , {Modifier3, Arg3}} - | Code]} + | Code]}; + 5 -> + <> = 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 -> + <> = 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 -> + <> = 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 -> + <> = 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]} 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 %% xx xx xx xx %% Arg3 Arg2 Arg1 Arg0 +%% For 5-8 args another Argument Spec Byte is used %% Bit pattern %% 00 : stack/unused (depending on instruction) %% 01 : argN %% 10 : varN %% 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} , {Arg1Type, Arg1} @@ -505,17 +697,15 @@ serialize_code([ ?ELEMENT | serialize_code(Rest)]; serialize_code([ ?SWITCH_VN , {Arg0Type, Arg0} - , {immediate, N} - | Rest]) when is_integer(N), N >= 0 -> + , {immediate, L} + | Rest]) -> ArgSpec = modifier_bits(Arg0Type) bor (modifier_bits(immediate) bsl 2), - {Serialization, Rest2} = serialize_n_ints(N, Rest), [?SWITCH_VN , ArgSpec , serialize_data(Arg0Type, Arg0) - , serialize_data(immediate, N) - | Serialization] ++ serialize_code(Rest2); + , serialize_data(immediate, L)] ++ serialize_code(Rest); serialize_code([B|Rest]) -> [B | serialize_code(Rest)]; serialize_code([]) -> []. diff --git a/src/aeb_fate_asm_scan.template b/src/aeb_fate_asm_scan.template index 9c6fd00..1fa686a 100644 --- a/src/aeb_fate_asm_scan.template +++ b/src/aeb_fate_asm_scan.template @@ -55,8 +55,8 @@ FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}. \: : {token, {to, TokenLine}}. \=\> : {token, {arrow, TokenLine}}. -\(\| : {token, {start_varaint, TokenLine}}. -\|\) : {token, {end_varaint, TokenLine}}. +\(\| : {token, {start_variant, TokenLine}}. +\|\) : {token, {end_variant, TokenLine}}. , : {token, {',', TokenLine}}. \( : {token, {'(', TokenLine}}. diff --git a/src/aeb_fate_generate_ops.erl b/src/aeb_fate_generate_ops.erl index 5cfe13a..54c10cf 100644 --- a/src/aeb_fate_generate_ops.erl +++ b/src/aeb_fate_generate_ops.erl @@ -1,7 +1,8 @@ -module(aeb_fate_generate_ops). -export([ gen_and_halt/1 - , generate/0]). + , generate/0 + , test_asm_generator/1]). gen_and_halt([SrcDirArg, IncludeDirArg]) -> 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."} , { '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_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."} , { '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."} @@ -411,8 +412,8 @@ gen_asm_pp(Module, Path, Ops) -> "-export([format_op/2]).\n\n" "format_arg(t, T) ->\n" " io_lib:format(\"~~p \", [T]);\n" - "format_arg(li, List) ->\n" - " [[\" \", E] || {immedate, E} <- List];\n" + "format_arg(li, {immediate, LI}) ->\n" + " aeb_fate_data:format(LI);\n" "format_arg(_, {immediate, I}) ->\n" " aeb_fate_data:format(I);\n" "format_arg(a, {arg, N}) -> io_lib:format(\"arg~~p\", [N]);\n" @@ -420,7 +421,7 @@ gen_asm_pp(Module, Path, Ops) -> "format_arg(a, {stack, 0}) -> \"a\";\n" "format_arg(a, {stack, N}) -> io_lib:format(\"a~~p\", [N]).\n\n" "lookup(Name, Symbols) ->\n" - " maps:get(Name, Symbols, Name).\n\n" + " maps:get(Name, Symbols, io_lib:format(\"~~w\",[Name])).\n\n" "~s" , [Formats]), @@ -499,3 +500,123 @@ gen_format(#{opname := Name, format := Args}) -> "\" \", format_arg(~w, Arg6)];", [Name, NameAsString, T0, T1, T2, T3, T4, T5, T6]) 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. diff --git a/test/aeb_fate_asm_test.erl b/test/aeb_fate_asm_test.erl index fc20dbd..33b3989 100644 --- a/test/aeb_fate_asm_test.erl +++ b/test/aeb_fate_asm_test.erl @@ -52,6 +52,7 @@ sources() -> , "tuple" , "mapofmap" , "immediates" + , "all_instructions" ]. check_roundtrip(File) -> diff --git a/test/asm_code/all_instructions.fate b/test/asm_code/all_instructions.fate new file mode 100644 index 0000000..21ce830 --- /dev/null +++ b/test/asm_code/all_instructions.fate @@ -0,0 +1,229 @@ +;; 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 var150 + + CALL foo + + CALL_R arg242 foo + + CALL_T foo + + CALL_TR a foo + + JUMP 2778181099722339546444847932597842403980 + + JUMPIF arg71 17 + + SWITCH_V2 var242 7 51 + + SWITCH_V3 var90 0x1bdd846f3 9 0x17cbdd6c9 + + SWITCH_VN arg153 [1, 2, 3] + + PUSH var118 + + DUPA + + DUP var85 + + POP (| 2 | 1 | ( 4557687389579322034215261600548680294108 ) |) + + STORE 0x23f57a6d7 a + + INCA + + INC var100 + + DECA + + DEC var230 + + ADD a111 a a + + SUB 93 arg198 a140 + + MUL var240 a77 arg67 + + DIV arg169 1 95 + + MOD a241 a a + + POW arg143 a a121 + + LT a252 var158 var204 + + GT var141 a195 6565006908676281259280322225737939009024 + + EQ arg16 a166 0x8f076589 + + ELT var117 0x8175205c 0xb659ba4a + + EGT a a a + + NEQ var105 a arg170 + + AND a154 var183 a55 + + OR var103 var201 a250 + + NOT arg158 a17 + + TUPLE 6 + + ELEMENT integer (| 2 | 0 | ( 7875086700039857579956050953972728274596, 35 ) |) a9 a27 + + MAP_EMPTY a180 + + MAP_LOOKUP var76 arg238 arg180 + + MAP_LOOKUPD a arg209 arg71 !<> + + MAP_UPDATE arg243 a13 false a + + MAP_DELETE arg237 arg138 0x16bb2da52 + + MAP_MEMBER a134 a49 arg231 + + MAP_FROM_LIST a250 8 + + NIL [ ] + + IS_NIL 0x21968d787 5311352343894713188976994917630885293949 + + CONS a arg209 57 + + HD arg242 a + + TL a var194 + + LENGTH var70 a236 + + STR_EQ (| 5 | 2 | (1, "foo", ()) |) 50 (| 2 | 1 | ( 0x17a9e8119 ) |) + + STR_JOIN a1 a85 <> + + INT_TO_STR a82 var203 + + ADDR_TO_STR arg159 a199 + + STR_REVERSE a36 a + + INT_TO_ADDR var161 arg92 + + VARIANT var252 a162 a 0xb1912372 + + VARIANT_TEST 11 arg173 [ (), 3 ] + + VARIANT_ELEMENT a103 a201 a + + BITS_NONEA + + BITS_NONE [ (| 2 | 1 | ( { 0xa0ee2284 => [ 6 ]} ) |) ] + + BITS_ALLA + + BITS_ALL "foo" + + BITS_ALL_N a a77 + + BITS_SET a53 var101 arg213 + + BITS_CLEAR arg142 a var157 + + BITS_TEST var125 ([(| 2 | 1 | ( 4 ) |) ]) 3084289254269705189827835600187262322355 + + BITS_SUM var197 a + + BITS_OR a var35 ("foo") + + BITS_AND a1 a8 arg213 + + BITS_DIFF a var24 a + + ADDRESS 8 + + BALANCE 2 + + ORIGIN var208 + + CALLER 90 + + GASPRICE a188 + + BLOCKHASH arg18 + + BENEFICIARY a + + TIMESTAMP arg84 + + GENERATION arg110 + + MICROBLOCK { 3 => 7374978216136870915189251106310661704403} + + DIFFICULTY var58 + + GASLIMIT a + + GAS { true => 0x10acb2ff2} + + LOG0 var170 arg108 + + LOG1 a [] arg209 + + LOG2 a var170 arg8 a + + LOG3 arg213 a #nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv [ "foo", [] ] var204 + + LOG4 a57 a 0x237fcc40c arg167 arg230 var59 + + DEACTIVATE + + SPEND arg243 var172 + + ORACLE_REGISTER a arg223 var193 arg60 a111 a182 + + 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 + + ABORT a + + EXIT (0x34df4f98) + + NOP + + RETURNR () diff --git a/test/asm_code/immediates.fate b/test/asm_code/immediates.fate index 8f32280..3efcc1a 100644 --- a/test/asm_code/immediates.fate +++ b/test/asm_code/immediates.fate @@ -69,5 +69,9 @@ FUNCTION address() : address RETURNR #deadbeef ;; Option(integer) = NONE | SOME(integer) -FUNCTION varaint() : {variant, [{tuple, []}, {tuple, [integer]}]} - RETURNR #deadbeef +FUNCTION variant_none() : {variant, [{tuple, []}, {tuple, [integer]}]} + RETURNR (| 2 | 0 | () |) + +;; Option(integer) = NONE | SOME(integer) +FUNCTION variant_some() : {variant, [{tuple, []}, {tuple, [integer]}]} + RETURNR (| 2 | 1 | (42) |) -- 2.30.2 From b632927127d5affc3710f23caf2cc680991b4574 Mon Sep 17 00:00:00 2001 From: Erik Stenman Date: Fri, 1 Mar 2019 16:23:30 +0100 Subject: [PATCH 2/2] Add ops to test 7 and 8 arguments. --- src/aeb_fate_asm.erl | 14 --- src/aeb_fate_generate_ops.erl | 21 +++- test/asm_code/all_instructions.fate | 172 ++++++++++++++-------------- 3 files changed, 106 insertions(+), 101 deletions(-) diff --git a/src/aeb_fate_asm.erl b/src/aeb_fate_asm.erl index 7a91981..cc9200d 100644 --- a/src/aeb_fate_asm.erl +++ b/src/aeb_fate_asm.erl @@ -710,20 +710,6 @@ serialize_code([B|Rest]) -> [B | serialize_code(Rest)]; 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) %% 01 : argN diff --git a/src/aeb_fate_generate_ops.erl b/src/aeb_fate_generate_ops.erl index 54c10cf..3b77417 100644 --- a/src/aeb_fate_generate_ops.erl +++ b/src/aeb_fate_generate_ops.erl @@ -137,8 +137,11 @@ ops_defs() -> , { 'SHA256', 16#7c, 0, false,3, atomic, sha256, ""} , { '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."} %% FUNCTION 16#fe "Function declaration and entrypoint." %% EXTEND 16#ff "Reserved for future extensions beyond one byte opcodes." @@ -498,7 +501,19 @@ gen_format(#{opname := Name, format := Args}) -> "\" \", format_arg(~w, Arg4)," "\" \", format_arg(~w, Arg5)," "\" \", 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) -> diff --git a/test/asm_code/all_instructions.fate b/test/asm_code/all_instructions.fate index 21ce830..0755a6e 100644 --- a/test/asm_code/all_instructions.fate +++ b/test/asm_code/all_instructions.fate @@ -6,187 +6,187 @@ FUNCTION foo () : {tuple, []} RETURN - RETURNR var150 + RETURNR a13 CALL foo - CALL_R arg242 foo + CALL_R arg125 foo CALL_T foo - CALL_TR a foo + CALL_TR arg245 foo - JUMP 2778181099722339546444847932597842403980 + JUMP 5514251025295783441695716053282666408426 - JUMPIF arg71 17 + JUMPIF arg196 0x12c651665 - SWITCH_V2 var242 7 51 + SWITCH_V2 a27 63 33 - SWITCH_V3 var90 0x1bdd846f3 9 0x17cbdd6c9 + SWITCH_V3 var4 0x1d61723dd 79 7 - SWITCH_VN arg153 [1, 2, 3] + SWITCH_VN #nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv [1, 2, 3] - PUSH var118 + PUSH var80 DUPA - DUP var85 + DUP a - POP (| 2 | 1 | ( 4557687389579322034215261600548680294108 ) |) + POP a107 - STORE 0x23f57a6d7 a + STORE arg183 var225 INCA - INC var100 + INC a25 DECA - DEC var230 + DEC a - ADD a111 a a + ADD a217 a a - SUB 93 arg198 a140 + SUB arg35 arg165 var74 - MUL var240 a77 arg67 + MUL 44 35 "foo" - DIV arg169 1 95 + DIV 263838340369912686645632650718169038811 a24 a - MOD a241 a a + MOD var113 arg80 arg207 - POW arg143 a a121 + POW a176 a a123 - LT a252 var158 var204 + LT a 78 var81 - GT var141 a195 6565006908676281259280322225737939009024 + GT arg19 4729414120208894485838100532547810615352 var175 - EQ arg16 a166 0x8f076589 + EQ 85 a arg164 - ELT var117 0x8175205c 0xb659ba4a + ELT a161 arg226 a168 - EGT a a a + EGT a131 1 var250 - NEQ var105 a arg170 + NEQ a85 a a83 - AND a154 var183 a55 + AND var255 0x294a24f6 var189 - OR var103 var201 a250 + OR (| 2 | 0 | ( (), (42) ) |) arg168 var107 - NOT arg158 a17 + NOT arg124 a - TUPLE 6 + TUPLE 5019186157739257888756115213149493826410 - ELEMENT integer (| 2 | 0 | ( 7875086700039857579956050953972728274596, 35 ) |) a9 a27 + ELEMENT integer arg148 var25 a219 - MAP_EMPTY a180 + MAP_EMPTY a135 - MAP_LOOKUP var76 arg238 arg180 + MAP_LOOKUP a82 a a143 - MAP_LOOKUPD a arg209 arg71 !<> + MAP_LOOKUPD var112 arg35 a163 var112 - MAP_UPDATE arg243 a13 false a + MAP_UPDATE false a0 a56 a - MAP_DELETE arg237 arg138 0x16bb2da52 + MAP_DELETE arg180 a var1 - MAP_MEMBER a134 a49 arg231 + MAP_MEMBER a { true => 4} 94 - MAP_FROM_LIST a250 8 + MAP_FROM_LIST () a159 - NIL [ ] + NIL arg91 - IS_NIL 0x21968d787 5311352343894713188976994917630885293949 + IS_NIL a121 var6 - CONS a arg209 57 + CONS arg185 "foo" a114 - HD arg242 a + HD a150 var124 - TL a var194 + TL arg223 a - LENGTH var70 a236 + LENGTH var216 a143 - STR_EQ (| 5 | 2 | (1, "foo", ()) |) 50 (| 2 | 1 | ( 0x17a9e8119 ) |) + STR_EQ { 203961992615221001243597889146034217896 => 0x1f53a1843} 281217554184165828643225535776787296845 a177 - STR_JOIN a1 a85 <> + STR_JOIN a a 7144184027126178769820155907121270843348 - INT_TO_STR a82 var203 + INT_TO_STR var238 a - ADDR_TO_STR arg159 a199 + ADDR_TO_STR a arg216 - STR_REVERSE a36 a + STR_REVERSE a174 #nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv - INT_TO_ADDR var161 arg92 + INT_TO_ADDR arg127 var207 - VARIANT var252 a162 a 0xb1912372 + VARIANT a a 0x1f7b72200 a - VARIANT_TEST 11 arg173 [ (), 3 ] + VARIANT_TEST a26 arg217 a - VARIANT_ELEMENT a103 a201 a + VARIANT_ELEMENT a86 arg103 arg108 BITS_NONEA - BITS_NONE [ (| 2 | 1 | ( { 0xa0ee2284 => [ 6 ]} ) |) ] + BITS_NONE a BITS_ALLA - BITS_ALL "foo" + BITS_ALL a164 - BITS_ALL_N a a77 + BITS_ALL_N a221 arg135 - BITS_SET a53 var101 arg213 + BITS_SET arg150 a48 { 0x1a715e2a6 => 3} - BITS_CLEAR arg142 a var157 + BITS_CLEAR arg98 a arg164 - BITS_TEST var125 ([(| 2 | 1 | ( 4 ) |) ]) 3084289254269705189827835600187262322355 + BITS_TEST a a242 (| 5 | 2 | (1, "foo", ()) |) - BITS_SUM var197 a + BITS_SUM a244 a71 - BITS_OR a var35 ("foo") + BITS_OR var20 var186 a - BITS_AND a1 a8 arg213 + BITS_AND a187 4 arg203 - BITS_DIFF a var24 a + BITS_DIFF var200 arg247 var20 - ADDRESS 8 + ADDRESS a237 - BALANCE 2 + BALANCE a231 - ORIGIN var208 + ORIGIN arg216 - CALLER 90 + CALLER a27 - GASPRICE a188 + GASPRICE arg119 - BLOCKHASH arg18 + BLOCKHASH arg110 - BENEFICIARY a + BENEFICIARY var163 - TIMESTAMP arg84 + TIMESTAMP a - GENERATION arg110 + GENERATION 242795038229506961431398379342231049652 - MICROBLOCK { 3 => 7374978216136870915189251106310661704403} + MICROBLOCK arg43 - DIFFICULTY var58 + DIFFICULTY var24 - GASLIMIT a + GASLIMIT arg220 - GAS { true => 0x10acb2ff2} + GAS var35 - LOG0 var170 arg108 + LOG0 a a85 - LOG1 a [] arg209 + LOG1 arg94 arg86 arg208 - LOG2 a var170 arg8 a + LOG2 a113 (| 5 | 2 | (1, "foo", ()) |) arg238 var108 - LOG3 arg213 a #nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv [ "foo", [] ] var204 + LOG3 arg255 arg15 arg211 var139 arg44 - LOG4 a57 a 0x237fcc40c arg167 arg230 var59 + LOG4 #nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv a247 a 9 a38 a DEACTIVATE - SPEND arg243 var172 + SPEND #nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv var136 - ORACLE_REGISTER a arg223 var193 arg60 a111 a182 + ORACLE_REGISTER arg29 48 ((| 5 | 2 | (1, "foo", ()) |)) arg65 { <> => false} <> ORACLE_QUERY @@ -220,9 +220,13 @@ FUNCTION foo () : {tuple, []} BLAKE2B + DUMMY7ARG a a 7607708484837907159893701471377343595877 (| 2 | 0 | ( [], [ 45, { 1 => 3441201581501946066216994494994943246334} ] ) |) a0 var56 "foo" + + DUMMY8ARG 3673679924816289365509492271980889822579 a69 arg242 var237 a175 arg106 () var255 + ABORT a - EXIT (0x34df4f98) + EXIT var120 NOP -- 2.30.2