Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Dec 2020 01:39:59 +0000 (UTC)
From:      Brandon Bergren <bdragon@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r368290 - in head/sys/powerpc: include powerpc
Message-ID:  <202012030139.0B31dxJX032955@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bdragon
Date: Thu Dec  3 01:39:59 2020
New Revision: 368290
URL: https://svnweb.freebsd.org/changeset/base/368290

Log:
  [PowerPC64LE] Fix LE VSX/fpr interop
  
  In the PCB struct, we need to match the VSX register file layout
  correctly, as the VSRs shadow the FPRs.
  
  In LE, we need to have a dword of padding before the fprs so they end up
  on the correct side, as the struct may be manipulated by either the FP
  routines or the VSX routines.
  
  Additionally, when saving and restoring fprs, we need to explicitly target
  the fpr union member so it gets offset correctly on LE.
  
  Fixes weirdness with FP registers in VSX-using programs (A FPR that was
  saved by the FP routines but restored by the VSX routines was becoming 0
  due to being loaded to the wrong side of the VSR.)
  
  Original patch by jhibbits.
  
  Reviewed by:	jhibbits
  Differential Revision:	https://reviews.freebsd.org/D27431

Modified:
  head/sys/powerpc/include/pcb.h
  head/sys/powerpc/powerpc/fpu.c

Modified: head/sys/powerpc/include/pcb.h
==============================================================================
--- head/sys/powerpc/include/pcb.h	Wed Dec  2 23:16:24 2020	(r368289)
+++ head/sys/powerpc/include/pcb.h	Thu Dec  3 01:39:59 2020	(r368290)
@@ -37,6 +37,8 @@
 #ifndef _MACHINE_PCB_H_
 #define	_MACHINE_PCB_H_
 
+#include <sys/endian.h>
+
 #include <machine/setjmp.h>
 
 #ifndef _STANDALONE
@@ -62,8 +64,16 @@ struct pcb {
 #define	PCB_CFSCR	0x40	/* Process had FSCR updated */
 	struct fpu {
 		union {
+#if _BYTE_ORDER == _BIG_ENDIAN
 			double fpr;
 			uint32_t vsr[4];
+#else
+			uint32_t vsr[4];
+			struct {
+				double padding;
+				double fpr;
+			};
+#endif
 		} fpr[32];
 		double	fpscr;	/* FPSCR stored as double for easier access */
 	} pcb_fpu;		/* Floating point processor */

Modified: head/sys/powerpc/powerpc/fpu.c
==============================================================================
--- head/sys/powerpc/powerpc/fpu.c	Wed Dec  2 23:16:24 2020	(r368289)
+++ head/sys/powerpc/powerpc/fpu.c	Thu Dec  3 01:39:59 2020	(r368290)
@@ -79,7 +79,7 @@ save_fpu_int(struct thread *td)
 	#undef SFP
 	} else {
 	#define SFP(n)   __asm ("stfd " #n ", 0(%0)" \
-			:: "b"(&pcb->pcb_fpu.fpr[n]));
+			:: "b"(&pcb->pcb_fpu.fpr[n].fpr));
 		SFP(0);		SFP(1);		SFP(2);		SFP(3);
 		SFP(4);		SFP(5);		SFP(6);		SFP(7);
 		SFP(8);		SFP(9);		SFP(10);	SFP(11);
@@ -164,7 +164,7 @@ enable_fpu(struct thread *td)
 	#undef LFP
 	} else {
 	#define LFP(n)   __asm ("lfd " #n ", 0(%0)" \
-			:: "b"(&pcb->pcb_fpu.fpr[n]));
+			:: "b"(&pcb->pcb_fpu.fpr[n].fpr));
 		LFP(0);		LFP(1);		LFP(2);		LFP(3);
 		LFP(4);		LFP(5);		LFP(6);		LFP(7);
 		LFP(8);		LFP(9);		LFP(10);	LFP(11);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202012030139.0B31dxJX032955>