anchor.diff:              ct:log("Did not find disassembly test for ~ts.~n~ts",
                      [Symbol, Anno])
       end.
  -    
  +
  +get_tmp_asm_files() ->
  +    {ok, Cwd} = file:get_cwd(),
  +    filelib:wildcard(filename:join(Cwd, "*.asm")).
  +
  +named_labels(_Config) ->
  +    %% Check that pretty printing of named labels is working. We do
  +    %% that by loading this module in an emulator running with +JDdump
  +    %% true and then checking that the produced jit_SUITE.asm contains
  +    %% a label for each exported function. We also check that the
  +    %% label for the non-exported function get_tmp_asm_files/0, which
  +    %% is used by this test, is present.
  +    Exports = proplists:get_value(exports, ?MODULE:module_info()),
  +    ModName = atom_to_list(?MODULE),
  +    ModulePath = filename:dirname(code:which(?MODULE)),
  +    Cmd = "erl +JDdump true -noshell -pa " ++ ModulePath ++ " -eval \""
  +        ++ ModName ++ ":module_info(),erlang:halt(0).\"",
  +    os:cmd(Cmd),
  +    {ok, Cwd} = file:get_cwd(),
  +    AsmFile = filename:join(Cwd, ModName ++ ".asm"),
  +    {ok, Data} = file:read_file(AsmFile),
  +    Expected = sets:from_list([ lists:flatten(io_lib:format("~p/~p", [N,A]))
  +                                || {N,A} <- Exports]
  +                              ++ ["get_tmp_asm_files/0"]),
  +    StripSeqNo = fun(Lbl) ->
  +                         %% In the Arm JIT, labels have the form
  +                         %% @Mod:Name/Arity-SequenceNumber, so strip
  +                         %% out the Mod part and the sequence number
  +                         %% as we can't know anything about them.
  +                         case re:run(Lbl, "^.*\:(.*)-[0-9]*$",
  +                                     [{capture,all_but_first,list}]) of
  +                             {match,[R]} -> R;
  +                             nomatch -> Lbl
  +                         end
  +                 end,
  +    case re:run(Data, "^(.*)\:\n",
  +                [global,multiline,{capture,all_but_first,list}]) of
  +        {match,Labels} ->
  +            Found = sets:from_list([ StripSeqNo(NA) || [NA] <- Labels]),
  +            case sets:is_subset(Expected, Found) of
  +                true ->
  +                    ok;
  +                false ->
  +                    ct:fail("Expected ~p, found ~p",
  +                            [sets:to_list(Expected), sets:to_list(Found)])
  +            end;
  +        _ ->
  +            ct:fail("No labels found in assembly dump")
  +    end.
  
positive.code:     [{perf, [symbols, annotate]}].
  
  all() ->
      [{group, perf}].
  
  init_per_suite(Config) ->
      case erlang:system_info(emu_flavor) of
  
negative.code: 
  -export([suite/0, groups/0, all/0,
           init_per_suite/1, end_per_suite/1,
           init_per_group/2, end_per_group/2,
           init_per_testcase/2, end_per_testcase/2]).
  -export([annotate/1, named_labels/1, symbols/1]).
  
  suite() ->
      [{timetrap, {minutes, 4}}].
  