Commit 6975f17f by Wim Lewis Committed by Andreas Tobler

ffi.c: Avoid clobbering cr3 and cr4, which are supposed to be callee-saved.

2009-06-16  Wim Lewis  <wiml@hhhh.org>

	* src/powerpc/ffi.c: Avoid clobbering cr3 and cr4, which are
	supposed to be callee-saved.
	* src/powerpc/sysv.S (small_struct_return_value): Fix overrun of
	return buffer for odd-size structs.

From-SVN: r148543
parent 7bbcc286
2009-06-16 Wim Lewis <wiml@hhhh.org>
* src/powerpc/ffi.c: Avoid clobbering cr3 and cr4, which are
supposed to be callee-saved.
* src/powerpc/sysv.S (small_struct_return_value): Fix overrun of
return buffer for odd-size structs.
2009-06-16 Andreas Tobler <a.tobler@schweiz.org> 2009-06-16 Andreas Tobler <a.tobler@schweiz.org>
PR libffi/40444 PR libffi/40444
......
...@@ -43,11 +43,12 @@ enum { ...@@ -43,11 +43,12 @@ enum {
FLAG_RETURNS_64BITS = 1 << (31-28), FLAG_RETURNS_64BITS = 1 << (31-28),
FLAG_RETURNS_128BITS = 1 << (31-27), /* cr6 */ FLAG_RETURNS_128BITS = 1 << (31-27), /* cr6 */
FLAG_SYSV_SMST_R4 = 1 << (31-26), /* use r4 for FFI_SYSV 8 byte
FLAG_SYSV_SMST_R4 = 1 << (31-16), /* cr4, use r4 for FFI_SYSV 8 byte
structs. */ structs. */
FLAG_SYSV_SMST_R3 = 1 << (31-15), /* cr3, use r3 for FFI_SYSV 4 byte FLAG_SYSV_SMST_R3 = 1 << (31-25), /* use r3 for FFI_SYSV 4 byte
structs. */ structs. */
/* Bits (31-24) through (31-19) store shift value for SMST */
FLAG_ARG_NEEDS_COPY = 1 << (31- 7), FLAG_ARG_NEEDS_COPY = 1 << (31- 7),
FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */ FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */
FLAG_4_GPR_ARGUMENTS = 1 << (31- 5), FLAG_4_GPR_ARGUMENTS = 1 << (31- 5),
...@@ -685,14 +686,14 @@ ffi_prep_cif_machdep (ffi_cif *cif) ...@@ -685,14 +686,14 @@ ffi_prep_cif_machdep (ffi_cif *cif)
if (size <= 4) if (size <= 4)
{ {
flags |= FLAG_SYSV_SMST_R3; flags |= FLAG_SYSV_SMST_R3;
flags |= 8 * (4 - size) << 4; flags |= 8 * (4 - size) << 8;
break; break;
} }
/* These structs are returned in r3 and r4. See above. */ /* These structs are returned in r3 and r4. See above. */
if (size <= 8) if (size <= 8)
{ {
flags |= FLAG_SYSV_SMST_R4; flags |= FLAG_SYSV_SMST_R3 | FLAG_SYSV_SMST_R4;
flags |= 8 * (8 - size) << 4; flags |= 8 * (8 - size) << 8;
break; break;
} }
} }
......
...@@ -136,29 +136,18 @@ L(float_return_value): ...@@ -136,29 +136,18 @@ L(float_return_value):
b L(done_return_value) b L(done_return_value)
L(small_struct_return_value): L(small_struct_return_value):
mtcrf 0x10,%r31 /* cr3 */ extrwi %r6,%r31,2,19 /* number of bytes padding = shift/8 */
bt- 15,L(smst_one_register) mtcrf 0x02,%r31 /* copy flags to cr[24:27] (cr6) */
mtcrf 0x08,%r31 /* cr4 */ extrwi %r5,%r31,5,19 /* r5 <- number of bits of padding */
bt- 16,L(smst_two_register) subfic %r6,%r6,4 /* r6 <- number of useful bytes in r3 */
b L(done_return_value) bf- 25,L(done_return_value) /* struct in r3 ? if not, done. */
/* smst_one_register: */
L(smst_one_register): slw %r3,%r3,%r5 /* Left-justify value in r3 */
rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */ mtxer %r6 /* move byte count to XER ... */
slw %r3,%r3,%r5 stswx %r3,0,%r30 /* ... and store that many bytes */
stw %r3,0(%r30) bf+ 26,L(done_return_value) /* struct in r3:r4 ? */
b L(done_return_value) add %r6,%r6,%r30 /* adjust pointer */
L(smst_two_register): stswi %r4,%r6,4 /* store last four bytes */
rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */
cmpwi %r5,0
subfic %r9,%r5,32
slw %r29,%r3,%r5
srw %r9,%r4,%r9
beq- L(smst_8byte)
or %r3,%r9,%r29
slw %r4,%r4,%r5
L(smst_8byte):
stw %r3,0(%r30)
stw %r4,4(%r30)
b L(done_return_value) b L(done_return_value)
.LFE1: .LFE1:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment