main.cpp
#include <stdio.h>
#include "../../commonfiles/miscdefs.h"
extern "C" void AvxGprCountZeroBits(Uint32 x, Uint32* lzcnt, Uint32* tzcnt);
extern "C" Uint32 AvxGprBextr(Uint32 x, Uint8 start, Uint8 length);
extern "C" Uint32 AvxGprAndNot(Uint32 x, Uint32 y);
void AvxGprCountZeroBitsCpp(void)
{
const int n = 5;
Uint32 x[n] = { 0x001000008, 0x00008000, 0x8000000, 0x00000001, 0 };
printf("\nResults for AvxGprCountZeroBits()\n");
for (int i = 0; i < n; i++)
{
Uint32 lzcnt, tzcnt;
AvxGprCountZeroBits(x[i], &lzcnt, &tzcnt);
printf("x: 0x%08X ", x[i]);
printf("lzcnt: %2u ", lzcnt);
printf("tzcnt: %2u\n", tzcnt);
}
}
void AvxGprExtractBitFieldCpp(void)
{
const int n = 3;
Uint32 x[n] = { 0x12345678, 0x80808080, 0xfedcba98 };
Uint8 start[n] = { 4, 7, 24 };
Uint8 len[n] = { 16, 9, 8 };
printf("\nResults for AvxGprExtractBitField()\n");
for (int i = 0; i < n; i++)
{
Uint32 bextr = AvxGprBextr(x[i], start[i], len[i]);
printf("x: 0x%08X ", x[i]);
printf("start: %2u ", start[i]);
printf("len: %2u ", len[i]);
printf("bextr: 0x%08X\n", bextr);
}
}
void AvxGprAndNotCpp(void)
{
const int n = 3;
Uint32 x[n] = { 0xf000000f, 0xff00ff00, 0xaaaaaaaa };
Uint32 y[n] = { 0x12345678, 0x12345678, 0xffaa5500 };
printf("\nResults for AvxGprAndNot()\n");
for (int i = 0; i < n; i++)
{
Uint32 andn = AvxGprAndNot(x[i], y[i]);
printf("x: 0x%08X y: 0x%08X z: 0x%08X\n", x[i], y[i], andn);
}
}
int main(int argc, char* argv[])
{
AvxGprCountZeroBitsCpp();
AvxGprExtractBitFieldCpp();
AvxGprAndNotCpp();
return 0;
}
avxbgprbitmanip.asm
; Name: avxbgprbitmanip.asm
;
; Build: g++ -c -m32 main.cpp -o main.o
; nasm -f elf32 -o avxbgprbitmanip.o avxbgprbitmanip.asm
; g++ -m32 -o avxbgprbitmanip avxbgprbitmanip.o main.o
;
; Source: Modern x86 Assembly Language Programming p. 486
global AvxGprCountZeroBits
global AvxGprBextr
global AvxGprAndNot
section .text
; extern "C" void AvxGprCountZeroBits(Uint32 x, Uint32* lzcnt, Uint32* tzcnt);
;
; Description: The following function demonstrates use of the lzcnt and
; tzcnt instructions.
;
; Requires: BMI1, LZCNT
AvxGprCountZeroBits:
mov eax,[esp+4] ;eax = x
lzcnt ecx,eax ;count leading zeros
mov edx,[esp+8]
mov [edx],ecx ;save result
tzcnt ecx,eax ;count trailing zeros
mov edx,[esp+12]
mov [edx],ecx ;save result
ret
; extern "C" Uint32 AvxGprBextr(Uint32 x, Uint8 start, Uint8 length);
;
; Description: The following function demonstrates use of the
; bextr instruction.
;
; Requires: BMI1
AvxGprBextr:
mov cl,[esp+8] ;cl = start index
mov ch,[esp+12] ;ch = length of bit field
bextr eax,[esp+4],ecx ;eax = extracted bit field
ret
; extern "C" Uint32 AvxGprAndNot_(Uint32 x, Uint32 y);
;
; Description: The following function demonstrates use of the
; andn instruction.
;
; Requires: BMI1
AvxGprAndNot:
mov ecx,[esp+4]
andn eax,ecx,[esp+8] ;eax = ~ecx & [esp+8]
ret
build
g++ -c -m32 main.cpp -o main.o
nasm -f elf32 -o avxgprbitmanip.o avxgprbitmanip.asm
g++ -m32 -o avxgprbitmanip avxgprbitmanip.o main.o