diff --git a/erlang/apps/sim/src/sim_core.erl b/erlang/apps/sim/src/sim_core.erl
index a795ac7..ec812d3 100644
--- a/erlang/apps/sim/src/sim_core.erl
+++ b/erlang/apps/sim/src/sim_core.erl
@@ -414,6 +414,70 @@ dispatch(Core, Mem, IR, EA) ->
8#575 -> sim_boolean:handle_SETZ(Core, Mem, IR, EA); % HLREI = HLRZI = SETZ
8#576 -> sim_halfword:handle_HLREM(Core, Mem, IR, EA);
8#577 -> sim_halfword:handle_HLRES(Core, Mem, IR, EA);
+ 8#600 -> next_pc(Core, Mem); % TRN = no-op
+ 8#601 -> next_pc(Core, Mem); % TLN = no-op
+ 8#602 -> sim_logical:handle_TRNE(Core, Mem, IR, EA);
+ 8#603 -> sim_logical:handle_TLNE(Core, Mem, IR, EA);
+ 8#604 -> skip(Core, Mem); % TRNA = SKIPA without the memory read
+ 8#605 -> skip(Core, Mem); % TLNA = SKIPA without the memory read
+ 8#606 -> sim_logical:handle_TRNN(Core, Mem, IR, EA);
+ 8#607 -> sim_logical:handle_TLNN(Core, Mem, IR, EA);
+ 8#610 -> sim_logical:handle_TDN(Core, Mem, IR, EA);
+ 8#611 -> sim_logical:handle_TSN(Core, Mem, IR, EA);
+ 8#612 -> sim_logical:handle_TDNE(Core, Mem, IR, EA);
+ 8#613 -> sim_logical:handle_TSNE(Core, Mem, IR, EA);
+ 8#614 -> sim_logical:handle_TDNA(Core, Mem, IR, EA);
+ 8#615 -> sim_logical:handle_TSNA(Core, Mem, IR, EA);
+ 8#616 -> sim_logical:handle_TDNN(Core, Mem, IR, EA);
+ 8#617 -> sim_logical:handle_TSNN(Core, Mem, IR, EA);
+ 8#620 -> sim_logical:handle_TRZ(Core, Mem, IR, EA);
+ 8#621 -> sim_logical:handle_TLZ(Core, Mem, IR, EA);
+ 8#622 -> sim_logical:handle_TRZE(Core, Mem, IR, EA);
+ 8#623 -> sim_logical:handle_TLZE(Core, Mem, IR, EA);
+ 8#624 -> sim_logical:handle_TRZA(Core, Mem, IR, EA);
+ 8#625 -> sim_logical:handle_TLZA(Core, Mem, IR, EA);
+ 8#626 -> sim_logical:handle_TRZN(Core, Mem, IR, EA);
+ 8#627 -> sim_logical:handle_TLZN(Core, Mem, IR, EA);
+ 8#630 -> sim_logical:handle_TDZ(Core, Mem, IR, EA);
+ 8#631 -> sim_logical:handle_TSZ(Core, Mem, IR, EA);
+ 8#632 -> sim_logical:handle_TDZE(Core, Mem, IR, EA);
+ 8#633 -> sim_logical:handle_TSZE(Core, Mem, IR, EA);
+ 8#634 -> sim_logical:handle_TDZA(Core, Mem, IR, EA);
+ 8#635 -> sim_logical:handle_TSZA(Core, Mem, IR, EA);
+ 8#636 -> sim_logical:handle_TDZN(Core, Mem, IR, EA);
+ 8#637 -> sim_logical:handle_TSZN(Core, Mem, IR, EA);
+ 8#640 -> sim_logical:handle_TRC(Core, Mem, IR, EA);
+ 8#641 -> sim_logical:handle_TLC(Core, Mem, IR, EA);
+ 8#642 -> sim_logical:handle_TRCE(Core, Mem, IR, EA);
+ 8#643 -> sim_logical:handle_TLCE(Core, Mem, IR, EA);
+ 8#644 -> sim_logical:handle_TRCA(Core, Mem, IR, EA);
+ 8#645 -> sim_logical:handle_TLCA(Core, Mem, IR, EA);
+ 8#646 -> sim_logical:handle_TRCN(Core, Mem, IR, EA);
+ 8#647 -> sim_logical:handle_TLCN(Core, Mem, IR, EA);
+ 8#650 -> sim_logical:handle_TDC(Core, Mem, IR, EA);
+ 8#651 -> sim_logical:handle_TSC(Core, Mem, IR, EA);
+ 8#652 -> sim_logical:handle_TDCE(Core, Mem, IR, EA);
+ 8#653 -> sim_logical:handle_TSCE(Core, Mem, IR, EA);
+ 8#654 -> sim_logical:handle_TDCA(Core, Mem, IR, EA);
+ 8#655 -> sim_logical:handle_TSCA(Core, Mem, IR, EA);
+ 8#656 -> sim_logical:handle_TDCN(Core, Mem, IR, EA);
+ 8#657 -> sim_logical:handle_TSCN(Core, Mem, IR, EA);
+ 8#660 -> sim_logical:handle_TRO(Core, Mem, IR, EA);
+ 8#661 -> sim_logical:handle_TLO(Core, Mem, IR, EA);
+ 8#662 -> sim_logical:handle_TROE(Core, Mem, IR, EA);
+ 8#663 -> sim_logical:handle_TLOE(Core, Mem, IR, EA);
+ 8#664 -> sim_logical:handle_TROA(Core, Mem, IR, EA);
+ 8#665 -> sim_logical:handle_TLOA(Core, Mem, IR, EA);
+ 8#666 -> sim_logical:handle_TRON(Core, Mem, IR, EA);
+ 8#667 -> sim_logical:handle_TLON(Core, Mem, IR, EA);
+ 8#670 -> sim_logical:handle_TDO(Core, Mem, IR, EA);
+ 8#671 -> sim_logical:handle_TSO(Core, Mem, IR, EA);
+ 8#672 -> sim_logical:handle_TDOE(Core, Mem, IR, EA);
+ 8#673 -> sim_logical:handle_TSOE(Core, Mem, IR, EA);
+ 8#674 -> sim_logical:handle_TDOA(Core, Mem, IR, EA);
+ 8#675 -> sim_logical:handle_TSOA(Core, Mem, IR, EA);
+ 8#676 -> sim_logical:handle_TDON(Core, Mem, IR, EA);
+ 8#677 -> sim_logical:handle_TSON(Core, Mem, IR, EA);
_ ->
PC = (Core#core.pc_section bsl 18) bor Core#core.pc_offset,
{Core, Mem, {error, {?MODULE, {dispatch, PC, IR, EA}}}}
diff --git a/erlang/apps/sim/src/sim_logical.erl b/erlang/apps/sim/src/sim_logical.erl
new file mode 100644
index 0000000..60d0800
--- /dev/null
+++ b/erlang/apps/sim/src/sim_logical.erl
@@ -0,0 +1,726 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%
+%%% simulator for pdp10-elf
+%%% Copyright (C) 2020 Mikael Pettersson
+%%%
+%%% This file is part of pdp10-tools.
+%%%
+%%% pdp10-tools is free software: you can redistribute it and/or modify
+%%% it under the terms of the GNU General Public License as published by
+%%% the Free Software Foundation, either version 3 of the License, or
+%%% (at your option) any later version.
+%%%
+%%% pdp10-tools is distributed in the hope that it will be useful,
+%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+%%% GNU General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with pdp10-tools. If not, see .
+%%%
+%%%=============================================================================
+%%%
+%%% 2.7 Logical Testing and Modification
+
+-module(sim_logical).
+
+-export([ handle_TDC/4
+ , handle_TDCE/4
+ , handle_TDCA/4
+ , handle_TDCN/4
+ , handle_TDN/4
+ , handle_TDNA/4
+ , handle_TDNE/4
+ , handle_TDNN/4
+ , handle_TDO/4
+ , handle_TDOA/4
+ , handle_TDOE/4
+ , handle_TDON/4
+ , handle_TDZ/4
+ , handle_TDZA/4
+ , handle_TDZE/4
+ , handle_TDZN/4
+ , handle_TLC/4
+ , handle_TLCA/4
+ , handle_TLCE/4
+ , handle_TLCN/4
+ , handle_TLNE/4
+ , handle_TLNN/4
+ , handle_TLO/4
+ , handle_TLOA/4
+ , handle_TLOE/4
+ , handle_TLON/4
+ , handle_TLZ/4
+ , handle_TLZA/4
+ , handle_TLZE/4
+ , handle_TLZN/4
+ , handle_TRC/4
+ , handle_TRCA/4
+ , handle_TRCE/4
+ , handle_TRCN/4
+ , handle_TRNE/4
+ , handle_TRNN/4
+ , handle_TRO/4
+ , handle_TROA/4
+ , handle_TROE/4
+ , handle_TRON/4
+ , handle_TRZ/4
+ , handle_TRZA/4
+ , handle_TRZE/4
+ , handle_TRZN/4
+ , handle_TSC/4
+ , handle_TSCA/4
+ , handle_TSCE/4
+ , handle_TSCN/4
+ , handle_TSN/4
+ , handle_TSNA/4
+ , handle_TSNE/4
+ , handle_TSNN/4
+ , handle_TSO/4
+ , handle_TSOA/4
+ , handle_TSOE/4
+ , handle_TSON/4
+ , handle_TSZ/4
+ , handle_TSZA/4
+ , handle_TSZE/4
+ , handle_TSZN/4
+ ]).
+
+-include("sim_core.hrl").
+
+%% 2.7 Logical Testing and Modification ========================================
+
+%% TRN - Test Right, No Modification, and Skip if Condition Satisfied
+
+-spec handle_TRNE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TRNE(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset,
+ handle_TxNE(Core, Mem, IR, Mask).
+
+-spec handle_TRNN(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TRNN(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset,
+ handle_TxNN(Core, Mem, IR, Mask).
+
+%% TRZ - Test Right, Zeros, and Skip if Condition Satisfied
+
+-spec handle_TRZ(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TRZ(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset,
+ handle_TxZ(Core, Mem, IR, Mask).
+
+-spec handle_TRZE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TRZE(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset,
+ handle_TxZE(Core, Mem, IR, Mask).
+
+-spec handle_TRZA(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TRZA(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset,
+ handle_TxZA(Core, Mem, IR, Mask).
+
+-spec handle_TRZN(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TRZN(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset,
+ handle_TxZN(Core, Mem, IR, Mask).
+
+%% TRC - Test Right, Complement, and Skip if Condition Satisfied
+
+-spec handle_TRC(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TRC(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset,
+ handle_TxC(Core, Mem, IR, Mask).
+
+-spec handle_TRCE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TRCE(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset,
+ handle_TxCE(Core, Mem, IR, Mask).
+
+-spec handle_TRCA(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TRCA(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset,
+ handle_TxCA(Core, Mem, IR, Mask).
+
+-spec handle_TRCN(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TRCN(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset,
+ handle_TxCN(Core, Mem, IR, Mask).
+
+%% TRO - Test Right, Ones, and Skip if Condition Satisfied
+
+-spec handle_TRO(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TRO(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset,
+ handle_TxO(Core, Mem, IR, Mask).
+
+-spec handle_TROE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TROE(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset,
+ handle_TxOE(Core, Mem, IR, Mask).
+
+-spec handle_TROA(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TROA(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset,
+ handle_TxOA(Core, Mem, IR, Mask).
+
+-spec handle_TRON(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TRON(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset,
+ handle_TxON(Core, Mem, IR, Mask).
+
+%% TLN - Test Left, No Modification, and Skip if Condition Satisfied
+
+-spec handle_TLNE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TLNE(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset bsl 18,
+ handle_TxNE(Core, Mem, IR, Mask).
+
+-spec handle_TLNN(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TLNN(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset bsl 18,
+ handle_TxNN(Core, Mem, IR, Mask).
+
+%% TLZ - Test Left, Zeros, and Skip if Condition Satisfied
+
+-spec handle_TLZ(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TLZ(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset bsl 18,
+ handle_TxZ(Core, Mem, IR, Mask).
+
+-spec handle_TLZE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TLZE(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset bsl 18,
+ handle_TxZE(Core, Mem, IR, Mask).
+
+-spec handle_TLZA(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TLZA(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset bsl 18,
+ handle_TxZA(Core, Mem, IR, Mask).
+
+-spec handle_TLZN(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TLZN(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset bsl 18,
+ handle_TxZN(Core, Mem, IR, Mask).
+
+%% TLC - Test Left, Complement, and Skip if Condition Satisfied
+
+-spec handle_TLC(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TLC(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset bsl 18,
+ handle_TxC(Core, Mem, IR, Mask).
+
+-spec handle_TLCE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TLCE(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset bsl 18,
+ handle_TxCE(Core, Mem, IR, Mask).
+
+-spec handle_TLCA(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TLCA(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset bsl 18,
+ handle_TxCA(Core, Mem, IR, Mask).
+
+-spec handle_TLCN(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TLCN(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset bsl 18,
+ handle_TxCN(Core, Mem, IR, Mask).
+
+%% TLO - Test Left, Ones, and Skip if Condition Satisfied
+
+-spec handle_TLO(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TLO(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset bsl 18,
+ handle_TxO(Core, Mem, IR, Mask).
+
+-spec handle_TLOE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TLOE(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset bsl 18,
+ handle_TxOE(Core, Mem, IR, Mask).
+
+-spec handle_TLOA(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TLOA(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset bsl 18,
+ handle_TxOA(Core, Mem, IR, Mask).
+
+-spec handle_TLON(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TLON(Core, Mem, IR, EA) ->
+ Mask = EA#ea.offset bsl 18,
+ handle_TxON(Core, Mem, IR, Mask).
+
+%% TDN - Test Direct, No Modification, and Skip if Condition Satisfied
+
+-spec handle_TDN(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDN(Core, Mem, IR, EA) ->
+ %% this reads memory, but is otherwise a no-op
+ case sim_core:c(Core, Mem, EA) of
+ {ok, _Mask} -> sim_core:next_pc(Core, Mem);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TDNE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDNE(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxNE(Core, Mem, IR, Mask);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TDNA(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDNA(Core, Mem, IR, EA) ->
+ %% this reads memory and skips, but has no other side-effect
+ case sim_core:c(Core, Mem, EA) of
+ {ok, _Mask} -> sim_core:skip(Core, Mem);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TDNN(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDNN(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxNN(Core, Mem, IR, Mask);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+%% TDZ - Test Direct, Zeros, and Skip if Condition Satisfied
+
+-spec handle_TDZ(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDZ(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxZ(Core, Mem, IR, Mask);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TDZE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDZE(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxZE(Core, Mem, IR, Mask);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TDZA(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDZA(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxZA(Core, Mem, IR, Mask);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TDZN(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDZN(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxZN(Core, Mem, IR, Mask);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+%% TDC - Test Direct, Complement, and Skip if Condition Satisfied
+
+-spec handle_TDC(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDC(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxC(Core, Mem, IR, Mask);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TDCE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDCE(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxCE(Core, Mem, IR, Mask);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TDCA(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDCA(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxCA(Core, Mem, IR, Mask);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TDCN(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDCN(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxCN(Core, Mem, IR, Mask);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+%% TDO - Test Direct, Ones, and Skip if Condition Satisfied
+
+-spec handle_TDO(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDO(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxO(Core, Mem, IR, Mask);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TDOE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDOE(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxOE(Core, Mem, IR, Mask);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TDOA(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDOA(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxOA(Core, Mem, IR, Mask);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TDON(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TDON(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxON(Core, Mem, IR, Mask);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+%% TSN - Test Swapped, No Modification, and Skip if Condition Satisfied
+
+-spec handle_TSN(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSN(Core, Mem, IR, EA) ->
+ %% this reads memory, but is otherwise a no-op
+ case sim_core:c(Core, Mem, EA) of
+ {ok, _Mask} -> sim_core:next_pc(Core, Mem);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TSNE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSNE(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxNE(Core, Mem, IR, swap_halves(Mask));
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TSNA(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSNA(Core, Mem, IR, EA) ->
+ %% this reads memory and skips, but has no other side-effect
+ case sim_core:c(Core, Mem, EA) of
+ {ok, _Mask} -> sim_core:skip(Core, Mem);
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TSNN(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSNN(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxNN(Core, Mem, IR, swap_halves(Mask));
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+%% TSZ - Test Swapped, Zeros, and Skip if Condition Satisfied
+
+-spec handle_TSZ(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSZ(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxZ(Core, Mem, IR, swap_halves(Mask));
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TSZE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSZE(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxZE(Core, Mem, IR, swap_halves(Mask));
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TSZA(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSZA(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxZA(Core, Mem, IR, swap_halves(Mask));
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TSZN(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSZN(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxZN(Core, Mem, IR, swap_halves(Mask));
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+%% TSC - Test Swapped, Complement, and Skip if Condition Satisfied
+
+-spec handle_TSC(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSC(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxC(Core, Mem, IR, swap_halves(Mask));
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TSCE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSCE(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxCE(Core, Mem, IR, swap_halves(Mask));
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TSCA(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSCA(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxCA(Core, Mem, IR, swap_halves(Mask));
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TSCN(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSCN(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxCN(Core, Mem, IR, swap_halves(Mask));
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+%% TSO - Test Swapped, Ones, and Skip if Condition Satisfied
+
+-spec handle_TSO(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSO(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxO(Core, Mem, IR, swap_halves(Mask));
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TSOE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSOE(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxOE(Core, Mem, IR, swap_halves(Mask));
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TSOA(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSOA(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxOA(Core, Mem, IR, swap_halves(Mask));
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+-spec handle_TSON(#core{}, sim_mem:mem(), IR :: word(), #ea{})
+ -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
+handle_TSON(Core, Mem, IR, EA) ->
+ case sim_core:c(Core, Mem, EA) of
+ {ok, Mask} -> handle_TxON(Core, Mem, IR, swap_halves(Mask));
+ {error, Reason} ->
+ sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason,
+ fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
+ end.
+
+%% Miscellaneous ===============================================================
+
+handle_TxC(Core, Mem, IR, Mask) ->
+ AC = IR band 8#17,
+ CA = sim_core:get_ac(Core, AC),
+ Core1 = sim_core:set_ac(Core, AC, CA bxor Mask),
+ sim_core:next_pc(Core1, Mem).
+
+handle_TxCA(Core, Mem, IR, Mask) ->
+ AC = IR band 8#17,
+ CA = sim_core:get_ac(Core, AC),
+ Core1 = sim_core:set_ac(Core, AC, CA bxor Mask),
+ sim_core:skip(Core1, Mem).
+
+handle_TxCE(Core, Mem, IR, Mask) ->
+ AC = IR band 8#17,
+ CA = sim_core:get_ac(Core, AC),
+ Core1 = sim_core:set_ac(Core, AC, CA bxor Mask),
+ case CA band Mask of
+ 0 -> sim_core:skip(Core1, Mem);
+ _ -> sim_core:next_pc(Core1, Mem)
+ end.
+
+handle_TxCN(Core, Mem, IR, Mask) ->
+ AC = IR band 8#17,
+ CA = sim_core:get_ac(Core, AC),
+ Core1 = sim_core:set_ac(Core, AC, CA bxor Mask),
+ case CA band Mask of
+ 0 -> sim_core:next_pc(Core1, Mem);
+ _ -> sim_core:skip(Core1, Mem)
+ end.
+
+handle_TxNE(Core, Mem, IR, Mask) ->
+ AC = IR band 8#17,
+ CA = sim_core:get_ac(Core, AC),
+ case CA band Mask of
+ 0 -> sim_core:skip(Core, Mem);
+ _ -> sim_core:next_pc(Core, Mem)
+ end.
+
+handle_TxNN(Core, Mem, IR, Mask) ->
+ AC = IR band 8#17,
+ CA = sim_core:get_ac(Core, AC),
+ case CA band Mask of
+ 0 -> sim_core:next_pc(Core, Mem);
+ _ -> sim_core:skip(Core, Mem)
+ end.
+
+handle_TxO(Core, Mem, IR, Mask) ->
+ AC = IR band 8#17,
+ CA = sim_core:get_ac(Core, AC),
+ Core1 = sim_core:set_ac(Core, AC, CA bor Mask),
+ sim_core:next_pc(Core1, Mem).
+
+handle_TxOA(Core, Mem, IR, Mask) ->
+ AC = IR band 8#17,
+ CA = sim_core:get_ac(Core, AC),
+ Core1 = sim_core:set_ac(Core, AC, CA bor Mask),
+ sim_core:skip(Core1, Mem).
+
+handle_TxOE(Core, Mem, IR, Mask) ->
+ AC = IR band 8#17,
+ CA = sim_core:get_ac(Core, AC),
+ Core1 = sim_core:set_ac(Core, AC, CA bor Mask),
+ case CA band Mask of
+ 0 -> sim_core:skip(Core1, Mem);
+ _ -> sim_core:next_pc(Core1, Mem)
+ end.
+
+handle_TxON(Core, Mem, IR, Mask) ->
+ AC = IR band 8#17,
+ CA = sim_core:get_ac(Core, AC),
+ Core1 = sim_core:set_ac(Core, AC, CA bor Mask),
+ case CA band Mask of
+ 0 -> sim_core:next_pc(Core1, Mem);
+ _ -> sim_core:skip(Core1, Mem)
+ end.
+
+handle_TxZ(Core, Mem, IR, Mask) ->
+ AC = IR band 8#17,
+ CA = sim_core:get_ac(Core, AC),
+ sim_core:next_pc(sim_core:set_ac(Core, AC, CA band bnot Mask), Mem).
+
+handle_TxZA(Core, Mem, IR, Mask) ->
+ AC = IR band 8#17,
+ CA = sim_core:get_ac(Core, AC),
+ sim_core:skip(sim_core:set_ac(Core, AC, CA band bnot Mask), Mem).
+
+handle_TxZE(Core, Mem, IR, Mask) ->
+ AC = IR band 8#17,
+ CA = sim_core:get_ac(Core, AC),
+ case CA band Mask of
+ 0 -> sim_core:skip(Core, Mem); % masked bits already zero
+ _ -> sim_core:next_pc(sim_core:set_ac(Core, AC, CA band bnot Mask), Mem)
+ end.
+
+handle_TxZN(Core, Mem, IR, Mask) ->
+ AC = IR band 8#17,
+ CA = sim_core:get_ac(Core, AC),
+ case CA band Mask of
+ 0 -> sim_core:next_pc(Core, Mem); % masked bits already zero
+ _ -> sim_core:skip(sim_core:set_ac(Core, AC, CA band bnot Mask), Mem)
+ end.
+
+swap_halves(Word) ->
+ Low18Mask = ((1 bsl 18) - 1),
+ ((Word band Low18Mask) bsl 18) bor ((Word bsr 18) band Low18Mask).
+
+ea_address(#ea{section = Section, offset = Offset}) ->
+ (Section bsl 18) bor Offset.
diff --git a/erlang/apps/sim/test/sim_logical_tests.erl b/erlang/apps/sim/test/sim_logical_tests.erl
new file mode 100644
index 0000000..016e703
--- /dev/null
+++ b/erlang/apps/sim/test/sim_logical_tests.erl
@@ -0,0 +1,1219 @@
+%%% -*- erlang-indent-level: 2 -*-
+%%%
+%%% simulator for pdp10-elf
+%%% Copyright (C) 2020 Mikael Pettersson
+%%%
+%%% This file is part of pdp10-tools.
+%%%
+%%% pdp10-tools is free software: you can redistribute it and/or modify
+%%% it under the terms of the GNU General Public License as published by
+%%% the Free Software Foundation, either version 3 of the License, or
+%%% (at your option) any later version.
+%%%
+%%% pdp10-tools is distributed in the hope that it will be useful,
+%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
+%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+%%% GNU General Public License for more details.
+%%%
+%%% You should have received a copy of the GNU General Public License
+%%% along with pdp10-tools. If not, see .
+%%%
+%%%=============================================================================
+%%%
+%%% Test cases for 2.7 Logical Testing and Modification
+
+-module(sim_logical_tests).
+
+-include("../src/sim_core.hrl").
+-include_lib("eunit/include/eunit.hrl").
+
+-define(DEFAULT_FLAGS, (1 bsl ?PDP10_PF_USER)).
+
+-define(LOW18(X), ((X) band ((1 bsl 18) - 1))).
+
+-define(INSN(OP, AC, I, X, Y),
+ (((OP) bsl (35 - 8)) bor
+ ((AC) bsl (35 - 12)) bor
+ ((I) bsl (35 - 13)) bor
+ ((X) bsl (35 - 17)) bor
+ ?LOW18(Y))).
+
+-define(COMMA2(LEFT, RIGHT), ((?LOW18(LEFT) bsl 18) bor ?LOW18(RIGHT))). % LEFT,,RIGHT in MACRO-10
+
+-define(EA(S, O), #ea{section = S, offset = O, islocal = false}).
+-define(AC(A), ?EA(1, A)).
+
+-define(INSN_INVALID, ?INSN(0, 0, 0, 0, 0)).
+
+-define(OP_MOVEI, 8#201).
+-define(OP_MOVSI, 8#205).
+-define(OP_TRN, 8#600).
+-define(OP_TLN, 8#601).
+-define(OP_TRNE, 8#602).
+-define(OP_TLNE, 8#603).
+-define(OP_TRNA, 8#604).
+-define(OP_TLNA, 8#605).
+-define(OP_TRNN, 8#606).
+-define(OP_TLNN, 8#607).
+-define(OP_TDN, 8#610).
+-define(OP_TSN, 8#611).
+-define(OP_TDNE, 8#612).
+-define(OP_TSNE, 8#613).
+-define(OP_TDNA, 8#614).
+-define(OP_TSNA, 8#615).
+-define(OP_TDNN, 8#616).
+-define(OP_TSNN, 8#617).
+-define(OP_TRZ, 8#620).
+-define(OP_TLZ, 8#621).
+-define(OP_TRZE, 8#622).
+-define(OP_TLZE, 8#623).
+-define(OP_TRZA, 8#624).
+-define(OP_TLZA, 8#625).
+-define(OP_TRZN, 8#626).
+-define(OP_TLZN, 8#627).
+-define(OP_TDZ, 8#630).
+-define(OP_TSZ, 8#631).
+-define(OP_TDZE, 8#632).
+-define(OP_TSZE, 8#633).
+-define(OP_TDZA, 8#634).
+-define(OP_TSZA, 8#635).
+-define(OP_TDZN, 8#636).
+-define(OP_TSZN, 8#637).
+-define(OP_TRC, 8#640).
+-define(OP_TLC, 8#641).
+-define(OP_TRCE, 8#642).
+-define(OP_TLCE, 8#643).
+-define(OP_TRCA, 8#644).
+-define(OP_TLCA, 8#645).
+-define(OP_TRCN, 8#646).
+-define(OP_TLCN, 8#647).
+-define(OP_TDC, 8#650).
+-define(OP_TSC, 8#651).
+-define(OP_TDCE, 8#652).
+-define(OP_TSCE, 8#653).
+-define(OP_TDCA, 8#654).
+-define(OP_TSCA, 8#655).
+-define(OP_TDCN, 8#656).
+-define(OP_TSCN, 8#657).
+-define(OP_TRO, 8#660).
+-define(OP_TLO, 8#661).
+-define(OP_TROE, 8#662).
+-define(OP_TLOE, 8#663).
+-define(OP_TROA, 8#664).
+-define(OP_TLOA, 8#665).
+-define(OP_TRON, 8#666).
+-define(OP_TLON, 8#667).
+-define(OP_TDO, 8#670).
+-define(OP_TSO, 8#671).
+-define(OP_TDOE, 8#672).
+-define(OP_TSOE, 8#673).
+-define(OP_TDOA, 8#674).
+-define(OP_TSOA, 8#675).
+-define(OP_TDON, 8#676).
+-define(OP_TSON, 8#677).
+
+%% 2.7 Logical Testing and Modification ========================================
+
+%% TRN - Test Right, No Modification, and Skip if Condition Satisfied
+
+trn_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRN, 1, 0, 0, 0)} % 1,,101/ TRN 1,
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]).
+
+trne_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRNE, 1, 0, 0, 8#070)} % 1,,101/ TRNE 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRNE, 1, 0, 0, 8#707)} % 1,,101/ TRNE 1,707
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]).
+
+trna_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRNA, 1, 0, 0, 0)} % 1,,101/ TRNA 1,
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]).
+
+trnn_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRNN, 1, 0, 0, 8#707)} % 1,,101/ TRNN 1,707
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRNN, 1, 0, 0, 8#070)} % 1,,101/ TRNN 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]).
+
+%% TRZ - Test Right, Zeros, and Skip if Condition Satisfied
+
+trz_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRZ, 1, 0, 0, 8#700)} % 1,,101/ TRZ 1,700
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]).
+
+trze_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRZE, 1, 0, 0, 8#070)} % 1,,101/ TRZE 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRZE, 1, 0, 0, 8#700)} % 1,,101/ TRZE 1,700
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]).
+
+trza_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRZA, 1, 0, 0, 8#700)} % 1,,101/ TRZA 1,700
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]).
+
+trzn_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRZN, 1, 0, 0, 8#700)} % 1,,101/ TRZN 1,700
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRZN, 1, 0, 0, 8#070)} % 1,,101/ TRZN 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]).
+
+%% TRC - Test Right, Complement, and Skip if Condition Satisfied
+
+trc_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRC, 1, 0, 0, 8#770)} % 1,,101/ TRC 1,770
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#077} % AC1 = 0,,077
+ ]).
+
+trce_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRCE, 1, 0, 0, 8#070)} % 1,,101/ TRCE 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#777} % AC1 = 0,,777
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRCE, 1, 0, 0, 8#700)} % 1,,101/ TRCE 1,700
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]).
+
+trca_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRCA, 1, 0, 0, 8#770)} % 1,,101/ TRCA 1,770
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#077} % AC1 = 0,,077
+ ]).
+
+trcn_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRCN, 1, 0, 0, 8#700)} % 1,,101/ TRCN 1,700
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRCN, 1, 0, 0, 8#070)} % 1,,101/ TRCN 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#777} % AC1 = 0,,777
+ ]).
+
+%% TRO - Test Right, Ones, and Skip if Condition Satisfied
+
+tro_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRO, 1, 0, 0, 8#070)} % 1,,101/ TRO 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#777} % AC1 = 0,,777
+ ]).
+
+troe_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TROE, 1, 0, 0, 8#070)} % 1,,101/ TROE 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#777} % AC1 = 0,,777
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TROE, 1, 0, 0, 8#720)} % 1,,101/ TROE 1,720
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#727} % AC1 = 0,,727
+ ]).
+
+troa_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TROA, 1, 0, 0, 8#720)} % 1,,101/ TROA 1,720
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#727} % AC1 = 0,,727
+ ]).
+
+tron_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRON, 1, 0, 0, 8#720)} % 1,,101/ TRON 1,720
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#727} % AC1 = 0,,727
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TRON, 1, 0, 0, 8#020)} % 1,,101/ TRON 1,020
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#727} % AC1 = 0,,727
+ ]).
+
+%% TLN - Test Left, No Modification, and Skip if Condition Satisfied
+
+tln_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLN, 1, 0, 0, 0)} % 1,,101/ TLN 1,
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), ?COMMA2(8#707, 0)} % AC1 = 707,,0
+ ]).
+
+tlne_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLNE, 1, 0, 0, 8#070)} % 1,,101/ TLNE 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), ?COMMA2(8#707, 0)} % AC1 = 707,,0
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLNE, 1, 0, 0, 8#707)} % 1,,101/ TLNE 1,707
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), ?COMMA2(8#707, 0)} % AC1 = 707,,0
+ ]).
+
+tlna_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLNA, 1, 0, 0, 0)} % 1,,101/ TLNA 1,
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), ?COMMA2(8#707, 0)} % AC1 = 707,,0
+ ]).
+
+tlnn_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLNN, 1, 0, 0, 8#707)} % 1,,101/ TLNN 1,707
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), ?COMMA2(8#707, 0)} % AC1 = 707,,0
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLNN, 1, 0, 0, 8#070)} % 1,,101/ TLNN 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), ?COMMA2(8#707, 0)} % AC1 = 707,,0
+ ]).
+
+%% TLZ - Test Left, Zeros, and Skip if Condition Satisfied
+
+tlz_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLZ, 1, 0, 0, 8#700)} % 1,,101/ TLZ 1,700
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), ?COMMA2(8#007, 0)} % AC1 = 007,,0
+ ]).
+
+tlze_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLZE, 1, 0, 0, 8#070)} % 1,,101/ TLZE 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), ?COMMA2(8#707, 0)} % AC1 = 707,,0
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLZE, 1, 0, 0, 8#700)} % 1,,101/ TLZE 1,700
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), ?COMMA2(8#007, 0)} % AC1 = 007,,0
+ ]).
+
+tlza_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLZA, 1, 0, 0, 8#700)} % 1,,101/ TLZA 1,700
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), ?COMMA2(8#007, 0)} % AC1 = 007,,0
+ ]).
+
+tlzn_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLZN, 1, 0, 0, 8#700)} % 1,,101/ TLZN 1,700
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), ?COMMA2(8#007, 0)} % AC1 = 007,,0
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLZN, 1, 0, 0, 8#070)} % 1,,101/ TLZN 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), ?COMMA2(8#707, 0)} % AC1 = 707,,0
+ ]).
+
+%% TLC - Test Left, Complement, and Skip if Condition Satisfied
+
+tlc_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLC, 1, 0, 0, 8#770)} % 1,,101/ TLC 1,770
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), ?COMMA2(8#077, 0)} % AC1 = 077,,0
+ ]).
+
+tlce_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLCE, 1, 0, 0, 8#070)} % 1,,101/ TLCE 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), ?COMMA2(8#777, 0)} % AC1 = 777,,0
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLCE, 1, 0, 0, 8#700)} % 1,,101/ TLCE 1,700
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), ?COMMA2(8#007, 0)} % AC1 = 007,,0
+ ]).
+
+tlca_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLCA, 1, 0, 0, 8#770)} % 1,,101/ TLCA 1,770
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), ?COMMA2(8#077, 0)} % AC1 = 077,,0
+ ]).
+
+tlcn_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLCN, 1, 0, 0, 8#700)} % 1,,101/ TLCN 1,700
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), ?COMMA2(8#007, 0)} % AC1 = 007,,0
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLCN, 1, 0, 0, 8#070)} % 1,,101/ TLCN 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), ?COMMA2(8#777, 0)} % AC1 = 777,,0
+ ]).
+
+%% TLO - Test Left, Ones, and Skip if Condition Satisfied
+
+tlo_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLO, 1, 0, 0, 8#070)} % 1,,101/ TLO 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), ?COMMA2(8#777, 0)} % AC1 = 777,,0
+ ]).
+
+tloe_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLOE, 1, 0, 0, 8#070)} % 1,,101/ TLOE 1,070
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), ?COMMA2(8#777, 0)} % AC1 = 777,,0
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLOE, 1, 0, 0, 8#720)} % 1,,101/ TLOE 1,720
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), ?COMMA2(8#727, 0)} % AC1 = 727,,0
+ ]).
+
+tloa_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLOA, 1, 0, 0, 8#720)} % 1,,101/ TLOA 1,720
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), ?COMMA2(8#727, 0)} % AC1 = 727,,0
+ ]).
+
+tlon_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLON, 1, 0, 0, 8#720)} % 1,,101/ TLON 1,720
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), ?COMMA2(8#727, 0)} % AC1 = 727,,0
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVSI, 1, 0, 0, 8#707)} % 1,,100/ MOVSI 1,707
+ , {1, 8#101, ?INSN(?OP_TLON, 1, 0, 0, 8#020)} % 1,,101/ TLON 1,020
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), ?COMMA2(8#727, 0)} % AC1 = 727,,0
+ ]).
+
+%% TDN - Test Direct, No Modification, and Skip if Condition Satisfied
+
+tdn_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDN, 1, 0, 0, 8#150)} % 1,,101/ TDN 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#150, 0} % 1,,150/ 0,,0
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]).
+
+tdne_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDNE, 1, 0, 0, 8#150)} % 1,,101/ TDNE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#070} % 1,,150/ 0,,070
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDNE, 1, 0, 0, 8#150)} % 1,,101/ TDNE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#707} % 1,,150/ 0,,707
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]).
+
+tdna_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDNA, 1, 0, 0, 8#150)} % 1,,101/ TDNA 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 0} % 1,,150/ 0,,0
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]).
+
+tdnn_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDNN, 1, 0, 0, 8#150)} % 1,,101/ TDNN 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#707} % 1,,150/ 0,,707
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDNN, 1, 0, 0, 8#150)} % 1,,101/ TDNN 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#070} % 1,,150/ 0,,070
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]).
+
+%% TDZ - Test Direct, Zeros, and Skip if Condition Satisfied
+
+tdz_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDZ, 1, 0, 0, 8#150)} % 1,,101/ TDZ 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#150, 8#700} % 1,,150/ 0,,700
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]).
+
+tdze_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDZE, 1, 0, 0, 8#150)} % 1,,101/ TDZE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#070} % 1,,150/ 0,,070
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDZE, 1, 0, 0, 8#150)} % 1,,101/ TDZE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#700} % 1,,150/ 0,,700
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]).
+
+tdza_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDZA, 1, 0, 0, 8#150)} % 1,,101/ TDZA 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#700} % 1,,150/ 0,,700
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]).
+
+tdzn_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDZN, 1, 0, 0, 8#150)} % 1,,101/ TDZN 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#700} % 1,,150/ 0,,700
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDZN, 1, 0, 0, 8#150)} % 1,,101/ TDZN 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#070} % 1,,150/ 0,,070
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]).
+
+%% TDC - Test Direct, Complement, and Skip if Condition Satisfied
+
+tdc_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDC, 1, 0, 0, 8#150)} % 1,,101/ TDC 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#150, 8#770} % 1,,150/ 0,,770
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#077} % AC1 = 0,,077
+ ]).
+
+tdce_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDCE, 1, 0, 0, 8#150)} % 1,,101/ TDCE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#070} % 1,,150/ 0,,070
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#777} % AC1 = 0,,777
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDCE, 1, 0, 0, 8#150)} % 1,,101/ TDCE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#700} % 1,,150/ 0,,700
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]).
+
+tdca_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDCA, 1, 0, 0, 8#150)} % 1,,101/ TDCA 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#770} % 1,,150/ 0,,770
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#077} % AC1 = 0,,077
+ ]).
+
+tdcn_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDCN, 1, 0, 0, 8#150)} % 1,,101/ TDCN 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#700} % 1,,150/ 0,,700
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDCN, 1, 0, 0, 8#150)} % 1,,101/ TDCN 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#070} % 1,,150/ 0,,070
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#777} % AC1 = 0,,777
+ ]).
+
+%% TDO - Test Direct, Ones, and Skip if Condition Satisfied
+
+tdo_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDO, 1, 0, 0, 8#150)} % 1,,101/ TDO 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#150, 8#070} % 1,,150/ 0,,070
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#777} % AC1 = 0,,777
+ ]).
+
+tdoe_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDOE, 1, 0, 0, 8#150)} % 1,,101/ TDOE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#070} % 1,,150/ 0,,070
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#777} % AC1 = 0,,777
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDOE, 1, 0, 0, 8#150)} % 1,,101/ TDOE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#720} % 1,,150/ 0,,720
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#727} % AC1 = 0,,727
+ ]).
+
+tdoa_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDOA, 1, 0, 0, 8#150)} % 1,,101/ TDOA 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#720} % 1,,150/ 0,,720
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#727} % AC1 = 0,,727
+ ]).
+
+tdon_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDON, 1, 0, 0, 8#150)} % 1,,101/ TDON 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#720} % 1,,150/ 0,,720
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#727} % AC1 = 0,,727
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TDON, 1, 0, 0, 8#150)} % 1,,101/ TDON 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 8#020} % 1,,150/ 0,,020
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#727} % AC1 = 0,,727
+ ]).
+
+%% TSN - Test Swapped, No Modification, and Skip if Condition Satisfied
+
+tsn_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSN, 1, 0, 0, 8#150)} % 1,,101/ TSN 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#150, 0} % 1,,150/ 0,,0
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]).
+
+tsne_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSNE, 1, 0, 0, 8#150)} % 1,,101/ TSNE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#070, 0)} % 1,,150/ 070,,0
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSNE, 1, 0, 0, 8#150)} % 1,,101/ TSNE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#707, 0)} % 1,,150/ 707,,0
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]).
+
+tsna_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSNA, 1, 0, 0, 8#150)} % 1,,101/ TSNA 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, 0} % 1,,150/ 0,,0
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]).
+
+tsnn_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSNN, 1, 0, 0, 8#150)} % 1,,101/ TSNN 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#707, 0)} % 1,,150/ 707,,0
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSNN, 1, 0, 0, 8#150)} % 1,,101/ TSNN 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#070, 0)} % 1,,150/ 070,,0
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]).
+
+%% TSZ - Test Swapped, Zeros, and Skip if Condition Satisfied
+
+tsz_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSZ, 1, 0, 0, 8#150)} % 1,,101/ TSZ 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#150, ?COMMA2(8#700, 0)} % 1,,150/ 700,,0
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]).
+
+tsze_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSZE, 1, 0, 0, 8#150)} % 1,,101/ TSZE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#070, 0)} % 1,,150/ 070,,0
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSZE, 1, 0, 0, 8#150)} % 1,,101/ TSZE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#700, 0)} % 1,,150/ 700,,0
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]).
+
+tsza_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSZA, 1, 0, 0, 8#150)} % 1,,101/ TSZA 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#700, 0)} % 1,,150/ 700,,0
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]).
+
+tszn_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSZN, 1, 0, 0, 8#150)} % 1,,101/ TSZN 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#700, 0)} % 1,,150/ 700,,0
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSZN, 1, 0, 0, 8#150)} % 1,,101/ TSZN 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#070, 0)} % 1,,150/ 070,,0
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#707} % AC1 = 0,,707
+ ]).
+
+%% TSC - Test Swapped, Complement, and Skip if Condition Satisfied
+
+tsc_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSC, 1, 0, 0, 8#150)} % 1,,101/ TSC 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#150, ?COMMA2(8#770, 0)} % 1,,150/ 770,,0
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#077} % AC1 = 0,,077
+ ]).
+
+tsce_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSCE, 1, 0, 0, 8#150)} % 1,,101/ TSCE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#070, 0)} % 1,,150/ 070,,0
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#777} % AC1 = 0,,777
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSCE, 1, 0, 0, 8#150)} % 1,,101/ TSCE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#700, 0)} % 1,,150/ 700,,0
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]).
+
+tsca_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSCA, 1, 0, 0, 8#150)} % 1,,101/ TSCA 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#770, 0)} % 1,,150/ 770,,0
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#077} % AC1 = 0,,077
+ ]).
+
+tscn_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSCN, 1, 0, 0, 8#150)} % 1,,101/ TSCN 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#700, 0)} % 1,,150/ 700,,0
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#007} % AC1 = 0,,007
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSCN, 1, 0, 0, 8#150)} % 1,,101/ TSCN 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#070, 0)} % 1,,150/ 070,,0
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#777} % AC1 = 0,,777
+ ]).
+
+%% TSO - Test Swapped, Ones, and Skip if Condition Satisfied
+
+tso_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSO, 1, 0, 0, 8#150)} % 1,,101/ TSO 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#150, ?COMMA2(8#070, 0)} % 1,,150/ 070,,0
+ ],
+ expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#777} % AC1 = 0,,777
+ ]).
+
+tsoe_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSOE, 1, 0, 0, 8#150)} % 1,,101/ TSOE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#070, 0)} % 1,,150/ 070,,0
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#777} % AC1 = 0,,777
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSOE, 1, 0, 0, 8#150)} % 1,,101/ TSOE 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#720, 0)} % 1,,150/ 720,,0
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#727} % AC1 = 0,,727
+ ]).
+
+tsoa_test() ->
+ Prog =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSOA, 1, 0, 0, 8#150)} % 1,,101/ TSOA 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#720, 0)} % 1,,150/ 720,,0
+ ],
+ expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#727} % AC1 = 0,,727
+ ]).
+
+tson_test() ->
+ Prog1 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSON, 1, 0, 0, 8#150)} % 1,,101/ TSON 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#720, 0)} % 1,,150/ 720,,0
+ ],
+ expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, % skip
+ [ {?AC(1), 8#727} % AC1 = 0,,727
+ ]),
+ Prog2 =
+ [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 8#707)} % 1,,100/ MOVEI 1,707
+ , {1, 8#101, ?INSN(?OP_TSON, 1, 0, 0, 8#150)} % 1,,101/ TSON 1,150
+ , {1, 8#102, ?INSN_INVALID} % 1,,102/
+ , {1, 8#103, ?INSN_INVALID} % 1,,103/
+ , {1, 8#150, ?COMMA2(8#020, 0)} % 1,,150/ 020,,0
+ ],
+ expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, % no skip
+ [ {?AC(1), 8#727} % AC1 = 0,,727
+ ]).
+
+%% Common code to run short sequences ==========================================
+
+expect(Prog, ACs, ExpectedPC, ExpectedFlags, ExpectedEs) ->
+ {Core, Mem} = init(Prog, ACs),
+ {Core1, Mem1, {error, {sim_core, {dispatch, PC, _IR, _EA}}}} = sim_core:run(Core, Mem),
+ ActualPC = {PC bsr 18, PC band ((1 bsl 18) - 1)},
+ ?assertEqual(ExpectedPC, ActualPC),
+ ?assertEqual(ExpectedFlags, Core1#core.flags),
+ lists:foreach(fun({EA, ExpectedE}) ->
+ {ok, ActualE} = sim_core:c(Core1, Mem1, EA),
+ ?assertEqual(ExpectedE, ActualE)
+ end, ExpectedEs),
+ sim_mem:delete(Mem).
+
+init(Prog, ACs) ->
+ {PCSection, PCOffset} = prog_pc(Prog),
+ Mem = init_mem(Prog),
+ Core = init_core(PCSection, PCOffset, ACs),
+ {Core, Mem}.
+
+prog_pc([{Section, Offset, _Word} | _Rest]) -> {Section, Offset}.
+
+init_mem(Prog) -> init_mem(Prog, sim_mem:new()).
+
+init_mem([], Mem) -> Mem;
+init_mem([{Section, Offset, Word} | Rest], Mem) ->
+ init_word(Section, Offset, Word, Mem),
+ init_mem(Rest, Mem).
+
+init_word(Section, Offset, Word, Mem) ->
+ Address = (Section bsl 18) bor Offset,
+ PFN = Address bsr 9,
+ case sim_mem:mquery(Mem, PFN) of
+ false -> sim_mem:mmap(Mem, PFN, 4+2, core);
+ {_Prot, _What} -> ok
+ end,
+ ok = sim_mem:write_word(Mem, Address, Word).
+
+init_core(PCSection, PCOffset, ACs) ->
+ #core{ pc_section = PCSection
+ , pc_offset = PCOffset
+ , acs = init_acs(ACs, list_to_tuple(lists:duplicate(16, 0)))
+ , flags = ?DEFAULT_FLAGS
+ }.
+
+init_acs([], ACS) -> ACS;
+init_acs([{AC, Val} | Rest], ACS) -> init_acs(Rest, setelement(AC + 1, Val, ACS)).