1/* Area:	ffi_call
2   Purpose:	Check sign extension of small ints passed in big registers
3   Limitations:	none.
4   PR:		rdar://7755419, rdar://8042065
5   Originator:	Greg Parker <gparker@apple.com>  */
6
7/* { dg-do run } */
8#include "ffitest.h"
9#include <stdint.h>
10
11int64_t s8_fn(int8_t arg) {
12    return arg;
13}
14
15int64_t s16_fn(int16_t arg) {
16    return arg;
17}
18
19int64_t s32_fn(int32_t arg) {
20    return arg;
21}
22
23int64_t s64_fn(int64_t arg) {
24    return arg;
25}
26
27int main(void)
28{
29    ffi_status err;
30    ffi_cif cif8, cif16, cif32, cif64;
31    ffi_type *argtype8[]  = { &ffi_type_sint8 };
32    ffi_type *argtype16[] = { &ffi_type_sint16 };
33    ffi_type *argtype32[] = { &ffi_type_sint32 };
34    ffi_type *argtype64[] = { &ffi_type_sint64 };
35    int8_t  arg8  = -0x12;
36    int16_t arg16 = -0x1234;
37    int32_t arg32 = -0x12345678;
38    int64_t arg64 = -0x1234567890abcdefLL;
39    void *argvalue8[]  = { &arg8 };
40    void *argvalue16[] = { &arg16 };
41    void *argvalue32[] = { &arg32 };
42    void *argvalue64[] = { &arg64 };
43    int64_t ret;
44
45    CHECK(ffi_prep_cif(&cif8,  FFI_DEFAULT_ABI, 1, &ffi_type_sint64, argtype8) == FFI_OK);
46
47    CHECK(ffi_prep_cif(&cif16, FFI_DEFAULT_ABI, 1, &ffi_type_sint64, argtype16) == FFI_OK);
48
49    CHECK(ffi_prep_cif(&cif32, FFI_DEFAULT_ABI, 1, &ffi_type_sint64, argtype32) == FFI_OK);
50
51    CHECK(ffi_prep_cif(&cif64, FFI_DEFAULT_ABI, 1, &ffi_type_sint64, argtype64) == FFI_OK);
52
53    ffi_call(&cif8,  FFI_FN(s8_fn),  &ret, argvalue8);
54    CHECK(ret == (int64_t)arg8);
55
56    ffi_call(&cif16, FFI_FN(s16_fn), &ret, argvalue16);
57    CHECK(ret == (int64_t)arg16);
58
59    ffi_call(&cif32, FFI_FN(s32_fn), &ret, argvalue32);
60    CHECK(ret == (int64_t)arg32);
61
62    ffi_call(&cif64, FFI_FN(s64_fn), &ret, argvalue64);
63    CHECK(ret == (int64_t)arg64);
64
65    return 0;
66}
67