bit access on value types.

Programming, for all ages and all languages.
Post Reply
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

bit access on value types.

Post by os64dev »

I have written a template class to manipulate bits in a value type and now i am interested in how many people would find it a use full feature/template. The template does take some performance issues into account so it is still fast.

Consider the following program fragment:

Code: Select all

static BitField<int8u> data;

data.bitRange(0, 4) = 0;    //- clear bits 0..3 (4 bits)     (data=0x00)
data(4, 4) = -1;            //- set bits 4..7 (4 bits) to -1 (data=0xF0)
data(1, 2) = -1;            //- set bits 1..2 (2 bits) to -1 (data=0xF6)
As the commentary already explains it should set the value type data to 0xF6. The example shows both the use of the bitRange function and the operator () equivalent. Below shows the assembly output of these C++ statements.

Code: Select all

c6 05 00 00 00 00 f6 	movb   $0xf6,0(%rip) 
GCC nicely optimizes this to one single instruction.

I am thinking of making a template class for value types, for instance int8, int16, int32, int64 and there unsigned equivalents were these bit manipulation function are incorporated.

Usefull or not.
Author of COBOS
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Post by Candy »

That's a pretty good idea. Could you perform a bit more checking to see what it makes from one side or two-side variable range settings?
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

Code: Select all

data.bitRange(base, 4) = 0;

8b 0d 00 00 00 00    	mov    0(%rip),%ecx
b8 0f 00 00 00       	mov    $0xf,%eax
d3 e0                	shl    %cl,%eax
f7 d0                	not    %eax
83 e0 f6             	and    $0xfffffffffffffff6,%eax
88 05 00 00 00 00    	mov    %al,0(%rip)

Code: Select all

data.bitRange(base, size) = 0;

ba 0f 00 00 00       	mov    $0xf,%edx
89 f1                	mov    %esi,%ecx
b8 01 00 00 00       	mov    $0x1,%eax
d3 e2                	shl    %cl,%edx
8b 0d 00 00 00 00    	mov    0(%rip),%ecx
f7 d2                	not    %edx
83 e2 f6             	and    $0xfffffffffffffff6,%edx
d3 e0                	shl    %cl,%eax
89 f1                	mov    %esi,%ecx
ff c8                	dec    %eax
d3 e0                	shl    %cl,%eax
f7 d0                	not    %eax
21 c2                	and    %eax,%edx
88 15 00 00 00 00    	mov    %dl,0(%rip)

Code: Select all

data.bitRange(base, size) = temp;

b8 0f 00 00 00       	mov    $0xf,%eax
d3 e0                	shl    %cl,%eax
f7 d0                	not    %eax
83 e0 f6             	and    $0xfffffffffffffff6,%eax
21 d0                	and    %edx,%eax
0f b6 15 00 00 00 00 	movzbl 0(%rip),%edx
d3 e2                	shl    %cl,%edx
21 d7                	and    %edx,%edi
09 f8                	or     %edi,%eax
88 05 00 00 00 00    	mov    %al,0(%rip)
edit: doesn't seem right need investigate a bit more.
edit2: nope is ok i guess
Author of COBOS
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

Ok i've implemented the basic ValueType<T> and made a small function to test its purpose. not quite the c++ example but it show its worth (i think).

The following function sets the total of vertical lines used by the VGA CRT controller :

Code: Select all

int8 _crt[0x19];

void SetVerticalTotal(int total) {
    _crt[0x06](0, 8) = total;
    _crt[0x07](0, 1) = total >> 8;
    _crt[0x07](5, 1) = total >> 9;
}
The GCC compilers compiles this to the following assembly:

Code: Select all

_Z16SetVerticalTotali:
    movzbl 0(%rip),%ecx
    mov    %edi,%eax
    mov    %dil,0(%rip)
    movsbl %ah,%edx
    sar    $0x9,%eax
    and    $0x1,%edx
    shl    $0x5,%eax
    and    $0x20,%eax
    and    $0xffffffffffffffde,%ecx
    or     %edx,%ecx
    or     %eax,%ecx
    mov    %cl,0(%rip)
    retq   
IMHO this is rather well optimised code and readable. In system programming general the bit positions and sizes are fixed so this example is well-suited.

Now i will have to rewrite most of my code. Setting descriptors and paging bits is going to be easy from now on .. Ok i'll stop promoting ;)
Author of COBOS
Post Reply