From ccf68cbf70ed2b2764d85270e758e6f7c03ed2a7 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Fri, 17 Jul 2020 23:55:52 +0200 Subject: [PATCH] sim: sim_moves: handle DMOVNM, add unit test --- erlang/apps/sim/src/sim_core.erl | 1 + erlang/apps/sim/src/sim_moves.erl | 20 ++++++++++++++++++++ erlang/apps/sim/test/sim_moves_tests.erl | 15 +++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/erlang/apps/sim/src/sim_core.erl b/erlang/apps/sim/src/sim_core.erl index 30dbb47..ff8dcae 100644 --- a/erlang/apps/sim/src/sim_core.erl +++ b/erlang/apps/sim/src/sim_core.erl @@ -234,6 +234,7 @@ dispatch(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#125 -> sim_moves:handle_DMOVNM(Core, Mem, IR, EA); 8#200 -> sim_moves:handle_MOVE(Core, Mem, IR, EA); 8#201 -> sim_moves:handle_MOVEI(Core, Mem, IR, EA); 8#202 -> sim_moves:handle_MOVEM(Core, Mem, IR, EA); diff --git a/erlang/apps/sim/src/sim_moves.erl b/erlang/apps/sim/src/sim_moves.erl index 0b35f91..d8d7651 100644 --- a/erlang/apps/sim/src/sim_moves.erl +++ b/erlang/apps/sim/src/sim_moves.erl @@ -28,6 +28,7 @@ , handle_DMOVE/4 , handle_DMOVEM/4 , handle_DMOVN/4 + , handle_DMOVNM/4 , handle_MOVE/4 , handle_MOVEI/4 , handle_MOVEM/4 @@ -345,6 +346,25 @@ handle_DMOVN(Core, Mem, IR, EA, Word0) -> fun(Core1, Mem1) -> handle_DMOVN(Core1, Mem1, IR, EA, Word0) end) end. +%% DMOVNM - Double Move Negative to Memory + +-spec handle_DMOVNM(#core{}, sim_mem:mem(), IR :: word(), #ea{}) + -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}. +handle_DMOVNM(Core, Mem, IR, EA) -> + AC = IR band 8#17, + Word0 = sim_core:get_ac(Core, AC), + Word1 = sim_core:get_ac(Core, ac_plus_1(AC)), + {Negative0, Negative1, Flags} = dnegate(Word0, Word1), + handle_DMOVNM(Core, Mem, Negative0, Negative1, Flags, EA). + +handle_DMOVNM(Core, Mem, Word0, Word1, Flags, EA) -> + case sim_core:cset(Core, Mem, EA, Word0) of + {ok, Core1} -> handle_MOVNM(Core1, Mem, Word1, Flags, ea_plus_1(EA)); + {error, Reason} -> + sim_core:page_fault(Core, Mem, ea_address(EA), write, Reason, + fun(Core1, Mem1) -> handle_DMOVNM(Core1, Mem1, Word0, Word1, Flags, EA) end) + end. + %% Miscellaneous =============================================================== ac_plus_1(AC) -> diff --git a/erlang/apps/sim/test/sim_moves_tests.erl b/erlang/apps/sim/test/sim_moves_tests.erl index 8734dbc..2ed0d3e 100644 --- a/erlang/apps/sim/test/sim_moves_tests.erl +++ b/erlang/apps/sim/test/sim_moves_tests.erl @@ -46,6 +46,7 @@ -define(OP_DMOVE, 8#120). -define(OP_DMOVN, 8#121). -define(OP_DMOVEM, 8#124). +-define(OP_DMOVNM, 8#125). -define(OP_MOVE, 8#200). -define(OP_MOVEI, 8#201). -define(OP_MOVEM, 8#202). @@ -433,6 +434,20 @@ dmovn_minint_test() -> , {#ea{section = 1, offset = 2, islocal = false}, 0} % AC2 = 0 ]). +dmovnm_test() -> + Prog = + [ {1, 8#100, ?INSN(?OP_MOVNI, 1, 0, 0, 1)} % 1,,100/ MOVNI 1,1 + , {1, 8#101, ?INSN(?OP_MOVNI, 2, 0, 0, 1)} % 1,,101/ MOVNI 2,1 + , {1, 8#102, ?INSN(?OP_DMOVNM, 1, 0, 0, 8#150)} % 1,,102/ DMOVNM 1,150 + , {1, 8#103, ?INSN_INVALID} % 1,,103/ + , {1, 8#150, 8#27} % 1,,150/ 0,,27 + , {1, 8#151, 8#27} % 1,,150/ 0,,27 + ], + expect(Prog, [], {1, 8#103}, ?DEFAULT_FLAGS, + [ {#ea{section = 1, offset = 8#150, islocal = false}, 0} % C(1,,150) = 0 + , {#ea{section = 1, offset = 8#151, islocal = false}, 1} % C(1,,151) = 1 + ]). + %% Common code to run short sequences ========================================== expect(Prog, ACs, ExpectedPC, ExpectedFlags, ExpectedEs) ->