diff options
Diffstat (limited to 'include/asm-sparc')
-rw-r--r-- | include/asm-sparc/bitops.h | 388 | ||||
-rw-r--r-- | include/asm-sparc/cpudata.h | 1 | ||||
-rw-r--r-- | include/asm-sparc/idprom.h | 26 | ||||
-rw-r--r-- | include/asm-sparc/oplib.h | 2 | ||||
-rw-r--r-- | include/asm-sparc/page.h | 4 | ||||
-rw-r--r-- | include/asm-sparc/pgtable.h | 6 | ||||
-rw-r--r-- | include/asm-sparc/poll.h | 1 | ||||
-rw-r--r-- | include/asm-sparc/smp.h | 9 | ||||
-rw-r--r-- | include/asm-sparc/socket.h | 2 | ||||
-rw-r--r-- | include/asm-sparc/spinlock.h | 25 | ||||
-rw-r--r-- | include/asm-sparc/uaccess.h | 47 |
11 files changed, 54 insertions, 457 deletions
diff --git a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h index 41722b5e45e..04aa3318f76 100644 --- a/include/asm-sparc/bitops.h +++ b/include/asm-sparc/bitops.h @@ -152,386 +152,22 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) : "memory", "cc"); } -/* - * non-atomic versions - */ -static inline void __set_bit(int nr, volatile unsigned long *addr) -{ - unsigned long mask = 1UL << (nr & 0x1f); - unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - - *p |= mask; -} - -static inline void __clear_bit(int nr, volatile unsigned long *addr) -{ - unsigned long mask = 1UL << (nr & 0x1f); - unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - - *p &= ~mask; -} - -static inline void __change_bit(int nr, volatile unsigned long *addr) -{ - unsigned long mask = 1UL << (nr & 0x1f); - unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - - *p ^= mask; -} - -static inline int __test_and_set_bit(int nr, volatile unsigned long *addr) -{ - unsigned long mask = 1UL << (nr & 0x1f); - unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - unsigned long old = *p; - - *p = old | mask; - return (old & mask) != 0; -} - -static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr) -{ - unsigned long mask = 1UL << (nr & 0x1f); - unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - unsigned long old = *p; - - *p = old & ~mask; - return (old & mask) != 0; -} - -static inline int __test_and_change_bit(int nr, volatile unsigned long *addr) -{ - unsigned long mask = 1UL << (nr & 0x1f); - unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - unsigned long old = *p; - - *p = old ^ mask; - return (old & mask) != 0; -} +#include <asm-generic/bitops/non-atomic.h> #define smp_mb__before_clear_bit() do { } while(0) #define smp_mb__after_clear_bit() do { } while(0) -/* The following routine need not be atomic. */ -static inline int test_bit(int nr, __const__ volatile unsigned long *addr) -{ - return (1UL & (((unsigned long *)addr)[nr >> 5] >> (nr & 31))) != 0UL; -} - -/* The easy/cheese version for now. */ -static inline unsigned long ffz(unsigned long word) -{ - unsigned long result = 0; - - while(word & 1) { - result++; - word >>= 1; - } - return result; -} - -/** - * __ffs - find first bit in word. - * @word: The word to search - * - * Undefined if no bit exists, so code should check against 0 first. - */ -static inline int __ffs(unsigned long word) -{ - int num = 0; - - if ((word & 0xffff) == 0) { - num += 16; - word >>= 16; - } - if ((word & 0xff) == 0) { - num += 8; - word >>= 8; - } - if ((word & 0xf) == 0) { - num += 4; - word >>= 4; - } - if ((word & 0x3) == 0) { - num += 2; - word >>= 2; - } - if ((word & 0x1) == 0) - num += 1; - return num; -} - -/* - * Every architecture must define this function. It's the fastest - * way of searching a 140-bit bitmap where the first 100 bits are - * unlikely to be set. It's guaranteed that at least one of the 140 - * bits is cleared. - */ -static inline int sched_find_first_bit(unsigned long *b) -{ - - if (unlikely(b[0])) - return __ffs(b[0]); - if (unlikely(b[1])) - return __ffs(b[1]) + 32; - if (unlikely(b[2])) - return __ffs(b[2]) + 64; - if (b[3]) - return __ffs(b[3]) + 96; - return __ffs(b[4]) + 128; -} - -/* - * ffs: find first bit set. This is defined the same way as - * the libc and compiler builtin ffs routines, therefore - * differs in spirit from the above ffz (man ffs). - */ -static inline int ffs(int x) -{ - if (!x) - return 0; - return __ffs((unsigned long)x) + 1; -} - -/* - * fls: find last (most-significant) bit set. - * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. - */ -#define fls(x) generic_fls(x) -#define fls64(x) generic_fls64(x) - -/* - * hweightN: returns the hamming weight (i.e. the number - * of bits set) of a N-bit word - */ -#define hweight32(x) generic_hweight32(x) -#define hweight16(x) generic_hweight16(x) -#define hweight8(x) generic_hweight8(x) - -/* - * find_next_zero_bit() finds the first zero bit in a bit string of length - * 'size' bits, starting the search at bit 'offset'. This is largely based - * on Linus's ALPHA routines, which are pretty portable BTW. - */ -static inline unsigned long find_next_zero_bit(const unsigned long *addr, - unsigned long size, unsigned long offset) -{ - const unsigned long *p = addr + (offset >> 5); - unsigned long result = offset & ~31UL; - unsigned long tmp; - - if (offset >= size) - return size; - size -= result; - offset &= 31UL; - if (offset) { - tmp = *(p++); - tmp |= ~0UL >> (32-offset); - if (size < 32) - goto found_first; - if (~tmp) - goto found_middle; - size -= 32; - result += 32; - } - while (size & ~31UL) { - if (~(tmp = *(p++))) - goto found_middle; - result += 32; - size -= 32; - } - if (!size) - return result; - tmp = *p; - -found_first: - tmp |= ~0UL << size; - if (tmp == ~0UL) /* Are any bits zero? */ - return result + size; /* Nope. */ -found_middle: - return result + ffz(tmp); -} - -/* - * Linus sez that gcc can optimize the following correctly, we'll see if this - * holds on the Sparc as it does for the ALPHA. - */ -#define find_first_zero_bit(addr, size) \ - find_next_zero_bit((addr), (size), 0) - -/** - * find_next_bit - find the first set bit in a memory region - * @addr: The address to base the search on - * @offset: The bitnumber to start searching at - * @size: The maximum size to search - * - * Scheduler induced bitop, do not use. - */ -static inline int find_next_bit(const unsigned long *addr, int size, int offset) -{ - const unsigned long *p = addr + (offset >> 5); - int num = offset & ~0x1f; - unsigned long word; - - word = *p++; - word &= ~((1 << (offset & 0x1f)) - 1); - while (num < size) { - if (word != 0) { - return __ffs(word) + num; - } - word = *p++; - num += 0x20; - } - return num; -} - -/** - * find_first_bit - find the first set bit in a memory region - * @addr: The address to start the search at - * @size: The maximum size to search - * - * Returns the bit-number of the first set bit, not the number of the byte - * containing a bit. - */ -#define find_first_bit(addr, size) \ - find_next_bit((addr), (size), 0) - -/* - */ -static inline int test_le_bit(int nr, __const__ unsigned long * addr) -{ - __const__ unsigned char *ADDR = (__const__ unsigned char *) addr; - return (ADDR[nr >> 3] >> (nr & 7)) & 1; -} - -/* - * non-atomic versions - */ -static inline void __set_le_bit(int nr, unsigned long *addr) -{ - unsigned char *ADDR = (unsigned char *)addr; - - ADDR += nr >> 3; - *ADDR |= 1 << (nr & 0x07); -} - -static inline void __clear_le_bit(int nr, unsigned long *addr) -{ - unsigned char *ADDR = (unsigned char *)addr; - - ADDR += nr >> 3; - *ADDR &= ~(1 << (nr & 0x07)); -} - -static inline int __test_and_set_le_bit(int nr, unsigned long *addr) -{ - int mask, retval; - unsigned char *ADDR = (unsigned char *)addr; - - ADDR += nr >> 3; - mask = 1 << (nr & 0x07); - retval = (mask & *ADDR) != 0; - *ADDR |= mask; - return retval; -} - -static inline int __test_and_clear_le_bit(int nr, unsigned long *addr) -{ - int mask, retval; - unsigned char *ADDR = (unsigned char *)addr; - - ADDR += nr >> 3; - mask = 1 << (nr & 0x07); - retval = (mask & *ADDR) != 0; - *ADDR &= ~mask; - return retval; -} - -static inline unsigned long find_next_zero_le_bit(const unsigned long *addr, - unsigned long size, unsigned long offset) -{ - const unsigned long *p = addr + (offset >> 5); - unsigned long result = offset & ~31UL; - unsigned long tmp; - - if (offset >= size) - return size; - size -= result; - offset &= 31UL; - if(offset) { - tmp = *(p++); - tmp |= __swab32(~0UL >> (32-offset)); - if(size < 32) - goto found_first; - if(~tmp) - goto found_middle; - size -= 32; - result += 32; - } - while(size & ~31UL) { - if(~(tmp = *(p++))) - goto found_middle; - result += 32; - size -= 32; - } - if(!size) - return result; - tmp = *p; - -found_first: - tmp = __swab32(tmp) | (~0UL << size); - if (tmp == ~0UL) /* Are any bits zero? */ - return result + size; /* Nope. */ - return result + ffz(tmp); - -found_middle: - return result + ffz(__swab32(tmp)); -} - -#define find_first_zero_le_bit(addr, size) \ - find_next_zero_le_bit((addr), (size), 0) - -#define ext2_set_bit(nr,addr) \ - __test_and_set_le_bit((nr),(unsigned long *)(addr)) -#define ext2_clear_bit(nr,addr) \ - __test_and_clear_le_bit((nr),(unsigned long *)(addr)) - -#define ext2_set_bit_atomic(lock, nr, addr) \ - ({ \ - int ret; \ - spin_lock(lock); \ - ret = ext2_set_bit((nr), (unsigned long *)(addr)); \ - spin_unlock(lock); \ - ret; \ - }) - -#define ext2_clear_bit_atomic(lock, nr, addr) \ - ({ \ - int ret; \ - spin_lock(lock); \ - ret = ext2_clear_bit((nr), (unsigned long *)(addr)); \ - spin_unlock(lock); \ - ret; \ - }) - -#define ext2_test_bit(nr,addr) \ - test_le_bit((nr),(unsigned long *)(addr)) -#define ext2_find_first_zero_bit(addr, size) \ - find_first_zero_le_bit((unsigned long *)(addr), (size)) -#define ext2_find_next_zero_bit(addr, size, off) \ - find_next_zero_le_bit((unsigned long *)(addr), (size), (off)) - -/* Bitmap functions for the minix filesystem. */ -#define minix_test_and_set_bit(nr,addr) \ - test_and_set_bit((nr),(unsigned long *)(addr)) -#define minix_set_bit(nr,addr) \ - set_bit((nr),(unsigned long *)(addr)) -#define minix_test_and_clear_bit(nr,addr) \ - test_and_clear_bit((nr),(unsigned long *)(addr)) -#define minix_test_bit(nr,addr) \ - test_bit((nr),(unsigned long *)(addr)) -#define minix_find_first_zero_bit(addr,size) \ - find_first_zero_bit((unsigned long *)(addr),(size)) +#include <asm-generic/bitops/ffz.h> +#include <asm-generic/bitops/__ffs.h> +#include <asm-generic/bitops/sched.h> +#include <asm-generic/bitops/ffs.h> +#include <asm-generic/bitops/fls.h> +#include <asm-generic/bitops/fls64.h> +#include <asm-generic/bitops/hweight.h> +#include <asm-generic/bitops/find.h> +#include <asm-generic/bitops/ext2-non-atomic.h> +#include <asm-generic/bitops/ext2-atomic.h> +#include <asm-generic/bitops/minix.h> #endif /* __KERNEL__ */ diff --git a/include/asm-sparc/cpudata.h b/include/asm-sparc/cpudata.h index ec0d9ef90a3..a2c4d51d36c 100644 --- a/include/asm-sparc/cpudata.h +++ b/include/asm-sparc/cpudata.h @@ -18,6 +18,7 @@ typedef struct { unsigned int counter; int prom_node; int mid; + int next; } cpuinfo_sparc; DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data); diff --git a/include/asm-sparc/idprom.h b/include/asm-sparc/idprom.h index d856e640acd..59083ed8523 100644 --- a/include/asm-sparc/idprom.h +++ b/include/asm-sparc/idprom.h @@ -7,27 +7,19 @@ #ifndef _SPARC_IDPROM_H #define _SPARC_IDPROM_H -/* Offset into the EEPROM where the id PROM is located on the 4c */ -#define IDPROM_OFFSET 0x7d8 +#include <linux/types.h> -/* On sun4m; physical. */ -/* MicroSPARC(-II) does not decode 31rd bit, but it works. */ -#define IDPROM_OFFSET_M 0xfd8 - -struct idprom -{ - unsigned char id_format; /* Format identifier (always 0x01) */ - unsigned char id_machtype; /* Machine type */ - unsigned char id_ethaddr[6]; /* Hardware ethernet address */ - long id_date; /* Date of manufacture */ - unsigned int id_sernum:24; /* Unique serial number */ - unsigned char id_cksum; /* Checksum - xor of the data bytes */ - unsigned char reserved[16]; +struct idprom { + u8 id_format; /* Format identifier (always 0x01) */ + u8 id_machtype; /* Machine type */ + u8 id_ethaddr[6]; /* Hardware ethernet address */ + s32 id_date; /* Date of manufacture */ + u32 id_sernum:24; /* Unique serial number */ + u8 id_cksum; /* Checksum - xor of the data bytes */ + u8 reserved[16]; }; extern struct idprom *idprom; extern void idprom_init(void); -#define IDPROM_SIZE (sizeof(struct idprom)) - #endif /* !(_SPARC_IDPROM_H) */ diff --git a/include/asm-sparc/oplib.h b/include/asm-sparc/oplib.h index d0d76b30eb4..f283f8aaf6a 100644 --- a/include/asm-sparc/oplib.h +++ b/include/asm-sparc/oplib.h @@ -165,6 +165,7 @@ enum prom_input_device { PROMDEV_ITTYA, /* input from ttya */ PROMDEV_ITTYB, /* input from ttyb */ PROMDEV_IRSC, /* input from rsc */ + PROMDEV_IVCONS, /* input from virtual-console */ PROMDEV_I_UNK, }; @@ -177,6 +178,7 @@ enum prom_output_device { PROMDEV_OTTYA, /* to ttya */ PROMDEV_OTTYB, /* to ttyb */ PROMDEV_ORSC, /* to rsc */ + PROMDEV_OVCONS, /* to virtual-console */ PROMDEV_O_UNK, }; diff --git a/include/asm-sparc/page.h b/include/asm-sparc/page.h index 9122684f6c1..ec3274b7ddf 100644 --- a/include/asm-sparc/page.h +++ b/include/asm-sparc/page.h @@ -152,8 +152,7 @@ extern unsigned long pfn_base; #define virt_to_phys __pa #define phys_to_virt __va -#define pfn_to_page(pfn) (mem_map + ((pfn)-(pfn_base))) -#define page_to_pfn(page) ((unsigned long)(((page) - mem_map) + pfn_base)) +#define ARCH_PFN_OFFSET (pfn_base) #define virt_to_page(kaddr) (mem_map + ((((unsigned long)(kaddr)-PAGE_OFFSET)>>PAGE_SHIFT))) #define pfn_valid(pfn) (((pfn) >= (pfn_base)) && (((pfn)-(pfn_base)) < max_mapnr)) @@ -164,6 +163,7 @@ extern unsigned long pfn_base; #endif /* __KERNEL__ */ +#include <asm-generic/memory_model.h> #include <asm-generic/page.h> #endif /* _SPARC_PAGE_H */ diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h index b33c35411e8..9eea8f4d41f 100644 --- a/include/asm-sparc/pgtable.h +++ b/include/asm-sparc/pgtable.h @@ -269,11 +269,14 @@ BTFIXUPDEF_CALL_CONST(pte_t, mk_pte, struct page *, pgprot_t) BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_phys, unsigned long, pgprot_t) BTFIXUPDEF_CALL_CONST(pte_t, mk_pte_io, unsigned long, pgprot_t, int) +BTFIXUPDEF_CALL_CONST(pgprot_t, pgprot_noncached, pgprot_t) #define mk_pte(page,pgprot) BTFIXUP_CALL(mk_pte)(page,pgprot) #define mk_pte_phys(page,pgprot) BTFIXUP_CALL(mk_pte_phys)(page,pgprot) #define mk_pte_io(page,pgprot,space) BTFIXUP_CALL(mk_pte_io)(page,pgprot,space) +#define pgprot_noncached(pgprot) BTFIXUP_CALL(pgprot_noncached)(pgprot) + BTFIXUPDEF_INT(pte_modify_mask) static pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute_const__; @@ -309,9 +312,6 @@ BTFIXUPDEF_CALL(pte_t *, pte_offset_kernel, pmd_t *, unsigned long) #define pte_unmap(pte) do{}while(0) #define pte_unmap_nested(pte) do{}while(0) -/* The permissions for pgprot_val to make a page mapped on the obio space */ -extern unsigned int pg_iobits; - /* Certain architectures need to do special things when pte's * within a page table are directly modified. Thus, the following * hook is made available. diff --git a/include/asm-sparc/poll.h b/include/asm-sparc/poll.h index 3ddcc6481f0..26f13fb3549 100644 --- a/include/asm-sparc/poll.h +++ b/include/asm-sparc/poll.h @@ -13,6 +13,7 @@ #define POLLWRBAND 256 #define POLLMSG 512 #define POLLREMOVE 1024 +#define POLLRDHUP 2048 struct pollfd { int fd; diff --git a/include/asm-sparc/smp.h b/include/asm-sparc/smp.h index 580c51d011d..98c46e3fbe8 100644 --- a/include/asm-sparc/smp.h +++ b/include/asm-sparc/smp.h @@ -81,16 +81,9 @@ static inline int smp_call_function(void (*func)(void *info), void *info, int no return 0; } -extern __volatile__ int __cpu_number_map[NR_CPUS]; -extern __volatile__ int __cpu_logical_map[NR_CPUS]; - static inline int cpu_logical_map(int cpu) { - return __cpu_logical_map[cpu]; -} -static inline int cpu_number_map(int cpu) -{ - return __cpu_number_map[cpu]; + return cpu; } static inline int hard_smp4m_processor_id(void) diff --git a/include/asm-sparc/socket.h b/include/asm-sparc/socket.h index 09575b608ad..4e0ce3a35ea 100644 --- a/include/asm-sparc/socket.h +++ b/include/asm-sparc/socket.h @@ -47,7 +47,7 @@ #define SO_TIMESTAMP 0x001d #define SCM_TIMESTAMP SO_TIMESTAMP -#define SO_PEERSEC 0x100e +#define SO_PEERSEC 0x001e /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 0x5001 diff --git a/include/asm-sparc/spinlock.h b/include/asm-sparc/spinlock.h index e344c98a6f5..3350c90c786 100644 --- a/include/asm-sparc/spinlock.h +++ b/include/asm-sparc/spinlock.h @@ -94,7 +94,7 @@ static inline void __read_lock(raw_rwlock_t *rw) #define __raw_read_lock(lock) \ do { unsigned long flags; \ local_irq_save(flags); \ - __raw_read_lock(lock); \ + __read_lock(lock); \ local_irq_restore(flags); \ } while(0) @@ -114,11 +114,11 @@ static inline void __read_unlock(raw_rwlock_t *rw) #define __raw_read_unlock(lock) \ do { unsigned long flags; \ local_irq_save(flags); \ - __raw_read_unlock(lock); \ + __read_unlock(lock); \ local_irq_restore(flags); \ } while(0) -extern __inline__ void __raw_write_lock(raw_rwlock_t *rw) +static inline void __raw_write_lock(raw_rwlock_t *rw) { register raw_rwlock_t *lp asm("g1"); lp = rw; @@ -131,9 +131,28 @@ extern __inline__ void __raw_write_lock(raw_rwlock_t *rw) : "g2", "g4", "memory", "cc"); } +static inline int __raw_write_trylock(raw_rwlock_t *rw) +{ + unsigned int val; + + __asm__ __volatile__("ldstub [%1 + 3], %0" + : "=r" (val) + : "r" (&rw->lock) + : "memory"); + + if (val == 0) { + val = rw->lock & ~0xff; + if (val) + ((volatile u8*)&rw->lock)[3] = 0; + } + + return (val == 0); +} + #define __raw_write_unlock(rw) do { (rw)->lock = 0; } while(0) #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) +#define __raw_read_trylock(lock) generic__raw_read_trylock(lock) #endif /* !(__ASSEMBLY__) */ diff --git a/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h index f8f1ec1f06e..3cf132e1aa2 100644 --- a/include/asm-sparc/uaccess.h +++ b/include/asm-sparc/uaccess.h @@ -120,17 +120,6 @@ case 8: __put_user_asm(x,d,addr,__pu_ret); break; \ default: __pu_ret = __put_user_bad(); break; \ } } else { __pu_ret = -EFAULT; } __pu_ret; }) -#define __put_user_check_ret(x,addr,size,retval) ({ \ -register int __foo __asm__ ("l1"); \ -if (__access_ok(addr,size)) { \ -switch (size) { \ -case 1: __put_user_asm_ret(x,b,addr,retval,__foo); break; \ -case 2: __put_user_asm_ret(x,h,addr,retval,__foo); break; \ -case 4: __put_user_asm_ret(x,,addr,retval,__foo); break; \ -case 8: __put_user_asm_ret(x,d,addr,retval,__foo); break; \ -default: if (__put_user_bad()) return retval; break; \ -} } else return retval; }) - #define __put_user_nocheck(x,addr,size) ({ \ register int __pu_ret; \ switch (size) { \ @@ -141,16 +130,6 @@ case 8: __put_user_asm(x,d,addr,__pu_ret); break; \ default: __pu_ret = __put_user_bad(); break; \ } __pu_ret; }) -#define __put_user_nocheck_ret(x,addr,size,retval) ({ \ -register int __foo __asm__ ("l1"); \ -switch (size) { \ -case 1: __put_user_asm_ret(x,b,addr,retval,__foo); break; \ -case 2: __put_user_asm_ret(x,h,addr,retval,__foo); break; \ -case 4: __put_user_asm_ret(x,,addr,retval,__foo); break; \ -case 8: __put_user_asm_ret(x,d,addr,retval,__foo); break; \ -default: if (__put_user_bad()) return retval; break; \ -} }) - #define __put_user_asm(x,size,addr,ret) \ __asm__ __volatile__( \ "/* Put user asm, inline. */\n" \ @@ -170,32 +149,6 @@ __asm__ __volatile__( \ : "=&r" (ret) : "r" (x), "m" (*__m(addr)), \ "i" (-EFAULT)) -#define __put_user_asm_ret(x,size,addr,ret,foo) \ -if (__builtin_constant_p(ret) && ret == -EFAULT) \ -__asm__ __volatile__( \ - "/* Put user asm ret, inline. */\n" \ -"1:\t" "st"#size " %1, %2\n\n\t" \ - ".section __ex_table,#alloc\n\t" \ - ".align 4\n\t" \ - ".word 1b, __ret_efault\n\n\t" \ - ".previous\n\n\t" \ - : "=r" (foo) : "r" (x), "m" (*__m(addr))); \ -else \ -__asm__ __volatile( \ - "/* Put user asm ret, inline. */\n" \ -"1:\t" "st"#size " %1, %2\n\n\t" \ - ".section .fixup,#alloc,#execinstr\n\t" \ - ".align 4\n" \ -"3:\n\t" \ - "ret\n\t" \ - " restore %%g0, %3, %%o0\n\t" \ - ".previous\n\n\t" \ - ".section __ex_table,#alloc\n\t" \ - ".align 4\n\t" \ - ".word 1b, 3b\n\n\t" \ - ".previous\n\n\t" \ - : "=r" (foo) : "r" (x), "m" (*__m(addr)), "i" (ret)) - extern int __put_user_bad(void); #define __get_user_check(x,addr,size,type) ({ \ |