Hi all,

This is a fix for bug 598 (https://bugs.open64.net/show_bug.cgi?id=598): 
implement 3 gcc builtin functions on x86-64: __builtin_apply_args / 
__builtin_apply / __builtin_return.

Here are the descriptions of those 3 functions:

Constructing Function Calls

Using the built-in functions described below, you can record the arguments a
function received, and call another function with the same arguments, without
knowing the number or types of the arguments.

You can also record the return value of that function call, and later return
that value, without knowing what data type the function tried to return (as
long as your caller expects that data type).

    * __builtin_apply_args
    * __builtin_apply
    * __builtin_return

__builtin_apply_args

void *__builtin_apply_args (void);

This built-in function returns a pointer to data describing how to perform a
call with the same arguments as were passed to the current function.

The function saves the arg pointer register, structure value address, and all
registers that might be used to pass arguments to a function into a block of
memory allocated on the stack. Then it returns the address of that block.
__builtin_apply

void *__builtin_apply (void (*fnc)(), void *args, int size);

This built-in function invokes function with a copy of the parameters described
by arguments and size.

The value of arguments should be the value returned by __builtin_apply_args.
The argument size specifies the size of the stack argument data, in bytes.

This function returns a pointer to data describing how to return whatever value
was returned by function. The data is saved in a block of memory allocated on
the stack.

It is not always simple to compute the proper value for size. The value is used
by __builtin_apply to compute the amount of data that should be pushed on the
stack and copied from the incoming argument area.
__builtin_return

void __builtin_return (void *result);

This built-in function returns the value described by result from the
containing function. You should specify, for result, a value returned by
__builtin_apply.

I attached the diff file and test case. Could someone please review this change?

Regards,
Roger
#include <stdio.h>
#include <stdarg.h>

#define ARGSIZE 256
#define FORMAT  "%llx"

typedef long long NType;

typedef struct SType {
    NType a;
    NType b;
} SType;

NType direct1(const char* format, ...) {
    va_list ap;
    va_start(ap, format);
    vprintf(format, ap);
    va_end(ap);
    return 0x1234567890abcdefLL;
}

NType direct2(const char* format, ...) {
    va_list ap;
    va_start(ap, format);
    vprintf(format, ap);
    va_end(ap);
    return 0xfedcba0987654321LL;
}

SType direct3() {
    SType value = {0x1234567890abcdefLL, 0xfedcba0987654321LL};
    return value;
}

NType indirect1(const char* format, ...) {
    void* args = __builtin_apply_args();
    void* result = __builtin_apply(direct1, args, ARGSIZE);
    __builtin_return(result);
}

SType indirect3() {
    SType s1;
    void* args = __builtin_apply_args();
    void* result = __builtin_apply(direct3, args, ARGSIZE);
    __builtin_return(result);
    return s1;
}

NType indirect12(const char* format, int v1, double v2, int flag) {
    format = "indirect1 %d %f\n";
    void* args1 = __builtin_apply_args();
    void* result1 = __builtin_apply(direct1, args1, ARGSIZE);

    format = "indirect2 %d %f\n";
    void* args2 = __builtin_apply_args();
    void* result2 = __builtin_apply(direct2, args2, ARGSIZE);

    if (flag)
        __builtin_return(result1);
    else
        __builtin_return(result2);

    printf("should not print this line\n");
    return 0;
}

int main(int argc, char* * argv) {
    NType v1 = direct1("  direct1 %d %d %d %d %d %d %d %d %d %d %f %f %f %f %f 
%f %f %f %f %f\n", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 
0.6, 0.7, 0.8, 0.9);

    NType v2 = indirect1("indirect1 %d %d %d %d %d %d %d %d %d %d %f %f %f %f 
%f %f %f %f %f %f\n", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0.0, 0.1, 0.2, 0.3, 0.4, 
0.5, 0.6, 0.7, 0.8, 0.9);

    NType v3 = direct1("  direct1 %d %f\n", 999, 999.999, 1);
    NType v4 = direct2("  direct2 %d %f\n", 999, 999.999, 0);

    NType v5 = indirect12("original1 %d %f\n", 999, 999.999, 1);
    NType v6 = indirect12("original2 %d %f\n", 999, 999.999, 0);

    SType v7 = direct3();
    SType v8 = indirect3();

    char format1[64], format2[64];
    snprintf(format1, 64, "%s %s %%d\n", FORMAT, FORMAT);
    snprintf(format2, 64, "%s %s %s %s %%d\n", FORMAT, FORMAT, FORMAT, FORMAT);

    printf(format1, v1, v2, v1 == v2);
    printf(format1, v3, v5, v3 == v5);
    printf(format1, v4, v6, v4 == v6);
    printf(format2, v7.a, v7.b, v8.a, v8.b, (v7.a == v8.a && v7.b == v8.b));
}

Attachment: 598.diff
Description: 598.diff

------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Open64-devel mailing list
Open64-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open64-devel

Reply via email to