diff --git a/erlang/apps/lib/src/libelf.erl b/erlang/apps/lib/src/libelf.erl index 951b849..ebbef28 100644 --- a/erlang/apps/lib/src/libelf.erl +++ b/erlang/apps/lib/src/libelf.erl @@ -707,7 +707,7 @@ read_Word(FP) -> read_uint36(FP). read_sint36(FP) -> case read_uint36(FP) of - {ok, UInt36} -> {ok, (UInt36 bxor (1 bsl 35)) - (1 bsl 35)}; % sign-extend + {ok, UInt36} -> {ok, sext:sext(UInt36, 36)}; {error, _Reason} = Error -> Error end. diff --git a/erlang/apps/lib/src/sext.erl b/erlang/apps/lib/src/sext.erl new file mode 100644 index 0000000..dcf085f --- /dev/null +++ b/erlang/apps/lib/src/sext.erl @@ -0,0 +1,30 @@ +%%% -*- erlang-indent-level: 2 -*- +%%% +%%% Sign-extend integers of given widths. +%%% Copyright (C) 2013-2025 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 . + +-module(sext). + +-export([ sext/2 + ]). + +-spec sext(non_neg_integer(), pos_integer()) -> integer(). +sext(Word, Width) -> + SignBit = 1 bsl (Width - 1), + Max = (1 bsl Width) - 1, + ((Word band Max) bxor SignBit) - SignBit. diff --git a/erlang/apps/od/src/od.erl b/erlang/apps/od/src/od.erl index aa1c110..034048e 100644 --- a/erlang/apps/od/src/od.erl +++ b/erlang/apps/od/src/od.erl @@ -1,7 +1,7 @@ %%% -*- erlang-indent-level: 2 -*- %%% %%% 'od' for files with 9-bit bytes -%%% Copyright (C) 2013-2023 Mikael Pettersson +%%% Copyright (C) 2013-2025 Mikael Pettersson %%% %%% This file is part of pdp10-tools. %%% @@ -333,7 +333,7 @@ print_number(Opts, UInt) -> OutputType = Opts#options.output_type, Number = case OutputType of - $d -> sign_extend(UInt, 9 * Opts#options.bytes_per_datum); + $d -> sext:sext(UInt, 9 * Opts#options.bytes_per_datum); _ -> UInt end, {Base, Pad} = @@ -345,11 +345,6 @@ print_number(Opts, UInt) -> end, io:format(" ~*.*.*B", [Opts#options.chars_per_datum, Base, Pad, Number]). -sign_extend(UInt, NrBits) -> - Max = (1 bsl NrBits) - 1, - SignBit = 1 bsl (NrBits - 1), - ((UInt band Max) bxor SignBit) - SignBit. - bytes_to_uint(B1, B2) -> % PDP10 has big-endian byte order ((B1 band 16#1FF) bsl 9) bor (B2 band 16#1FF). diff --git a/erlang/apps/sim/src/sim_arithmetic.erl b/erlang/apps/sim/src/sim_arithmetic.erl index af4261e..b5d6a4f 100644 --- a/erlang/apps/sim/src/sim_arithmetic.erl +++ b/erlang/apps/sim/src/sim_arithmetic.erl @@ -1,7 +1,7 @@ %%% -*- erlang-indent-level: 2 -*- %%% %%% simulator for pdp10-elf -%%% Copyright (C) 2020 Mikael Pettersson +%%% Copyright (C) 2020-2025 Mikael Pettersson %%% %%% This file is part of pdp10-tools. %%% @@ -933,9 +933,7 @@ sub1(Word) -> %% Sign-extend a uint36_t() to the full width of its representation type. -spec sext36(uint36_t()) -> integer(). sext36(X) -> - UInt36Sbit = 1 bsl (36 - 1), - UInt36Max = (1 bsl 36) - 1, - ((X band UInt36Max) bxor UInt36Sbit) - UInt36Sbit. + sext:sext(X, 36). set_non_zero_ac(Core, IR, Word) -> case IR band 8#17 of diff --git a/erlang/apps/sim/src/sim_core.erl b/erlang/apps/sim/src/sim_core.erl index c351302..9c3d9ae 100644 --- a/erlang/apps/sim/src/sim_core.erl +++ b/erlang/apps/sim/src/sim_core.erl @@ -1,7 +1,7 @@ %%% -*- erlang-indent-level: 2 -*- %%% %%% simulator for pdp10-elf -%%% Copyright (C) 2018-2020 Mikael Pettersson +%%% Copyright (C) 2018-2025 Mikael Pettersson %%% %%% This file is part of pdp10-tools. %%% @@ -606,9 +606,7 @@ bit36(X, BIT) -> bits36(X, BIT, BIT). %% Sign-extend a uint18_t() to the full width of its representation type. -spec sext18(uint18_t()) -> integer(). sext18(X) -> - UInt18Sbit = 1 bsl (18 - 1), - UInt18Max = (1 bsl 18) - 1, - ((X band UInt18Max) bxor UInt18Sbit) - UInt18Sbit. + sext:sext(X, 18). %% This implements Word := C(E). -spec c(#core{}, sim_mem:mem(), #ea{})