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: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
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: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))
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 goes to play some more with this function
8-bit bitfield merge in PIC assembler:
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
C++ bit transpose:
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;
}
I number my bits right to left, because that seems most natural to me, and to the applications I've seen. Code not tested.
Quote from: Adron on May 31, 2004, 08:37 AMI number my bits right to left, because that seems most natural to me, and to the applications I've seen.
I agree. However, bits in PPC instructions are numbered left to right, so I programmed accordingly. :-\