Implementation of mode attribute

Per subject, implementation of the gcc mode attribute (e.g. int x
__attribute__((mode(HI)));). Most significant usage is in the glibc
headers to implement intN_t and friends (PR2204).

The implementation is pretty straightforward: it modifies the type of
the declaration to correspond to the type corresponding to the
specified mode. Currently, the mappings are hardcoded, and only
completely correct for X86. We should probably add some way to get
integers/floats of specific widths from the ASTContext.

There's also a way to use the mode attribute to specify vectors, but
per gcc it's deprecated, and there aren't any headers on my system
using it. If we do end up needing it, it's should be easy to add.

One bug that's kind of out of the scope of this patch: we're currently
processing attributes in the wrong order. For example, take the
following declaration:
float x __attribute((mode(DF),vector_size(16)));
This should declare a variable with the LLVM type <2 x double> (a
vector of size 16 with DFMode elements), but that doesn't work with
this patch because we process the vector_size attribute first. I
haven't actually seen any code which does this, though, so I won't
worry about it for the moment.

-Eli

t.txt (7.64 KB)

You have a typo in a comment :stuck_out_tongue:

+/// HandleAddressSpaceTypeAttribute - Process a mode attribute on the
+/// specified type.
+QualType Sema::HandleModeTypeAttribute(QualType Type,
+ AttributeList *Attr) {

Also these aren't supported in the switch() to look for the RetTy (not sure if it was by distraction or if they are really unsupported..).

+ if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false; break; }
+ if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false; break; }

Nuno

You have a typo in a comment :stuck_out_tongue:

+/// HandleAddressSpaceTypeAttribute - Process a mode attribute on the
+/// specified type.
+QualType Sema::HandleModeTypeAttribute(QualType Type,
+ AttributeList *Attr) {

Thanks.

Also these aren't supported in the switch() to look for the RetTy (not sure
if it was by distraction or if they are really unsupported..).

+ if (!memcmp(Str, "XF", 2)) { DestWidth = 96; IntegerMode = false;
break; }
+ if (!memcmp(Str, "TF", 2)) { DestWidth = 128; IntegerMode = false;
break; }

Nuno

The issue is that there isn't any appropriate way to map them onto
existing types. If I assumed X86, I could map XFmode to long double,
but that isn't right for any other platform. On x86-64, XFmode is
illegal, and TFmode is x87DoubleExtended; on PPC, XFmode is illegal,
and TFmode is IEEEquad. The whole thing is rather messy.

TImode is also unimplemented because clang doesn't have a 128-bit
integer type currently.

-Eli