Bit operation of extract flags into 24 bit integer

Mike

I saw a line in xen's kernel code (file: xen/include/asm-x86/x86_64/page.h), but cannot understand why they are doing this:

/* Extract flags into 24-bit integer, or turn 24-bit flags into a pte mask. */                                                                      
#define get_pte_flags(x) (((int)((x) >> 40) & ~0xFFF) | ((int)(x) & 0xFFF))                                                                         
#define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 40) | ((x) & 0xFFF))     

As to

#define get_pte_flags(x) (((int)((x) >> 40) & ~0xFFF) | ((int)(x) & 0xFFF)) 

I understand ((int)(x) & 0xFFF) will extract the last 24 bits of x, but why they need the first part ((int)((x) >> 40) & ~0xFFF) ?

As to

  #define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 40) | ((x) & 0xFFF))  

I'm lost at the purpose of ((intpte_t)((x) & ~0xFFF) << 40). It should be 0 in my opinion. Then why do we need it?

Thanks,

Travis Griggs

I had to look twice at their code. Because it took me a minute to realize that 0xFFF is not 24 bits, it's only 12 bits. So take an example 64 bit input: 0xAABBCCDDEEFF1122. Shift it right by 40, and you get 0x0000000000AABBCC. ~0xFFF is shorthand in this case for 0xFFFFFFFFFFFFF000. And them together, and you get 0x0000000000AAB000. So basically, they grabbed the top 12 bits and moved them down. Then they or that with the bottom 12 bits. So they end up with 0x0000000000AAB122.

The other half does the opposite, takes 24 bits at the bottom, cuts them in half and puts 12 at the top and 12 at the bottom.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related