svn commit: r361612 - head/sys/mips/mips

Adrian Chadd adrian at FreeBSD.org
Fri May 29 00:05:44 UTC 2020


Author: adrian
Date: Fri May 29 00:05:43 2020
New Revision: 361612
URL: https://svnweb.freebsd.org/changeset/base/361612

Log:
  [mips] fix up the assembly generation of unaligned exception loads
  
  I noticed that unaligned accesses were returning garbage values.
  
  Give test data like this:
  
  char testdata[] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x5a };
  
  Iterating through uint32_t space 1 byte at a time should
  look like this:
  
  freebsd-carambola2:/mnt# ./test
  Hello, world!
  offset 0 pointer 0x410b00 value 0x12345678 0x12345678
  offset 1 pointer 0x410b01 value 0x3456789a 0x3456789a
  offset 2 pointer 0x410b02 value 0x56789abc 0x56789abc
  offset 3 pointer 0x410b03 value 0x789abcde 0x789abcde
  offset 4 pointer 0x410b04 value 0x9abcdef1 0x9abcdef1
  offset 5 pointer 0x410b05 value 0xbcdef123 0xbcdef123
  offset 6 pointer 0x410b06 value 0xdef12345 0xdef12345
  offset 7 pointer 0x410b07 value 0xf1234567 0xf1234567
  
  .. but to begin with it looked like this:
  
  offset 0 value 0x12345678
  offset 1 value 0x00410a9a
  offset 2 value 0x00419abc
  offset 3 value 0x009abcde
  offset 4 value 0x9abcdef1
  offset 5 value 0x00410a23
  offset 6 value 0x00412345
  offset 7 value 0x00234567
  
  The amusing reason? The compiler is generating the lwr/lwl incorrectly.
  Here's an example after I tried to replace the two macros with a single
  invocation and offset, rather than having the compiler compile in addiu
  to s3 - but the bug is the same:
  
  1044: 8a620003 lwl v0,0(s3)
  1048: 9a730000 lwr s3,3(s3)
  
  .. which is just totally trashy and wrong.
  
  This explicitly tells the compiler to treat the output as being read
  and written to, which is what lwl/lwr does with the destination
  register.
  
  I think a subsequent commit should unify these macros to skip an addiu,
  but that can be a later commit.
  
  Reviewed by:	jhb
  Differential Revision:	https://reviews.freebsd.org/D25040

Modified:
  head/sys/mips/mips/trap.c

Modified: head/sys/mips/mips/trap.c
==============================================================================
--- head/sys/mips/mips/trap.c	Fri May 29 00:01:47 2020	(r361611)
+++ head/sys/mips/mips/trap.c	Fri May 29 00:05:43 2020	(r361612)
@@ -114,22 +114,22 @@ SYSCTL_INT(_machdep, OID_AUTO, trap_debug, CTLFLAG_RW,
 
 #define	lwl_macro(data, addr)						\
 	__asm __volatile ("lwl %0, 0x0(%1)"				\
-			: "=r" (data)	/* outputs */			\
+			: "+r" (data)	/* outputs */			\
 			: "r" (addr));	/* inputs */
 
 #define	lwr_macro(data, addr)						\
 	__asm __volatile ("lwr %0, 0x0(%1)"				\
-			: "=r" (data)	/* outputs */			\
+			: "+r" (data)	/* outputs */			\
 			: "r" (addr));	/* inputs */
 
 #define	ldl_macro(data, addr)						\
 	__asm __volatile ("ldl %0, 0x0(%1)"				\
-			: "=r" (data)	/* outputs */			\
+			: "+r" (data)	/* outputs */			\
 			: "r" (addr));	/* inputs */
 
 #define	ldr_macro(data, addr)						\
 	__asm __volatile ("ldr %0, 0x0(%1)"				\
-			: "=r" (data)	/* outputs */			\
+			: "+r" (data)	/* outputs */			\
 			: "r" (addr));	/* inputs */
 
 #define	sb_macro(data, addr)						\
@@ -1528,7 +1528,7 @@ mips_unaligned_load_store(struct trapframe *frame, int
 {
 	register_t *reg = (register_t *) frame;
 	u_int32_t inst = *((u_int32_t *)(intptr_t)pc);
-	register_t value_msb, value;
+	register_t value_msb = 0, value = 0;
 	unsigned size;
 
 	/*


More information about the svn-src-head mailing list