--- a/avcall/avcall-powerpc64-elfv2-linux.S
+++ b/avcall/avcall-powerpc64-elfv2-linux.S
@@ -1,308 +1,326 @@
 	.file	"avcall-powerpc64.c"
 	.machine power4
 	.abiversion 2
-	.section	".toc","aw"
 	.section	".text"
 	.align 2
 	.p2align 4,,15
 	.globl avcall_call
 	.type	avcall_call, @function
 avcall_call:
-0:	addis 2,12,.TOC.-0b@ha
-	addi 2,2,.TOC.-0b@l
+.LFB0:
+	.cfi_startproc
+.LCF0:
+0:	addis 2,12,.TOC.-.LCF0@ha
+	addi 2,2,.TOC.-.LCF0@l
 	.localentry	avcall_call,.-avcall_call
 	mflr 0
+	std 29,-24(1)
 	std 30,-16(1)
 	std 31,-8(1)
+	.cfi_register 65, 0
+	.cfi_offset 29, -24
+	.cfi_offset 30, -16
+	.cfi_offset 31, -8
 	mr 30,3
 	std 0,16(1)
-	stdu 1,-112(1)
-	ld 3,48(3)
-	ld 9,40(30)
+	stdu 1,-144(1)
+	.cfi_def_cfa_offset 144
+	.cfi_offset 65, 16
+	ld 29,48(3)
+	ld 5,40(3)
 	mr 31,1
-	ld 10,0(1)
-	subf 9,3,9
-	stdu 10,-2064(1)
-	sradi 9,9,3
-	cmpwi 7,9,8
-	ble 7,.L6
-	addi 10,9,-9
-	addi 8,1,96
-	addi 9,3,56
-	rldicl 10,10,0,32
-	addi 8,8,-8
-	addi 10,10,8
-	sldi 10,10,3
-	add 10,3,10
-	.p2align 4,,15
+	.cfi_def_cfa_register 31
+	ld 9,0(1)
+	ld 10,-28688(13)
+	std 10,104(31)
+	li 10,0
+	subf 5,29,5
+	stdu 9,-2048(1)
+	sradi 5,5,3
+	cmpwi 0,5,8
+	ble 0,.L5
+	addi 5,5,-9
+	addi 3,1,96
+	addi 4,29,64
+	rldic 5,5,3,29
+	addi 5,5,8
+	bl memcpy
+	nop
 .L5:
-	ldu 7,8(9)
-	cmpld 7,10,9
-	stdu 7,8(8)
-	bne 7,.L5
-.L6:
 	ld 10,64(30)
 	addi 9,30,72
 	subf 9,9,10
 	sradi 9,9,3
+	cmpwi 0,9,0
 	extsw 9,9
-	cmpwi 7,9,0
-	ble 7,.L4
-	cmpwi 7,9,1
-	beq 7,.L7
-	cmpwi 7,9,2
-	beq 7,.L8
-	cmpwi 7,9,3
-	beq 7,.L9
-	cmpwi 7,9,4
-	beq 7,.L10
-	cmpwi 7,9,5
-	beq 7,.L11
-	cmpwi 7,9,6
-	beq 7,.L12
-	cmpwi 7,9,7
-	beq 7,.L13
-	cmpwi 7,9,8
-	beq 7,.L14
-	cmpwi 7,9,9
-	beq 7,.L15
-	cmpwi 7,9,10
-	beq 7,.L16
-	cmpwi 7,9,11
-	beq 7,.L17
-	cmpwi 7,9,12
-	beq 7,.L18
+	ble 0,.L4
+	cmpwi 0,9,1
+	beq 0,.L6
+	cmpwi 0,9,2
+	beq 0,.L7
+	cmpwi 0,9,3
+	beq 0,.L8
+	cmpwi 0,9,4
+	beq 0,.L9
+	cmpwi 0,9,5
+	beq 0,.L10
+	cmpwi 0,9,6
+	beq 0,.L11
+	cmpwi 0,9,7
+	beq 0,.L12
+	cmpwi 0,9,8
+	beq 0,.L13
+	cmpwi 0,9,9
+	beq 0,.L14
+	cmpwi 0,9,10
+	beq 0,.L15
+	cmpwi 0,9,11
+	beq 0,.L16
+	cmpwi 0,9,12
+	beq 0,.L17
 	lfd 13,168(30)
-.L18:
-	lfd 12,160(30)
 .L17:
-	lfd 11,152(30)
+	lfd 12,160(30)
 .L16:
-	lfd 10,144(30)
+	lfd 11,152(30)
 .L15:
-	lfd 9,136(30)
+	lfd 10,144(30)
 .L14:
-	lfd 8,128(30)
+	lfd 9,136(30)
 .L13:
-	lfd 7,120(30)
+	lfd 8,128(30)
 .L12:
-	lfd 6,112(30)
+	lfd 7,120(30)
 .L11:
-	lfd 5,104(30)
+	lfd 6,112(30)
 .L10:
-	lfd 4,96(30)
+	lfd 5,104(30)
 .L9:
-	lfd 3,88(30)
+	lfd 4,96(30)
 .L8:
-	lfd 2,80(30)
+	lfd 3,88(30)
 .L7:
+	lfd 2,80(30)
+.L6:
 	lfd 1,72(30)
 .L4:
-	ld 11,8(30)
-	ld 9,48(3)
-	ld 10,56(3)
-	ld 8,40(3)
-	ld 7,32(3)
-	ld 6,24(3)
-	ld 5,16(3)
-	ld 4,8(3)
-	mtctr 11
-	ld 3,0(3)
-	mr 12,11
+	ld 12,8(30)
+	ld 9,48(29)
+	ld 10,56(29)
+	ld 8,40(29)
+	ld 7,32(29)
+	ld 6,24(29)
+	ld 5,16(29)
+	ld 4,8(29)
+	mtctr 12
+	ld 3,0(29)
 	std 2,24(1)
 	bctrl
 	ld 2,24(1)
 	lwz 9,24(30)
-	cmplwi 7,9,1
-	beq 7,.L19
-	cmplwi 7,9,2
-	beq 7,.L43
-	cmplwi 7,9,3
-	beq 7,.L43
-	cmplwi 7,9,4
-	beq 7,.L43
-	cmplwi 7,9,5
-	beq 7,.L44
-	cmplwi 7,9,6
-	beq 7,.L44
-	cmplwi 7,9,7
-	beq 7,.L45
-	cmplwi 7,9,8
-	beq 7,.L45
-	cmplwi 7,9,9
-	beq 7,.L49
-	cmplwi 7,9,10
-	beq 7,.L49
-	cmplwi 7,9,11
-	beq 7,.L49
-	cmplwi 7,9,12
-	beq 7,.L49
-	cmplwi 7,9,13
-	beq 7,.L51
-	cmplwi 7,9,14
-	beq 7,.L52
-	cmplwi 7,9,15
-	beq 7,.L49
-	cmplwi 7,9,16
-	bne 7,.L19
+	cmplwi 0,9,1
+	beq 0,.L19
+	cmplwi 0,9,2
+	beq 0,.L58
+	cmplwi 0,9,3
+	beq 0,.L58
+	cmplwi 0,9,4
+	beq 0,.L58
+	cmplwi 0,9,5
+	beq 0,.L59
+	cmplwi 0,9,6
+	beq 0,.L59
+	cmplwi 0,9,7
+	beq 0,.L60
+	cmplwi 0,9,8
+	beq 0,.L60
+	cmplwi 0,9,9
+	beq 0,.L64
+	cmplwi 0,9,10
+	beq 0,.L64
+	cmplwi 0,9,11
+	beq 0,.L64
+	cmplwi 0,9,12
+	beq 0,.L64
+	cmplwi 0,9,13
+	beq 0,.L67
+	cmplwi 0,9,14
+	beq 0,.L68
+	cmplwi 0,9,15
+	beq 0,.L64
+	cmplwi 0,9,16
+	bne 0,.L19
 	lwz 9,0(30)
-	rldicl. 10,9,55,63
+	andi. 9,9,0x200
 	beq 0,.L19
 	ld 10,32(30)
 	addi 9,10,-1
-	cmpldi 7,9,15
-	bgt 7,.L19
-	ld 8,16(30)
-	cmpldi 7,10,8
-	rldicl 9,8,0,61
-	rldicr 8,8,0,60
-	add 10,10,9
-	bgt 7,.L34
-	cmpldi 7,10,8
-	bgt 7,.L35
-	slwi 10,10,3
-	li 7,2
-	ld 6,0(8)
-	slwi 9,9,3
-	addi 10,10,-1
-	sld 10,7,10
-	li 7,1
-	sld 7,7,9
-	sld 9,3,9
-	subf 10,7,10
-	xor 9,9,6
-	and 9,10,9
-	xor 9,9,6
-	std 9,0(8)
+	cmpldi 0,9,15
+	bgt 0,.L19
+	cmpldi 0,10,1
+	ld 9,16(30)
+	rlwinm 8,3,0,0xff
+	beq 0,.L65
+	cmpldi 0,10,2
+	beq 0,.L69
+	cmpldi 0,10,3
+	rldicl 8,3,48,56
+	beq 0,.L70
+	cmpldi 0,10,4
+	beq 0,.L71
+	cmpldi 0,10,5
+	rldicl 8,3,32,56
+	beq 0,.L72
+	cmpldi 0,10,6
+	rldicl 7,3,24,56
+	beq 0,.L73
+	cmpldi 0,10,7
+	rldicl 10,3,16,56
+	beq 0,.L74
+	std 3,0(9)
+	ld 10,32(30)
+	cmpldi 0,10,8
+	beq 0,.L19
+	cmpldi 0,10,9
+	beq 0,.L75
+	cmpldi 0,10,10
+	beq 0,.L76
+	cmpldi 0,10,11
+	beq 0,.L77
+	cmpldi 0,10,12
+	beq 0,.L78
+	cmpldi 0,10,13
+	beq 0,.L79
+	cmpldi 0,10,14
+	beq 0,.L80
+	cmpldi 0,10,15
+	beq 0,.L81
+	cmpldi 0,10,16
+	bne 0,.L19
+	std 4,8(9)
+	.p2align 4,,15
 .L19:
-	addi 1,31,112
+	ld 9,104(31)
+	ld 10,-28688(13)
+	xor. 9,9,10
+	li 10,0
+	bne 0,.L82
+	addi 1,31,144
+	.cfi_remember_state
+	.cfi_def_cfa 1, 0
 	li 3,0
 	ld 0,16(1)
+	ld 29,-24(1)
 	ld 30,-16(1)
 	ld 31,-8(1)
 	mtlr 0
+	.cfi_restore 65
+	.cfi_restore 31
+	.cfi_restore 30
+	.cfi_restore 29
 	blr
 	.p2align 4,,15
-.L43:
+.L58:
+	.cfi_restore_state
 	ld 9,16(30)
 	stb 3,0(9)
-	addi 1,31,112
-	li 3,0
-	ld 0,16(1)
-	ld 30,-16(1)
-	ld 31,-8(1)
-	mtlr 0
-	blr
-.L45:
-	ld 9,16(30)
-	stw 3,0(9)
 	b .L19
 	.p2align 4,,15
-.L44:
+.L59:
 	ld 9,16(30)
 	sth 3,0(9)
-	addi 1,31,112
-	li 3,0
-	ld 0,16(1)
-	ld 30,-16(1)
-	ld 31,-8(1)
-	mtlr 0
-	blr
-	.p2align 4,,15
-.L49:
+	b .L19
+.L60:
 	ld 9,16(30)
-	std 3,0(9)
-	addi 1,31,112
-	li 3,0
-	ld 0,16(1)
-	ld 30,-16(1)
-	ld 31,-8(1)
-	mtlr 0
-	blr
-.L52:
+	stw 3,0(9)
+	b .L19
+.L64:
 	ld 9,16(30)
-	stfd 1,0(9)
+	std 3,0(9)
 	b .L19
-.L51:
+.L67:
 	ld 9,16(30)
 	stfs 1,0(9)
 	b .L19
-.L34:
-	rldicl 9,9,0,32
-	ld 11,0(8)
-	li 6,-1
-	cmpldi 7,10,16
-	slwi 5,9,3
-	sld 7,3,5
-	sld 6,6,5
-	xor 7,7,11
-	and 7,6,7
-	xor 7,7,11
-	std 7,0(8)
-	ble 7,.L53
-	mulli 9,9,-8
-	ld 11,16(8)
-	slwi 10,10,3
-	li 7,2
-	addi 10,10,-129
-	addi 9,9,64
-	sld 7,7,10
-	srad 6,4,9
-	srad 3,3,9
-	addi 7,7,-1
-	sld 9,4,5
-	xor 10,6,11
-	or 9,3,9
-	and 10,7,10
-	std 9,8(8)
-	xor 10,10,11
-	std 10,16(8)
+.L68:
+	ld 9,16(30)
+	stfd 1,0(9)
 	b .L19
-.L35:
-	rldicl 9,9,0,32
-	slwi 10,10,3
-	ld 11,0(8)
-	ld 4,8(8)
-	li 7,2
-	mulli 6,9,-8
-	addi 10,10,-65
-	slwi 9,9,3
-	sld 10,7,10
-	sld 5,3,9
-	li 7,-1
-	addi 6,6,64
-	addi 10,10,-1
-	sld 7,7,9
-	srad 3,3,6
-	xor 6,5,11
-	xor 9,3,4
-	and 7,7,6
-	and 9,10,9
-	xor 10,7,11
-	xor 9,9,4
-	std 10,0(8)
-	std 9,8(8)
+.L70:
+	sth 3,1(9)
+.L65:
+	stb 8,0(9)
 	b .L19
-.L53:
-	mulli 9,9,-4
-	slwi 10,10,3
-	ld 11,8(8)
-	sld 4,4,5
-	addi 10,10,-65
-	li 6,2
-	addi 9,9,32
-	sld 10,6,10
-	srad 3,3,9
-	srad 9,3,9
-	or 7,9,4
-	addi 9,10,-1
-	xor 10,7,11
-	and 9,10,9
-	xor 9,9,11
-	std 9,8(8)
+.L82:
+	bl __stack_chk_fail
+	nop
+.L81:
+	srdi 6,4,32
+	sradi 7,4,24
+	sradi 8,4,16
+	sradi 10,4,8
+	stw 6,8(9)
+	stb 7,12(9)
+	stb 8,13(9)
+	stb 10,14(9)
+	b .L19
+.L72:
+	stw 3,1(9)
+	stb 8,0(9)
+	b .L19
+.L71:
+	stw 3,0(9)
+	b .L19
+.L69:
+	sth 3,0(9)
+	b .L19
+.L80:
+	srdi 7,4,32
+	sradi 8,4,24
+	sradi 10,4,16
+	stw 7,8(9)
+	stb 8,12(9)
+	stb 10,13(9)
+	b .L19
+.L79:
+	srdi 8,4,32
+	sradi 10,4,24
+	stw 8,8(9)
+	stb 10,12(9)
+	b .L19
+.L78:
+	srdi 4,4,32
+	stw 4,8(9)
+	b .L19
+.L77:
+	srdi 8,4,48
+	sradi 10,4,40
+	sth 8,8(9)
+	stb 10,10(9)
+	b .L19
+.L76:
+	srdi 4,4,48
+	sth 4,8(9)
+	b .L19
+.L75:
+	sradi 4,4,56
+	stb 4,8(9)
+	b .L19
+.L74:
+	stw 3,3(9)
+	stb 8,2(9)
+	stb 7,1(9)
+	stb 10,0(9)
+	b .L19
+.L73:
+	stw 3,2(9)
+	stb 8,1(9)
+	stb 7,0(9)
 	b .L19
 	.long 0
-	.byte 0,0,0,1,128,2,0,0
+	.byte 0,0,0,1,128,3,0,0
+	.cfi_endproc
+.LFE0:
 	.size	avcall_call,.-avcall_call
 #if defined __linux__ || defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __DragonFly__
 	.section .note.GNU-stack,"",@progbits
--- a/avcall/avcall-powerpc64.c
+++ b/avcall/avcall-powerpc64.c
@@ -178,111 +178,111 @@ avcall_call(av_alist* list)
       /* In the ELFv2 ABI, gcc returns structs of size <= 16 in registers. */
       if (l->rsize > 0 && l->rsize <= 16) {
         void* raddr = l->raddr;
-        #if 0 /* Unoptimized */
+        #if 1 /* Unoptimized */
         if (l->rsize == 1) {
           ((unsigned char *)raddr)[0] = (unsigned char)(iret);
         } else
         if (l->rsize == 2) {
-          ((unsigned char *)raddr)[0] = (unsigned char)(iret);
-          ((unsigned char *)raddr)[1] = (unsigned char)(iret>>8);
+          ((unsigned char *)raddr)[1] = (unsigned char)(iret);
+          ((unsigned char *)raddr)[0] = (unsigned char)(iret>>8);
         } else
         if (l->rsize == 3) {
-          ((unsigned char *)raddr)[0] = (unsigned char)(iret);
+          ((unsigned char *)raddr)[2] = (unsigned char)(iret);
           ((unsigned char *)raddr)[1] = (unsigned char)(iret>>8);
-          ((unsigned char *)raddr)[2] = (unsigned char)(iret>>16);
+          ((unsigned char *)raddr)[0] = (unsigned char)(iret>>16);
         } else
         if (l->rsize == 4) {
-          ((unsigned char *)raddr)[0] = (unsigned char)(iret);
-          ((unsigned char *)raddr)[1] = (unsigned char)(iret>>8);
-          ((unsigned char *)raddr)[2] = (unsigned char)(iret>>16);
-          ((unsigned char *)raddr)[3] = (unsigned char)(iret>>24);
+          ((unsigned char *)raddr)[3] = (unsigned char)(iret);
+          ((unsigned char *)raddr)[2] = (unsigned char)(iret>>8);
+          ((unsigned char *)raddr)[1] = (unsigned char)(iret>>16);
+          ((unsigned char *)raddr)[0] = (unsigned char)(iret>>24);
         } else
         if (l->rsize == 5) {
-          ((unsigned char *)raddr)[0] = (unsigned char)(iret);
-          ((unsigned char *)raddr)[1] = (unsigned char)(iret>>8);
+          ((unsigned char *)raddr)[4] = (unsigned char)(iret);
+          ((unsigned char *)raddr)[3] = (unsigned char)(iret>>8);
           ((unsigned char *)raddr)[2] = (unsigned char)(iret>>16);
-          ((unsigned char *)raddr)[3] = (unsigned char)(iret>>24);
-          ((unsigned char *)raddr)[4] = (unsigned char)(iret>>32);
+          ((unsigned char *)raddr)[1] = (unsigned char)(iret>>24);
+          ((unsigned char *)raddr)[0] = (unsigned char)(iret>>32);
         } else
         if (l->rsize == 6) {
-          ((unsigned char *)raddr)[0] = (unsigned char)(iret);
-          ((unsigned char *)raddr)[1] = (unsigned char)(iret>>8);
-          ((unsigned char *)raddr)[2] = (unsigned char)(iret>>16);
-          ((unsigned char *)raddr)[3] = (unsigned char)(iret>>24);
-          ((unsigned char *)raddr)[4] = (unsigned char)(iret>>32);
-          ((unsigned char *)raddr)[5] = (unsigned char)(iret>>40);
+          ((unsigned char *)raddr)[5] = (unsigned char)(iret);
+          ((unsigned char *)raddr)[4] = (unsigned char)(iret>>8);
+          ((unsigned char *)raddr)[3] = (unsigned char)(iret>>16);
+          ((unsigned char *)raddr)[2] = (unsigned char)(iret>>24);
+          ((unsigned char *)raddr)[1] = (unsigned char)(iret>>32);
+          ((unsigned char *)raddr)[0] = (unsigned char)(iret>>40);
         } else
         if (l->rsize == 7) {
-          ((unsigned char *)raddr)[0] = (unsigned char)(iret);
-          ((unsigned char *)raddr)[1] = (unsigned char)(iret>>8);
-          ((unsigned char *)raddr)[2] = (unsigned char)(iret>>16);
+          ((unsigned char *)raddr)[6] = (unsigned char)(iret);
+          ((unsigned char *)raddr)[5] = (unsigned char)(iret>>8);
+          ((unsigned char *)raddr)[4] = (unsigned char)(iret>>16);
           ((unsigned char *)raddr)[3] = (unsigned char)(iret>>24);
-          ((unsigned char *)raddr)[4] = (unsigned char)(iret>>32);
-          ((unsigned char *)raddr)[5] = (unsigned char)(iret>>40);
-          ((unsigned char *)raddr)[6] = (unsigned char)(iret>>48);
+          ((unsigned char *)raddr)[2] = (unsigned char)(iret>>32);
+          ((unsigned char *)raddr)[1] = (unsigned char)(iret>>40);
+          ((unsigned char *)raddr)[0] = (unsigned char)(iret>>48);
         } else
         if (l->rsize >= 8 && l->rsize <= 16) {
-          ((unsigned char *)raddr)[0] = (unsigned char)(iret);
-          ((unsigned char *)raddr)[1] = (unsigned char)(iret>>8);
-          ((unsigned char *)raddr)[2] = (unsigned char)(iret>>16);
-          ((unsigned char *)raddr)[3] = (unsigned char)(iret>>24);
-          ((unsigned char *)raddr)[4] = (unsigned char)(iret>>32);
-          ((unsigned char *)raddr)[5] = (unsigned char)(iret>>40);
-          ((unsigned char *)raddr)[6] = (unsigned char)(iret>>48);
-          ((unsigned char *)raddr)[7] = (unsigned char)(iret>>56);
+          ((unsigned char *)raddr)[7] = (unsigned char)(iret);
+          ((unsigned char *)raddr)[6] = (unsigned char)(iret>>8);
+          ((unsigned char *)raddr)[5] = (unsigned char)(iret>>16);
+          ((unsigned char *)raddr)[4] = (unsigned char)(iret>>24);
+          ((unsigned char *)raddr)[3] = (unsigned char)(iret>>32);
+          ((unsigned char *)raddr)[2] = (unsigned char)(iret>>40);
+          ((unsigned char *)raddr)[1] = (unsigned char)(iret>>48);
+          ((unsigned char *)raddr)[0] = (unsigned char)(iret>>56);
           if (l->rsize == 8) {
           } else
           if (l->rsize == 9) {
-            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2);
+            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2>>56);
           } else
           if (l->rsize == 10) {
-            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2);
-            ((unsigned char *)raddr)[8+1] = (unsigned char)(iret2>>8);
+            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2>>56);
+            ((unsigned char *)raddr)[8+1] = (unsigned char)(iret2>>48);
           } else
           if (l->rsize == 11) {
-            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2);
-            ((unsigned char *)raddr)[8+1] = (unsigned char)(iret2>>8);
-            ((unsigned char *)raddr)[8+2] = (unsigned char)(iret2>>16);
+            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2>>56);
+            ((unsigned char *)raddr)[8+1] = (unsigned char)(iret2>>48);
+            ((unsigned char *)raddr)[8+2] = (unsigned char)(iret2>>40);
           } else
           if (l->rsize == 12) {
-            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2);
-            ((unsigned char *)raddr)[8+1] = (unsigned char)(iret2>>8);
-            ((unsigned char *)raddr)[8+2] = (unsigned char)(iret2>>16);
-            ((unsigned char *)raddr)[8+3] = (unsigned char)(iret2>>24);
+            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2>>56);
+            ((unsigned char *)raddr)[8+1] = (unsigned char)(iret2>>48);
+            ((unsigned char *)raddr)[8+2] = (unsigned char)(iret2>>40);
+            ((unsigned char *)raddr)[8+3] = (unsigned char)(iret2>>32);
           } else
           if (l->rsize == 13) {
-            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2);
-            ((unsigned char *)raddr)[8+1] = (unsigned char)(iret2>>8);
-            ((unsigned char *)raddr)[8+2] = (unsigned char)(iret2>>16);
-            ((unsigned char *)raddr)[8+3] = (unsigned char)(iret2>>24);
-            ((unsigned char *)raddr)[8+4] = (unsigned char)(iret2>>32);
+            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2>>56);
+            ((unsigned char *)raddr)[8+1] = (unsigned char)(iret2>>48);
+            ((unsigned char *)raddr)[8+2] = (unsigned char)(iret2>>40);
+            ((unsigned char *)raddr)[8+3] = (unsigned char)(iret2>>32);
+            ((unsigned char *)raddr)[8+4] = (unsigned char)(iret2>>24);
           } else
           if (l->rsize == 14) {
-            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2);
-            ((unsigned char *)raddr)[8+1] = (unsigned char)(iret2>>8);
-            ((unsigned char *)raddr)[8+2] = (unsigned char)(iret2>>16);
-            ((unsigned char *)raddr)[8+3] = (unsigned char)(iret2>>24);
-            ((unsigned char *)raddr)[8+4] = (unsigned char)(iret2>>32);
-            ((unsigned char *)raddr)[8+5] = (unsigned char)(iret2>>40);
+            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2>>56);
+            ((unsigned char *)raddr)[8+1] = (unsigned char)(iret2>>48);
+            ((unsigned char *)raddr)[8+2] = (unsigned char)(iret2>>40);
+            ((unsigned char *)raddr)[8+3] = (unsigned char)(iret2>>32);
+            ((unsigned char *)raddr)[8+4] = (unsigned char)(iret2>>24);
+            ((unsigned char *)raddr)[8+5] = (unsigned char)(iret2>>16);
           } else
           if (l->rsize == 15) {
-            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2);
-            ((unsigned char *)raddr)[8+1] = (unsigned char)(iret2>>8);
-            ((unsigned char *)raddr)[8+2] = (unsigned char)(iret2>>16);
-            ((unsigned char *)raddr)[8+3] = (unsigned char)(iret2>>24);
-            ((unsigned char *)raddr)[8+4] = (unsigned char)(iret2>>32);
-            ((unsigned char *)raddr)[8+5] = (unsigned char)(iret2>>40);
-            ((unsigned char *)raddr)[8+6] = (unsigned char)(iret2>>48);
+            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2>>56);
+            ((unsigned char *)raddr)[8+1] = (unsigned char)(iret2>>48);
+            ((unsigned char *)raddr)[8+2] = (unsigned char)(iret2>>40);
+            ((unsigned char *)raddr)[8+3] = (unsigned char)(iret2>>32);
+            ((unsigned char *)raddr)[8+4] = (unsigned char)(iret2>>24);
+            ((unsigned char *)raddr)[8+5] = (unsigned char)(iret2>>16);
+            ((unsigned char *)raddr)[8+6] = (unsigned char)(iret2>>8);
           } else
           if (l->rsize == 16) {
-            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2);
-            ((unsigned char *)raddr)[8+1] = (unsigned char)(iret2>>8);
-            ((unsigned char *)raddr)[8+2] = (unsigned char)(iret2>>16);
-            ((unsigned char *)raddr)[8+3] = (unsigned char)(iret2>>24);
-            ((unsigned char *)raddr)[8+4] = (unsigned char)(iret2>>32);
-            ((unsigned char *)raddr)[8+5] = (unsigned char)(iret2>>40);
-            ((unsigned char *)raddr)[8+6] = (unsigned char)(iret2>>48);
-            ((unsigned char *)raddr)[8+7] = (unsigned char)(iret2>>56);
+            ((unsigned char *)raddr)[8+0] = (unsigned char)(iret2>>56);
+            ((unsigned char *)raddr)[8+1] = (unsigned char)(iret2>>48);
+            ((unsigned char *)raddr)[8+2] = (unsigned char)(iret2>>40);
+            ((unsigned char *)raddr)[8+3] = (unsigned char)(iret2>>32);
+            ((unsigned char *)raddr)[8+4] = (unsigned char)(iret2>>24);
+            ((unsigned char *)raddr)[8+5] = (unsigned char)(iret2>>16);
+            ((unsigned char *)raddr)[8+6] = (unsigned char)(iret2>>8);
+            ((unsigned char *)raddr)[8+7] = (unsigned char)(iret2);
           }
         }
         #else /* Optimized: fewer conditional jumps, fewer memory accesses */
--- a/vacall/vacall-powerpc64-elfv2-linux.S
+++ b/vacall/vacall-powerpc64-elfv2-linux.S
@@ -1,9 +1,8 @@
 	.file	"vacall-powerpc64.c"
-	.machine power4
 	.abiversion 2
-	.section	".toc","aw"
 	.section	".text"
 	.section	".toc","aw"
+	.align 3
 .LC0:
 	.quad	vacall_function
 	.section	".text"
@@ -12,40 +11,50 @@
 	.globl vacall_receiver
 	.type	vacall_receiver, @function
 vacall_receiver:
-0:	addis 2,12,.TOC.-0b@ha
-	addi 2,2,.TOC.-0b@l
+.LFB0:
+	.cfi_startproc
+.LCF0:
+0:	addis 2,12,.TOC.-.LCF0@ha
+	addi 2,2,.TOC.-.LCF0@l
 	.localentry	vacall_receiver,.-vacall_receiver
 	mflr 0
 	std 31,-8(1)
+	std 30,-16(1)
 	addis 11,2,.LC0@toc@ha
-	ld 12,.LC0@toc@l(11)
-	li 11,0
 	std 0,16(1)
 	stdu 1,-224(1)
-	mr 31,1
-	ld 0,0(12)
+	.cfi_def_cfa_offset 224
+	.cfi_offset 65, 16
+	.cfi_offset 31, -8
+	.cfi_offset 30, -16
+	li 0,0
+	ld 12,.LC0@toc@l(11)
 	std 2,24(1)
+	mr 31,1
+	.cfi_def_cfa_register 31
+	addi 11,31,256
+	ld 30,-28688(13)
+	std 30,200(31)
+	li 30,0
+	std 6,280(31)
+	ld 6,0(12)
 	std 9,304(31)
 	li 9,0
 	std 3,256(31)
-	addi 3,31,32
 	std 4,264(31)
+	stfd 1,96(31)
 	std 5,272(31)
-	mtctr 0
-	stw 9,32(31)
-	std 6,280(31)
 	std 7,288(31)
 	std 8,296(31)
+	mtctr 6
 	std 10,312(31)
-	stfd 1,96(31)
-	addi 9,31,256
 	stfd 2,104(31)
 	stfd 3,112(31)
 	stfd 4,120(31)
+	mr 12,6
 	stfd 5,128(31)
-	mr 12,0
-	std 9,56(31)
 	stfd 6,136(31)
+	addi 3,31,32
 	stfd 7,144(31)
 	stfd 8,152(31)
 	stfd 9,160(31)
@@ -53,173 +62,232 @@ vacall_receiver:
 	stfd 11,176(31)
 	stfd 12,184(31)
 	stfd 13,192(31)
-	std 11,64(31)
-	stw 11,72(31)
-	stw 11,88(31)
+	stw 0,32(31)
+	std 11,56(31)
+	std 9,64(31)
+	stw 9,72(31)
+	stw 9,88(31)
 	bctrl
 	ld 2,24(1)
 	lwz 9,72(31)
 	cmpdi 7,9,0
 	beq 7,.L1
 	cmplwi 7,9,1
-	beq 7,.L27
+	beq 7,.L41
 	cmplwi 7,9,2
-	beq 7,.L30
+	beq 7,.L45
 	cmplwi 7,9,3
-	beq 7,.L27
+	beq 7,.L41
 	cmplwi 7,9,4
-	beq 7,.L31
+	beq 7,.L46
 	cmplwi 7,9,5
-	beq 7,.L32
+	beq 7,.L47
 	cmplwi 7,9,6
-	beq 7,.L33
+	beq 7,.L48
 	cmplwi 7,9,7
-	beq 7,.L34
+	beq 7,.L49
 	cmplwi 7,9,8
-	beq 7,.L28
+	beq 7,.L42
 	cmplwi 7,9,9
-	beq 7,.L28
+	beq 7,.L42
 	cmplwi 7,9,10
-	beq 7,.L28
+	beq 7,.L42
 	cmplwi 7,9,11
-	beq 7,.L28
+	beq 7,.L42
 	cmplwi 7,9,12
-	beq 7,.L35
+	beq 7,.L50
 	cmplwi 7,9,13
-	beq 7,.L36
+	beq 7,.L51
 	cmplwi 7,9,14
-	beq 7,.L28
+	beq 7,.L42
 	cmplwi 7,9,15
 	bne 7,.L1
 	lwz 9,32(31)
-	rldicl. 10,9,54,63
+	andi. 9,9,0x400
 	beq 0,.L1
-	ld 9,80(31)
-	addi 10,9,-1
-	cmpldi 7,10,15
+	ld 10,80(31)
+	addi 9,10,-1
+	cmpldi 7,9,15
 	bgt 7,.L1
+	cmpldi 7,10,1
 	ld 8,64(31)
-	cmpldi 7,9,8
-	rldicl 10,8,0,61
-	rldicr 8,8,0,60
-	add 9,9,10
-	bgt 7,.L17
-	cmpldi 7,9,8
-	slwi 9,9,3
-	bgt 7,.L18
-	ld 7,0(8)
-	addi 9,9,-1
-	li 8,2
-	slwi 10,10,3
-	sld 9,8,9
-	addi 9,9,-1
-	and 9,9,7
-	srad 3,9,10
+	lbz 9,0(8)
+	beq 7,.L52
+	cmpldi 7,10,2
+	beq 7,.L53
+	cmpldi 7,10,3
+	lbz 7,1(8)
+	lbz 6,2(8)
+	beq 7,.L54
+	cmpldi 7,10,4
+	beq 7,.L55
+	cmpldi 7,10,5
+	beq 7,.L56
+	cmpldi 7,10,6
+	beq 7,.L57
+	cmpldi 7,10,7
+	beq 7,.L58
+	cmpldi 7,10,8
+	ld 3,0(8)
+	beq 7,.L1
+	cmpldi 7,10,9
+	lbz 9,8(8)
+	sldi 9,9,56
+	beq 7,.L59
+	lbz 7,9(8)
+	cmpldi 7,10,10
+	sldi 7,7,48
+	or 7,7,9
+	beq 7,.L60
+	cmpldi 7,10,11
+	lbz 9,10(8)
+	sldi 9,9,40
+	beq 7,.L43
+	cmpldi 7,10,12
+	lbz 6,11(8)
+	sldi 6,6,32
+	beq 7,.L61
+	cmpldi 7,10,13
+	lbz 5,12(8)
+	sldi 5,5,24
+	beq 7,.L62
+	cmpldi 7,10,14
+	lbz 11,13(8)
+	sldi 11,11,16
+	beq 7,.L63
+	cmpldi 7,10,15
+	beq 7,.L64
+	ld 4,8(8)
+	.p2align 4,,15
 .L1:
+	ld 9,200(31)
+	ld 10,-28688(13)
+	xor. 9,9,10
+	li 10,0
+	bne 0,.L65
 	addi 1,31,224
+	.cfi_remember_state
+	.cfi_def_cfa 1, 0
 	ld 0,16(1)
+	ld 30,-16(1)
 	ld 31,-8(1)
 	mtlr 0
+	.cfi_restore 65
+	.cfi_restore 31
+	.cfi_restore 30
 	blr
 	.p2align 4,,15
-.L27:
-	addi 1,31,224
+.L41:
+	.cfi_restore_state
 	lbz 3,40(31)
-	ld 0,16(1)
-	ld 31,-8(1)
-	mtlr 0
-	blr
+	b .L1
 	.p2align 4,,15
-.L30:
-	lbz 9,40(31)
-	extsb 3,9
+.L45:
+	lbz 3,40(31)
+	extsb 3,3
 	b .L1
 	.p2align 4,,15
-.L28:
-	ld 3,40(31)
+.L48:
+	lwa 3,40(31)
 	b .L1
 	.p2align 4,,15
-.L31:
+.L46:
 	lha 3,40(31)
 	b .L1
 	.p2align 4,,15
-.L32:
+.L47:
 	lhz 3,40(31)
 	b .L1
 	.p2align 4,,15
-.L33:
-	lwa 3,40(31)
-	b .L1
-	.p2align 4,,15
-.L35:
-	lfs 1,40(31)
+.L42:
+	ld 3,40(31)
 	b .L1
 	.p2align 4,,15
-.L34:
+.L49:
 	lwz 3,40(31)
 	b .L1
-.L36:
+.L50:
+	lfs 1,40(31)
+	b .L1
+.L51:
 	lfd 1,40(31)
 	b .L1
-.L17:
-	cmpldi 7,9,16
-	rldicl 10,10,0,32
-	slwi 9,9,3
-	ble 7,.L37
-	li 7,2
-	addi 9,9,-129
-	ld 11,16(8)
-	ld 5,0(8)
-	mulli 6,10,-8
-	sld 9,7,9
-	ld 7,8(8)
-	addi 8,9,-1
-	slwi 9,10,3
-	addi 6,6,64
-	and 10,8,11
-	srad 8,5,9
-	sld 5,7,6
-	srad 9,7,9
-	sld 10,10,6
-	or 3,8,5
-	or 4,10,9
-	b .L1
-.L18:
-	rldicl 10,10,0,32
-	li 7,2
-	ld 6,8(8)
-	ld 8,0(8)
-	addi 9,9,-65
-	sld 9,7,9
-	mulli 7,10,-8
-	slwi 10,10,3
-	addi 9,9,-1
-	srad 10,8,10
-	and 9,9,6
-	addi 7,7,64
-	sld 9,9,7
-	or 3,9,10
-	b .L1
-.L37:
-	li 7,2
-	addi 9,9,-65
-	ld 5,8(8)
-	ld 6,0(8)
-	sld 9,7,9
-	mulli 7,10,-4
-	addi 9,9,-1
-	addi 7,7,32
-	and 8,9,5
-	slwi 9,10,3
-	sld 10,8,7
-	srad 6,6,9
-	srad 4,8,9
-	sld 7,10,7
-	or 3,6,7
+.L65:
+	bl __stack_chk_fail
+	nop
+.L64:
+	or 4,9,6
+	lbz 9,14(8)
+	or 4,4,5
+	sldi 9,9,8
+	or 4,4,11
+	or 4,4,9
+	or 4,4,7
+	b .L1
+.L63:
+	or 4,9,6
+	or 4,4,5
+	or 4,4,11
+	or 4,4,7
+	b .L1
+.L55:
+	lwz 3,0(8)
+	b .L1
+.L54:
+	sldi 7,7,8
+	sldi 9,9,16
+	or 9,7,9
+	or 3,9,6
+	b .L1
+.L53:
+	lhz 3,0(8)
+	b .L1
+.L52:
+	mr 3,9
+	b .L1
+.L62:
+	or 9,9,6
+	or 4,9,5
+	or 4,4,7
+	b .L1
+.L61:
+	or 9,9,6
+.L43:
+	or 4,9,7
+	b .L1
+.L60:
+	mr 4,7
+	b .L1
+.L59:
+	mr 4,9
+	b .L1
+.L58:
+	sldi 6,6,32
+	sldi 7,7,40
+	lwz 3,3(8)
+	sldi 9,9,48
+	or 7,6,7
+	or 3,7,3
+	or 3,3,9
+	b .L1
+.L57:
+	sldi 7,7,32
+	sldi 9,9,40
+	lwz 3,2(8)
+	or 9,7,9
+	or 3,9,3
+	b .L1
+.L56:
+	lwz 3,1(8)
+	sldi 9,9,32
+	or 3,3,9
 	b .L1
 	.long 0
-	.byte 0,0,0,1,128,1,0,0
+	.byte 0,0,0,1,128,2,0,0
+	.cfi_endproc
+.LFE0:
 	.size	vacall_receiver,.-vacall_receiver
+	.gnu_attribute 4, 9
 #if defined __linux__ || defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __DragonFly__
 	.section .note.GNU-stack,"",@progbits
 #endif
--- a/vacall/vacall-powerpc64.c
+++ b/vacall/vacall-powerpc64.c
@@ -140,111 +140,111 @@ vacall_receiver (__vaword word1, __vaword word2, __vaword word3, __vaword word4,
     if (list.flags & __VA_REGISTER_STRUCT_RETURN) {
       /* In the ELFv2 ABI, gcc returns structs of size <= 16 in registers. */
       if (list.rsize > 0 && list.rsize <= 16) {
-        #if 0 /* Unoptimized */
+        #if 1 /* Unoptimized */
         if (list.rsize == 1) {
           iret =   (__varword)((unsigned char *) list.raddr)[0];
         } else
         if (list.rsize == 2) {
-          iret =  ((__varword)((unsigned char *) list.raddr)[0])
-                | ((__varword)((unsigned char *) list.raddr)[1] << 8);
+          iret =  ((__varword)((unsigned char *) list.raddr)[1])
+                | ((__varword)((unsigned char *) list.raddr)[0] << 8);
         } else
         if (list.rsize == 3) {
-          iret =  ((__varword)((unsigned char *) list.raddr)[0])
+          iret =  ((__varword)((unsigned char *) list.raddr)[2])
                 | ((__varword)((unsigned char *) list.raddr)[1] << 8)
-                | ((__varword)((unsigned char *) list.raddr)[2] << 16);
+                | ((__varword)((unsigned char *) list.raddr)[0] << 16);
         } else
         if (list.rsize == 4) {
-          iret =  ((__varword)((unsigned char *) list.raddr)[0])
-                | ((__varword)((unsigned char *) list.raddr)[1] << 8)
-                | ((__varword)((unsigned char *) list.raddr)[2] << 16)
-                | ((__varword)((unsigned char *) list.raddr)[3] << 24);
+          iret =  ((__varword)((unsigned char *) list.raddr)[3])
+                | ((__varword)((unsigned char *) list.raddr)[2] << 8)
+                | ((__varword)((unsigned char *) list.raddr)[1] << 16)
+                | ((__varword)((unsigned char *) list.raddr)[0] << 24);
         } else
         if (list.rsize == 5) {
-          iret =  ((__varword)((unsigned char *) list.raddr)[0])
-                | ((__varword)((unsigned char *) list.raddr)[1] << 8)
+          iret =  ((__varword)((unsigned char *) list.raddr)[4])
+                | ((__varword)((unsigned char *) list.raddr)[3] << 8)
                 | ((__varword)((unsigned char *) list.raddr)[2] << 16)
-                | ((__varword)((unsigned char *) list.raddr)[3] << 24)
-                | ((__varword)((unsigned char *) list.raddr)[4] << 32);
+                | ((__varword)((unsigned char *) list.raddr)[1] << 24)
+                | ((__varword)((unsigned char *) list.raddr)[0] << 32);
         } else
         if (list.rsize == 6) {
-          iret =  ((__varword)((unsigned char *) list.raddr)[0])
-                | ((__varword)((unsigned char *) list.raddr)[1] << 8)
-                | ((__varword)((unsigned char *) list.raddr)[2] << 16)
-                | ((__varword)((unsigned char *) list.raddr)[3] << 24)
-                | ((__varword)((unsigned char *) list.raddr)[4] << 32)
-                | ((__varword)((unsigned char *) list.raddr)[5] << 40);
+          iret =  ((__varword)((unsigned char *) list.raddr)[5])
+                | ((__varword)((unsigned char *) list.raddr)[4] << 8)
+                | ((__varword)((unsigned char *) list.raddr)[3] << 16)
+                | ((__varword)((unsigned char *) list.raddr)[2] << 24)
+                | ((__varword)((unsigned char *) list.raddr)[1] << 32)
+                | ((__varword)((unsigned char *) list.raddr)[0] << 40);
         } else
         if (list.rsize == 7) {
-          iret =  ((__varword)((unsigned char *) list.raddr)[0])
-                | ((__varword)((unsigned char *) list.raddr)[1] << 8)
-                | ((__varword)((unsigned char *) list.raddr)[2] << 16)
+          iret =  ((__varword)((unsigned char *) list.raddr)[6])
+                | ((__varword)((unsigned char *) list.raddr)[5] << 8)
+                | ((__varword)((unsigned char *) list.raddr)[4] << 16)
                 | ((__varword)((unsigned char *) list.raddr)[3] << 24)
-                | ((__varword)((unsigned char *) list.raddr)[4] << 32)
-                | ((__varword)((unsigned char *) list.raddr)[5] << 40)
-                | ((__varword)((unsigned char *) list.raddr)[6] << 48);
+                | ((__varword)((unsigned char *) list.raddr)[2] << 32)
+                | ((__varword)((unsigned char *) list.raddr)[1] << 40)
+                | ((__varword)((unsigned char *) list.raddr)[0] << 48);
         } else
         if (list.rsize >= 8 && list.rsize <= 16) {
-          iret =  ((__varword)((unsigned char *) list.raddr)[0])
-                | ((__varword)((unsigned char *) list.raddr)[1] << 8)
-                | ((__varword)((unsigned char *) list.raddr)[2] << 16)
-                | ((__varword)((unsigned char *) list.raddr)[3] << 24)
-                | ((__varword)((unsigned char *) list.raddr)[4] << 32)
-                | ((__varword)((unsigned char *) list.raddr)[5] << 40)
-                | ((__varword)((unsigned char *) list.raddr)[6] << 48)
-                | ((__varword)((unsigned char *) list.raddr)[7] << 56);
+          iret =  ((__varword)((unsigned char *) list.raddr)[7])
+                | ((__varword)((unsigned char *) list.raddr)[6] << 8)
+                | ((__varword)((unsigned char *) list.raddr)[5] << 16)
+                | ((__varword)((unsigned char *) list.raddr)[4] << 24)
+                | ((__varword)((unsigned char *) list.raddr)[3] << 32)
+                | ((__varword)((unsigned char *) list.raddr)[2] << 40)
+                | ((__varword)((unsigned char *) list.raddr)[1] << 48)
+                | ((__varword)((unsigned char *) list.raddr)[0] << 56);
           if (list.rsize == 8) {
           } else
           if (list.rsize == 9) {
-            iret2 =   (__varword)((unsigned char *) list.raddr)[8];
+            iret2 =   (__varword)((unsigned char *) list.raddr)[8] << 56;
           } else
           if (list.rsize == 10) {
-            iret2 =  ((__varword)((unsigned char *) list.raddr)[8])
-                   | ((__varword)((unsigned char *) list.raddr)[9] << 8);
+            iret2 =  ((__varword)((unsigned char *) list.raddr)[8] << 56)
+                   | ((__varword)((unsigned char *) list.raddr)[9] << 48);
           } else
           if (list.rsize == 11) {
-            iret2 =  ((__varword)((unsigned char *) list.raddr)[8])
-                   | ((__varword)((unsigned char *) list.raddr)[9] << 8)
-                   | ((__varword)((unsigned char *) list.raddr)[10] << 16);
+            iret2 =  ((__varword)((unsigned char *) list.raddr)[8] << 56)
+                   | ((__varword)((unsigned char *) list.raddr)[9] << 48)
+                   | ((__varword)((unsigned char *) list.raddr)[10] << 40);
           } else
           if (list.rsize == 12) {
-            iret2 =  ((__varword)((unsigned char *) list.raddr)[8])
-                   | ((__varword)((unsigned char *) list.raddr)[9] << 8)
-                   | ((__varword)((unsigned char *) list.raddr)[10] << 16)
-                   | ((__varword)((unsigned char *) list.raddr)[11] << 24);
+            iret2 =  ((__varword)((unsigned char *) list.raddr)[8] << 56)
+                   | ((__varword)((unsigned char *) list.raddr)[9] << 48)
+                   | ((__varword)((unsigned char *) list.raddr)[10] << 40)
+                   | ((__varword)((unsigned char *) list.raddr)[11] << 32);
           } else
           if (list.rsize == 13) {
-            iret2 =  ((__varword)((unsigned char *) list.raddr)[8])
-                   | ((__varword)((unsigned char *) list.raddr)[9] << 8)
-                   | ((__varword)((unsigned char *) list.raddr)[10] << 16)
-                   | ((__varword)((unsigned char *) list.raddr)[11] << 24)
-                   | ((__varword)((unsigned char *) list.raddr)[12] << 32);
+            iret2 =  ((__varword)((unsigned char *) list.raddr)[8] << 56)
+                   | ((__varword)((unsigned char *) list.raddr)[9] << 48)
+                   | ((__varword)((unsigned char *) list.raddr)[10] << 40)
+                   | ((__varword)((unsigned char *) list.raddr)[11] << 32)
+                   | ((__varword)((unsigned char *) list.raddr)[12] << 24);
           } else
           if (list.rsize == 14) {
-            iret2 =  ((__varword)((unsigned char *) list.raddr)[8])
-                   | ((__varword)((unsigned char *) list.raddr)[9] << 8)
-                   | ((__varword)((unsigned char *) list.raddr)[10] << 16)
-                   | ((__varword)((unsigned char *) list.raddr)[11] << 24)
-                   | ((__varword)((unsigned char *) list.raddr)[12] << 32)
-                   | ((__varword)((unsigned char *) list.raddr)[13] << 40);
+            iret2 =  ((__varword)((unsigned char *) list.raddr)[8] << 56)
+                   | ((__varword)((unsigned char *) list.raddr)[9] << 48)
+                   | ((__varword)((unsigned char *) list.raddr)[10] << 40)
+                   | ((__varword)((unsigned char *) list.raddr)[11] << 32)
+                   | ((__varword)((unsigned char *) list.raddr)[12] << 24)
+                   | ((__varword)((unsigned char *) list.raddr)[13] << 16);
           } else
           if (list.rsize == 15) {
-            iret2 =  ((__varword)((unsigned char *) list.raddr)[8])
-                   | ((__varword)((unsigned char *) list.raddr)[9] << 8)
-                   | ((__varword)((unsigned char *) list.raddr)[10] << 16)
-                   | ((__varword)((unsigned char *) list.raddr)[11] << 24)
-                   | ((__varword)((unsigned char *) list.raddr)[12] << 32)
-                   | ((__varword)((unsigned char *) list.raddr)[13] << 40)
-                   | ((__varword)((unsigned char *) list.raddr)[14] << 48);
+            iret2 =  ((__varword)((unsigned char *) list.raddr)[8] << 56)
+                   | ((__varword)((unsigned char *) list.raddr)[9] << 48)
+                   | ((__varword)((unsigned char *) list.raddr)[10] << 40)
+                   | ((__varword)((unsigned char *) list.raddr)[11] << 32)
+                   | ((__varword)((unsigned char *) list.raddr)[12] << 24)
+                   | ((__varword)((unsigned char *) list.raddr)[13] << 16)
+                   | ((__varword)((unsigned char *) list.raddr)[14] << 8);
           } else
           if (list.rsize == 16) {
-            iret2 =  ((__varword)((unsigned char *) list.raddr)[8])
-                   | ((__varword)((unsigned char *) list.raddr)[9] << 8)
-                   | ((__varword)((unsigned char *) list.raddr)[10] << 16)
-                   | ((__varword)((unsigned char *) list.raddr)[11] << 24)
-                   | ((__varword)((unsigned char *) list.raddr)[12] << 32)
-                   | ((__varword)((unsigned char *) list.raddr)[13] << 40)
-                   | ((__varword)((unsigned char *) list.raddr)[14] << 48)
-                   | ((__varword)((unsigned char *) list.raddr)[15] << 56);
+            iret2 =  ((__varword)((unsigned char *) list.raddr)[8] << 56)
+                   | ((__varword)((unsigned char *) list.raddr)[9] << 48)
+                   | ((__varword)((unsigned char *) list.raddr)[10] << 40)
+                   | ((__varword)((unsigned char *) list.raddr)[11] << 32)
+                   | ((__varword)((unsigned char *) list.raddr)[12] << 24)
+                   | ((__varword)((unsigned char *) list.raddr)[13] << 16)
+                   | ((__varword)((unsigned char *) list.raddr)[14] << 8)
+                   | ((__varword)((unsigned char *) list.raddr)[15]);
           }
         }
         #else /* Optimized: fewer conditional jumps, fewer memory accesses */
--- a/callback/vacall_r/vacall-powerpc64-elfv2-linux.S
+++ b/callback/vacall_r/vacall-powerpc64-elfv2-linux.S
@@ -1,45 +1,56 @@
 	.file	"vacall-powerpc64.c"
-	.machine power4
 	.abiversion 2
-	.section	".toc","aw"
 	.section	".text"
 	.align 2
 	.p2align 4,,15
 	.type	callback_receiver, @function
 callback_receiver:
-0:	addis 2,12,.TOC.-0b@ha
-	addi 2,2,.TOC.-0b@l
+.LFB0:
+	.cfi_startproc
+.LCF0:
+0:	addis 2,12,.TOC.-.LCF0@ha
+	addi 2,2,.TOC.-.LCF0@l
 	.localentry	callback_receiver,.-callback_receiver
 	mflr 0
-	std 30,-16(1)
+	std 28,-32(1)
+	std 29,-24(1)
 	std 31,-8(1)
+	std 30,-16(1)
 	std 0,16(1)
-	stdu 1,-224(1)
-	li 0,0
-	ld 30,0(11)
+	stdu 1,-240(1)
+	.cfi_def_cfa_offset 240
+	.cfi_offset 65, 16
+	.cfi_offset 28, -32
+	.cfi_offset 29, -24
+	.cfi_offset 31, -8
+	.cfi_offset 30, -16
+	li 28,0
+	std 2,24(1)
 	mr 31,1
-	std 3,256(31)
-	std 4,264(31)
-	addi 4,31,32
-	ld 3,8(11)
-	std 9,304(31)
-	mtctr 30
+	.cfi_def_cfa_register 31
+	addi 29,31,272
+	ld 0,-28688(13)
+	std 0,200(31)
+	li 0,0
+	ld 0,0(11)
+	std 9,320(31)
 	li 9,0
-	std 5,272(31)
-	std 6,280(31)
-	std 7,288(31)
-	std 8,296(31)
-	stw 9,32(31)
-	std 10,312(31)
 	stfd 1,96(31)
+	std 3,272(31)
+	std 4,280(31)
+	std 5,288(31)
 	stfd 2,104(31)
-	mr 12,30
-	addi 9,31,256
+	mtctr 0
+	std 6,296(31)
+	std 7,304(31)
+	std 8,312(31)
+	std 10,328(31)
 	stfd 3,112(31)
 	stfd 4,120(31)
 	stfd 5,128(31)
 	stfd 6,136(31)
-	std 9,56(31)
+	mr 12,0
+	addi 4,31,32
 	stfd 7,144(31)
 	stfd 8,152(31)
 	stfd 9,160(31)
@@ -47,195 +58,266 @@
 	stfd 11,176(31)
 	stfd 12,184(31)
 	stfd 13,192(31)
-	std 0,64(31)
-	stw 0,72(31)
-	stw 0,88(31)
-	std 2,24(1)
+	ld 3,8(11)
+	stw 28,32(31)
+	std 9,64(31)
+	stw 9,72(31)
+	stw 9,88(31)
+	std 29,56(31)
 	bctrl
 	ld 2,24(1)
 	lwz 9,72(31)
 	cmpdi 7,9,0
 	beq 7,.L1
 	cmplwi 7,9,1
-	beq 7,.L27
+	beq 7,.L41
 	cmplwi 7,9,2
-	beq 7,.L30
+	beq 7,.L45
 	cmplwi 7,9,3
-	beq 7,.L27
+	beq 7,.L41
 	cmplwi 7,9,4
-	beq 7,.L31
+	beq 7,.L46
 	cmplwi 7,9,5
-	beq 7,.L32
+	beq 7,.L47
 	cmplwi 7,9,6
-	beq 7,.L33
+	beq 7,.L48
 	cmplwi 7,9,7
-	beq 7,.L34
+	beq 7,.L49
 	cmplwi 7,9,8
-	beq 7,.L28
+	beq 7,.L42
 	cmplwi 7,9,9
-	beq 7,.L28
+	beq 7,.L42
 	cmplwi 7,9,10
-	beq 7,.L28
+	beq 7,.L42
 	cmplwi 7,9,11
-	beq 7,.L28
+	beq 7,.L42
 	cmplwi 7,9,12
-	beq 7,.L35
+	beq 7,.L50
 	cmplwi 7,9,13
-	beq 7,.L36
+	beq 7,.L51
 	cmplwi 7,9,14
-	beq 7,.L28
+	beq 7,.L42
 	cmplwi 7,9,15
 	bne 7,.L1
 	lwz 9,32(31)
-	rldicl. 10,9,54,63
+	andi. 9,9,0x400
 	beq 0,.L1
-	ld 9,80(31)
-	addi 10,9,-1
-	cmpldi 7,10,15
+	ld 10,80(31)
+	addi 9,10,-1
+	cmpldi 7,9,15
 	bgt 7,.L1
+	cmpldi 7,10,1
 	ld 8,64(31)
-	cmpldi 7,9,8
-	rldicl 10,8,0,61
-	rldicr 8,8,0,60
-	add 9,9,10
-	bgt 7,.L17
-	cmpldi 7,9,8
-	slwi 9,9,3
-	bgt 7,.L18
-	ld 7,0(8)
-	addi 9,9,-1
-	li 8,2
-	slwi 10,10,3
-	sld 9,8,9
-	addi 9,9,-1
-	and 9,9,7
-	srad 3,9,10
+	lbz 9,0(8)
+	beq 7,.L52
+	cmpldi 7,10,2
+	beq 7,.L53
+	cmpldi 7,10,3
+	lbz 7,1(8)
+	lbz 6,2(8)
+	beq 7,.L54
+	cmpldi 7,10,4
+	beq 7,.L55
+	cmpldi 7,10,5
+	beq 7,.L56
+	cmpldi 7,10,6
+	beq 7,.L57
+	cmpldi 7,10,7
+	beq 7,.L58
+	cmpldi 7,10,8
+	ld 3,0(8)
+	beq 7,.L1
+	cmpldi 7,10,9
+	lbz 9,8(8)
+	sldi 9,9,56
+	beq 7,.L59
+	lbz 7,9(8)
+	cmpldi 7,10,10
+	sldi 7,7,48
+	or 7,7,9
+	beq 7,.L60
+	cmpldi 7,10,11
+	lbz 9,10(8)
+	sldi 9,9,40
+	beq 7,.L43
+	cmpldi 7,10,12
+	lbz 6,11(8)
+	sldi 6,6,32
+	beq 7,.L61
+	cmpldi 7,10,13
+	lbz 5,12(8)
+	sldi 5,5,24
+	beq 7,.L62
+	cmpldi 7,10,14
+	lbz 0,13(8)
+	sldi 0,0,16
+	beq 7,.L63
+	cmpldi 7,10,15
+	beq 7,.L64
+	ld 4,8(8)
+	.p2align 4,,15
 .L1:
-	addi 1,31,224
+	ld 9,200(31)
+	ld 10,-28688(13)
+	xor. 9,9,10
+	li 10,0
+	bne 0,.L65
+	addi 1,31,240
+	.cfi_remember_state
+	.cfi_def_cfa 1, 0
 	ld 0,16(1)
+	ld 28,-32(1)
+	ld 29,-24(1)
 	ld 30,-16(1)
 	ld 31,-8(1)
 	mtlr 0
+	.cfi_restore 65
+	.cfi_restore 31
+	.cfi_restore 30
+	.cfi_restore 29
+	.cfi_restore 28
 	blr
 	.p2align 4,,15
-.L27:
-	addi 1,31,224
+.L41:
+	.cfi_restore_state
 	lbz 3,40(31)
-	ld 0,16(1)
-	ld 30,-16(1)
-	ld 31,-8(1)
-	mtlr 0
-	blr
+	b .L1
 	.p2align 4,,15
-.L30:
-	lbz 9,40(31)
-	extsb 3,9
+.L45:
+	lbz 3,40(31)
+	extsb 3,3
 	b .L1
 	.p2align 4,,15
-.L28:
-	ld 3,40(31)
+.L48:
+	lwa 3,40(31)
 	b .L1
 	.p2align 4,,15
-.L31:
+.L46:
 	lha 3,40(31)
 	b .L1
 	.p2align 4,,15
-.L32:
+.L47:
 	lhz 3,40(31)
 	b .L1
 	.p2align 4,,15
-.L33:
-	lwa 3,40(31)
-	b .L1
-	.p2align 4,,15
-.L35:
-	lfs 1,40(31)
+.L42:
+	ld 3,40(31)
 	b .L1
 	.p2align 4,,15
-.L34:
+.L49:
 	lwz 3,40(31)
 	b .L1
-.L36:
+.L50:
+	lfs 1,40(31)
+	b .L1
+.L51:
 	lfd 1,40(31)
 	b .L1
-.L17:
-	cmpldi 7,9,16
-	rldicl 10,10,0,32
-	slwi 9,9,3
-	ble 7,.L37
-	li 7,2
-	addi 9,9,-129
-	ld 0,16(8)
-	ld 5,0(8)
-	mulli 6,10,-8
-	sld 9,7,9
-	ld 7,8(8)
-	addi 8,9,-1
-	slwi 9,10,3
-	addi 6,6,64
-	and 10,8,0
-	srad 8,5,9
-	sld 5,7,6
-	srad 9,7,9
-	sld 10,10,6
-	or 3,8,5
-	or 4,10,9
-	b .L1
-.L18:
-	rldicl 10,10,0,32
-	li 7,2
-	ld 6,8(8)
-	ld 8,0(8)
-	addi 9,9,-65
-	sld 9,7,9
-	mulli 7,10,-8
-	slwi 10,10,3
-	addi 9,9,-1
-	srad 10,8,10
-	and 9,9,6
-	addi 7,7,64
-	sld 9,9,7
-	or 3,9,10
-	b .L1
-.L37:
-	li 7,2
-	addi 9,9,-65
-	ld 5,8(8)
-	ld 6,0(8)
-	sld 9,7,9
-	mulli 7,10,-4
-	addi 9,9,-1
-	addi 7,7,32
-	and 8,9,5
-	slwi 9,10,3
-	sld 10,8,7
-	srad 6,6,9
-	srad 4,8,9
-	sld 7,10,7
-	or 3,6,7
+.L65:
+	bl __stack_chk_fail
+	nop
+.L64:
+	or 4,9,6
+	lbz 9,14(8)
+	or 4,4,5
+	sldi 9,9,8
+	or 4,4,0
+	or 4,4,9
+	or 4,4,7
+	b .L1
+.L63:
+	or 4,9,6
+	or 4,4,5
+	or 4,4,0
+	or 4,4,7
+	b .L1
+.L55:
+	lwz 3,0(8)
+	b .L1
+.L54:
+	sldi 7,7,8
+	sldi 9,9,16
+	or 9,7,9
+	or 3,9,6
+	b .L1
+.L53:
+	lhz 3,0(8)
+	b .L1
+.L52:
+	mr 3,9
+	b .L1
+.L62:
+	or 9,9,6
+	or 4,9,5
+	or 4,4,7
+	b .L1
+.L61:
+	or 9,9,6
+.L43:
+	or 4,9,7
+	b .L1
+.L60:
+	mr 4,7
+	b .L1
+.L59:
+	mr 4,9
+	b .L1
+.L58:
+	sldi 6,6,32
+	sldi 7,7,40
+	lwz 3,3(8)
+	sldi 9,9,48
+	or 7,6,7
+	or 3,7,3
+	or 3,3,9
+	b .L1
+.L57:
+	sldi 7,7,32
+	sldi 9,9,40
+	lwz 3,2(8)
+	or 9,7,9
+	or 3,9,3
+	b .L1
+.L56:
+	lwz 3,1(8)
+	sldi 9,9,32
+	or 3,3,9
 	b .L1
 	.long 0
-	.byte 0,0,0,1,128,2,0,0
+	.byte 0,0,0,1,128,4,0,0
+	.cfi_endproc
+.LFE0:
 	.size	callback_receiver,.-callback_receiver
 	.align 2
 	.p2align 4,,15
 	.globl callback_get_receiver
 	.type	callback_get_receiver, @function
 callback_get_receiver:
-0:	addis 2,12,.TOC.-0b@ha
-	addi 2,2,.TOC.-0b@l
+.LFB1:
+	.cfi_startproc
+.LCF1:
+0:	addis 2,12,.TOC.-.LCF1@ha
+	addi 2,2,.TOC.-.LCF1@l
 	.localentry	callback_get_receiver,.-callback_get_receiver
 	std 31,-8(1)
 	stdu 1,-48(1)
+	.cfi_def_cfa_offset 48
+	.cfi_offset 31, -8
 	addis 3,2,callback_receiver@toc@ha
 	addi 3,3,callback_receiver@toc@l
 	mr 31,1
+	.cfi_def_cfa_register 31
 	addi 1,31,48
+	.cfi_def_cfa 1, 0
 	ld 31,-8(1)
+	.cfi_restore 31
 	blr
 	.long 0
 	.byte 0,0,0,0,128,1,0,0
+	.cfi_endproc
+.LFE1:
 	.size	callback_get_receiver,.-callback_get_receiver
+	.gnu_attribute 4, 9
 #if defined __linux__ || defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __DragonFly__
 	.section .note.GNU-stack,"",@progbits
 #endif