Linux MIPS Architecture development
 help / color / mirror / Atom feed
* inconsistent operand constraints in 'asm' in unaligned.h:66 using gcc 3.4
@ 2004-04-23  3:22 Bradley D. LaRonde
  2004-04-23  3:22 ` Bradley D. LaRonde
  2004-04-23 13:07 ` Maciej W. Rozycki
  0 siblings, 2 replies; 5+ messages in thread
From: Bradley D. LaRonde @ 2004-04-23  3:22 UTC (permalink / raw)
  To: linux-mips

gcc 3.4 complians about:

include/asm/unaligned.h:66: error: inconsistent operand constraints in an
`asm'

from linux CVS 2.4 branch.  That's:

/*
 * Store doubleword ununaligned.
 */
static inline void __stq_u(unsigned long __val, unsigned long long * __addr)
{
        __asm__("usw\t%1, %0\n\t"
                "usw\t%D1, 4+%0"
                : "=m" (*__addr)
                : "r" (__val));
}

I was baffled by the "%D1" syntax until Thiemo Seufer pointed out that %D1
assembled to "one register higher than the register chosen for %1".
Ooooookay.  But gcc complains about a constraint problem.  Maybe "r" and
"%Dn" don't get along (long)?

Anyway... what about __val's type?  I would expect that to be "unsigned long
long" for -mabi=32.  Otherwise will "%D" get what the asm author expected?
If I do change it to "unsigned long long" then I get two of the constraint
errors.  Ooooookay.  Anyone got a constraint that means "consecutive
register pair"?

I finally decided to punt and write:

static inline void __stq_u(unsigned long long __val, unsigned long long *
__addr)
{
        *__addr = __val;
}

Is this OK?  Is there a better solution?


Regards,
Brad

^ permalink raw reply	[flat|nested] 5+ messages in thread

* inconsistent operand constraints in 'asm' in unaligned.h:66 using gcc 3.4
  2004-04-23  3:22 inconsistent operand constraints in 'asm' in unaligned.h:66 using gcc 3.4 Bradley D. LaRonde
@ 2004-04-23  3:22 ` Bradley D. LaRonde
  2004-04-23 13:07 ` Maciej W. Rozycki
  1 sibling, 0 replies; 5+ messages in thread
From: Bradley D. LaRonde @ 2004-04-23  3:22 UTC (permalink / raw)
  To: linux-mips

gcc 3.4 complians about:

include/asm/unaligned.h:66: error: inconsistent operand constraints in an
`asm'

from linux CVS 2.4 branch.  That's:

/*
 * Store doubleword ununaligned.
 */
static inline void __stq_u(unsigned long __val, unsigned long long * __addr)
{
        __asm__("usw\t%1, %0\n\t"
                "usw\t%D1, 4+%0"
                : "=m" (*__addr)
                : "r" (__val));
}

I was baffled by the "%D1" syntax until Thiemo Seufer pointed out that %D1
assembled to "one register higher than the register chosen for %1".
Ooooookay.  But gcc complains about a constraint problem.  Maybe "r" and
"%Dn" don't get along (long)?

Anyway... what about __val's type?  I would expect that to be "unsigned long
long" for -mabi=32.  Otherwise will "%D" get what the asm author expected?
If I do change it to "unsigned long long" then I get two of the constraint
errors.  Ooooookay.  Anyone got a constraint that means "consecutive
register pair"?

I finally decided to punt and write:

static inline void __stq_u(unsigned long long __val, unsigned long long *
__addr)
{
        *__addr = __val;
}

Is this OK?  Is there a better solution?


Regards,
Brad

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: inconsistent operand constraints in 'asm' in unaligned.h:66 using gcc 3.4
  2004-04-23  3:22 inconsistent operand constraints in 'asm' in unaligned.h:66 using gcc 3.4 Bradley D. LaRonde
  2004-04-23  3:22 ` Bradley D. LaRonde
@ 2004-04-23 13:07 ` Maciej W. Rozycki
  2004-04-23 13:14   ` Ralf Baechle
  1 sibling, 1 reply; 5+ messages in thread
From: Maciej W. Rozycki @ 2004-04-23 13:07 UTC (permalink / raw)
  To: Bradley D. LaRonde, Ralf Baechle; +Cc: linux-mips

On Thu, 22 Apr 2004, Bradley D. LaRonde wrote:

> gcc 3.4 complians about:
> 
> include/asm/unaligned.h:66: error: inconsistent operand constraints in an
> `asm'
> 
> from linux CVS 2.4 branch.  That's:
> 
> /*
>  * Store doubleword ununaligned.
>  */
> static inline void __stq_u(unsigned long __val, unsigned long long * __addr)
> {
>         __asm__("usw\t%1, %0\n\t"
>                 "usw\t%D1, 4+%0"
>                 : "=m" (*__addr)
>                 : "r" (__val));
> }

 As usually recent gcc is invaluable in finding dubious constructs. ;-)

> I finally decided to punt and write:
> 
> static inline void __stq_u(unsigned long long __val, unsigned long long *
> __addr)
> {
>         *__addr = __val;
> }
> 
> Is this OK?  Is there a better solution?

 No.  Yes.

 Reviving old tricks about unaligned data I've come with the following
implementation:

void __stq_u(unsigned long long __val, unsigned long long *__addr)
{
	typedef struct {
		unsigned long long v __attribute__((packed));
	} ull_u_t;
	ull_u_t *a = (ull_u_t *)__addr;

        a->v = __val;
}

which yields a nice and desirable code:

unaligned.o:     file format elf32-tradlittlemips

Disassembly of section .text:

00000000 <__stq_u>:
   0:	a8c40003 	swl	a0,3(a2)
   4:	b8c40000 	swr	a0,0(a2)
   8:	a8c50007 	swl	a1,7(a2)
   c:	03e00008 	jr	ra
  10:	b8c50004 	swr	a1,4(a2)
	...

I'm pretty sure it works fine with gcc 2.95.x as well -- for Alpha it used
to, even with such antiques as egcs 1.1.2.

 Ralf, I can see 2.6 already does the right thing -- I suppose you won't
mind me backporting (copying?) it?

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: inconsistent operand constraints in 'asm' in unaligned.h:66 using gcc 3.4
  2004-04-23 13:07 ` Maciej W. Rozycki
@ 2004-04-23 13:14   ` Ralf Baechle
  2004-06-15 13:57     ` Maciej W. Rozycki
  0 siblings, 1 reply; 5+ messages in thread
From: Ralf Baechle @ 2004-04-23 13:14 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Bradley D. LaRonde, linux-mips

On Fri, Apr 23, 2004 at 03:07:43PM +0200, Maciej W. Rozycki wrote:

> I'm pretty sure it works fine with gcc 2.95.x as well -- for Alpha it used
> to, even with such antiques as egcs 1.1.2.
> 
>  Ralf, I can see 2.6 already does the right thing -- I suppose you won't
> mind me backporting (copying?) it?

I certainly won't.  I think the 2.4 implementation was originally written
necessary upto egcs 1.0 which were generating correct but very inefficient
code for __attribute((packed)).

  Ralf

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: inconsistent operand constraints in 'asm' in unaligned.h:66 using gcc 3.4
  2004-04-23 13:14   ` Ralf Baechle
@ 2004-06-15 13:57     ` Maciej W. Rozycki
  0 siblings, 0 replies; 5+ messages in thread
From: Maciej W. Rozycki @ 2004-06-15 13:57 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Bradley D. LaRonde, linux-mips

On Fri, 23 Apr 2004, Ralf Baechle wrote:

> >  Ralf, I can see 2.6 already does the right thing -- I suppose you won't
> > mind me backporting (copying?) it?
> 
> I certainly won't.  I think the 2.4 implementation was originally written
> necessary upto egcs 1.0 which were generating correct but very inefficient
> code for __attribute((packed)).

 I've applied the following changes, which update the files to the
corresponding one from 2.6, modulo trivial formatting fixes.

 We may consider renaming function arguments to something less
Alpha-specific in the future. ;-)

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

patch-mips-2.4.26-20040531-mips-unaligned-1
diff -up --recursive --new-file linux-mips-2.4.26-20040531.macro/include/asm-mips/unaligned.h linux-mips-2.4.26-20040531/include/asm-mips/unaligned.h
--- linux-mips-2.4.26-20040531.macro/include/asm-mips/unaligned.h	2002-08-06 02:58:21.000000000 +0000
+++ linux-mips-2.4.26-20040531/include/asm-mips/unaligned.h	2004-06-14 20:53:34.000000000 +0000
@@ -3,157 +3,142 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1999, 2000 by Ralf Baechle
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1996, 1999, 2000, 2001, 2003 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_UNALIGNED_H
 #define _ASM_UNALIGNED_H
 
-extern void __get_unaligned_bad_length(void);
-extern void __put_unaligned_bad_length(void);
+#include <linux/types.h>
 
 /*
- * Load double unaligned.
+ * get_unaligned - get value from possibly mis-aligned location
+ * @ptr: pointer to value
+ *
+ * This macro should be used for accessing values larger in size than
+ * single bytes at locations that are expected to be improperly aligned,
+ * e.g. retrieving a u16 value from a location not u16-aligned.
  *
- * This could have been implemented in plain C like IA64 but egcs 1.0.3a
- * inflates this to 23 instructions ...
+ * Note that unaligned accesses can be very expensive on some architectures.
  */
-static inline unsigned long long __ldq_u(const unsigned long long * __addr)
-{
-	unsigned long long __res;
+#define get_unaligned(ptr) \
+	((__typeof__(*(ptr)))__get_unaligned((ptr), sizeof(*(ptr))))
 
-	__asm__("ulw\t%0, %1\n\t"
-		"ulw\t%D0, 4+%1"
-		: "=&r" (__res)
-		: "m" (*__addr));
-
-	return __res;
-}
+/*
+ * put_unaligned - put value to a possibly mis-aligned location
+ * @val: value to place
+ * @ptr: pointer to location
+ *
+ * This macro should be used for placing values larger in size than
+ * single bytes at locations that are expected to be improperly aligned,
+ * e.g. writing a u16 value to a location not u16-aligned.
+ *
+ * Note that unaligned accesses can be very expensive on some architectures.
+ */
+#define put_unaligned(x,ptr) \
+	__put_unaligned((__u64)(x), (ptr), sizeof(*(ptr)))
 
 /*
- * Load word unaligned.
+ * This is a silly but good way to make sure that
+ * the get/put functions are indeed always optimized,
+ * and that we use the correct sizes.
  */
-static inline unsigned long __ldl_u(const unsigned int * __addr)
-{
-	unsigned long __res;
+extern void bad_unaligned_access_length(void);
 
-	__asm__("ulw\t%0,%1"
-		: "=&r" (__res)
-		: "m" (*__addr));
+/*
+ * EGCS 1.1 knows about arbitrary unaligned loads.  Define some
+ * packed structures to talk about such things with.
+ */
 
-	return __res;
-}
+struct __una_u64 { __u64 x __attribute__((packed)); };
+struct __una_u32 { __u32 x __attribute__((packed)); };
+struct __una_u16 { __u16 x __attribute__((packed)); };
 
 /*
- * Load halfword unaligned.
+ * Elemental unaligned loads
  */
-static inline unsigned long __ldw_u(const unsigned short * __addr)
+
+static inline __u64 __uldq(const __u64 * r11)
 {
-	unsigned long __res;
+	const struct __una_u64 *ptr = (const struct __una_u64 *) r11;
+	return ptr->x;
+}
 
-	__asm__("ulh\t%0,%1"
-		: "=&r" (__res)
-		: "m" (*__addr));
+static inline __u32 __uldl(const __u32 * r11)
+{
+	const struct __una_u32 *ptr = (const struct __una_u32 *) r11;
+	return ptr->x;
+}
 
-	return __res;
+static inline __u16 __uldw(const __u16 * r11)
+{
+	const struct __una_u16 *ptr = (const struct __una_u16 *) r11;
+	return ptr->x;
 }
 
 /*
- * Store doubleword ununaligned.
+ * Elemental unaligned stores
  */
-static inline void __stq_u(unsigned long __val, unsigned long long * __addr)
+
+static inline void __ustq(__u64 r5, __u64 * r11)
 {
-	__asm__("usw\t%1, %0\n\t"
-		"usw\t%D1, 4+%0"
-		: "=m" (*__addr)
-		: "r" (__val));
+	struct __una_u64 *ptr = (struct __una_u64 *) r11;
+	ptr->x = r5;
 }
 
-/*
- * Store long ununaligned.
- */
-static inline void __stl_u(unsigned long __val, unsigned int * __addr)
+static inline void __ustl(__u32 r5, __u32 * r11)
 {
-	__asm__("usw\t%1, %0"
-		: "=m" (*__addr)
-		: "r" (__val));
+	struct __una_u32 *ptr = (struct __una_u32 *) r11;
+	ptr->x = r5;
 }
 
-/*
- * Store word ununaligned.
- */
-static inline void __stw_u(unsigned long __val, unsigned short * __addr)
+static inline void __ustw(__u16 r5, __u16 * r11)
 {
-	__asm__("ush\t%1, %0"
-		: "=m" (*__addr)
-		: "r" (__val));
+	struct __una_u16 *ptr = (struct __una_u16 *) r11;
+	ptr->x = r5;
 }
 
-/*
- * get_unaligned - get value from possibly mis-aligned location
- * @ptr: pointer to value
- *
- * This macro should be used for accessing values larger in size than
- * single bytes at locations that are expected to be improperly aligned,
- * e.g. retrieving a u16 value from a location not u16-aligned.
- *
- * Note that unaligned accesses can be very expensive on some architectures.
- */
-#define get_unaligned(ptr)						\
-({									\
-	__typeof__(*(ptr)) __val;					\
-									\
-	switch (sizeof(*(ptr))) {					\
-	case 1:								\
-		__val = *(const unsigned char *)ptr;			\
-		break;							\
-	case 2:								\
-		__val = __ldw_u((const unsigned short *)ptr);		\
-		break;							\
-	case 4:								\
-		__val = __ldl_u((const unsigned int *)ptr);		\
-		break;							\
-	case 8:								\
-		__val = __ldq_u((const unsigned long long *)ptr);	\
-		break;							\
-	default:							\
-		__get_unaligned_bad_length();				\
-		break;							\
-	}								\
-									\
-	__val;								\
-})
+static inline __u64 __get_unaligned(const void *ptr, size_t size)
+{
+	__u64 val;
 
-/*
- * put_unaligned - put value to a possibly mis-aligned location
- * @val: value to place
- * @ptr: pointer to location
- *
- * This macro should be used for placing values larger in size than
- * single bytes at locations that are expected to be improperly aligned,
- * e.g. writing a u16 value to a location not u16-aligned.
- *
- * Note that unaligned accesses can be very expensive on some architectures.
- */
-#define put_unaligned(val,ptr)						\
-do {									\
-	switch (sizeof(*(ptr))) {					\
-	case 1:								\
-		*(unsigned char *)(ptr) = (val);			\
-		break;							\
-	case 2:								\
-		__stw_u(val, (unsigned short *)(ptr));			\
-		break;							\
-	case 4:								\
-		__stl_u(val, (unsigned int *)(ptr));			\
-		break;							\
-	case 8:								\
-		__stq_u(val, (unsigned long long *)(ptr));		\
-		break;							\
-	default:							\
-		__put_unaligned_bad_length();				\
-		break;							\
-	}								\
-} while(0)
+	switch (size) {
+	case 1:
+		val = *(const __u8 *)ptr;
+		break;
+	case 2:
+		val = __uldw((const __u16 *)ptr);
+		break;
+	case 4:
+		val = __uldl((const __u32 *)ptr);
+		break;
+	case 8:
+		val = __uldq((const __u64 *)ptr);
+		break;
+	default:
+		bad_unaligned_access_length();
+	}
+	return val;
+}
+
+static inline void __put_unaligned(__u64 val, void *ptr, size_t size)
+{
+	switch (size) {
+	      case 1:
+		*(__u8 *)ptr = (val);
+	        break;
+	      case 2:
+		__ustw(val, (__u16 *)ptr);
+		break;
+	      case 4:
+		__ustl(val, (__u32 *)ptr);
+		break;
+	      case 8:
+		__ustq(val, (__u64 *)ptr);
+		break;
+	      default:
+	    	bad_unaligned_access_length();
+	}
+}
 
 #endif /* _ASM_UNALIGNED_H */
diff -up --recursive --new-file linux-mips-2.4.26-20040531.macro/include/asm-mips64/unaligned.h linux-mips-2.4.26-20040531/include/asm-mips64/unaligned.h
--- linux-mips-2.4.26-20040531.macro/include/asm-mips64/unaligned.h	2002-10-02 17:22:56.000000000 +0000
+++ linux-mips-2.4.26-20040531/include/asm-mips64/unaligned.h	2004-06-14 20:53:34.000000000 +0000
@@ -3,152 +3,142 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1999, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 1996, 1999, 2000, 2001, 2003 by Ralf Baechle
  * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_UNALIGNED_H
 #define _ASM_UNALIGNED_H
 
-extern void __get_unaligned_bad_length(void);
-extern void __put_unaligned_bad_length(void);
+#include <linux/types.h>
 
 /*
- * Load quad unaligned.
+ * get_unaligned - get value from possibly mis-aligned location
+ * @ptr: pointer to value
+ *
+ * This macro should be used for accessing values larger in size than
+ * single bytes at locations that are expected to be improperly aligned,
+ * e.g. retrieving a u16 value from a location not u16-aligned.
+ *
+ * Note that unaligned accesses can be very expensive on some architectures.
  */
-static inline unsigned long __ldq_u(const unsigned long * __addr)
-{
-	unsigned long __res;
-
-	__asm__("uld\t%0,%1"
-		: "=&r" (__res)
-		: "m" (*__addr));
+#define get_unaligned(ptr) \
+	((__typeof__(*(ptr)))__get_unaligned((ptr), sizeof(*(ptr))))
 
-	return __res;
-}
+/*
+ * put_unaligned - put value to a possibly mis-aligned location
+ * @val: value to place
+ * @ptr: pointer to location
+ *
+ * This macro should be used for placing values larger in size than
+ * single bytes at locations that are expected to be improperly aligned,
+ * e.g. writing a u16 value to a location not u16-aligned.
+ *
+ * Note that unaligned accesses can be very expensive on some architectures.
+ */
+#define put_unaligned(x,ptr) \
+	__put_unaligned((__u64)(x), (ptr), sizeof(*(ptr)))
 
 /*
- * Load long unaligned.
+ * This is a silly but good way to make sure that
+ * the get/put functions are indeed always optimized,
+ * and that we use the correct sizes.
  */
-static inline unsigned long __ldl_u(const unsigned int * __addr)
-{
-	unsigned long __res;
+extern void bad_unaligned_access_length(void);
 
-	__asm__("ulw\t%0,%1"
-		: "=&r" (__res)
-		: "m" (*__addr));
+/*
+ * EGCS 1.1 knows about arbitrary unaligned loads.  Define some
+ * packed structures to talk about such things with.
+ */
 
-	return __res;
-}
+struct __una_u64 { __u64 x __attribute__((packed)); };
+struct __una_u32 { __u32 x __attribute__((packed)); };
+struct __una_u16 { __u16 x __attribute__((packed)); };
 
 /*
- * Load word unaligned.
+ * Elemental unaligned loads
  */
-static inline unsigned long __ldw_u(const unsigned short * __addr)
+
+static inline __u64 __uldq(const __u64 * r11)
 {
-	unsigned long __res;
+	const struct __una_u64 *ptr = (const struct __una_u64 *) r11;
+	return ptr->x;
+}
 
-	__asm__("ulh\t%0,%1"
-		: "=&r" (__res)
-		: "m" (*__addr));
+static inline __u32 __uldl(const __u32 * r11)
+{
+	const struct __una_u32 *ptr = (const struct __una_u32 *) r11;
+	return ptr->x;
+}
 
-	return __res;
+static inline __u16 __uldw(const __u16 * r11)
+{
+	const struct __una_u16 *ptr = (const struct __una_u16 *) r11;
+	return ptr->x;
 }
 
 /*
- * Store quad unaligned.
+ * Elemental unaligned stores
  */
-static inline void __stq_u(unsigned long __val, unsigned long * __addr)
+
+static inline void __ustq(__u64 r5, __u64 * r11)
 {
-	__asm__("usd\t%1, %0"
-		: "=m" (*__addr)
-		: "r" (__val));
+	struct __una_u64 *ptr = (struct __una_u64 *) r11;
+	ptr->x = r5;
 }
 
-/*
- * Store long unaligned.
- */
-static inline void __stl_u(unsigned long __val, unsigned int * __addr)
+static inline void __ustl(__u32 r5, __u32 * r11)
 {
-	__asm__("usw\t%1, %0"
-		: "=m" (*__addr)
-		: "r" (__val));
+	struct __una_u32 *ptr = (struct __una_u32 *) r11;
+	ptr->x = r5;
 }
 
-/*
- * Store word unaligned.
- */
-static inline void __stw_u(unsigned long __val, unsigned short * __addr)
+static inline void __ustw(__u16 r5, __u16 * r11)
 {
-	__asm__("ush\t%1, %0"
-		: "=m" (*__addr)
-		: "r" (__val));
+	struct __una_u16 *ptr = (struct __una_u16 *) r11;
+	ptr->x = r5;
 }
 
-/*
- * get_unaligned - get value from possibly mis-aligned location
- * @ptr: pointer to value
- *
- * This macro should be used for accessing values larger in size than
- * single bytes at locations that are expected to be improperly aligned,
- * e.g. retrieving a u16 value from a location not u16-aligned.
- *
- * Note that unaligned accesses can be very expensive on some architectures.
- */
-#define get_unaligned(ptr)						\
-({									\
-	__typeof__(*(ptr)) __val;					\
-									\
-	switch (sizeof(*(ptr))) {					\
-	case 1:								\
-		__val = *(const unsigned char *)(ptr);			\
-		break;							\
-	case 2:								\
-		__val = __ldw_u((const unsigned short *)(ptr));		\
-		break;							\
-	case 4:								\
-		__val = __ldl_u((const unsigned int *)(ptr));		\
-		break;							\
-	case 8:								\
-		__val = __ldq_u((const unsigned long *)(ptr));		\
-		break;							\
-	default:							\
-		__get_unaligned_bad_length();				\
-		break;							\
-	}								\
-									\
-	__val;								\
-})
+static inline __u64 __get_unaligned(const void *ptr, size_t size)
+{
+	__u64 val;
 
-/*
- * put_unaligned - put value to a possibly mis-aligned location
- * @val: value to place
- * @ptr: pointer to location
- *
- * This macro should be used for placing values larger in size than
- * single bytes at locations that are expected to be improperly aligned,
- * e.g. writing a u16 value to a location not u16-aligned.
- *
- * Note that unaligned accesses can be very expensive on some architectures.
- */
-#define put_unaligned(val,ptr)						\
-do {									\
-	switch (sizeof(*(ptr))) {					\
-	case 1:								\
-		*(unsigned char *)(ptr) = (val);			\
-		break;							\
-	case 2:								\
-		__stw_u((val), (unsigned short *)(ptr));		\
-		break;							\
-	case 4:								\
-		__stl_u((val), (unsigned int *)(ptr));			\
-		break;							\
-	case 8:								\
-		__stq_u((val), (unsigned long long *)(ptr));		\
-		break;							\
-	default:							\
-		__put_unaligned_bad_length();				\
-		break;							\
-	}								\
-} while(0)
+	switch (size) {
+	case 1:
+		val = *(const __u8 *)ptr;
+		break;
+	case 2:
+		val = __uldw((const __u16 *)ptr);
+		break;
+	case 4:
+		val = __uldl((const __u32 *)ptr);
+		break;
+	case 8:
+		val = __uldq((const __u64 *)ptr);
+		break;
+	default:
+		bad_unaligned_access_length();
+	}
+	return val;
+}
+
+static inline void __put_unaligned(__u64 val, void *ptr, size_t size)
+{
+	switch (size) {
+	      case 1:
+		*(__u8 *)ptr = (val);
+	        break;
+	      case 2:
+		__ustw(val, (__u16 *)ptr);
+		break;
+	      case 4:
+		__ustl(val, (__u32 *)ptr);
+		break;
+	      case 8:
+		__ustq(val, (__u64 *)ptr);
+		break;
+	      default:
+	    	bad_unaligned_access_length();
+	}
+}
 
 #endif /* _ASM_UNALIGNED_H */

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2004-06-15 13:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-04-23  3:22 inconsistent operand constraints in 'asm' in unaligned.h:66 using gcc 3.4 Bradley D. LaRonde
2004-04-23  3:22 ` Bradley D. LaRonde
2004-04-23 13:07 ` Maciej W. Rozycki
2004-04-23 13:14   ` Ralf Baechle
2004-06-15 13:57     ` Maciej W. Rozycki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox