mirror of
https://github.com/mikpe/pdp10-tools.git
synced 2026-01-22 10:32:25 +00:00
sim: sim_arithmetic: handle JUMP{L,E,LE,A,GE,N,G}, sim_core: handle JUMP as no-op, add unit tests
This commit is contained in:
parent
d1bddcde04
commit
1f2c56260f
@ -40,6 +40,13 @@
|
||||
, handle_CAML/4
|
||||
, handle_CAMLE/4
|
||||
, handle_CAMN/4
|
||||
, handle_JUMPA/4
|
||||
, handle_JUMPE/4
|
||||
, handle_JUMPG/4
|
||||
, handle_JUMPGE/4
|
||||
, handle_JUMPL/4
|
||||
, handle_JUMPLE/4
|
||||
, handle_JUMPN/4
|
||||
]).
|
||||
|
||||
-include("sim_core.hrl").
|
||||
@ -234,8 +241,93 @@ handle_CAMG(Core, Mem, IR, EA) ->
|
||||
fun(Core1, Mem1) -> ?FUNCTION_NAME(Core1, Mem1, IR, EA) end)
|
||||
end.
|
||||
|
||||
%% JUMP - Jump if AC Condition Satisfied
|
||||
|
||||
-spec handle_JUMPL(#core{}, sim_mem:mem(), IR :: word(), #ea{})
|
||||
-> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
|
||||
handle_JUMPL(Core, Mem, IR, EA) ->
|
||||
AC = IR band 8#17,
|
||||
CA = sim_core:get_ac(Core, AC),
|
||||
jump_if_L(Core, Mem, CA, EA).
|
||||
|
||||
-spec handle_JUMPE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
|
||||
-> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
|
||||
handle_JUMPE(Core, Mem, IR, EA) ->
|
||||
AC = IR band 8#17,
|
||||
CA = sim_core:get_ac(Core, AC),
|
||||
jump_if_E(Core, Mem, CA, EA).
|
||||
|
||||
-spec handle_JUMPLE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
|
||||
-> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
|
||||
handle_JUMPLE(Core, Mem, IR, EA) ->
|
||||
AC = IR band 8#17,
|
||||
CA = sim_core:get_ac(Core, AC),
|
||||
jump_if_LE(Core, Mem, CA, EA).
|
||||
|
||||
-spec handle_JUMPA(#core{}, sim_mem:mem(), IR :: word(), #ea{})
|
||||
-> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
|
||||
handle_JUMPA(Core, Mem, _IR, EA) ->
|
||||
jump(Core, Mem, EA).
|
||||
|
||||
-spec handle_JUMPGE(#core{}, sim_mem:mem(), IR :: word(), #ea{})
|
||||
-> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
|
||||
handle_JUMPGE(Core, Mem, IR, EA) ->
|
||||
AC = IR band 8#17,
|
||||
CA = sim_core:get_ac(Core, AC),
|
||||
jump_if_GE(Core, Mem, CA, EA).
|
||||
|
||||
-spec handle_JUMPN(#core{}, sim_mem:mem(), IR :: word(), #ea{})
|
||||
-> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
|
||||
handle_JUMPN(Core, Mem, IR, EA) ->
|
||||
AC = IR band 8#17,
|
||||
CA = sim_core:get_ac(Core, AC),
|
||||
jump_if_N(Core, Mem, CA, EA).
|
||||
|
||||
-spec handle_JUMPG(#core{}, sim_mem:mem(), IR :: word(), #ea{})
|
||||
-> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}.
|
||||
handle_JUMPG(Core, Mem, IR, EA) ->
|
||||
AC = IR band 8#17,
|
||||
CA = sim_core:get_ac(Core, AC),
|
||||
jump_if_G(Core, Mem, CA, EA).
|
||||
|
||||
%% Miscellaneous ===============================================================
|
||||
|
||||
jump_if_E(Core, Mem, X, EA) ->
|
||||
case X =:= 0 of
|
||||
true -> jump(Core, Mem, EA);
|
||||
false -> sim_core:next_pc(Core, Mem)
|
||||
end.
|
||||
|
||||
jump_if_G(Core, Mem, X, EA) ->
|
||||
case sext36(X) > 0 of
|
||||
true -> jump(Core, Mem, EA);
|
||||
false -> sim_core:next_pc(Core, Mem)
|
||||
end.
|
||||
|
||||
jump_if_GE(Core, Mem, X, EA) ->
|
||||
case sext36(X) >= 0 of
|
||||
true -> jump(Core, Mem, EA);
|
||||
false -> sim_core:next_pc(Core, Mem)
|
||||
end.
|
||||
|
||||
jump_if_L(Core, Mem, X, EA) ->
|
||||
case sext36(X) < 0 of
|
||||
true -> jump(Core, Mem, EA);
|
||||
false -> sim_core:next_pc(Core, Mem)
|
||||
end.
|
||||
|
||||
jump_if_LE(Core, Mem, X, EA) ->
|
||||
case sext36(X) =< 0 of
|
||||
true -> jump(Core, Mem, EA);
|
||||
false -> sim_core:next_pc(Core, Mem)
|
||||
end.
|
||||
|
||||
jump_if_N(Core, Mem, X, EA) ->
|
||||
case X =/= 0 of
|
||||
true -> jump(Core, Mem, EA);
|
||||
false -> sim_core:next_pc(Core, Mem)
|
||||
end.
|
||||
|
||||
jump(Core, Mem, EA) ->
|
||||
sim_core:run(Core#core{pc_offset = EA#ea.offset}, Mem).
|
||||
|
||||
|
||||
@ -304,6 +304,14 @@ dispatch(Core, Mem, IR, EA) ->
|
||||
8#315 -> sim_arithmetic:handle_CAMGE(Core, Mem, IR, EA);
|
||||
8#316 -> sim_arithmetic:handle_CAMN(Core, Mem, IR, EA);
|
||||
8#317 -> sim_arithmetic:handle_CAMG(Core, Mem, IR, EA);
|
||||
8#320 -> next_pc(Core, Mem); % JUMP = no-op
|
||||
8#321 -> sim_arithmetic:handle_JUMPL(Core, Mem, IR, EA);
|
||||
8#322 -> sim_arithmetic:handle_JUMPE(Core, Mem, IR, EA);
|
||||
8#323 -> sim_arithmetic:handle_JUMPLE(Core, Mem, IR, EA);
|
||||
8#324 -> sim_arithmetic:handle_JUMPA(Core, Mem, IR, EA);
|
||||
8#325 -> sim_arithmetic:handle_JUMPGE(Core, Mem, IR, EA);
|
||||
8#326 -> sim_arithmetic:handle_JUMPN(Core, Mem, IR, EA);
|
||||
8#327 -> sim_arithmetic:handle_JUMPG(Core, Mem, IR, EA);
|
||||
8#400 -> sim_boolean:handle_SETZ(Core, Mem, IR, EA);
|
||||
8#401 -> sim_boolean:handle_SETZ(Core, Mem, IR, EA); % SETZI = SETZ
|
||||
8#402 -> sim_boolean:handle_SETZM(Core, Mem, IR, EA);
|
||||
|
||||
@ -67,6 +67,14 @@
|
||||
-define(OP_CAMGE, 8#315).
|
||||
-define(OP_CAMN, 8#316).
|
||||
-define(OP_CAMG, 8#317).
|
||||
-define(OP_JUMP, 8#320).
|
||||
-define(OP_JUMPL, 8#321).
|
||||
-define(OP_JUMPE, 8#322).
|
||||
-define(OP_JUMPLE, 8#323).
|
||||
-define(OP_JUMPA, 8#324).
|
||||
-define(OP_JUMPGE, 8#325).
|
||||
-define(OP_JUMPN, 8#326).
|
||||
-define(OP_JUMPG, 8#327).
|
||||
|
||||
%% 2.6.1 Add One to Both Halves of AC and Jump =================================
|
||||
|
||||
@ -386,6 +394,133 @@ camg_test() ->
|
||||
],
|
||||
expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, []). % no skip
|
||||
|
||||
%% JUMP - Jump if AC Condition Satisfied
|
||||
|
||||
jump_test() ->
|
||||
Prog =
|
||||
[ {1, 8#100, ?INSN(?OP_JUMP, 0, 0, 0, 0)} % 1,,100/ JUMP
|
||||
, {1, 8#101, ?INSN_INVALID} % 1,,101/ <invalid>
|
||||
],
|
||||
expect(Prog, [], {1, 8#101}, ?DEFAULT_FLAGS, []). % no jump
|
||||
|
||||
jumpl_test() ->
|
||||
Prog1 =
|
||||
[ {1, 8#100, ?INSN(?OP_MOVNI, 1, 0, 0, 3)} % 1,,100/ MOVNI 1,3
|
||||
, {1, 8#101, ?INSN(?OP_JUMPL, 1, 0, 0, 8#103)} % 1,,101/ JUMPL 1,103
|
||||
, {1, 8#102, ?INSN_INVALID} % 1,,102/ <invalid>
|
||||
, {1, 8#103, ?INSN_INVALID} % 1,,103/ <invalid>
|
||||
],
|
||||
expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, []), % jump
|
||||
Prog2 =
|
||||
[ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 3)} % 1,,100/ MOVEI 1,3
|
||||
, {1, 8#101, ?INSN(?OP_JUMPL, 1, 0, 0, 8#103)} % 1,,101/ JUMPL 1,103
|
||||
, {1, 8#102, ?INSN_INVALID} % 1,,102/ <invalid>
|
||||
, {1, 8#103, ?INSN_INVALID} % 1,,103/ <invalid>
|
||||
],
|
||||
expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, []). % no jump
|
||||
|
||||
jumpe_test() ->
|
||||
Prog1 =
|
||||
[ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 0)} % 1,,100/ MOVEI 1,0
|
||||
, {1, 8#101, ?INSN(?OP_JUMPE, 1, 0, 0, 8#103)} % 1,,101/ JUMPE 1,103
|
||||
, {1, 8#102, ?INSN_INVALID} % 1,,102/ <invalid>
|
||||
, {1, 8#103, ?INSN_INVALID} % 1,,103/ <invalid>
|
||||
],
|
||||
expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, []), % jump
|
||||
Prog2 =
|
||||
[ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 3)} % 1,,100/ MOVEI 1,3
|
||||
, {1, 8#101, ?INSN(?OP_JUMPE, 1, 0, 0, 8#103)} % 1,,101/ JUMPE 1,103
|
||||
, {1, 8#102, ?INSN_INVALID} % 1,,102/ <invalid>
|
||||
, {1, 8#103, ?INSN_INVALID} % 1,,103/ <invalid>
|
||||
],
|
||||
expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, []). % no jump
|
||||
|
||||
jumple_test() ->
|
||||
Prog1 =
|
||||
[ {1, 8#100, ?INSN(?OP_MOVNI, 1, 0, 0, 3)} % 1,,100/ MOVNI 1,3
|
||||
, {1, 8#101, ?INSN(?OP_JUMPLE, 1, 0, 0, 8#103)} % 1,,101/ JUMPLE 1,103
|
||||
, {1, 8#102, ?INSN_INVALID} % 1,,102/ <invalid>
|
||||
, {1, 8#103, ?INSN_INVALID} % 1,,103/ <invalid>
|
||||
],
|
||||
expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, []), % jump
|
||||
Prog2 =
|
||||
[ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 0)} % 1,,100/ MOVEI 1,0
|
||||
, {1, 8#101, ?INSN(?OP_JUMPLE, 1, 0, 0, 8#103)} % 1,,101/ JUMPLE 1,103
|
||||
, {1, 8#102, ?INSN_INVALID} % 1,,102/ <invalid>
|
||||
, {1, 8#103, ?INSN_INVALID} % 1,,103/ <invalid>
|
||||
],
|
||||
expect(Prog2, [], {1, 8#103}, ?DEFAULT_FLAGS, []), % jump
|
||||
Prog3 =
|
||||
[ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 3)} % 1,,100/ MOVEI 1,3
|
||||
, {1, 8#101, ?INSN(?OP_JUMPLE, 1, 0, 0, 8#103)} % 1,,101/ JUMPLE 1,103
|
||||
, {1, 8#102, ?INSN_INVALID} % 1,,102/ <invalid>
|
||||
, {1, 8#103, ?INSN_INVALID} % 1,,103/ <invalid>
|
||||
],
|
||||
expect(Prog3, [], {1, 8#102}, ?DEFAULT_FLAGS, []). % no jump
|
||||
|
||||
jumpa_test() ->
|
||||
Prog =
|
||||
[ {1, 8#100, ?INSN(?OP_JUMPA, 0, 0, 0, 8#102)} % 1,,100/ JUMPA 102
|
||||
, {1, 8#101, ?INSN_INVALID} % 1,,101/ <invalid>
|
||||
, {1, 8#102, ?INSN_INVALID} % 1,,102/ <invalid>
|
||||
],
|
||||
expect(Prog, [], {1, 8#102}, ?DEFAULT_FLAGS, []). % jump
|
||||
|
||||
jumpge_test() ->
|
||||
Prog1 =
|
||||
[ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 3)} % 1,,100/ MOVEI 1,3
|
||||
, {1, 8#101, ?INSN(?OP_JUMPGE, 1, 0, 0, 8#103)} % 1,,101/ JUMPGE 1,103
|
||||
, {1, 8#102, ?INSN_INVALID} % 1,,102/ <invalid>
|
||||
, {1, 8#103, ?INSN_INVALID} % 1,,103/ <invalid>
|
||||
],
|
||||
expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, []), % jump
|
||||
Prog2 =
|
||||
[ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 0)} % 1,,100/ MOVEI 1,0
|
||||
, {1, 8#101, ?INSN(?OP_JUMPGE, 1, 0, 0, 8#103)} % 1,,101/ JUMPGE 1,103
|
||||
, {1, 8#102, ?INSN_INVALID} % 1,,102/ <invalid>
|
||||
, {1, 8#103, ?INSN_INVALID} % 1,,103/ <invalid>
|
||||
],
|
||||
expect(Prog2, [], {1, 8#103}, ?DEFAULT_FLAGS, []), % jump
|
||||
Prog3 =
|
||||
[ {1, 8#100, ?INSN(?OP_MOVNI, 1, 0, 0, 3)} % 1,,100/ MOVNI 1,3
|
||||
, {1, 8#101, ?INSN(?OP_JUMPGE, 1, 0, 0, 8#103)} % 1,,101/ JUMPGE 1,103
|
||||
, {1, 8#102, ?INSN_INVALID} % 1,,102/ <invalid>
|
||||
, {1, 8#103, ?INSN_INVALID} % 1,,103/ <invalid>
|
||||
],
|
||||
expect(Prog3, [], {1, 8#102}, ?DEFAULT_FLAGS, []). % no jump
|
||||
|
||||
jumpn_test() ->
|
||||
Prog1 =
|
||||
[ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 3)} % 1,,100/ MOVEI 1,3
|
||||
, {1, 8#101, ?INSN(?OP_JUMPN, 1, 0, 0, 8#103)} % 1,,101/ JUMPN 1,103
|
||||
, {1, 8#102, ?INSN_INVALID} % 1,,102/ <invalid>
|
||||
, {1, 8#103, ?INSN_INVALID} % 1,,103/ <invalid>
|
||||
],
|
||||
expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, []), % jump
|
||||
Prog2 =
|
||||
[ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 0)} % 1,,100/ MOVEI 1,0
|
||||
, {1, 8#101, ?INSN(?OP_JUMPN, 1, 0, 0, 8#103)} % 1,,101/ JUMPN 1,103
|
||||
, {1, 8#102, ?INSN_INVALID} % 1,,102/ <invalid>
|
||||
, {1, 8#103, ?INSN_INVALID} % 1,,103/ <invalid>
|
||||
],
|
||||
expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, []). % no jump
|
||||
|
||||
jumpg_test() ->
|
||||
Prog1 =
|
||||
[ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, 3)} % 1,,100/ MOVEI 1,3
|
||||
, {1, 8#101, ?INSN(?OP_JUMPG, 1, 0, 0, 8#103)} % 1,,101/ JUMPG 1,103
|
||||
, {1, 8#102, ?INSN_INVALID} % 1,,102/ <invalid>
|
||||
, {1, 8#103, ?INSN_INVALID} % 1,,103/ <invalid>
|
||||
],
|
||||
expect(Prog1, [], {1, 8#103}, ?DEFAULT_FLAGS, []), % jump
|
||||
Prog2 =
|
||||
[ {1, 8#100, ?INSN(?OP_MOVNI, 1, 0, 0, 3)} % 1,,100/ MOVNI 1,3
|
||||
, {1, 8#101, ?INSN(?OP_JUMPG, 1, 0, 0, 8#103)} % 1,,101/ JUMPG 1,103
|
||||
, {1, 8#102, ?INSN_INVALID} % 1,,102/ <invalid>
|
||||
, {1, 8#103, ?INSN_INVALID} % 1,,103/ <invalid>
|
||||
],
|
||||
expect(Prog2, [], {1, 8#102}, ?DEFAULT_FLAGS, []). % no jump
|
||||
|
||||
%% Common code to run short sequences ==========================================
|
||||
|
||||
expect(Prog, ACs, ExpectedPC, ExpectedFlags, ExpectedEs) ->
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user