Thread: Converting two 32-bit ints to a u_int64_t...

  1. #1
    Registered User
    Join Date
    May 2002
    Posts
    100

    Converting two 32-bit ints to a u_int64_t...

    I have a function that retrieves the high and low order bits of the CPUs cycle-counter (Using GCC asm):

    Code:
    void access_counter(unsigned *hi, unsigned *lo) {
            asm("rdtsc; movl %%edx,%0; movl %%eax,%1"
            : "=r" (*hi), "=r" (*lo)
            :
            : "%edx", "%eax");
    }
    ... And I am writing a function that returns a u_int64_t based on the high and low order bits of access_counter():

    Code:
    u_int64_t get_cycles(void) {
            unsigned hi, lo;
            u_int64_t hi_shift;
    
            access_counter(&hi, &lo);
    
            hi_shift = hi;
    
            return (hi_shift << 32) + lo;
    }
    ... This seems like the correct way of doing this. The only problem is that I cannot think of a way to check if it is correct. So I was hoping someone could look this over and see if this correctly returns the value of the cycle counter as a u_int64_t.

    Thanks

  2. #2
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    That should work, but a union would be easier.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  3. #3
    Registered User
    Join Date
    May 2002
    Posts
    100
    Quote Originally Posted by iMalc View Post
    That should work, but a union would be easier.
    I've never heard of unions in C. How would that work in this context?

    Also.. How could I print a u_int64_t to stdout? %lld doesn't seem to work.

  4. #4
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    It's not u_int64_t, it's uint64_t. [edit]u_int64_t exists on some platforms.[/edit]

    lld is the conversion specification for a long long signed int.

    Use PRIu64 in inttypes.h:
    Code:
    uint64_t a=123;
    printf("It is: &#37;" PRIu64 "\n",a);
    see 7.8.1 of the C standard.
    Last edited by robwhit; 02-16-2008 at 08:40 PM.

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by elfjuice View Post
    I've never heard of unions in C. How would that work in this context?

    Also.. How could I print a u_int64_t to stdout? &#37;lld doesn't seem to work.
    This is a slightly simplified version of LARGE_INTEGER from WinNT.h in VS2005 Express:
    Code:
    typedef union _LARGE_INTEGER {
        struct {
            DWORD LowPart;
            LONG HighPart;
        };
        LONGLONG QuadPart;
    } LARGE_INTEGER;
    You can use it like this:
    Code:
    u_int64_t get_cycles(void) {
            LARGE_INTEGER l;
    
            access_counter(&l.HighPart, &l.LowPart);
    
            return l.QuadPart;
    }
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #6
    Registered User
    Join Date
    May 2002
    Posts
    100
    Quote Originally Posted by robwhit View Post
    It's not u_int64_t, it's uint64_t.

    llu is the conversion specification for a long long unsigned int.

    Use PRIu64 in inttypes.h:
    Code:
    uint64_t a=123;
    printf("It is: " PRIu64 "\n",a);
    see 7.8.1 of the C standard.
    It is u_int64_t as defined in sys/types.h (unix).

    Thanks for the help. But if my shift method works correctly then I will leave it how it is.

    Thanks again.

  7. #7
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Yes, I had been doing some research on that and it appears that I'll have to eat my words.

    My post has been edited to reflect some changes.

    I can't find anywhere that u_int64_t is anything other than an unsigned long long int, so I guess you could use &#37;llu, which coincidentally goes right against what I originally had my post saying.[edit]ok that's not true either... lemme do some more research...[/edit]
    Last edited by robwhit; 02-16-2008 at 08:36 PM.

  8. #8
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Yes! I found it. Yes, I was looking all that time.

    u_int64_t i;
    printf ("&#37;ju", (uintmax_t) i);

    http://www.daemonnews.org/mailinglis.../msg00397.html

    This will work for any integer type under C99, regardless of what the typedef is.
    Last edited by robwhit; 02-16-2008 at 08:39 PM.

  9. #9
    Registered User
    Join Date
    May 2002
    Posts
    100
    Quote Originally Posted by robwhit View Post
    Yes! I found it. Yes, I was looking all that time.

    u_int64_t i;
    printf ("%ju", (uintmax_t) i);

    http://www.daemonnews.org/mailinglis.../msg00397.html

    This will work for any integer type under C99, regardless of what the typedef is.
    Awesome. That helps.

    Thanks

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Converting Chars to Ints
    By sycorax in forum C++ Programming
    Replies: 2
    Last Post: 09-06-2005, 10:40 PM
  2. Converting 24bits RGB to 8 bit Grayscale
    By FearOfTheDark in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 01-29-2003, 06:17 AM
  3. 16 bit or 32 bit
    By Juganoo in forum C Programming
    Replies: 9
    Last Post: 12-19-2002, 07:24 AM
  4. Replies: 2
    Last Post: 08-05-2002, 02:19 PM
  5. 32 bit or 16 ???
    By GiraffeMan in forum C Programming
    Replies: 11
    Last Post: 04-24-2002, 12:56 PM