• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #if defined(__ppc__) || defined(__ppc64__)
2 
3 /* -----------------------------------------------------------------------
4    ffi.c - Copyright (c) 1998 Geoffrey Keating
5 
6    PowerPC Foreign Function Interface
7 
8    Darwin ABI support (c) 2001 John Hornkvist
9    AIX ABI support (c) 2002 Free Software Foundation, Inc.
10 
11    Permission is hereby granted, free of charge, to any person obtaining
12    a copy of this software and associated documentation files (the
13    ``Software''), to deal in the Software without restriction, including
14    without limitation the rights to use, copy, modify, merge, publish,
15    distribute, sublicense, and/or sell copies of the Software, and to
16    permit persons to whom the Software is furnished to do so, subject to
17    the following conditions:
18 
19    The above copyright notice and this permission notice shall be included
20    in all copies or substantial portions of the Software.
21 
22    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
23    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
26    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28    OTHER DEALINGS IN THE SOFTWARE.
29    ----------------------------------------------------------------------- */
30 
31 #include <ffi.h>
32 #include <ffi_common.h>
33 
34 #include <stdbool.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <ppc-darwin.h>
38 #include <architecture/ppc/mode_independent_asm.h>
39 
40 #if 0
41 #if defined(POWERPC_DARWIN)
42 #include <libkern/OSCacheControl.h>	// for sys_icache_invalidate()
43 #endif
44 
45 #else
46 
47 #pragma weak sys_icache_invalidate
48 extern void sys_icache_invalidate(void *start, size_t len);
49 
50 #endif
51 
52 
53 extern void ffi_closure_ASM(void);
54 
55 // The layout of a function descriptor.  A C function pointer really
56 // points to one of these.
57 typedef struct aix_fd_struct {
58   void*	code_pointer;
59   void*	toc;
60 } aix_fd;
61 
62 /* ffi_prep_args is called by the assembly routine once stack space
63    has been allocated for the function's arguments.
64 
65    The stack layout we want looks like this:
66 
67    |   Return address from ffi_call_DARWIN      |	higher addresses
68    |--------------------------------------------|
69    |   Previous backchain pointer      4/8      |	    stack pointer here
70    |--------------------------------------------|-\ <<< on entry to
71    |   Saved r28-r31                 (4/8)*4    | |	    ffi_call_DARWIN
72    |--------------------------------------------| |
73    |   Parameters      (at least 8*(4/8)=32/64) | | (176) +112 - +288
74    |--------------------------------------------| |
75    |   Space for GPR2                  4/8      | |
76    |--------------------------------------------| |	stack	|
77    |   Reserved						 (4/8)*2    | |	grows	|
78    |--------------------------------------------| |	down	V
79    |   Space for callee's LR           4/8      | |
80    |--------------------------------------------| |	lower addresses
81    |   Saved CR                        4/8      | |
82    |--------------------------------------------| |     stack pointer here
83    |   Current backchain pointer       4/8      | |     during
84    |--------------------------------------------|-/ <<< ffi_call_DARWIN
85 
86 	Note: ppc64 CR is saved in the low word of a long on the stack.
87 */
88 
89 /*@-exportheader@*/
90 void
ffi_prep_args(extended_cif * inEcif,unsigned * const stack)91 ffi_prep_args(
92 	extended_cif*	inEcif,
93 	unsigned *const	stack)
94 /*@=exportheader@*/
95 {
96 	/*	Copy the ecif to a local var so we can trample the arg.
97 		BC note: test this with GP later for possible problems...	*/
98 	volatile extended_cif*	ecif	= inEcif;
99 
100 	const unsigned bytes	= ecif->cif->bytes;
101 	const unsigned flags	= ecif->cif->flags;
102 
103 	/*	Cast the stack arg from int* to long*. sizeof(long) == 4 in 32-bit mode
104 		and 8 in 64-bit mode.	*/
105 	unsigned long *const longStack	= (unsigned long *const)stack;
106 
107 	/* 'stacktop' points at the previous backchain pointer.	*/
108 #if defined(__ppc64__)
109 	//	In ppc-darwin.s, an extra 96 bytes is reserved for the linkage area,
110 	//	saved registers, and an extra FPR.
111 	unsigned long *const stacktop	=
112 		(unsigned long *)(unsigned long)((char*)longStack + bytes + 96);
113 #elif defined(__ppc__)
114 	unsigned long *const stacktop	= longStack + (bytes / sizeof(long));
115 #else
116 #error undefined architecture
117 #endif
118 
119 	/* 'fpr_base' points at the space for fpr1, and grows upwards as
120 		we use FPR registers.  */
121 	double*		fpr_base = (double*)(stacktop - ASM_NEEDS_REGISTERS) -
122 		NUM_FPR_ARG_REGISTERS;
123 
124 #if defined(__ppc64__)
125 	//	64-bit saves an extra register, and uses an extra FPR. Knock fpr_base
126 	//	down a couple pegs.
127 	fpr_base -= 2;
128 #endif
129 
130 	unsigned int	fparg_count = 0;
131 
132 	/* 'next_arg' grows up as we put parameters in it.  */
133 	unsigned long*	next_arg = longStack + 6; /* 6 reserved positions.  */
134 
135 	int				i;
136 	double			double_tmp;
137 	void**			p_argv = ecif->avalue;
138 	unsigned long	gprvalue;
139 	ffi_type**		ptr = ecif->cif->arg_types;
140 
141 	/* Check that everything starts aligned properly.  */
142 	FFI_ASSERT(stack == SF_ROUND(stack));
143 	FFI_ASSERT(stacktop == SF_ROUND(stacktop));
144 	FFI_ASSERT(bytes == SF_ROUND(bytes));
145 
146 	/*	Deal with return values that are actually pass-by-reference.
147 		Rule:
148 		Return values are referenced by r3, so r4 is the first parameter.  */
149 
150 	if (flags & FLAG_RETVAL_REFERENCE)
151 		*next_arg++ = (unsigned long)(char*)ecif->rvalue;
152 
153 	/* Now for the arguments.  */
154 	for (i = ecif->cif->nargs; i > 0; i--, ptr++, p_argv++)
155     {
156 		switch ((*ptr)->type)
157 		{
158 			/*	If a floating-point parameter appears before all of the general-
159 				purpose registers are filled, the corresponding GPRs that match
160 				the size of the floating-point parameter are shadowed for the
161 				benefit of vararg and pre-ANSI functions.	*/
162 			case FFI_TYPE_FLOAT:
163 				double_tmp = *(float*)*p_argv;
164 
165 				if (fparg_count < NUM_FPR_ARG_REGISTERS)
166 					*fpr_base++ = double_tmp;
167 
168 				*(double*)next_arg = double_tmp;
169 
170 				next_arg++;
171 				fparg_count++;
172 				FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
173 
174 				break;
175 
176 			case FFI_TYPE_DOUBLE:
177 				double_tmp = *(double*)*p_argv;
178 
179 				if (fparg_count < NUM_FPR_ARG_REGISTERS)
180 					*fpr_base++ = double_tmp;
181 
182 				*(double*)next_arg = double_tmp;
183 
184 				next_arg += MODE_CHOICE(2,1);
185 				fparg_count++;
186 				FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
187 
188 				break;
189 
190 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
191 			case FFI_TYPE_LONGDOUBLE:
192 #if defined(__ppc64__)
193 				if (fparg_count < NUM_FPR_ARG_REGISTERS)
194 					*(long double*)fpr_base	= *(long double*)*p_argv;
195 #elif defined(__ppc__)
196 				if (fparg_count < NUM_FPR_ARG_REGISTERS - 1)
197 					*(long double*)fpr_base	= *(long double*)*p_argv;
198 				else if (fparg_count == NUM_FPR_ARG_REGISTERS - 1)
199 					*(double*)fpr_base	= *(double*)*p_argv;
200 #else
201 #error undefined architecture
202 #endif
203 
204 				*(long double*)next_arg	= *(long double*)*p_argv;
205 				fparg_count += 2;
206 				fpr_base += 2;
207 				next_arg += MODE_CHOICE(4,2);
208 				FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
209 
210 				break;
211 #endif	//	FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
212 
213 			case FFI_TYPE_UINT64:
214 			case FFI_TYPE_SINT64:
215 #if defined(__ppc64__)
216 				gprvalue = *(long long*)*p_argv;
217 				goto putgpr;
218 #elif defined(__ppc__)
219 				*(long long*)next_arg = *(long long*)*p_argv;
220 				next_arg += 2;
221 				break;
222 #else
223 #error undefined architecture
224 #endif
225 
226 			case FFI_TYPE_POINTER:
227 				gprvalue = *(unsigned long*)*p_argv;
228 				goto putgpr;
229 
230 			case FFI_TYPE_UINT8:
231 				gprvalue = *(unsigned char*)*p_argv;
232 				goto putgpr;
233 
234 			case FFI_TYPE_SINT8:
235 				gprvalue = *(signed char*)*p_argv;
236 				goto putgpr;
237 
238 			case FFI_TYPE_UINT16:
239 				gprvalue = *(unsigned short*)*p_argv;
240 				goto putgpr;
241 
242 			case FFI_TYPE_SINT16:
243 				gprvalue = *(signed short*)*p_argv;
244 				goto putgpr;
245 
246 			case FFI_TYPE_STRUCT:
247 			{
248 #if defined(__ppc64__)
249 				unsigned int	gprSize = 0;
250 				unsigned int	fprSize = 0;
251 
252 				ffi64_struct_to_reg_form(*ptr, (char*)*p_argv, NULL, &fparg_count,
253 					(char*)next_arg, &gprSize, (char*)fpr_base, &fprSize);
254 				next_arg += gprSize / sizeof(long);
255 				fpr_base += fprSize / sizeof(double);
256 
257 #elif defined(__ppc__)
258 				char*	dest_cpy = (char*)next_arg;
259 
260 			/*	Structures that match the basic modes (QI 1 byte, HI 2 bytes,
261 				SI 4 bytes) are aligned as if they were those modes.
262 				Structures with 3 byte in size are padded upwards.  */
263 				unsigned size_al = (*ptr)->size;
264 
265 			/*	If the first member of the struct is a double, then align
266 				the struct to double-word.  */
267 				if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
268 					size_al = ALIGN((*ptr)->size, 8);
269 
270 				if (ecif->cif->abi == FFI_DARWIN)
271 				{
272 					if (size_al < 3)
273 						dest_cpy += 4 - size_al;
274 				}
275 
276 				memcpy((char*)dest_cpy, (char*)*p_argv, size_al);
277 				next_arg += (size_al + 3) / 4;
278 #else
279 #error undefined architecture
280 #endif
281 				break;
282 			}
283 
284 			case FFI_TYPE_INT:
285 			case FFI_TYPE_UINT32:
286 			case FFI_TYPE_SINT32:
287 				gprvalue = *(unsigned*)*p_argv;
288 
289 putgpr:
290 				*next_arg++ = gprvalue;
291 				break;
292 
293 			default:
294 				break;
295 		}
296 	}
297 
298   /* Check that we didn't overrun the stack...  */
299   //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
300   //FFI_ASSERT((unsigned *)fpr_base
301   //	     <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
302   //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
303 }
304 
305 #if defined(__ppc64__)
306 
307 bool
ffi64_struct_contains_fp(const ffi_type * inType)308 ffi64_struct_contains_fp(
309 	const ffi_type*	inType)
310 {
311 	bool			containsFP	= false;
312 	unsigned int	i;
313 
314 	for (i = 0; inType->elements[i] != NULL && !containsFP; i++)
315 	{
316 		if (inType->elements[i]->type == FFI_TYPE_FLOAT		||
317 			inType->elements[i]->type == FFI_TYPE_DOUBLE	||
318 			inType->elements[i]->type == FFI_TYPE_LONGDOUBLE)
319 			containsFP = true;
320 		else if (inType->elements[i]->type == FFI_TYPE_STRUCT)
321 			containsFP = ffi64_struct_contains_fp(inType->elements[i]);
322 	}
323 
324 	return containsFP;
325 }
326 
327 #endif	// defined(__ppc64__)
328 
329 /* Perform machine dependent cif processing.  */
330 ffi_status
ffi_prep_cif_machdep(ffi_cif * cif)331 ffi_prep_cif_machdep(
332 	ffi_cif*	cif)
333 {
334 	/* All this is for the DARWIN ABI.  */
335 	int				i;
336 	ffi_type**		ptr;
337 	int				intarg_count = 0;
338 	int				fparg_count = 0;
339 	unsigned int	flags = 0;
340 	unsigned int	size_al = 0;
341 
342 	/*	All the machine-independent calculation of cif->bytes will be wrong.
343 		Redo the calculation for DARWIN.  */
344 
345 	/*	Space for the frame pointer, callee's LR, CR, etc, and for
346 		the asm's temp regs.  */
347 	unsigned int	bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
348 
349 	/*	Return value handling.  The rules are as follows:
350 		- 32-bit (or less) integer values are returned in gpr3;
351 		- Structures of size <= 4 bytes also returned in gpr3;
352 		- 64-bit integer values and structures between 5 and 8 bytes are
353 			returned in gpr3 and gpr4;
354 		- Single/double FP values are returned in fpr1;
355 		- Long double FP (if not equivalent to double) values are returned in
356 			fpr1 and fpr2;
357 		- Larger structures values are allocated space and a pointer is passed
358 			as the first argument.  */
359 	switch (cif->rtype->type)
360 	{
361 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
362 		case FFI_TYPE_LONGDOUBLE:
363 			flags |= FLAG_RETURNS_128BITS;
364 			flags |= FLAG_RETURNS_FP;
365 			break;
366 #endif	// FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
367 
368 		case FFI_TYPE_DOUBLE:
369 			flags |= FLAG_RETURNS_64BITS;
370 			/* Fall through.  */
371 		case FFI_TYPE_FLOAT:
372 			flags |= FLAG_RETURNS_FP;
373 			break;
374 
375 #if defined(__ppc64__)
376 		case FFI_TYPE_POINTER:
377 #endif
378 		case FFI_TYPE_UINT64:
379 		case FFI_TYPE_SINT64:
380 			flags |= FLAG_RETURNS_64BITS;
381 			break;
382 
383 		case FFI_TYPE_STRUCT:
384 		{
385 #if defined(__ppc64__)
386 
387 			if (ffi64_stret_needs_ptr(cif->rtype, NULL, NULL))
388 			{
389 				flags |= FLAG_RETVAL_REFERENCE;
390 				flags |= FLAG_RETURNS_NOTHING;
391 				intarg_count++;
392 			}
393 			else
394 			{
395 				flags |= FLAG_RETURNS_STRUCT;
396 
397 				if (ffi64_struct_contains_fp(cif->rtype))
398 					flags |= FLAG_STRUCT_CONTAINS_FP;
399 			}
400 
401 #elif defined(__ppc__)
402 
403 			flags |= FLAG_RETVAL_REFERENCE;
404 			flags |= FLAG_RETURNS_NOTHING;
405 			intarg_count++;
406 
407 #else
408 #error undefined architecture
409 #endif
410 			break;
411 		}
412 
413 		case FFI_TYPE_VOID:
414 			flags |= FLAG_RETURNS_NOTHING;
415 			break;
416 
417 		default:
418 			/* Returns 32-bit integer, or similar.  Nothing to do here.  */
419 			break;
420 	}
421 
422 	/*	The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
423 		first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
424 		goes on the stack.  Structures are passed as a pointer to a copy of
425 		the structure. Stuff on the stack needs to keep proper alignment.  */
426 	for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
427 	{
428 		switch ((*ptr)->type)
429 		{
430 			case FFI_TYPE_FLOAT:
431 			case FFI_TYPE_DOUBLE:
432 				fparg_count++;
433 				/*	If this FP arg is going on the stack, it must be
434 					8-byte-aligned.  */
435 				if (fparg_count > NUM_FPR_ARG_REGISTERS
436 					&& intarg_count % 2 != 0)
437 					intarg_count++;
438 				break;
439 
440 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
441 			case FFI_TYPE_LONGDOUBLE:
442 				fparg_count += 2;
443 				/*	If this FP arg is going on the stack, it must be
444 					8-byte-aligned.  */
445 
446 				if (
447 #if defined(__ppc64__)
448 					fparg_count > NUM_FPR_ARG_REGISTERS + 1
449 #elif defined(__ppc__)
450 					fparg_count > NUM_FPR_ARG_REGISTERS
451 #else
452 #error undefined architecture
453 #endif
454 					&& intarg_count % 2 != 0)
455 					intarg_count++;
456 
457 				intarg_count += 2;
458 				break;
459 #endif	// FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
460 
461 			case FFI_TYPE_UINT64:
462 			case FFI_TYPE_SINT64:
463 				/*	'long long' arguments are passed as two words, but
464 					either both words must fit in registers or both go
465 					on the stack.  If they go on the stack, they must
466 					be 8-byte-aligned.  */
467 				if (intarg_count == NUM_GPR_ARG_REGISTERS - 1
468 					|| (intarg_count >= NUM_GPR_ARG_REGISTERS
469 					&& intarg_count % 2 != 0))
470 					intarg_count++;
471 
472 				intarg_count += MODE_CHOICE(2,1);
473 
474 				break;
475 
476 			case FFI_TYPE_STRUCT:
477 				size_al = (*ptr)->size;
478 				/*	If the first member of the struct is a double, then align
479 					the struct to double-word.  */
480 				if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
481 					size_al = ALIGN((*ptr)->size, 8);
482 
483 #if defined(__ppc64__)
484 				// Look for FP struct members.
485 				unsigned int	j;
486 
487 				for (j = 0; (*ptr)->elements[j] != NULL; j++)
488 				{
489 					if ((*ptr)->elements[j]->type == FFI_TYPE_FLOAT	||
490 						(*ptr)->elements[j]->type == FFI_TYPE_DOUBLE)
491 					{
492 						fparg_count++;
493 
494 						if (fparg_count > NUM_FPR_ARG_REGISTERS)
495 							intarg_count++;
496 					}
497 					else if ((*ptr)->elements[j]->type == FFI_TYPE_LONGDOUBLE)
498 					{
499 						fparg_count += 2;
500 
501 						if (fparg_count > NUM_FPR_ARG_REGISTERS + 1)
502 							intarg_count += 2;
503 					}
504 					else
505 						intarg_count++;
506 				}
507 #elif defined(__ppc__)
508 				intarg_count += (size_al + 3) / 4;
509 #else
510 #error undefined architecture
511 #endif
512 
513 				break;
514 
515 			default:
516 				/*	Everything else is passed as a 4/8-byte word in a GPR, either
517 					the object itself or a pointer to it.  */
518 				intarg_count++;
519 				break;
520 		}
521 	}
522 
523 	/* Space for the FPR registers, if needed.  */
524 	if (fparg_count != 0)
525 	{
526 		flags |= FLAG_FP_ARGUMENTS;
527 #if defined(__ppc64__)
528 		bytes += (NUM_FPR_ARG_REGISTERS + 1) * sizeof(double);
529 #elif defined(__ppc__)
530 		bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
531 #else
532 #error undefined architecture
533 #endif
534 	}
535 
536 	/* Stack space.  */
537 #if defined(__ppc64__)
538 	if ((intarg_count + fparg_count) > NUM_GPR_ARG_REGISTERS)
539 		bytes += (intarg_count + fparg_count) * sizeof(long);
540 #elif defined(__ppc__)
541 	if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
542 		bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
543 #else
544 #error undefined architecture
545 #endif
546 	else
547 		bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
548 
549 	/* The stack space allocated needs to be a multiple of 16/32 bytes.  */
550 	bytes = SF_ROUND(bytes);
551 
552 	cif->flags = flags;
553 	cif->bytes = bytes;
554 
555 	return FFI_OK;
556 }
557 
558 /*@-declundef@*/
559 /*@-exportheader@*/
560 extern void
561 ffi_call_AIX(
562 /*@out@*/	extended_cif*,
563 			unsigned,
564 			unsigned,
565 /*@out@*/	unsigned*,
566 			void (*fn)(void),
567 			void (*fn2)(extended_cif*, unsigned *const));
568 
569 extern void
570 ffi_call_DARWIN(
571 /*@out@*/	extended_cif*,
572 			unsigned long,
573 			unsigned,
574 /*@out@*/	unsigned*,
575 			void (*fn)(void),
576 			void (*fn2)(extended_cif*, unsigned *const));
577 /*@=declundef@*/
578 /*@=exportheader@*/
579 
580 void
ffi_call(ffi_cif * cif,void (* fn)(void),void * rvalue,void ** avalue)581 ffi_call(
582 /*@dependent@*/	ffi_cif*	cif,
583 				void		(*fn)(void),
584 /*@out@*/		void*		rvalue,
585 /*@dependent@*/	void**		avalue)
586 {
587 	extended_cif ecif;
588 
589 	ecif.cif = cif;
590 	ecif.avalue = avalue;
591 
592 	/*	If the return value is a struct and we don't have a return
593 		value address then we need to make one.  */
594 	if ((rvalue == NULL) &&
595 		(cif->rtype->type == FFI_TYPE_STRUCT))
596 	{
597 		/*@-sysunrecog@*/
598 		ecif.rvalue = alloca(cif->rtype->size);
599 		/*@=sysunrecog@*/
600 	}
601 	else
602 		ecif.rvalue = rvalue;
603 
604 	switch (cif->abi)
605 	{
606 		case FFI_AIX:
607 			/*@-usedef@*/
608 			ffi_call_AIX(&ecif, -cif->bytes,
609 				cif->flags, ecif.rvalue, fn, ffi_prep_args);
610 			/*@=usedef@*/
611 			break;
612 
613 		case FFI_DARWIN:
614 			/*@-usedef@*/
615 			ffi_call_DARWIN(&ecif, -(long)cif->bytes,
616 				cif->flags, ecif.rvalue, fn, ffi_prep_args);
617 			/*@=usedef@*/
618 			break;
619 
620 		default:
621 			FFI_ASSERT(0);
622 			break;
623     }
624 }
625 
626 /* here I'd like to add the stack frame layout we use in darwin_closure.S
627    and aix_clsoure.S
628 
629    SP previous -> +---------------------------------------+ <--- child frame
630 		  | back chain to caller 4                |
631 		  +---------------------------------------+ 4
632 		  | saved CR 4                            |
633 		  +---------------------------------------+ 8
634 		  | saved LR 4                            |
635 		  +---------------------------------------+ 12
636 		  | reserved for compilers 4              |
637 		  +---------------------------------------+ 16
638 		  | reserved for binders 4                |
639 		  +---------------------------------------+ 20
640 		  | saved TOC pointer 4                   |
641 		  +---------------------------------------+ 24
642 		  | always reserved 8*4=32 (previous GPRs)|
643 		  | according to the linkage convention   |
644 		  | from AIX                              |
645 		  +---------------------------------------+ 56
646 		  | our FPR area 13*8=104                 |
647 		  | f1                                    |
648 		  | .                                     |
649 		  | f13                                   |
650 		  +---------------------------------------+ 160
651 		  | result area 8                         |
652 		  +---------------------------------------+ 168
653 		  | alignement to the next multiple of 16 |
654 SP current -->    +---------------------------------------+ 176 <- parent frame
655 		  | back chain to caller 4                |
656 		  +---------------------------------------+ 180
657 		  | saved CR 4                            |
658 		  +---------------------------------------+ 184
659 		  | saved LR 4                            |
660 		  +---------------------------------------+ 188
661 		  | reserved for compilers 4              |
662 		  +---------------------------------------+ 192
663 		  | reserved for binders 4                |
664 		  +---------------------------------------+ 196
665 		  | saved TOC pointer 4                   |
666 		  +---------------------------------------+ 200
667 		  | always reserved 8*4=32  we store our  |
668 		  | GPRs here                             |
669 		  | r3                                    |
670 		  | .                                     |
671 		  | r10                                   |
672 		  +---------------------------------------+ 232
673 		  | overflow part                         |
674 		  +---------------------------------------+ xxx
675 		  | ????                                  |
676 		  +---------------------------------------+ xxx
677 */
678 
679 #if !defined(POWERPC_DARWIN)
680 
681 #define MIN_LINE_SIZE 32
682 
683 static void
flush_icache(char * addr)684 flush_icache(
685 	char*	addr)
686 {
687 #ifndef _AIX
688 	__asm__ volatile (
689 		"dcbf 0,%0\n"
690 		"sync\n"
691 		"icbi 0,%0\n"
692 		"sync\n"
693 		"isync"
694 		: : "r" (addr) : "memory");
695 #endif
696 }
697 
698 static void
flush_range(char * addr,int size)699 flush_range(
700 	char*	addr,
701 	int		size)
702 {
703 	int i;
704 
705 	for (i = 0; i < size; i += MIN_LINE_SIZE)
706 		flush_icache(addr + i);
707 
708 	flush_icache(addr + size - 1);
709 }
710 
711 #endif	// !defined(POWERPC_DARWIN)
712 
713 ffi_status
ffi_prep_closure(ffi_closure * closure,ffi_cif * cif,void (* fun)(ffi_cif *,void *,void **,void *),void * user_data)714 ffi_prep_closure(
715 	ffi_closure*	closure,
716 	ffi_cif*		cif,
717 	void			(*fun)(ffi_cif*, void*, void**, void*),
718 	void*			user_data)
719 {
720 	switch (cif->abi)
721 	{
722 		case FFI_DARWIN:
723 		{
724 			FFI_ASSERT (cif->abi == FFI_DARWIN);
725 
726 			unsigned int*	tramp = (unsigned int*)&closure->tramp[0];
727 
728 #if defined(__ppc64__)
729 			tramp[0] = 0x7c0802a6;	//	mflr	r0
730 			tramp[1] = 0x429f0005;	//	bcl		20,31,+0x8
731 			tramp[2] = 0x7d6802a6;	//	mflr	r11
732 			tramp[3] = 0x7c0803a6;	//	mtlr	r0
733 			tramp[4] = 0xe98b0018;	//	ld		r12,24(r11)
734 			tramp[5] = 0x7d8903a6;	//	mtctr	r12
735 			tramp[6] = 0xe96b0020;	//	ld		r11,32(r11)
736 			tramp[7] = 0x4e800420;	//	bctr
737 			*(unsigned long*)&tramp[8] = (unsigned long)ffi_closure_ASM;
738 			*(unsigned long*)&tramp[10] = (unsigned long)closure;
739 #elif defined(__ppc__)
740 			tramp[0] = 0x7c0802a6;	//	mflr	r0
741 			tramp[1] = 0x429f0005;	//	bcl		20,31,+0x8
742 			tramp[2] = 0x7d6802a6;	//	mflr	r11
743 			tramp[3] = 0x7c0803a6;	//	mtlr	r0
744 			tramp[4] = 0x818b0018;	//	lwz		r12,24(r11)
745 			tramp[5] = 0x7d8903a6;	//	mtctr	r12
746 			tramp[6] = 0x816b001c;	//	lwz		r11,28(r11)
747 			tramp[7] = 0x4e800420;	//	bctr
748 			tramp[8] = (unsigned long)ffi_closure_ASM;
749 			tramp[9] = (unsigned long)closure;
750 #else
751 #error undefined architecture
752 #endif
753 
754 			closure->cif = cif;
755 			closure->fun = fun;
756 			closure->user_data = user_data;
757 
758 			// Flush the icache. Only necessary on Darwin.
759 #if defined(POWERPC_DARWIN)
760 			sys_icache_invalidate(closure->tramp, FFI_TRAMPOLINE_SIZE);
761 #else
762 			flush_range(closure->tramp, FFI_TRAMPOLINE_SIZE);
763 #endif
764 
765 			break;
766 		}
767 
768 		case FFI_AIX:
769 		{
770 			FFI_ASSERT (cif->abi == FFI_AIX);
771 
772 			ffi_aix_trampoline_struct*	tramp_aix =
773 				(ffi_aix_trampoline_struct*)(closure->tramp);
774 			aix_fd*	fd = (aix_fd*)(void*)ffi_closure_ASM;
775 
776 			tramp_aix->code_pointer = fd->code_pointer;
777 			tramp_aix->toc = fd->toc;
778 			tramp_aix->static_chain = closure;
779 			closure->cif = cif;
780 			closure->fun = fun;
781 			closure->user_data = user_data;
782 			break;
783 		}
784 
785 		default:
786 			return FFI_BAD_ABI;
787 	}
788 
789 	return FFI_OK;
790 }
791 
792 #if defined(__ppc__)
793 	typedef double ldbits[2];
794 
795 	typedef union
796 	{
797 		ldbits lb;
798 		long double ld;
799 	} ldu;
800 #endif
801 
802 typedef union
803 {
804 	float	f;
805 	double	d;
806 } ffi_dblfl;
807 
808 /*	The trampoline invokes ffi_closure_ASM, and on entry, r11 holds the
809 	address of the closure. After storing the registers that could possibly
810 	contain parameters to be passed into the stack frame and setting up space
811 	for a return value, ffi_closure_ASM invokes the following helper function
812 	to do most of the work.  */
813 int
ffi_closure_helper_DARWIN(ffi_closure * closure,void * rvalue,unsigned long * pgr,ffi_dblfl * pfr)814 ffi_closure_helper_DARWIN(
815 	ffi_closure*	closure,
816 	void*			rvalue,
817 	unsigned long*	pgr,
818 	ffi_dblfl*		pfr)
819 {
820 	/*	rvalue is the pointer to space for return value in closure assembly
821 		pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM
822 		pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM.  */
823 
824 #if defined(__ppc__)
825 	ldu	temp_ld;
826 #endif
827 
828 	double				temp;
829 	unsigned int		i;
830 	unsigned int		nf = 0;	/* number of FPRs already used.  */
831 	unsigned int		ng = 0;	/* number of GPRs already used.  */
832 	ffi_cif*			cif = closure->cif;
833 	long				avn = cif->nargs;
834 	void**				avalue = alloca(cif->nargs * sizeof(void*));
835 	ffi_type**			arg_types = cif->arg_types;
836 
837 	/*	Copy the caller's structure return value address so that the closure
838 		returns the data directly to the caller.  */
839 #if defined(__ppc64__)
840 	if (cif->rtype->type == FFI_TYPE_STRUCT &&
841 		ffi64_stret_needs_ptr(cif->rtype, NULL, NULL))
842 #elif defined(__ppc__)
843 	if (cif->rtype->type == FFI_TYPE_STRUCT)
844 #else
845 #error undefined architecture
846 #endif
847 	{
848 		rvalue = (void*)*pgr;
849 		pgr++;
850 		ng++;
851 	}
852 
853 	/* Grab the addresses of the arguments from the stack frame.  */
854 	for (i = 0; i < avn; i++)
855 	{
856 		switch (arg_types[i]->type)
857 		{
858 			case FFI_TYPE_SINT8:
859 			case FFI_TYPE_UINT8:
860 				avalue[i] = (char*)pgr + MODE_CHOICE(3,7);
861 				ng++;
862 				pgr++;
863 				break;
864 
865 			case FFI_TYPE_SINT16:
866 			case FFI_TYPE_UINT16:
867 				avalue[i] = (char*)pgr + MODE_CHOICE(2,6);
868 				ng++;
869 				pgr++;
870 				break;
871 
872 #if defined(__ppc__)
873 			case FFI_TYPE_POINTER:
874 #endif
875 			case FFI_TYPE_SINT32:
876 			case FFI_TYPE_UINT32:
877 				avalue[i] = (char*)pgr + MODE_CHOICE(0,4);
878 				ng++;
879 				pgr++;
880 
881 				break;
882 
883 			case FFI_TYPE_STRUCT:
884 				if (cif->abi == FFI_DARWIN)
885 				{
886 #if defined(__ppc64__)
887 					unsigned int	gprSize = 0;
888 					unsigned int	fprSize	= 0;
889 					unsigned int	savedFPRSize = fprSize;
890 
891 					avalue[i] = alloca(arg_types[i]->size);
892 					ffi64_struct_to_ram_form(arg_types[i], (const char*)pgr,
893 						&gprSize, (const char*)pfr, &fprSize, &nf, avalue[i], NULL);
894 
895 					ng	+= gprSize / sizeof(long);
896 					pgr	+= gprSize / sizeof(long);
897 					pfr	+= (fprSize - savedFPRSize) / sizeof(double);
898 
899 #elif defined(__ppc__)
900 					/*	Structures that match the basic modes (QI 1 byte, HI 2 bytes,
901 						SI 4 bytes) are aligned as if they were those modes.  */
902 					unsigned int	size_al	= size_al = arg_types[i]->size;
903 
904 					/*	If the first member of the struct is a double, then align
905 						the struct to double-word.  */
906 					if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
907 						size_al = ALIGN(arg_types[i]->size, 8);
908 
909 					if (size_al < 3)
910 						avalue[i] = (void*)pgr + MODE_CHOICE(4,8) - size_al;
911 					else
912 						avalue[i] = (void*)pgr;
913 
914 					ng	+= (size_al + 3) / sizeof(long);
915 					pgr += (size_al + 3) / sizeof(long);
916 #else
917 #error undefined architecture
918 #endif
919 				}
920 
921 				break;
922 
923 #if defined(__ppc64__)
924 			case FFI_TYPE_POINTER:
925 #endif
926 			case FFI_TYPE_SINT64:
927 			case FFI_TYPE_UINT64:
928 				/* Long long ints are passed in 1 or 2 GPRs.  */
929 				avalue[i] = pgr;
930 				ng += MODE_CHOICE(2,1);
931 				pgr += MODE_CHOICE(2,1);
932 
933 				break;
934 
935 			case FFI_TYPE_FLOAT:
936 				/*	A float value consumes a GPR.
937 					There are 13 64-bit floating point registers.  */
938 				if (nf < NUM_FPR_ARG_REGISTERS)
939 				{
940 					temp = pfr->d;
941 					pfr->f = (float)temp;
942 					avalue[i] = pfr;
943 					pfr++;
944 				}
945 				else
946 					avalue[i] = pgr;
947 
948 				nf++;
949 				ng++;
950 				pgr++;
951 				break;
952 
953 			case FFI_TYPE_DOUBLE:
954 				/*	A double value consumes one or two GPRs.
955 					There are 13 64bit floating point registers.  */
956 				if (nf < NUM_FPR_ARG_REGISTERS)
957 				{
958 					avalue[i] = pfr;
959 					pfr++;
960 				}
961 				else
962 					avalue[i] = pgr;
963 
964 				nf++;
965 				ng += MODE_CHOICE(2,1);
966 				pgr += MODE_CHOICE(2,1);
967 
968 				break;
969 
970 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
971 
972 			case FFI_TYPE_LONGDOUBLE:
973 #if defined(__ppc64__)
974 				if (nf < NUM_FPR_ARG_REGISTERS)
975 				{
976 					avalue[i] = pfr;
977 					pfr += 2;
978 				}
979 #elif defined(__ppc__)
980 				/*	A long double value consumes 2/4 GPRs and 2 FPRs.
981 					There are 13 64bit floating point registers.  */
982 				if (nf < NUM_FPR_ARG_REGISTERS - 1)
983 				{
984 					avalue[i] = pfr;
985 					pfr += 2;
986 				}
987 				/*	Here we have the situation where one part of the long double
988 					is stored in fpr13 and the other part is already on the stack.
989 					We use a union to pass the long double to avalue[i].  */
990 				else if (nf == NUM_FPR_ARG_REGISTERS - 1)
991 				{
992 					memcpy (&temp_ld.lb[0], pfr, sizeof(temp_ld.lb[0]));
993 					memcpy (&temp_ld.lb[1], pgr + 2, sizeof(temp_ld.lb[1]));
994 					avalue[i] = &temp_ld.ld;
995 				}
996 #else
997 #error undefined architecture
998 #endif
999 				else
1000 					avalue[i] = pgr;
1001 
1002 				nf += 2;
1003 				ng += MODE_CHOICE(4,2);
1004 				pgr += MODE_CHOICE(4,2);
1005 
1006 				break;
1007 
1008 #endif	/*	FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE	*/
1009 
1010 			default:
1011 				FFI_ASSERT(0);
1012 				break;
1013 		}
1014 	}
1015 
1016 	(closure->fun)(cif, rvalue, avalue, closure->user_data);
1017 
1018 	/* Tell ffi_closure_ASM to perform return type promotions.  */
1019 	return cif->rtype->type;
1020 }
1021 
1022 #if defined(__ppc64__)
1023 
1024 /*	ffi64_struct_to_ram_form
1025 
1026 	Rebuild a struct's natural layout from buffers of concatenated registers.
1027 	Return the number of registers used.
1028 	inGPRs[0-7] == r3, inFPRs[0-7] == f1 ...
1029 */
1030 void
ffi64_struct_to_ram_form(const ffi_type * inType,const char * inGPRs,unsigned int * ioGPRMarker,const char * inFPRs,unsigned int * ioFPRMarker,unsigned int * ioFPRsUsed,char * outStruct,unsigned int * ioStructMarker)1031 ffi64_struct_to_ram_form(
1032 	const ffi_type*	inType,
1033 	const char*		inGPRs,
1034 	unsigned int*	ioGPRMarker,
1035 	const char*		inFPRs,
1036 	unsigned int*	ioFPRMarker,
1037 	unsigned int*	ioFPRsUsed,
1038 	char*			outStruct,	// caller-allocated
1039 	unsigned int*	ioStructMarker)
1040 {
1041 	unsigned int	srcGMarker		= 0;
1042 	unsigned int	srcFMarker		= 0;
1043 	unsigned int	savedFMarker	= 0;
1044 	unsigned int	fprsUsed		= 0;
1045 	unsigned int	savedFPRsUsed	= 0;
1046 	unsigned int	destMarker		= 0;
1047 
1048 	static unsigned int	recurseCount	= 0;
1049 
1050 	if (ioGPRMarker)
1051 		srcGMarker	= *ioGPRMarker;
1052 
1053 	if (ioFPRMarker)
1054 	{
1055 		srcFMarker		= *ioFPRMarker;
1056 		savedFMarker	= srcFMarker;
1057 	}
1058 
1059 	if (ioFPRsUsed)
1060 	{
1061 		fprsUsed		= *ioFPRsUsed;
1062 		savedFPRsUsed	= fprsUsed;
1063 	}
1064 
1065 	if (ioStructMarker)
1066 		destMarker	= *ioStructMarker;
1067 
1068 	size_t			i;
1069 
1070 	switch (inType->size)
1071 	{
1072 		case 1: case 2: case 4:
1073 			srcGMarker += 8 - inType->size;
1074 			break;
1075 
1076 		default:
1077 			break;
1078 	}
1079 
1080 	for (i = 0; inType->elements[i] != NULL; i++)
1081 	{
1082 		switch (inType->elements[i]->type)
1083 		{
1084 			case FFI_TYPE_FLOAT:
1085 				srcFMarker = ALIGN(srcFMarker, 4);
1086 				srcGMarker = ALIGN(srcGMarker, 4);
1087 				destMarker = ALIGN(destMarker, 4);
1088 
1089 				if (fprsUsed < NUM_FPR_ARG_REGISTERS)
1090 				{
1091 					*(float*)&outStruct[destMarker]	=
1092 						(float)*(double*)&inFPRs[srcFMarker];
1093 					srcFMarker += 8;
1094 					fprsUsed++;
1095 				}
1096 				else
1097 					*(float*)&outStruct[destMarker]	=
1098 						(float)*(double*)&inGPRs[srcGMarker];
1099 
1100 				srcGMarker += 4;
1101 				destMarker += 4;
1102 
1103 				// Skip to next GPR if next element won't fit and we're
1104 				// not already at a register boundary.
1105 				if (inType->elements[i + 1] != NULL && (destMarker % 8))
1106 				{
1107 					if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
1108 						(!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
1109 						(ALIGN(srcGMarker, 8) - srcGMarker) < 2) &&
1110 						(!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
1111 						(ALIGN(srcGMarker, 8) - srcGMarker) < 4))
1112 						srcGMarker	= ALIGN(srcGMarker, 8);
1113 				}
1114 
1115 				break;
1116 
1117 			case FFI_TYPE_DOUBLE:
1118 				srcFMarker = ALIGN(srcFMarker, 8);
1119 				destMarker = ALIGN(destMarker, 8);
1120 
1121 				if (fprsUsed < NUM_FPR_ARG_REGISTERS)
1122 				{
1123 					*(double*)&outStruct[destMarker]	=
1124 						*(double*)&inFPRs[srcFMarker];
1125 					srcFMarker += 8;
1126 					fprsUsed++;
1127 				}
1128 				else
1129 					*(double*)&outStruct[destMarker]	=
1130 						*(double*)&inGPRs[srcGMarker];
1131 
1132 				destMarker += 8;
1133 
1134 				// Skip next GPR
1135 				srcGMarker += 8;
1136 				srcGMarker = ALIGN(srcGMarker, 8);
1137 
1138 				break;
1139 
1140 			case FFI_TYPE_LONGDOUBLE:
1141 				destMarker = ALIGN(destMarker, 16);
1142 
1143 				if (fprsUsed < NUM_FPR_ARG_REGISTERS)
1144 				{
1145 					srcFMarker = ALIGN(srcFMarker, 8);
1146 					srcGMarker = ALIGN(srcGMarker, 8);
1147 					*(long double*)&outStruct[destMarker]	=
1148 						*(long double*)&inFPRs[srcFMarker];
1149 					srcFMarker += 16;
1150 					fprsUsed += 2;
1151 				}
1152 				else
1153 				{
1154 					srcFMarker = ALIGN(srcFMarker, 16);
1155 					srcGMarker = ALIGN(srcGMarker, 16);
1156 					*(long double*)&outStruct[destMarker]	=
1157 						*(long double*)&inGPRs[srcGMarker];
1158 				}
1159 
1160 				destMarker += 16;
1161 
1162 				// Skip next 2 GPRs
1163 				srcGMarker += 16;
1164 				srcGMarker = ALIGN(srcGMarker, 8);
1165 
1166 				break;
1167 
1168 			case FFI_TYPE_UINT8:
1169 			case FFI_TYPE_SINT8:
1170 			{
1171 				if (inType->alignment == 1)	// chars only
1172 				{
1173 					if (inType->size == 1)
1174 						outStruct[destMarker++] = inGPRs[srcGMarker++];
1175 					else if (inType->size == 2)
1176 					{
1177 						outStruct[destMarker++] = inGPRs[srcGMarker++];
1178 						outStruct[destMarker++] = inGPRs[srcGMarker++];
1179 						i++;
1180 					}
1181 					else
1182 					{
1183 						memcpy(&outStruct[destMarker],
1184 							&inGPRs[srcGMarker], inType->size);
1185 						srcGMarker += inType->size;
1186 						destMarker += inType->size;
1187 						i += inType->size - 1;
1188 					}
1189 				}
1190 				else	// chars and other stuff
1191 				{
1192 					outStruct[destMarker++] = inGPRs[srcGMarker++];
1193 
1194 					// Skip to next GPR if next element won't fit and we're
1195 					// not already at a register boundary.
1196 					if (inType->elements[i + 1] != NULL && (srcGMarker % 8))
1197 					{
1198 						if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
1199 							(!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
1200 							(ALIGN(srcGMarker, 8) - srcGMarker) < 2) &&
1201 							(!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
1202 							(ALIGN(srcGMarker, 8) - srcGMarker) < 4))
1203 							srcGMarker	= ALIGN(srcGMarker, inType->alignment);	// was 8
1204 					}
1205 				}
1206 
1207 				break;
1208 			}
1209 
1210 			case FFI_TYPE_UINT16:
1211 			case FFI_TYPE_SINT16:
1212 				srcGMarker = ALIGN(srcGMarker, 2);
1213 				destMarker = ALIGN(destMarker, 2);
1214 
1215 				*(short*)&outStruct[destMarker] =
1216 					*(short*)&inGPRs[srcGMarker];
1217 				srcGMarker += 2;
1218 				destMarker += 2;
1219 
1220 				break;
1221 
1222 			case FFI_TYPE_INT:
1223 			case FFI_TYPE_UINT32:
1224 			case FFI_TYPE_SINT32:
1225 				srcGMarker = ALIGN(srcGMarker, 4);
1226 				destMarker = ALIGN(destMarker, 4);
1227 
1228 				*(int*)&outStruct[destMarker] =
1229 					*(int*)&inGPRs[srcGMarker];
1230 				srcGMarker += 4;
1231 				destMarker += 4;
1232 
1233 				break;
1234 
1235 			case FFI_TYPE_POINTER:
1236 			case FFI_TYPE_UINT64:
1237 			case FFI_TYPE_SINT64:
1238 				srcGMarker = ALIGN(srcGMarker, 8);
1239 				destMarker = ALIGN(destMarker, 8);
1240 
1241 				*(long long*)&outStruct[destMarker] =
1242 					*(long long*)&inGPRs[srcGMarker];
1243 				srcGMarker += 8;
1244 				destMarker += 8;
1245 
1246 				break;
1247 
1248 			case FFI_TYPE_STRUCT:
1249 				recurseCount++;
1250 				ffi64_struct_to_ram_form(inType->elements[i], inGPRs,
1251 					&srcGMarker, inFPRs, &srcFMarker, &fprsUsed,
1252 					outStruct, &destMarker);
1253 				recurseCount--;
1254 				break;
1255 
1256 			default:
1257 				FFI_ASSERT(0);	// unknown element type
1258 				break;
1259 		}
1260 	}
1261 
1262 	srcGMarker = ALIGN(srcGMarker, inType->alignment);
1263 
1264 	// Take care of the special case for 16-byte structs, but not for
1265 	// nested structs.
1266 	if (recurseCount == 0 && srcGMarker == 16)
1267 	{
1268 		*(long double*)&outStruct[0] = *(long double*)&inGPRs[0];
1269 		srcFMarker	= savedFMarker;
1270 		fprsUsed	= savedFPRsUsed;
1271 	}
1272 
1273 	if (ioGPRMarker)
1274 		*ioGPRMarker = ALIGN(srcGMarker, 8);
1275 
1276 	if (ioFPRMarker)
1277 		*ioFPRMarker = srcFMarker;
1278 
1279 	if (ioFPRsUsed)
1280 		*ioFPRsUsed	= fprsUsed;
1281 
1282 	if (ioStructMarker)
1283 		*ioStructMarker	= ALIGN(destMarker, 8);
1284 }
1285 
1286 /*	ffi64_struct_to_reg_form
1287 
1288 	Copy a struct's elements into buffers that can be sliced into registers.
1289 	Return the sizes of the output buffers in bytes. Pass NULL buffer pointers
1290 	to calculate size only.
1291 	outGPRs[0-7] == r3, outFPRs[0-7] == f1 ...
1292 */
1293 void
ffi64_struct_to_reg_form(const ffi_type * inType,const char * inStruct,unsigned int * ioStructMarker,unsigned int * ioFPRsUsed,char * outGPRs,unsigned int * ioGPRSize,char * outFPRs,unsigned int * ioFPRSize)1294 ffi64_struct_to_reg_form(
1295 	const ffi_type*	inType,
1296 	const char*		inStruct,
1297 	unsigned int*	ioStructMarker,
1298 	unsigned int*	ioFPRsUsed,
1299 	char*			outGPRs,	// caller-allocated
1300 	unsigned int*	ioGPRSize,
1301 	char*			outFPRs,	// caller-allocated
1302 	unsigned int*	ioFPRSize)
1303 {
1304 	size_t			i;
1305 	unsigned int	srcMarker		= 0;
1306 	unsigned int	destGMarker		= 0;
1307 	unsigned int	destFMarker		= 0;
1308 	unsigned int	savedFMarker	= 0;
1309 	unsigned int	fprsUsed		= 0;
1310 	unsigned int	savedFPRsUsed	= 0;
1311 
1312 	static unsigned int	recurseCount	= 0;
1313 
1314 	if (ioStructMarker)
1315 		srcMarker	= *ioStructMarker;
1316 
1317 	if (ioFPRsUsed)
1318 	{
1319 		fprsUsed		= *ioFPRsUsed;
1320 		savedFPRsUsed	= fprsUsed;
1321 	}
1322 
1323 	if (ioGPRSize)
1324 		destGMarker	= *ioGPRSize;
1325 
1326 	if (ioFPRSize)
1327 	{
1328 		destFMarker		= *ioFPRSize;
1329 		savedFMarker	= destFMarker;
1330 	}
1331 
1332 	switch (inType->size)
1333 	{
1334 		case 1: case 2: case 4:
1335 			destGMarker += 8 - inType->size;
1336 			break;
1337 
1338 		default:
1339 			break;
1340 	}
1341 
1342 	for (i = 0; inType->elements[i] != NULL; i++)
1343 	{
1344 		switch (inType->elements[i]->type)
1345 		{
1346 			// Shadow floating-point types in GPRs for vararg and pre-ANSI
1347 			// functions.
1348 			case FFI_TYPE_FLOAT:
1349 				// Nudge markers to next 4/8-byte boundary
1350 				srcMarker = ALIGN(srcMarker, 4);
1351 				destGMarker = ALIGN(destGMarker, 4);
1352 				destFMarker = ALIGN(destFMarker, 8);
1353 
1354 				if (fprsUsed < NUM_FPR_ARG_REGISTERS)
1355 				{
1356 					if (outFPRs != NULL && inStruct != NULL)
1357 						*(double*)&outFPRs[destFMarker] =
1358 							(double)*(float*)&inStruct[srcMarker];
1359 
1360 					destFMarker += 8;
1361 					fprsUsed++;
1362 				}
1363 
1364 				if (outGPRs != NULL && inStruct != NULL)
1365 					*(double*)&outGPRs[destGMarker] =
1366 						(double)*(float*)&inStruct[srcMarker];
1367 
1368 				srcMarker += 4;
1369 				destGMarker += 4;
1370 
1371 				// Skip to next GPR if next element won't fit and we're
1372 				// not already at a register boundary.
1373 				if (inType->elements[i + 1] != NULL && (srcMarker % 8))
1374 				{
1375 					if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
1376 						(!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
1377 						(ALIGN(destGMarker, 8) - destGMarker) < 2) &&
1378 						(!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
1379 						(ALIGN(destGMarker, 8) - destGMarker) < 4))
1380 						destGMarker	= ALIGN(destGMarker, 8);
1381 				}
1382 
1383 				break;
1384 
1385 			case FFI_TYPE_DOUBLE:
1386 				srcMarker = ALIGN(srcMarker, 8);
1387 				destFMarker = ALIGN(destFMarker, 8);
1388 
1389 				if (fprsUsed < NUM_FPR_ARG_REGISTERS)
1390 				{
1391 					if (outFPRs != NULL && inStruct != NULL)
1392 						*(double*)&outFPRs[destFMarker] =
1393 							*(double*)&inStruct[srcMarker];
1394 
1395 					destFMarker += 8;
1396 					fprsUsed++;
1397 				}
1398 
1399 				if (outGPRs != NULL && inStruct != NULL)
1400 					*(double*)&outGPRs[destGMarker] =
1401 						*(double*)&inStruct[srcMarker];
1402 
1403 				srcMarker += 8;
1404 
1405 				// Skip next GPR
1406 				destGMarker += 8;
1407 				destGMarker = ALIGN(destGMarker, 8);
1408 
1409 				break;
1410 
1411 			case FFI_TYPE_LONGDOUBLE:
1412 				srcMarker = ALIGN(srcMarker, 16);
1413 
1414 				if (fprsUsed < NUM_FPR_ARG_REGISTERS)
1415 				{
1416 					destFMarker = ALIGN(destFMarker, 8);
1417 					destGMarker = ALIGN(destGMarker, 8);
1418 
1419 					if (outFPRs != NULL && inStruct != NULL)
1420 						*(long double*)&outFPRs[destFMarker] =
1421 							*(long double*)&inStruct[srcMarker];
1422 
1423 					if (outGPRs != NULL && inStruct != NULL)
1424 						*(long double*)&outGPRs[destGMarker] =
1425 							*(long double*)&inStruct[srcMarker];
1426 
1427 					destFMarker += 16;
1428 					fprsUsed += 2;
1429 				}
1430 				else
1431 				{
1432 				 	destGMarker = ALIGN(destGMarker, 16);
1433 
1434 					 if (outGPRs != NULL && inStruct != NULL)
1435 						*(long double*)&outGPRs[destGMarker] =
1436 							*(long double*)&inStruct[srcMarker];
1437 				}
1438 
1439 				srcMarker += 16;
1440 				destGMarker += 16;	// Skip next 2 GPRs
1441 				destGMarker = ALIGN(destGMarker, 8);	// was 16
1442 
1443 				break;
1444 
1445 			case FFI_TYPE_UINT8:
1446 			case FFI_TYPE_SINT8:
1447 				if (inType->alignment == 1)	// bytes only
1448 				{
1449 					if (inType->size == 1)
1450 					{
1451 						if (outGPRs != NULL && inStruct != NULL)
1452 							outGPRs[destGMarker] = inStruct[srcMarker];
1453 
1454 						srcMarker++;
1455 						destGMarker++;
1456 					}
1457 					else if (inType->size == 2)
1458 					{
1459 						if (outGPRs != NULL && inStruct != NULL)
1460 						{
1461 							outGPRs[destGMarker] = inStruct[srcMarker];
1462 							outGPRs[destGMarker + 1] = inStruct[srcMarker + 1];
1463 						}
1464 
1465 						srcMarker += 2;
1466 						destGMarker += 2;
1467 
1468 						i++;
1469 					}
1470 					else
1471 					{
1472 						if (outGPRs != NULL && inStruct != NULL)
1473 						{
1474 							// Avoid memcpy for small chunks.
1475 							if (inType->size <= sizeof(long))
1476 								*(long*)&outGPRs[destGMarker] =
1477 									*(long*)&inStruct[srcMarker];
1478 							else
1479 								memcpy(&outGPRs[destGMarker],
1480 									&inStruct[srcMarker], inType->size);
1481 						}
1482 
1483 						srcMarker += inType->size;
1484 						destGMarker += inType->size;
1485 						i += inType->size - 1;
1486 					}
1487 				}
1488 				else	// bytes and other stuff
1489 				{
1490 					if (outGPRs != NULL && inStruct != NULL)
1491 						outGPRs[destGMarker] = inStruct[srcMarker];
1492 
1493 					srcMarker++;
1494 					destGMarker++;
1495 
1496 					// Skip to next GPR if next element won't fit and we're
1497 					// not already at a register boundary.
1498 					if (inType->elements[i + 1] != NULL && (destGMarker % 8))
1499 					{
1500 						if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) &&
1501 							(!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) ||
1502 							(ALIGN(destGMarker, 8) - destGMarker) < 2) &&
1503 							(!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) ||
1504 							(ALIGN(destGMarker, 8) - destGMarker) < 4))
1505 							destGMarker	= ALIGN(destGMarker, inType->alignment);	// was 8
1506 					}
1507 				}
1508 
1509 				break;
1510 
1511 			case FFI_TYPE_UINT16:
1512 			case FFI_TYPE_SINT16:
1513 				srcMarker = ALIGN(srcMarker, 2);
1514 				destGMarker = ALIGN(destGMarker, 2);
1515 
1516 				if (outGPRs != NULL && inStruct != NULL)
1517 					*(short*)&outGPRs[destGMarker] =
1518 						*(short*)&inStruct[srcMarker];
1519 
1520 				srcMarker += 2;
1521 				destGMarker += 2;
1522 
1523 				if (inType->elements[i + 1] == NULL)
1524 					destGMarker	= ALIGN(destGMarker, inType->alignment);
1525 
1526 				break;
1527 
1528 			case FFI_TYPE_INT:
1529 			case FFI_TYPE_UINT32:
1530 			case FFI_TYPE_SINT32:
1531 				srcMarker = ALIGN(srcMarker, 4);
1532 				destGMarker = ALIGN(destGMarker, 4);
1533 
1534 				if (outGPRs != NULL && inStruct != NULL)
1535 					*(int*)&outGPRs[destGMarker] =
1536 						*(int*)&inStruct[srcMarker];
1537 
1538 				srcMarker += 4;
1539 				destGMarker += 4;
1540 
1541 				break;
1542 
1543 			case FFI_TYPE_POINTER:
1544 			case FFI_TYPE_UINT64:
1545 			case FFI_TYPE_SINT64:
1546 				srcMarker = ALIGN(srcMarker, 8);
1547 				destGMarker = ALIGN(destGMarker, 8);
1548 
1549 				if (outGPRs != NULL && inStruct != NULL)
1550 					*(long long*)&outGPRs[destGMarker] =
1551 						*(long long*)&inStruct[srcMarker];
1552 
1553 				srcMarker += 8;
1554 				destGMarker += 8;
1555 
1556 				if (inType->elements[i + 1] == NULL)
1557 					destGMarker	= ALIGN(destGMarker, inType->alignment);
1558 
1559 				break;
1560 
1561 			case FFI_TYPE_STRUCT:
1562 				recurseCount++;
1563 				ffi64_struct_to_reg_form(inType->elements[i],
1564 					inStruct, &srcMarker, &fprsUsed, outGPRs,
1565 					&destGMarker, outFPRs, &destFMarker);
1566 				recurseCount--;
1567 				break;
1568 
1569 			default:
1570 				FFI_ASSERT(0);
1571 				break;
1572 		}
1573 	}
1574 
1575 	destGMarker	= ALIGN(destGMarker, inType->alignment);
1576 
1577 	// Take care of the special case for 16-byte structs, but not for
1578 	// nested structs.
1579 	if (recurseCount == 0 && destGMarker == 16)
1580 	{
1581 		if (outGPRs != NULL && inStruct != NULL)
1582 			*(long double*)&outGPRs[0] = *(long double*)&inStruct[0];
1583 
1584 		destFMarker	= savedFMarker;
1585 		fprsUsed	= savedFPRsUsed;
1586 	}
1587 
1588 	if (ioStructMarker)
1589 		*ioStructMarker	= ALIGN(srcMarker, 8);
1590 
1591 	if (ioFPRsUsed)
1592 		*ioFPRsUsed	= fprsUsed;
1593 
1594 	if (ioGPRSize)
1595 		*ioGPRSize = ALIGN(destGMarker, 8);
1596 
1597 	if (ioFPRSize)
1598 		*ioFPRSize = ALIGN(destFMarker, 8);
1599 }
1600 
1601 /*	ffi64_stret_needs_ptr
1602 
1603 	Determine whether a returned struct needs a pointer in r3 or can fit
1604 	in registers.
1605 */
1606 
1607 bool
ffi64_stret_needs_ptr(const ffi_type * inType,unsigned short * ioGPRCount,unsigned short * ioFPRCount)1608 ffi64_stret_needs_ptr(
1609 	const ffi_type*	inType,
1610 	unsigned short*	ioGPRCount,
1611 	unsigned short*	ioFPRCount)
1612 {
1613 	// Obvious case first- struct is larger than combined FPR size.
1614 	if (inType->size > 14 * 8)
1615 		return true;
1616 
1617 	// Now the struct can physically fit in registers, determine if it
1618 	// also fits logically.
1619 	bool			needsPtr	= false;
1620 	unsigned short	gprsUsed	= 0;
1621 	unsigned short	fprsUsed	= 0;
1622 	size_t			i;
1623 
1624 	if (ioGPRCount)
1625 		gprsUsed = *ioGPRCount;
1626 
1627 	if (ioFPRCount)
1628 		fprsUsed = *ioFPRCount;
1629 
1630 	for (i = 0; inType->elements[i] != NULL && !needsPtr; i++)
1631 	{
1632 		switch (inType->elements[i]->type)
1633 		{
1634 			case FFI_TYPE_FLOAT:
1635 			case FFI_TYPE_DOUBLE:
1636 				gprsUsed++;
1637 				fprsUsed++;
1638 
1639 				if (fprsUsed > 13)
1640 					needsPtr = true;
1641 
1642 				break;
1643 
1644 			case FFI_TYPE_LONGDOUBLE:
1645 				gprsUsed += 2;
1646 				fprsUsed += 2;
1647 
1648 				if (fprsUsed > 14)
1649 					needsPtr = true;
1650 
1651 				break;
1652 
1653 			case FFI_TYPE_UINT8:
1654 			case FFI_TYPE_SINT8:
1655 			{
1656 				gprsUsed++;
1657 
1658 				if (gprsUsed > 8)
1659 				{
1660 					needsPtr = true;
1661 					break;
1662 				}
1663 
1664 				if (inType->elements[i + 1] == NULL)	// last byte in the struct
1665 					break;
1666 
1667 				// Count possible contiguous bytes ahead, up to 8.
1668 				unsigned short j;
1669 
1670 				for (j = 1; j < 8; j++)
1671 				{
1672 					if (inType->elements[i + j] == NULL ||
1673 						!FFI_TYPE_1_BYTE(inType->elements[i + j]->type))
1674 						break;
1675 				}
1676 
1677 				i += j - 1;	// allow for i++ before the test condition
1678 
1679 				break;
1680 			}
1681 
1682 			case FFI_TYPE_UINT16:
1683 			case FFI_TYPE_SINT16:
1684 			case FFI_TYPE_INT:
1685 			case FFI_TYPE_UINT32:
1686 			case FFI_TYPE_SINT32:
1687 			case FFI_TYPE_POINTER:
1688 			case FFI_TYPE_UINT64:
1689 			case FFI_TYPE_SINT64:
1690 				gprsUsed++;
1691 
1692 				if (gprsUsed > 8)
1693 					needsPtr = true;
1694 
1695 				break;
1696 
1697 			case FFI_TYPE_STRUCT:
1698 				needsPtr = ffi64_stret_needs_ptr(
1699 					inType->elements[i], &gprsUsed, &fprsUsed);
1700 
1701 				break;
1702 
1703 			default:
1704 				FFI_ASSERT(0);
1705 				break;
1706 		}
1707 	}
1708 
1709 	if (ioGPRCount)
1710 		*ioGPRCount = gprsUsed;
1711 
1712 	if (ioFPRCount)
1713 		*ioFPRCount = fprsUsed;
1714 
1715 	return needsPtr;
1716 }
1717 
1718 /*	ffi64_data_size
1719 
1720 	Calculate the size in bytes of an ffi type.
1721 */
1722 
1723 unsigned int
ffi64_data_size(const ffi_type * inType)1724 ffi64_data_size(
1725 	const ffi_type*	inType)
1726 {
1727 	unsigned int	size = 0;
1728 
1729 	switch (inType->type)
1730 	{
1731 		case FFI_TYPE_UINT8:
1732 		case FFI_TYPE_SINT8:
1733 			size = 1;
1734 			break;
1735 
1736 		case FFI_TYPE_UINT16:
1737 		case FFI_TYPE_SINT16:
1738 			size = 2;
1739 			break;
1740 
1741 		case FFI_TYPE_INT:
1742 		case FFI_TYPE_UINT32:
1743 		case FFI_TYPE_SINT32:
1744 		case FFI_TYPE_FLOAT:
1745 			size = 4;
1746 			break;
1747 
1748 		case FFI_TYPE_POINTER:
1749 		case FFI_TYPE_UINT64:
1750 		case FFI_TYPE_SINT64:
1751 		case FFI_TYPE_DOUBLE:
1752 			size = 8;
1753 			break;
1754 
1755 		case FFI_TYPE_LONGDOUBLE:
1756 			size = 16;
1757 			break;
1758 
1759 		case FFI_TYPE_STRUCT:
1760 			ffi64_struct_to_reg_form(
1761 				inType, NULL, NULL, NULL, NULL, &size, NULL, NULL);
1762 			break;
1763 
1764 		case FFI_TYPE_VOID:
1765 			break;
1766 
1767 		default:
1768 			FFI_ASSERT(0);
1769 			break;
1770 	}
1771 
1772 	return size;
1773 }
1774 
1775 #endif	/*	defined(__ppc64__)	*/
1776 #endif	/* __ppc__ || __ppc64__ */
1777