Page 1 of 1

bit access on value types.

Posted: Thu Oct 04, 2007 8:15 am
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.

Posted: Thu Oct 04, 2007 10:19 am
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?

Posted: Thu Oct 04, 2007 12:31 pm
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

Posted: Thu Oct 04, 2007 10:43 pm
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 ;)