From 9bc547c6f7b3475304e6867a2bddd0abd1b65fd2 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Fri, 17 Jul 2020 23:15:15 +0200 Subject: [PATCH] sim: sim_moves: handle DMOVN, add unit tests --- erlang/apps/sim/src/sim_core.erl | 1 + erlang/apps/sim/src/sim_moves.erl | 46 ++++++++++++++++++++++++ erlang/apps/sim/test/sim_moves_tests.erl | 41 +++++++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/erlang/apps/sim/src/sim_core.erl b/erlang/apps/sim/src/sim_core.erl index a01c838..30dbb47 100644 --- a/erlang/apps/sim/src/sim_core.erl +++ b/erlang/apps/sim/src/sim_core.erl @@ -232,6 +232,7 @@ dispatch(Core, Mem, IR, EA) -> case IR bsr 4 of 8#104 -> sim_kernel:handle_JSYS(Core, Mem, IR, EA); 8#120 -> sim_moves:handle_DMOVE(Core, Mem, IR, EA); + 8#121 -> sim_moves:handle_DMOVN(Core, Mem, IR, EA); 8#124 -> sim_moves:handle_DMOVEM(Core, Mem, IR, EA); 8#200 -> sim_moves:handle_MOVE(Core, Mem, IR, EA); 8#201 -> sim_moves:handle_MOVEI(Core, Mem, IR, EA); diff --git a/erlang/apps/sim/src/sim_moves.erl b/erlang/apps/sim/src/sim_moves.erl index 1764ff0..0b35f91 100644 --- a/erlang/apps/sim/src/sim_moves.erl +++ b/erlang/apps/sim/src/sim_moves.erl @@ -27,6 +27,7 @@ -export([ handle_EXCH/4 , handle_DMOVE/4 , handle_DMOVEM/4 + , handle_DMOVN/4 , handle_MOVE/4 , handle_MOVEI/4 , handle_MOVEM/4 @@ -317,6 +318,33 @@ handle_DMOVEM(Core, Mem, Word0, Word1, EA) -> fun(Core1, Mem1) -> handle_DMOVEM(Core1, Mem1, Word0, Word1, EA) end) end. +%% DMOVN - Double Move Negative + +-spec handle_DMOVN(#core{}, sim_mem:mem(), IR :: word(), #ea{}) + -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}. +handle_DMOVN(Core, Mem, IR, EA) -> + case sim_core:c(Core, Mem, EA) of + {ok, Word0} -> + handle_DMOVN(Core, Mem, IR, ea_plus_1(EA), Word0); + {error, Reason} -> + sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason, + fun(Core1, Mem1) -> handle_DMOVN(Core1, Mem1, IR, EA) end) + end. + +handle_DMOVN(Core, Mem, IR, EA, Word0) -> + case sim_core:c(Core, Mem, EA) of + {ok, Word1} -> + {Negative0, Negative1, Flags} = dnegate(Word0, Word1), + AC = IR band 8#17, + Core1 = sim_core:set_ac(Core, AC, Negative0), + Core2 = sim_core:set_ac(Core1, ac_plus_1(AC), Negative1), + Core3 = sim_core:set_flags(Core2, Flags), + sim_core:next_pc(Core3, Mem); + {error, Reason} -> + sim_core:page_fault(Core, Mem, ea_address(EA), read, Reason, + fun(Core1, Mem1) -> handle_DMOVN(Core1, Mem1, IR, EA, Word0) end) + end. + %% Miscellaneous =============================================================== ac_plus_1(AC) -> @@ -362,6 +390,24 @@ negate(Word) -> {Negated, _Flags = 0} end. +dnegate(Word0, Word1) -> + DWord = (Word0 bsl 35) bor (Word1 band ((1 bsl 35) - 1)), + Negated = (-DWord) band ((1 bsl 71) - 1), + Flags = + case Negated of + 0 -> % negating 0 + (1 bsl ?PDP10_PF_CARRY_1) bor (1 bsl ?PDP10_PF_CARRY_0); + DWord -> % negating -2^70 + (1 bsl ?PDP10_PF_TRAP_1) bor + (1 bsl ?PDP10_PF_OVERFLOW) bor + (1 bsl ?PDP10_PF_CARRY_1); + _ -> + 0 + end, + Negated1 = Negated band ((1 bsl 35) - 1), + Negated0 = Negated bsr 35, + {Negated0, Negated1, Flags}. + set_non_zero_ac(Core, _AC = 0, _Word) -> Core; set_non_zero_ac(Core, AC, Word) -> sim_core:set_ac(Core, AC, Word). diff --git a/erlang/apps/sim/test/sim_moves_tests.erl b/erlang/apps/sim/test/sim_moves_tests.erl index 270a7a3..8734dbc 100644 --- a/erlang/apps/sim/test/sim_moves_tests.erl +++ b/erlang/apps/sim/test/sim_moves_tests.erl @@ -44,6 +44,7 @@ -define(OP_INVALID, 0). -define(OP_DMOVE, 8#120). +-define(OP_DMOVN, 8#121). -define(OP_DMOVEM, 8#124). -define(OP_MOVE, 8#200). -define(OP_MOVEI, 8#201). @@ -392,6 +393,46 @@ dmovem_test() -> , {#ea{section = 1, offset = 8#151, islocal = false}, 8#27} % C(1,,151) = 27 ]). +dmovn_no_flags_test() -> + Prog = + [ {1, 8#100, ?INSN(?OP_DMOVN, 1, 0, 0, 8#150)} % 1,,100/ DMOVN 1,150 + , {1, 8#101, ?INSN_INVALID} % 1,,101/ + , {1, 8#150, ?COMMA2(-1, -1)} % 1,,150/ -1 + , {1, 8#151, ?COMMA2(-1, -1)} % 1,,151/ -1 + ], + expect(Prog, [], {1, 8#101}, ?DEFAULT_FLAGS, + [ {#ea{section = 1, offset = 1, islocal = false}, 0} % AC1 = 0 + , {#ea{section = 1, offset = 2, islocal = false}, 1} % AC2 = 1 + ]). + +dmovn_zero_test() -> + Prog = + [ {1, 8#100, ?INSN(?OP_MOVEI, 1, 0, 0, -1)} % 1,,100/ MOVEI 1,-1 + , {1, 8#101, ?INSN(?OP_MOVEI, 2, 0, 0, -1)} % 1,,101/ MOVEI 2,-1 + , {1, 8#102, ?INSN(?OP_DMOVN, 1, 0, 0, 8#150)} % 1,,102/ DMOVN 1,150 + , {1, 8#103, ?INSN_INVALID} % 1,,103/ + , {1, 8#150, 0} % 1,,150/ 0 + , {1, 8#151, 0} % 1,,151/ 0 + ], + Flags = ?DEFAULT_FLAGS bor (1 bsl ?PDP10_PF_CARRY_1) bor (1 bsl ?PDP10_PF_CARRY_0), + expect(Prog, [], {1, 8#103}, Flags, + [ {#ea{section = 1, offset = 1, islocal = false}, 0} % AC1 = 0 + , {#ea{section = 1, offset = 2, islocal = false}, 0} % AC2 = 0 + ]). + +dmovn_minint_test() -> + Prog = + [ {1, 8#100, ?INSN(?OP_DMOVN, 1, 0, 0, 8#150)} % 1,,100/ DMOVN 1,150 + , {1, 8#101, ?INSN_INVALID} % 1,,101/ + , {1, 8#150, 1 bsl 35} % 1,,150/ 400000,,0 + , {1, 8#151, 0} % 1,,151/ 0 + ], + Flags = ?DEFAULT_FLAGS bor (1 bsl ?PDP10_PF_OVERFLOW) bor (1 bsl ?PDP10_PF_CARRY_1), + expect(Prog, [], {1, 8#101}, Flags, + [ {#ea{section = 1, offset = 1, islocal = false}, 1 bsl 35} % AC1 = 400000,,0 + , {#ea{section = 1, offset = 2, islocal = false}, 0} % AC2 = 0 + ]). + %% Common code to run short sequences ========================================== expect(Prog, ACs, ExpectedPC, ExpectedFlags, ExpectedEs) ->