Valhalla Legends Forums Archive | General Programming | merging (joining?) bitfields within a 32-bit integer

AuthorMessageTime
tA-Kane
I've written a function that "merges" multiple bitfields to a single bitfield (that is, taken the example bitmask 00111000110011001 and put it into 00000000011111111), in REALbasic (essentially VB). I was wondering how you guys might do (have done?) it, though?

The reason I'm doing this is that I've read that some PPC32 assembly instructions have operands that are spread across multiple bitfields (though, I have yet to come across such an instance), and figured it wouldn't be bad to try my hand at implementing such an occurance, since it could also have uses in encryption (even if it is weak encryption).

So, here's the "master" function (and required support) that creates the resulting value from the multiple bitfields:[code]BitField As Object
StartBit(-1) As Integer
EndBit(-1) As Integer
End Object

Function GetMaskedMergedBitFieldsValue(Value As Integer, Field As BitField) As Integer
'bit zero is leftmost bit
'field.startbit (array) is the start bit for that field indice
'field.endbit (array) is the end bit for that field indice
'the bitfields don't have to be in order with this joining algorithm (eg, field 1 can precede field 0 in the bitwise order)
Dim rVal, Buffer, BitCount, i, Bound As Integer

If Field = Nil Then
Return 0'Bad field object
End If

Bound = uBound(Field.StartBit)
If Bound = -1 Then
Return 0'No bitfield
End If

rVal = 0'For ease of porting to C... this isn't needed in RB though, since it's automatically initialized to 0
For i = 0 To Bound
Buffer = GetBitField(Field.StartBit(i), Field.EndBit(i))
Buffer = BitwiseAnd(Value, Buffer)
Buffer = UnsignedRightBitShift(Buffer, 31-Field.EndBit(i))'RB doesn't have bitshifting capabilities, so this is a plugin function that I wrote in C that simple returns the value sifted to the right X by bits
BitCount = (Field.EndBit(i) - Field.StartBit(i)) + 1
rVal = UnsignedLeftBitShift(rVal, BitCount)'similar to UnsignedRightBitShift()... need to move the return value to the left to allow room for the current field
rVal = BitwiseOr(rVal, Buffer)'now, add the buffer to the return value
Next

Return rVal
End Function

Function GetBitField(StartBit As Integer, EndBit As Integer) As Integer
Dim rVal, i, Bound As Integer

rVal = 0'again, ease of porting to C
For i = StartBit To EndBit
rVal = BitwiseOr(rVal, GetBit(i))
Next

Return rVal
End Function

Function GetBit(BitNumber As Integer) As Integer
Return UnsignedLeftBitShift(1, 31-BitNum)'bits numbered (left to right) 0 to 31
End Function[/code]

I'm testing the code right now (forgot to do that before I started typing this up), but does anyone have any comments?

Edit: Successfully tested! Try out this code:[code]Dim Field As BitField

Field = New BitField
Field.StartBit.Append 0
Field.EndBit.Append 0
Field.StartBit.Append 2
Field.EndBit.Append 4
Field.StartBit.Append 29
Field.EndBit.Append 31
MsgBox Bin(GetMaskedMergedBitFieldsValue(&b10111000000000000000000000000111, Field))[/code]

Assuming VB has a Bin() function, and Bin() returns the binary form of an integer, you should see seven 1s in a message box. The first one is from the left-most bitfield (with a field length of 1 bit), the next 3 from the second bitfield (with a field length of 3 bits), and the last 3 from the last bitfield (with a field length of 3 bits).

Again, any comments would be appreciated.

[me=tA-Kane]goes to play some more with this function[/me]
May 31, 2004, 6:25 AM
Adron
8-bit bitfield merge in PIC assembler:

[code]

i equ 0xc
mask equ 0xd
value equ 0xe
merged equ 0xf


mergebits
movlw 8
movwf i
clrf merged, f
shiftbits
rlf value, f
btfsc mask, 7
rlf merged, f
rlf mask, f
decfsz i, f
goto shiftbits
return
[/code]
May 31, 2004, 1:28 PM
Adron
C++ bit transpose:

[code]
struct bittransposition {
int srcpos, dstpos, len;
};

typedef std::list<bittransposition> transpositionlist;

unsigned transposebits(unsigned input, transpositionlist &definition)
{
unsigned value = 0;
transpositionlist::iterator it;
for(it = definition.begin(); it != definition.end(); it++) {
value |= ((input >> it->srcpos) & ((1 << it->len) - 1)) << it->dstpos;
}
return value;
}

[/code]


I number my bits right to left, because that seems most natural to me, and to the applications I've seen. Code not tested.
May 31, 2004, 1:37 PM
tA-Kane
[quote author=Adron link=board=5;threadid=7048;start=0#msg62928 date=1086010623]I number my bits right to left, because that seems most natural to me, and to the applications I've seen.[/quote]I agree. However, bits in PPC instructions are numbered left to right, so I programmed accordingly. :-\
June 1, 2004, 4:19 AM

Search