Add a compatibility function attribute (and flag) for nacl-gcc to
be ABI compatible with llvm/PNaCl.

Due to the fact that llvm bitcode loses information about the original source,
(unions, alignment) it is hard to match the ABI (see notes for known issues:
https://docs.google.com/a/google.com/document/d/1P3WrT_LHwN20gbs75LnHuMrbd804fSdSHKGK7Q3B20k/edit?hl=en_US#bookmark=id.sb20hms96tga).

Thus, for now, we make an attribute (and flag) to pass and return
structures and unions on the stack. Vectors and scalars can still use registers. This is calling convention is easy
to match. With this nacl-gcc is calling convention compatible with
pnacl. If at some point in the future we get richer type information
in bitcode we could do without this.

*****
Example uses of the attribute:

typedef struct {int x; float y; } s1;

typedef  void (__attribute__((pnaclcall)) *pnacl_fp)(int, s1, int);
typedef  s1 (__attribute__((pnaclcall)) *pnacl_ret_fp)(int, int) ;

extern void foo(int x, s1 y, int z);

__attribute__((pnaclcall)) void bar(int x, s1 y, int z)
{
  foo(x, y, z);
  if (x > 0)
    bar(x - 1, y, z);
}

void bar_fp_casted(void) {
  s1 s = { 80, 81.0f };
  void (__attribute__((pnaclcall)) *temp_fp)(int, s1, int) ;
  temp_fp = (pnacl_fp)&foo;
  (*temp_fp)(79, s, 82);
}

void bar_fp_casted2(void) {
  s1 s = { 80, 81.0f };
  void (*temp_fp)(int, s1, int) = &foo;
  (*(pnacl_fp)temp_fp)(79, s, 82);
}

*****

BUG= http://code.google.com/p/nativeclient/issues/detail?id=1819
BUG= http://code.google.com/p/nativeclient/issues/detail?id=2413
TEST= http://codereview.chromium.org/8502006/
and toolchain trybots

Review URL: http://codereview.chromium.org/8479017
4 files changed