extint.erl: add support for converting between octets and 16/32/64-bit types

This commit is contained in:
Mikael Pettersson
2025-08-11 17:46:08 +02:00
parent d9055597f9
commit 1f230f9e61
2 changed files with 72 additions and 14 deletions

View File

@@ -1,6 +1,11 @@
%%% -*- erlang-indent-level: 2 -*-
%%%
%%% converts between 18 and 36-bit integers and sequences of nonets
%%% Converts between fixed-width integers and sequences of bytes.
%%% 16/32/64-bit integers are sequences of octets, while
%%% 18/36-bit integers are sequences of nonets.
%%%
%%% For now, all conversions are big-endian.
%%%
%%% Copyright (C) 2013-2025 Mikael Pettersson
%%%
%%% This file is part of pdp10-tools.
@@ -20,24 +25,56 @@
-module(extint).
-export([ uint18_to_ext/1
-export([ uint16_from_ext/1
, uint16_to_ext/1
, uint18_from_ext/1
, uint36_to_ext/1
, uint18_to_ext/1
, uint32_from_ext/1
, uint32_to_ext/1
, uint36_from_ext/1
, uint36_to_ext/1
, uint64_from_ext/1
, uint64_to_ext/1
]).
-include_lib("lib/include/stdint.hrl").
%% The PDP10 is big-endian, so the conversions here are big-endian.
%% The bytes (nonets) are numbered in storage order.
-spec uint16_from_ext([uint8_t()]) -> uint16_t().
uint16_from_ext([B0, B1]) ->
((B0 band ?UINT8_MAX) bsl 8) bor (B1 band ?UINT8_MAX).
-spec uint16_to_ext(uint16_t()) -> [uint8_t()].
uint16_to_ext(U16) ->
[_B0 = (U16 bsr 8) band ?UINT8_MAX, _B1 = U16 band ?UINT8_MAX].
-spec uint18_from_ext([uint9_t()]) -> uint18_t().
uint18_from_ext([B0, B1]) ->
((B0 band ?UINT9_MAX) bsl 9) bor (B1 band ?UINT9_MAX).
-spec uint18_to_ext(uint18_t()) -> [uint9_t()].
uint18_to_ext(U18) ->
[_B0 = (U18 bsr 9) band ?UINT9_MAX, _B1 = U18 band ?UINT9_MAX].
-spec uint18_from_ext([uint9_t()]) -> uint18_t().
uint18_from_ext([B0, B1]) ->
((B0 band ?UINT9_MAX) bsl 9) bor (B1 band ?UINT9_MAX).
-spec uint32_from_ext([uint8_t()]) -> uint32_t().
uint32_from_ext([B0, B1, B2, B3]) ->
((B0 band ?UINT8_MAX) bsl 24) bor
((B1 band ?UINT8_MAX) bsl 16) bor
((B2 band ?UINT8_MAX) bsl 8) bor
(B3 band ?UINT8_MAX).
-spec uint32_to_ext(uint32_t()) -> [uint8_t()].
uint32_to_ext(U32) ->
[_B0 = (U32 bsr 24) band ?UINT8_MAX,
_B1 = (U32 bsr 16) band ?UINT8_MAX,
_B2 = (U32 bsr 8) band ?UINT8_MAX,
_B3 = U32 band ?UINT8_MAX].
-spec uint36_from_ext([uint9_t()]) -> uint36_t().
uint36_from_ext([B0, B1, B2, B3]) ->
((B0 band ?UINT9_MAX) bsl 27) bor
((B1 band ?UINT9_MAX) bsl 18) bor
((B2 band ?UINT9_MAX) bsl 9) bor
(B3 band ?UINT9_MAX).
-spec uint36_to_ext(uint36_t()) -> [uint9_t()].
uint36_to_ext(U36) ->
@@ -46,9 +83,24 @@ uint36_to_ext(U36) ->
_B2 = (U36 bsr 9) band ?UINT9_MAX,
_B3 = U36 band ?UINT9_MAX].
-spec uint36_from_ext([uint9_t()]) -> uint36_t().
uint36_from_ext([B0, B1, B2, B3]) ->
((B0 band ?UINT9_MAX) bsl 27) bor
((B1 band ?UINT9_MAX) bsl 18) bor
((B2 band ?UINT9_MAX) bsl 9) bor
(B3 band ?UINT9_MAX).
-spec uint64_from_ext([uint8_t()]) -> uint64_t().
uint64_from_ext([B0, B1, B2, B3, B4, B5, B6, B7]) ->
((B0 band ?UINT8_MAX) bsl 56) bor
((B1 band ?UINT8_MAX) bsl 48) bor
((B2 band ?UINT8_MAX) bsl 40) bor
((B3 band ?UINT8_MAX) bsl 32) bor
((B4 band ?UINT8_MAX) bsl 24) bor
((B5 band ?UINT8_MAX) bsl 16) bor
((B6 band ?UINT8_MAX) bsl 8) bor
(B7 band ?UINT8_MAX).
-spec uint64_to_ext(uint64_t()) -> [uint8_t()].
uint64_to_ext(U64) ->
[_B0 = (U64 bsr 56) band ?UINT8_MAX,
_B1 = (U64 bsr 48) band ?UINT8_MAX,
_B2 = (U64 bsr 40) band ?UINT8_MAX,
_B3 = (U64 bsr 32) band ?UINT8_MAX,
_B4 = (U64 bsr 24) band ?UINT8_MAX,
_B5 = (U64 bsr 16) band ?UINT8_MAX,
_B6 = (U64 bsr 8) band ?UINT8_MAX,
_B7 = U64 band ?UINT8_MAX].

View File

@@ -72,6 +72,12 @@
%% only called from tests
, {sim_core, run, 2}
%% actual unused exports
, {extint, uint16_from_ext, 1}
, {extint, uint16_to_ext, 1}
, {extint, uint32_from_ext, 1}
, {extint, uint32_to_ext, 1}
, {extint, uint64_from_ext, 1}
, {extint, uint64_to_ext, 1}
, {libelf, read_PhTab, 4}
, {pdp10_opcodes, cpu_device_from_name, 2}
, {pdp10_opcodes, models_from_name, 1}