gm2
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Portable bitwise operations library (was Re: Portability Considerati


From: Benjamin Kowarsch
Subject: Re: Portable bitwise operations library (was Re: Portability Considerations)
Date: Wed, 20 Mar 2024 18:22:47 +0900

On Tue, 19 Mar 2024 at 12:40, Alice Osako wrote:
I've written what are working ISO-compatible implementations of BIT,
SETBIT, BWNOT, BWAND, BWOR, BWXOR, SHL, and SHR, using only the ISO
primitives, though they are painful kludges which I am frankly
embarrassed by - especially the shifts.

https://github.com/Schol-R-LEA/Modula-2-Portable-Bit-Manipulation/tree/main

There has to be a better solution

Indeed, here is one:

https://github.com/m2sf/m2bsk/blob/master/src/lib/imp/CardBitOps.mod

I just don't understand why you don't want to use the code from my libraries.

come up with without resorting to either the GCC-specific libraries, or
importing assembly code. Even then, the claim to being 'portable' is
probably questionable at best. The fact that there is a constant which
defines the word width, which would have to be manually modified for the
correct value, makes the question of 'portability' pointless.

There is no need to modify this manually, it can be determined at compile time.

https://github.com/m2sf/m2bsk/blob/master/src/lib/CardBitOps.def

And yes, I did have to resort to using variant record aliasing to write
the two specialized cast utility functions, and worse, to looping on the
bits for the shifts. I am truly uncomfortable with this approach, but
couldn't think of a better one within the constraints of generic ISO code.

There is no need for neither casting nor loops.

There are four cases:

(1) shift factor = 0
(2) shift factor < bitwidth
(3) shift factor = bitwidth
(4) shift factor > bitwidth

For #1 you return the operand as is. For #3 you return zero. For #4 you can also return zero, or exclude the case by defining a subrange type for the shift factor argument that limits the passed in value to range [0..bitwidth]. This leaves only case #2.

For shifting left, you first determine the bit at the position bitwidth - shift factor, this bit is pivotal. Then you determine the bits that will be shifting out by shifting right using a shift factor of two to the power of the index of the pivotal bit. Then you clear the bits that will be shifted out. Then you shift left by multiplying with two to the power of the shift factor.

To efficiently calculate powers of two, you initialise an array of powers of two during module initialisation, each value simply calculated by multiplying the previous value by two. You can then use the array like a power of two function.

For clearing the bits to be shifted out, my library contains a procedure ClearMSBtoN which also only uses basic math.

Other shifts (including shifting through carry) and rotations can be done using the same principle and with basic math alone.

The library I linked to is pretty well documented, so if you absolutely don't want to use it for whatever reason, study it, understand it, and recreate it.

By the way, does the GCC implementation of Modula-2 support inline
assembly, or would I have to wrap the assembly/C code into functions and
import them?

In Modula-2 it is considered best practice to write an interface module in Modula-2 and the implementation in the desired language, such as assembly or C. The mechanism how to tell the compiler that an interface module is intended for a foreign implementation differs from compiler to compiler. Thus far GM2 uses the syntax FOR "C" after the module name in the module header of the interface module. However, Gaius announced that he will change this to the way defined in M2R10 with a pragma <*FFI="C"*> after the module name in the module header of the interface module.
 
I am not certain how I would proceed with a version that is compatible
with PIM (any edition); it is probably something that would have to be
done on a per-implementation basis.

If you use my library/code, or if you recreate one of your own following the same approach, it will work on PIM and ISO.

regards
benjamin 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]