public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
* libffi on the HPPA (parisc)
@ 2019-04-13 18:26 Georg Bege
  2019-04-13 21:34 ` Georg Bege
  0 siblings, 1 reply; 2+ messages in thread
From: Georg Bege @ 2019-04-13 18:26 UTC (permalink / raw)
  To: libffi-discuss

[-- Attachment #1: Type: text/plain, Size: 1917 bytes --]

Hello guys,

Im recently tinkering with PARISC machines which I've left.
I've got two of them, one with HPUX 11iv1 (old, I know) and one with Linux.

According to the libffi main page, HPPA is indeed supported (not on 
Linux, but this is outdated?).
I've written a simple test code, in order to sanity check libffi's basic 
functionality.

This code is working fine on i386 and amd64.. just for reference.
My main goal is getting libffi working (eg. ported) to HPUX LP64... I've 
began consulting the proper documents from HP and learning a bit of 
PARISC asm.. but Im still at the beginning.

Right now, I wanted to confirm the functionality which is obviously 
existing...
The first try I've given is on the C8k with Gentoo Linux:

Linux hppa 4.9.49-gentoo-r1-hppa64 #4 SMP Fri Jun 8 19:33:13 CEST 2018 
parisc64 PA8900 (Shortfin) 9000/785/C8000 GNU/Linux

therion@hppa ~ $ qlist -Iv libffi
dev-libs/libffi-3.2.1
virtual/libffi-3.0.13-r1

So far so good... I've this installation now for a while...
The thing is that my test code is failing with 64bit signed integers.

Im hoping that any of you may look into it, or can lend me a hand - was 
this ever supposed to work? Is it actually working?
My test code is buggy? If so which part? :)

Since it's just test I'll attach my code here.

Output:
---------------snip--------------------
therion@hppa ~ $ ./test-ffi
Signed 8bit integer result:	126
Unsigned 8bit integer result:	254
Signed 16bit integer result:	32766
Unsigned 16bit integer result:	65534
Signed 32bit integer result:	2147483646
Unsigned 32bit integer result:	4294967294
Signed 64bit integer result:	0, expected: 2147483646
test-ffi: test-ffi.c:151: main: Assertion `*src == result' failed.
Aborted
---------------snip--------------------

best regards,
-- 
Georg Bege
Mail: georg@bege.email
XMPP: therion@ninth-art.de
IRC: megaTherion @ Freenode

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: test-ffi.c --]
[-- Type: text/x-csrc; name="test-ffi.c", Size: 6672 bytes --]

/**
 * libffi C99 test code
 * - proves that libffi calls are working correctly
 * copyright (C) 2019 <georg@bege.email>
 * Created on:	12th April 2019
 * Modified on:	13th April 2019
 */
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <assert.h>
#include <ffi.h>
#include <inttypes.h>
#include <float.h>

typedef void (*ffi_callback)(void);

typedef struct {
	int _1;
	int _2;
} simple_t;

/* adder functors */
int8_t		add_signed8(int8_t a, int8_t b)			{ return a + b; }
uint8_t 	add_unsigned8(uint8_t a, uint8_t b)		{ return a + b; }
int16_t 	add_signed16(int16_t a, int16_t b)		{ return a + b; }
uint16_t	add_unsigned16(uint16_t a, uint16_t b)	{ return a + b; }
int32_t 	add_signed32(int32_t a, int32_t b)		{ return a + b; }
uint32_t 	add_unsigned32(uint32_t a, uint32_t b)	{ return a + b; }
int64_t 	add_signed64(int64_t a, int64_t b)		{ return a + b; }
uint64_t 	add_unsigned64(uint64_t a, uint64_t b)	{ return a + b; }
float		add_floatS(float a, float b)			{ return a + b; }
double		add_floatD(double a, double b)			{ return a + b; }

simple_t	add_simple(simple_t a, simple_t b) {
	simple_t ret = { a._1 + b._1, a._2 + b._2 };
	return ret;
}

/* ffi proxy function */
ffi_arg call(ffi_type **args, void **values, ffi_type *retarg,
			 size_t len, ffi_callback func)
{
	ffi_cif cif;
	ffi_arg rc;
	
	/* Iniitalize the cif */
	int ret = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, len, retarg, args);
	if(ret != FFI_OK) {
		fprintf(stderr, "[%s] Cant prepare ffi context: %d\n", __func__, ret);
		exit(EXIT_FAILURE);
	}
	
	ffi_call(&cif, func, &rc, values);
	return rc;
}

int main(void) {
	ffi_cif cif;

	/* 8bit signed integer test */
	{
		int8_t a = (CHAR_MAX / 2) + 1, b = (CHAR_MAX / 2) - 1;
		const int8_t result = a + b;
		
		ffi_type *args[] = {&ffi_type_sint8, &ffi_type_sint8};
		void *values[] = {&a, &b};
		
		ffi_arg rc = call(args, values, &ffi_type_sint8, 2, (ffi_callback)add_signed8);
		printf("Signed 8bit integer result:\t%"PRIi8"\n", (int8_t)rc);
		assert( (int8_t)rc == result );
	}
	
	/* 8bit unsigned integer test */
	{
		uint8_t a = (UCHAR_MAX / 2) + 1, b = (UCHAR_MAX / 2) - 1;
		const uint8_t result = a + b;
		
		ffi_type *args[] = {&ffi_type_uint8, &ffi_type_uint8};
		void *values[] = {&a, &b};
		
		ffi_arg rc = call(args, values, &ffi_type_uint8, 2, (ffi_callback)add_unsigned8);
		printf("Unsigned 8bit integer result:\t%"PRIu8"\n", (uint8_t)rc);
		assert( (uint8_t)rc == result);
	}
	
	/* 16bit signed integer test */
	{
		int16_t a = (SHRT_MAX / 2) + 1, b = (SHRT_MAX / 2) - 1;
		const int16_t result = a + b;
		
		ffi_type *args[] = {&ffi_type_sint16, &ffi_type_sint16};
		void *values[] = {&a, &b};
		
		ffi_arg rc = call(args, values, &ffi_type_sint16, 2, (ffi_callback)add_signed16);
		printf("Signed 16bit integer result:\t%"PRIi16"\n", (int16_t)rc);
		assert( (int16_t)rc == result );
	}
	
	/* 16bit unsigned integer test */
	{
		uint16_t a = (USHRT_MAX / 2) + 1, b = (USHRT_MAX / 2) - 1;
		const uint16_t result = a + b;
		
		ffi_type *args[] = {&ffi_type_uint16, &ffi_type_uint16};
		void *values[] = {&a, &b};
		
		ffi_arg rc = call(args, values, &ffi_type_uint16, 2, (ffi_callback)add_unsigned16);
		printf("Unsigned 16bit integer result:\t%"PRIu16"\n", (uint16_t)rc);
		assert( (uint16_t)rc == result );
	}
	
	/* 32bit signed integer test */
	{
		int32_t a = (INT_MAX / 2) + 1, b = (INT_MAX / 2) - 1;
		const int32_t result = a + b;
		
		ffi_type *args[] = {&ffi_type_sint32, &ffi_type_sint32};
		void *values[] = {&a, &b};
	
		ffi_arg rc = call(args, values, &ffi_type_sint32, 2, (ffi_callback)add_signed32);
		printf("Signed 32bit integer result:\t%"PRIi32"\n", (int32_t)rc);
		assert( (int32_t)rc == result );
	}
	
	/* 32bit unsigned integer test */
	{
		uint32_t a = (UINT_MAX / 2) + 1, b = (UINT_MAX / 2) - 1;
		const uint32_t result = a + b;
		
		ffi_type *args[] = {&ffi_type_uint32, &ffi_type_uint32};
		void *values[] = {&a, &b};
		
		ffi_arg rc = call(args, values, &ffi_type_uint32, 2, (ffi_callback)add_unsigned32);
		printf("Unsigned 32bit integer result:\t%"PRIu32"\n", (uint32_t)rc);
		assert( (uint32_t)rc == result );
	}
	
	/* 64bit signed integer test */
	{
		int64_t a = (LONG_MAX / 2) + 1, b = (LONG_MAX / 2) - 1;
		const int64_t result = a + b;
		
		ffi_type *args[] = {&ffi_type_sint64, &ffi_type_sint64};
		void *values[] = {&a, &b};
		
		ffi_arg rc = call(args, values, &ffi_type_sint64, 2, (ffi_callback)add_signed64);
		const int64_t *src = (int64_t*)&rc;
		
		printf("Signed 64bit integer result:\t%"PRIi64", expected: %"PRIi64"\n", *src, result);
		assert( *src == result );
	}
	
	/* 64bit unsigned integer test */
	{
		uint64_t a = (ULONG_MAX / 2) + 1, b = (ULONG_MAX / 2) - 1;
		const uint64_t result = a + b;
		
		ffi_type *args[] = {&ffi_type_uint64, &ffi_type_uint64};
		void *values[] = {&a, &b};
		
		ffi_arg rc = call(args, values, &ffi_type_uint64, 2, (ffi_callback)add_unsigned64);
		const uint64_t *urc = (uint64_t*)&rc;
		
		printf("Unsigned 64bit integer result:\t%"PRIu64"\n", *urc);
		assert( *urc == result );
	}
	
	/* single precision float test */
	{
		float a = (FLT_MAX / 2.0F) + 0.5F, b = (FLT_MAX / 2.0F) - 0.5F;
		const float result = a + b;
		
		ffi_type *args[] = {&ffi_type_float, &ffi_type_float};
		void *values[] = {&a, &b};
		
		ffi_arg rc = call(args, values, &ffi_type_float, 2, (ffi_callback)add_floatS);
		const float *frc = (float*)&rc;
		
		printf("Single precision float result:\t%f\n", *frc);
		assert( *frc == result );
	}
	
	/* double precision float test */
	{
		double a = (DBL_MAX / 2.0) + 0.5, b = (DBL_MAX / 2.0) - 0.5;
		const double result = a + b;
		
		ffi_type *args[] = {&ffi_type_double, &ffi_type_double};
		void *values[] = {&a, &b};
		
		ffi_arg rc = call(args, values, &ffi_type_double, 2, (ffi_callback)add_floatD);
		const double *frc = (double*)&rc;
		
		printf("Double precision float result:\t%lf\n", *frc);
		assert( *frc == result );
	}
	
#if 0
	/* struct test */
	{
		simple_t a = {(INT_MAX / 2) + 1, (INT_MAX / 2) - 1};
		simple_t b = {(INT_MAX / 2) - 1, (INT_MAX / 2) + 1};
		const simple_t result = {a._1 + b._1, a._2 + b._2};
		
		ffi_type *args[] = {&ffi_type_pointer, &ffi_type_pointer};
		void *values[] = {&a, &b};
		
		ffi_arg rc = call(args, values, &ffi_type_pointer, 2, (ffi_callback)add_simple);
		const simple_t *src = (simple_t*)&rc;
		
		printf("Simple_t result:\t%d, %d\n", src->_1, src->_2);
		assert( src->_1 == result._1 && src->_2 == result._2 );
	}
#endif
	
	exit(EXIT_SUCCESS);
}

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-04-13 21:34 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-13 18:26 libffi on the HPPA (parisc) Georg Bege
2019-04-13 21:34 ` Georg Bege

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).