28

This arose from a question earlier today on the subject of bignum libraries and gcc specific hacks to the C language. Specifically, these two declarations were used:

typedef unsigned int dword_t __attribute__((mode(DI)));

On 32 bit systems and

typedef unsigned int dword_t __attribute__((mode(TI)));

On 64-bit systems.

I assume given this is an extension to the C language that there exists no way to achieve whatever it achieves in current (C99) standards.

So my questions are simple: is that assumption correct? And what do these statements do to the underlying memory? I think the result is I have 2*sizeof(uint32_t) for a dword in 32-bit systems and 2*sizeof(uint64_t) for 64-bit systems, am I correct?

phuclv
  • 37,963
  • 15
  • 156
  • 475

2 Answers2

32

These allow you to explicitly specify a size for a type without depending on compiler or machine semantics, such as the size of 'long' or 'int'.

They are described fairly well on this page.

I quote from that page:

QI: An integer that is as wide as the smallest addressable unit, usually 8 bits.

HI: An integer, twice as wide as a QI mode integer, usually 16 bits.

SI: An integer, four times as wide as a QI mode integer, usually 32 bits.

DI: An integer, eight times as wide as a QI mode integer, usually 64 bits.

SF: A floating point value, as wide as a SI mode integer, usually 32 bits.

DF: A floating point value, as wide as a DI mode integer, usually 64 bits.

So DI is essentially sizeof(char) * 8.

Further explanation, including TI mode, can be found here (possibly better than the first link, but both provided for reference).

So TI is essentially sizeof(char) * 16 (128 bits).


The old links are now dead, so here's the official GCC documentation.

Pharap
  • 3,826
  • 5
  • 37
  • 51
Matthew Iselin
  • 10,400
  • 4
  • 51
  • 62
  • Just what I needed, +1. Is there no "standard" way to get around this then, I take it? i.e. declare say a 128-bit type? In its current usage, we can `dword = word << 1` safely and easily; I'd rather not replace that with a function etc if I can help it. –  Dec 30 '10 at 00:31
  • 1
    @Ninefingers: In GCC you can use `__int128` I believe: http://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html. – Matthew Iselin Dec 30 '10 at 00:34
  • 1
    @Ninefingers: GCC supports the extension types `__int128_t` and `__uint128_t` (at least on 64-bit platforms, not sure about 32-bit targets) – Stephen Canon Dec 30 '10 at 14:19
  • 2
    what about `__attribute__((mode(SD)))` ? – haelix Oct 24 '14 at 07:06
  • @haelix same as SF but for doubles? – berkus Aug 26 '17 at 12:38
3

@haelix Just read this question and I also tried to understand this thing. By my reading: you can find the definitions in the [gcc/gcc/machmode.def] in GCC source tree. For 'SD' it should be:

    /* Decimal floating point modes.  */ 
DECIMAL_FLOAT_MODE (SD, 4, decimal_single_format);

and 'DECIMAL_FLOAT_MODE' says:

     DECIMAL_FLOAT_MODE (MODE, BYTESIZE, FORMAT);
declares MODE to be of class DECIMAL_FLOAT and BYTESIZE bytes
wide.  All of the bits of its representation are significant.
CoryXie
  • 124
  • 3