Page 1 of 1

64-bit type (2xlong)

Posted: Sun Mar 26, 2006 1:23 pm
by Candamir
I'm trying to get a memory map from grub, and there you have two addresses (base_low and base_high) and both are unsigned long. When trying to combine these two, I get the following compiler exception:

Code: Select all

warning: left shift count >= width of type
This is the code:

Code: Select all

       puts("Map entry:\n\tBase address = ");
      puthex((mmap->base_addr_high << 32) ^ mmap->base_addr_low);
      puts(          "\n\tLength      = ");
      puthex((mmap->length_high << 32) ^ mmap->length_low);
      puts(          "\n\tType        = ");
      puthex(mmap->type);
      puts("\n");
I know the output functions are a little bit archaic as I haven't finished my console driver (printf, scanf, basically) ;)

I understand the meaning of the warning, but AFAIK, there isn't any bigger operator than long (?). So is there any easy way round it?

Re:64-bit type (2xlong)

Posted: Sun Mar 26, 2006 1:49 pm
by paulbarker
There's 32 bits in a long, so left or right shifting by 32 bits will always shift you're data completely out of the variable.

You want a 64bit value, for GCC use:

Code: Select all

unsigned long long ll = ((unsigned long long)mmap->base_addr_high) << 32) ^ mmap->base_addr_low)
Notice the typecast to long long before the shift, just to make absolutely sure the compiler knows what we want (I'm usually more pedantic than the compiler).

Re:64-bit type (2xlong)

Posted: Sun Mar 26, 2006 2:08 pm
by Candamir
Thanks! BTW, is this also possible for greater sizes? (unsigned long long long long, e.g.) or is it possible to combine it (long int char)?

Re:64-bit type (2xlong)

Posted: Sun Mar 26, 2006 2:17 pm
by paulbarker
64bit values are the largest that GCC supports natively, I think. They're certainly the largest required by the C standard (#include <stdint.h> and use the types int64_t and uint64_t if you can).

On the x86, you'll have problems with integers greater than 64bits since you get 4 core registers of 32bits each. A 128bit value would use all 4 registers (eax-edx). Larger size integers are usually supported by a 'big int' or 'big num' software library, for situations like cryptography where 1024bit (or more) arithmatic is needed.

I don't think the phrase 'int char' will work but I've never tried it. If 'int char' works, I'd assume 'long int char' works.

Lastly, anything ending 'long' or 'short' implicitly has 'int' on the end. 'long' is really just an alias for 'long int', etc.

Re:64-bit type (2xlong)

Posted: Sun Mar 26, 2006 5:14 pm
by Rob
Is there a reason you are using XOR (^) instead of OR (|) ?

Re:64-bit type (2xlong)

Posted: Sun Mar 26, 2006 5:24 pm
by Candamir
Good question. There's no reason at all. Which one would be faster, though?

Re:64-bit type (2xlong)

Posted: Mon Mar 27, 2006 1:32 am
by RetainSoftware
XOR is totally wrong/unclear here, though it might work it should be either OR or an addition of the lo and hi values.

And for the speed requirement. It doesn't matter because the time to execute XOR or OR is nothing compared to the put functions.