Search code examples
c++assemblyneon

NEON assembly code, how to convert BYTE to float?


now i have a code want to improve. the datatype of src data is byte. i want to calculate with float and store the result to byte. but i dont know how to convert datatype of data bwtween BYTE and float. I develop on Android NDK. the C++ code i want to improve followed:

void DoEffect(BYTE *pSrc, float rat){
//image data:BGRA
float red, green, blue;
red = pSrc[RED_CHANNEL] * rat;
green = pSrc[GREEN_CHANNEL] * rat;
blue = pSrc[BLUE_CHANNEL] * rat;

//  some step to calculate the result;
//  red = ...
//  ...
//

pSrc[RED_CHANNEL] = (BYTE)red;
pSrc[GREEN_CHANNEL] = (BYTE)green;
pSrc[BLUE_CHANNEL] = (BYTE)blue;

}

and my neon asm code:

void DoEffect_neon_asm(BYTE *pSrc, float rat){
__asm__ __volatile__(
        "vld4.8     {d0-d3},[%[src]]    \n"
        "vdupq.32   {d4, d5}, [%[rat]]  \n"
        "# convert src data to float?       \n"
        "code: convert byte to float        \n"
        "# calculate result         \n"
        "..                 \n"
        "# convert result to byte       \n"
        "code: convert float to byte        \n"
        :[src]"r"(pSrc), [rat]"r"(rat)
);

}

my problem is how to code "code: convert byte to float" and "code: convert float to byte" listed in "neon asm code".


Solution

  • Converting bytes to floats is fairly straightforward. The code below will do this for one register of bytes:

    "vmovl.u8       q3, d2                      \n\t"   //Expand to 16-bit
    "vmovl.u16      q10, d6                     \n\t"   //Expand to 32-bit
    "vmovl.u16      q11, d7                     \n\t"
    "vcvt.f32.u32   q10, q10                    \n\t"   //Convert to float
    "vcvt.f32.u32   q11, q11                    \n\t"
    

    Converting back to bytes is almost exactly the reverse process. Use vcvt.u32.f32 and vmovn instead.

    Also, if you're new to NEON, I would recommend reading the documentation thoroughly. It's a good way to get a handle on the instructions.