cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

unaligned-emul.h (26856B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later */
      2#ifndef _ASM_MIPS_UNALIGNED_EMUL_H
      3#define _ASM_MIPS_UNALIGNED_EMUL_H
      4
      5#include <asm/asm.h>
      6
      7#ifdef __BIG_ENDIAN
      8#define  _LoadHW(addr, value, res, type)  \
      9do {                                                \
     10	__asm__ __volatile__ (".set\tnoat\n"        \
     11		"1:\t"type##_lb("%0", "0(%2)")"\n"  \
     12		"2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
     13		"sll\t%0, 0x8\n\t"                  \
     14		"or\t%0, $1\n\t"                    \
     15		"li\t%1, 0\n"                       \
     16		"3:\t.set\tat\n\t"                  \
     17		".insn\n\t"                         \
     18		".section\t.fixup,\"ax\"\n\t"       \
     19		"4:\tli\t%1, %3\n\t"                \
     20		"j\t3b\n\t"                         \
     21		".previous\n\t"                     \
     22		".section\t__ex_table,\"a\"\n\t"    \
     23		STR(PTR_WD)"\t1b, 4b\n\t"           \
     24		STR(PTR_WD)"\t2b, 4b\n\t"           \
     25		".previous"                         \
     26		: "=&r" (value), "=r" (res)         \
     27		: "r" (addr), "i" (-EFAULT));       \
     28} while (0)
     29
     30#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
     31#define  _LoadW(addr, value, res, type)   \
     32do {                                                \
     33	__asm__ __volatile__ (                      \
     34		"1:\t"type##_lwl("%0", "(%2)")"\n"   \
     35		"2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
     36		"li\t%1, 0\n"                       \
     37		"3:\n\t"                            \
     38		".insn\n\t"                         \
     39		".section\t.fixup,\"ax\"\n\t"       \
     40		"4:\tli\t%1, %3\n\t"                \
     41		"j\t3b\n\t"                         \
     42		".previous\n\t"                     \
     43		".section\t__ex_table,\"a\"\n\t"    \
     44		STR(PTR_WD)"\t1b, 4b\n\t"           \
     45		STR(PTR_WD)"\t2b, 4b\n\t"           \
     46		".previous"                         \
     47		: "=&r" (value), "=r" (res)         \
     48		: "r" (addr), "i" (-EFAULT));       \
     49} while (0)
     50
     51#else /* CONFIG_CPU_NO_LOAD_STORE_LR */
     52/* For CPUs without lwl instruction */
     53#define  _LoadW(addr, value, res, type) \
     54do {                                                \
     55	__asm__ __volatile__ (			    \
     56		".set\tpush\n"			    \
     57		".set\tnoat\n\t"		    \
     58		"1:"type##_lb("%0", "0(%2)")"\n\t"  \
     59		"2:"type##_lbu("$1", "1(%2)")"\n\t" \
     60		"sll\t%0, 0x8\n\t"		    \
     61		"or\t%0, $1\n\t"		    \
     62		"3:"type##_lbu("$1", "2(%2)")"\n\t" \
     63		"sll\t%0, 0x8\n\t"		    \
     64		"or\t%0, $1\n\t"		    \
     65		"4:"type##_lbu("$1", "3(%2)")"\n\t" \
     66		"sll\t%0, 0x8\n\t"		    \
     67		"or\t%0, $1\n\t"		    \
     68		"li\t%1, 0\n"			    \
     69		".set\tpop\n"			    \
     70		"10:\n\t"			    \
     71		".insn\n\t"			    \
     72		".section\t.fixup,\"ax\"\n\t"	    \
     73		"11:\tli\t%1, %3\n\t"		    \
     74		"j\t10b\n\t"			    \
     75		".previous\n\t"			    \
     76		".section\t__ex_table,\"a\"\n\t"    \
     77		STR(PTR_WD)"\t1b, 11b\n\t"	    \
     78		STR(PTR_WD)"\t2b, 11b\n\t"	    \
     79		STR(PTR_WD)"\t3b, 11b\n\t"	    \
     80		STR(PTR_WD)"\t4b, 11b\n\t"	    \
     81		".previous"			    \
     82		: "=&r" (value), "=r" (res)	    \
     83		: "r" (addr), "i" (-EFAULT));       \
     84} while (0)
     85
     86#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
     87
     88#define  _LoadHWU(addr, value, res, type) \
     89do {                                                \
     90	__asm__ __volatile__ (                      \
     91		".set\tnoat\n"                      \
     92		"1:\t"type##_lbu("%0", "0(%2)")"\n" \
     93		"2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
     94		"sll\t%0, 0x8\n\t"                  \
     95		"or\t%0, $1\n\t"                    \
     96		"li\t%1, 0\n"                       \
     97		"3:\n\t"                            \
     98		".insn\n\t"                         \
     99		".set\tat\n\t"                      \
    100		".section\t.fixup,\"ax\"\n\t"       \
    101		"4:\tli\t%1, %3\n\t"                \
    102		"j\t3b\n\t"                         \
    103		".previous\n\t"                     \
    104		".section\t__ex_table,\"a\"\n\t"    \
    105		STR(PTR_WD)"\t1b, 4b\n\t"           \
    106		STR(PTR_WD)"\t2b, 4b\n\t"           \
    107		".previous"                         \
    108		: "=&r" (value), "=r" (res)         \
    109		: "r" (addr), "i" (-EFAULT));       \
    110} while (0)
    111
    112#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
    113#define  _LoadWU(addr, value, res, type)  \
    114do {                                                \
    115	__asm__ __volatile__ (                      \
    116		"1:\t"type##_lwl("%0", "(%2)")"\n"  \
    117		"2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
    118		"dsll\t%0, %0, 32\n\t"              \
    119		"dsrl\t%0, %0, 32\n\t"              \
    120		"li\t%1, 0\n"                       \
    121		"3:\n\t"                            \
    122		".insn\n\t"                         \
    123		"\t.section\t.fixup,\"ax\"\n\t"     \
    124		"4:\tli\t%1, %3\n\t"                \
    125		"j\t3b\n\t"                         \
    126		".previous\n\t"                     \
    127		".section\t__ex_table,\"a\"\n\t"    \
    128		STR(PTR_WD)"\t1b, 4b\n\t"           \
    129		STR(PTR_WD)"\t2b, 4b\n\t"           \
    130		".previous"                         \
    131		: "=&r" (value), "=r" (res)         \
    132		: "r" (addr), "i" (-EFAULT));       \
    133} while (0)
    134
    135#define  _LoadDW(addr, value, res)  \
    136do {                                                \
    137	__asm__ __volatile__ (                      \
    138		"1:\tldl\t%0, (%2)\n"               \
    139		"2:\tldr\t%0, 7(%2)\n\t"            \
    140		"li\t%1, 0\n"                       \
    141		"3:\n\t"                            \
    142		".insn\n\t"                         \
    143		"\t.section\t.fixup,\"ax\"\n\t"     \
    144		"4:\tli\t%1, %3\n\t"                \
    145		"j\t3b\n\t"                         \
    146		".previous\n\t"                     \
    147		".section\t__ex_table,\"a\"\n\t"    \
    148		STR(PTR_WD)"\t1b, 4b\n\t"           \
    149		STR(PTR_WD)"\t2b, 4b\n\t"           \
    150		".previous"                         \
    151		: "=&r" (value), "=r" (res)         \
    152		: "r" (addr), "i" (-EFAULT));       \
    153} while (0)
    154
    155#else /* CONFIG_CPU_NO_LOAD_STORE_LR */
    156/* For CPUs without lwl and ldl instructions */
    157#define  _LoadWU(addr, value, res, type) \
    158do {                                                \
    159	__asm__ __volatile__ (			    \
    160		".set\tpush\n\t"		    \
    161		".set\tnoat\n\t"		    \
    162		"1:"type##_lbu("%0", "0(%2)")"\n\t" \
    163		"2:"type##_lbu("$1", "1(%2)")"\n\t" \
    164		"sll\t%0, 0x8\n\t"		    \
    165		"or\t%0, $1\n\t"		    \
    166		"3:"type##_lbu("$1", "2(%2)")"\n\t" \
    167		"sll\t%0, 0x8\n\t"		    \
    168		"or\t%0, $1\n\t"		    \
    169		"4:"type##_lbu("$1", "3(%2)")"\n\t" \
    170		"sll\t%0, 0x8\n\t"		    \
    171		"or\t%0, $1\n\t"		    \
    172		"li\t%1, 0\n"			    \
    173		".set\tpop\n"			    \
    174		"10:\n\t"			    \
    175		".insn\n\t"			    \
    176		".section\t.fixup,\"ax\"\n\t"	    \
    177		"11:\tli\t%1, %3\n\t"		    \
    178		"j\t10b\n\t"			    \
    179		".previous\n\t"			    \
    180		".section\t__ex_table,\"a\"\n\t"    \
    181		STR(PTR_WD)"\t1b, 11b\n\t"	    \
    182		STR(PTR_WD)"\t2b, 11b\n\t"	    \
    183		STR(PTR_WD)"\t3b, 11b\n\t"	    \
    184		STR(PTR_WD)"\t4b, 11b\n\t"	    \
    185		".previous"			    \
    186		: "=&r" (value), "=r" (res)	    \
    187		: "r" (addr), "i" (-EFAULT));       \
    188} while (0)
    189
    190#define  _LoadDW(addr, value, res)  \
    191do {                                                \
    192	__asm__ __volatile__ (			    \
    193		".set\tpush\n\t"		    \
    194		".set\tnoat\n\t"		    \
    195		"1:lb\t%0, 0(%2)\n\t"		    \
    196		"2:lbu\t $1, 1(%2)\n\t"		    \
    197		"dsll\t%0, 0x8\n\t"		    \
    198		"or\t%0, $1\n\t"		    \
    199		"3:lbu\t$1, 2(%2)\n\t"		    \
    200		"dsll\t%0, 0x8\n\t"		    \
    201		"or\t%0, $1\n\t"		    \
    202		"4:lbu\t$1, 3(%2)\n\t"		    \
    203		"dsll\t%0, 0x8\n\t"		    \
    204		"or\t%0, $1\n\t"		    \
    205		"5:lbu\t$1, 4(%2)\n\t"		    \
    206		"dsll\t%0, 0x8\n\t"		    \
    207		"or\t%0, $1\n\t"		    \
    208		"6:lbu\t$1, 5(%2)\n\t"		    \
    209		"dsll\t%0, 0x8\n\t"		    \
    210		"or\t%0, $1\n\t"		    \
    211		"7:lbu\t$1, 6(%2)\n\t"		    \
    212		"dsll\t%0, 0x8\n\t"		    \
    213		"or\t%0, $1\n\t"		    \
    214		"8:lbu\t$1, 7(%2)\n\t"		    \
    215		"dsll\t%0, 0x8\n\t"		    \
    216		"or\t%0, $1\n\t"		    \
    217		"li\t%1, 0\n"			    \
    218		".set\tpop\n\t"			    \
    219		"10:\n\t"			    \
    220		".insn\n\t"			    \
    221		".section\t.fixup,\"ax\"\n\t"	    \
    222		"11:\tli\t%1, %3\n\t"		    \
    223		"j\t10b\n\t"			    \
    224		".previous\n\t"			    \
    225		".section\t__ex_table,\"a\"\n\t"    \
    226		STR(PTR_WD)"\t1b, 11b\n\t"	    \
    227		STR(PTR_WD)"\t2b, 11b\n\t"	    \
    228		STR(PTR_WD)"\t3b, 11b\n\t"	    \
    229		STR(PTR_WD)"\t4b, 11b\n\t"	    \
    230		STR(PTR_WD)"\t5b, 11b\n\t"	    \
    231		STR(PTR_WD)"\t6b, 11b\n\t"	    \
    232		STR(PTR_WD)"\t7b, 11b\n\t"	    \
    233		STR(PTR_WD)"\t8b, 11b\n\t"	    \
    234		".previous"			    \
    235		: "=&r" (value), "=r" (res)	    \
    236		: "r" (addr), "i" (-EFAULT));       \
    237} while (0)
    238
    239#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
    240
    241
    242#define  _StoreHW(addr, value, res, type) \
    243do {                                                \
    244	__asm__ __volatile__ (                      \
    245		".set\tnoat\n"                      \
    246		"1:\t"type##_sb("%1", "1(%2)")"\n"  \
    247		"srl\t$1, %1, 0x8\n"                \
    248		"2:\t"type##_sb("$1", "0(%2)")"\n"  \
    249		".set\tat\n\t"                      \
    250		"li\t%0, 0\n"                       \
    251		"3:\n\t"                            \
    252		".insn\n\t"                         \
    253		".section\t.fixup,\"ax\"\n\t"       \
    254		"4:\tli\t%0, %3\n\t"                \
    255		"j\t3b\n\t"                         \
    256		".previous\n\t"                     \
    257		".section\t__ex_table,\"a\"\n\t"    \
    258		STR(PTR_WD)"\t1b, 4b\n\t"           \
    259		STR(PTR_WD)"\t2b, 4b\n\t"           \
    260		".previous"                         \
    261		: "=r" (res)                        \
    262		: "r" (value), "r" (addr), "i" (-EFAULT));\
    263} while (0)
    264
    265#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
    266#define  _StoreW(addr, value, res, type)  \
    267do {                                                \
    268	__asm__ __volatile__ (                      \
    269		"1:\t"type##_swl("%1", "(%2)")"\n"  \
    270		"2:\t"type##_swr("%1", "3(%2)")"\n\t"\
    271		"li\t%0, 0\n"                       \
    272		"3:\n\t"                            \
    273		".insn\n\t"                         \
    274		".section\t.fixup,\"ax\"\n\t"       \
    275		"4:\tli\t%0, %3\n\t"                \
    276		"j\t3b\n\t"                         \
    277		".previous\n\t"                     \
    278		".section\t__ex_table,\"a\"\n\t"    \
    279		STR(PTR_WD)"\t1b, 4b\n\t"           \
    280		STR(PTR_WD)"\t2b, 4b\n\t"           \
    281		".previous"                         \
    282		: "=r" (res)                                \
    283		: "r" (value), "r" (addr), "i" (-EFAULT));  \
    284} while (0)
    285
    286#define  _StoreDW(addr, value, res) \
    287do {                                                \
    288	__asm__ __volatile__ (                      \
    289		"1:\tsdl\t%1,(%2)\n"                \
    290		"2:\tsdr\t%1, 7(%2)\n\t"            \
    291		"li\t%0, 0\n"                       \
    292		"3:\n\t"                            \
    293		".insn\n\t"                         \
    294		".section\t.fixup,\"ax\"\n\t"       \
    295		"4:\tli\t%0, %3\n\t"                \
    296		"j\t3b\n\t"                         \
    297		".previous\n\t"                     \
    298		".section\t__ex_table,\"a\"\n\t"    \
    299		STR(PTR_WD)"\t1b, 4b\n\t"           \
    300		STR(PTR_WD)"\t2b, 4b\n\t"           \
    301		".previous"                         \
    302		: "=r" (res)                                \
    303		: "r" (value), "r" (addr), "i" (-EFAULT));  \
    304} while (0)
    305
    306#else /* CONFIG_CPU_NO_LOAD_STORE_LR */
    307#define  _StoreW(addr, value, res, type)  \
    308do {                                                \
    309	__asm__ __volatile__ (                      \
    310		".set\tpush\n\t"		    \
    311		".set\tnoat\n\t"		    \
    312		"1:"type##_sb("%1", "3(%2)")"\n\t"  \
    313		"srl\t$1, %1, 0x8\n\t"		    \
    314		"2:"type##_sb("$1", "2(%2)")"\n\t"  \
    315		"srl\t$1, $1,  0x8\n\t"		    \
    316		"3:"type##_sb("$1", "1(%2)")"\n\t"  \
    317		"srl\t$1, $1, 0x8\n\t"		    \
    318		"4:"type##_sb("$1", "0(%2)")"\n\t"  \
    319		".set\tpop\n\t"			    \
    320		"li\t%0, 0\n"			    \
    321		"10:\n\t"			    \
    322		".insn\n\t"			    \
    323		".section\t.fixup,\"ax\"\n\t"	    \
    324		"11:\tli\t%0, %3\n\t"		    \
    325		"j\t10b\n\t"			    \
    326		".previous\n\t"			    \
    327		".section\t__ex_table,\"a\"\n\t"    \
    328		STR(PTR_WD)"\t1b, 11b\n\t"	    \
    329		STR(PTR_WD)"\t2b, 11b\n\t"	    \
    330		STR(PTR_WD)"\t3b, 11b\n\t"	    \
    331		STR(PTR_WD)"\t4b, 11b\n\t"	    \
    332		".previous"			    \
    333		: "=&r" (res)				    \
    334		: "r" (value), "r" (addr), "i" (-EFAULT)    \
    335		: "memory");                                \
    336} while (0)
    337
    338#define  _StoreDW(addr, value, res) \
    339do {                                                \
    340	__asm__ __volatile__ (                      \
    341		".set\tpush\n\t"		    \
    342		".set\tnoat\n\t"		    \
    343		"1:sb\t%1, 7(%2)\n\t"		    \
    344		"dsrl\t$1, %1, 0x8\n\t"		    \
    345		"2:sb\t$1, 6(%2)\n\t"		    \
    346		"dsrl\t$1, $1, 0x8\n\t"		    \
    347		"3:sb\t$1, 5(%2)\n\t"		    \
    348		"dsrl\t$1, $1, 0x8\n\t"		    \
    349		"4:sb\t$1, 4(%2)\n\t"		    \
    350		"dsrl\t$1, $1, 0x8\n\t"		    \
    351		"5:sb\t$1, 3(%2)\n\t"		    \
    352		"dsrl\t$1, $1, 0x8\n\t"		    \
    353		"6:sb\t$1, 2(%2)\n\t"		    \
    354		"dsrl\t$1, $1, 0x8\n\t"		    \
    355		"7:sb\t$1, 1(%2)\n\t"		    \
    356		"dsrl\t$1, $1, 0x8\n\t"		    \
    357		"8:sb\t$1, 0(%2)\n\t"		    \
    358		"dsrl\t$1, $1, 0x8\n\t"		    \
    359		".set\tpop\n\t"			    \
    360		"li\t%0, 0\n"			    \
    361		"10:\n\t"			    \
    362		".insn\n\t"			    \
    363		".section\t.fixup,\"ax\"\n\t"	    \
    364		"11:\tli\t%0, %3\n\t"		    \
    365		"j\t10b\n\t"			    \
    366		".previous\n\t"			    \
    367		".section\t__ex_table,\"a\"\n\t"    \
    368		STR(PTR_WD)"\t1b, 11b\n\t"	    \
    369		STR(PTR_WD)"\t2b, 11b\n\t"	    \
    370		STR(PTR_WD)"\t3b, 11b\n\t"	    \
    371		STR(PTR_WD)"\t4b, 11b\n\t"	    \
    372		STR(PTR_WD)"\t5b, 11b\n\t"	    \
    373		STR(PTR_WD)"\t6b, 11b\n\t"	    \
    374		STR(PTR_WD)"\t7b, 11b\n\t"	    \
    375		STR(PTR_WD)"\t8b, 11b\n\t"	    \
    376		".previous"			    \
    377		: "=&r" (res)				    \
    378		: "r" (value), "r" (addr), "i" (-EFAULT)    \
    379		: "memory");                                \
    380} while (0)
    381
    382#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
    383
    384#else /* __BIG_ENDIAN */
    385
    386#define  _LoadHW(addr, value, res, type)  \
    387do {                                                \
    388	__asm__ __volatile__ (".set\tnoat\n"        \
    389		"1:\t"type##_lb("%0", "1(%2)")"\n"  \
    390		"2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
    391		"sll\t%0, 0x8\n\t"                  \
    392		"or\t%0, $1\n\t"                    \
    393		"li\t%1, 0\n"                       \
    394		"3:\t.set\tat\n\t"                  \
    395		".insn\n\t"                         \
    396		".section\t.fixup,\"ax\"\n\t"       \
    397		"4:\tli\t%1, %3\n\t"                \
    398		"j\t3b\n\t"                         \
    399		".previous\n\t"                     \
    400		".section\t__ex_table,\"a\"\n\t"    \
    401		STR(PTR_WD)"\t1b, 4b\n\t"           \
    402		STR(PTR_WD)"\t2b, 4b\n\t"           \
    403		".previous"                         \
    404		: "=&r" (value), "=r" (res)         \
    405		: "r" (addr), "i" (-EFAULT));       \
    406} while (0)
    407
    408#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
    409#define  _LoadW(addr, value, res, type)   \
    410do {                                                \
    411	__asm__ __volatile__ (                      \
    412		"1:\t"type##_lwl("%0", "3(%2)")"\n" \
    413		"2:\t"type##_lwr("%0", "(%2)")"\n\t"\
    414		"li\t%1, 0\n"                       \
    415		"3:\n\t"                            \
    416		".insn\n\t"                         \
    417		".section\t.fixup,\"ax\"\n\t"       \
    418		"4:\tli\t%1, %3\n\t"                \
    419		"j\t3b\n\t"                         \
    420		".previous\n\t"                     \
    421		".section\t__ex_table,\"a\"\n\t"    \
    422		STR(PTR_WD)"\t1b, 4b\n\t"           \
    423		STR(PTR_WD)"\t2b, 4b\n\t"           \
    424		".previous"                         \
    425		: "=&r" (value), "=r" (res)         \
    426		: "r" (addr), "i" (-EFAULT));       \
    427} while (0)
    428
    429#else /* CONFIG_CPU_NO_LOAD_STORE_LR */
    430/* For CPUs without lwl instruction */
    431#define  _LoadW(addr, value, res, type) \
    432do {                                                \
    433	__asm__ __volatile__ (			    \
    434		".set\tpush\n"			    \
    435		".set\tnoat\n\t"		    \
    436		"1:"type##_lb("%0", "3(%2)")"\n\t"  \
    437		"2:"type##_lbu("$1", "2(%2)")"\n\t" \
    438		"sll\t%0, 0x8\n\t"		    \
    439		"or\t%0, $1\n\t"		    \
    440		"3:"type##_lbu("$1", "1(%2)")"\n\t" \
    441		"sll\t%0, 0x8\n\t"		    \
    442		"or\t%0, $1\n\t"		    \
    443		"4:"type##_lbu("$1", "0(%2)")"\n\t" \
    444		"sll\t%0, 0x8\n\t"		    \
    445		"or\t%0, $1\n\t"		    \
    446		"li\t%1, 0\n"			    \
    447		".set\tpop\n"			    \
    448		"10:\n\t"			    \
    449		".insn\n\t"			    \
    450		".section\t.fixup,\"ax\"\n\t"	    \
    451		"11:\tli\t%1, %3\n\t"		    \
    452		"j\t10b\n\t"			    \
    453		".previous\n\t"			    \
    454		".section\t__ex_table,\"a\"\n\t"    \
    455		STR(PTR_WD)"\t1b, 11b\n\t"	    \
    456		STR(PTR_WD)"\t2b, 11b\n\t"	    \
    457		STR(PTR_WD)"\t3b, 11b\n\t"	    \
    458		STR(PTR_WD)"\t4b, 11b\n\t"	    \
    459		".previous"			    \
    460		: "=&r" (value), "=r" (res)	    \
    461		: "r" (addr), "i" (-EFAULT));       \
    462} while (0)
    463
    464#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
    465
    466
    467#define  _LoadHWU(addr, value, res, type) \
    468do {                                                \
    469	__asm__ __volatile__ (                      \
    470		".set\tnoat\n"                      \
    471		"1:\t"type##_lbu("%0", "1(%2)")"\n" \
    472		"2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
    473		"sll\t%0, 0x8\n\t"                  \
    474		"or\t%0, $1\n\t"                    \
    475		"li\t%1, 0\n"                       \
    476		"3:\n\t"                            \
    477		".insn\n\t"                         \
    478		".set\tat\n\t"                      \
    479		".section\t.fixup,\"ax\"\n\t"       \
    480		"4:\tli\t%1, %3\n\t"                \
    481		"j\t3b\n\t"                         \
    482		".previous\n\t"                     \
    483		".section\t__ex_table,\"a\"\n\t"    \
    484		STR(PTR_WD)"\t1b, 4b\n\t"           \
    485		STR(PTR_WD)"\t2b, 4b\n\t"           \
    486		".previous"                         \
    487		: "=&r" (value), "=r" (res)         \
    488		: "r" (addr), "i" (-EFAULT));       \
    489} while (0)
    490
    491#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
    492#define  _LoadWU(addr, value, res, type)  \
    493do {                                                \
    494	__asm__ __volatile__ (                      \
    495		"1:\t"type##_lwl("%0", "3(%2)")"\n" \
    496		"2:\t"type##_lwr("%0", "(%2)")"\n\t"\
    497		"dsll\t%0, %0, 32\n\t"              \
    498		"dsrl\t%0, %0, 32\n\t"              \
    499		"li\t%1, 0\n"                       \
    500		"3:\n\t"                            \
    501		".insn\n\t"                         \
    502		"\t.section\t.fixup,\"ax\"\n\t"     \
    503		"4:\tli\t%1, %3\n\t"                \
    504		"j\t3b\n\t"                         \
    505		".previous\n\t"                     \
    506		".section\t__ex_table,\"a\"\n\t"    \
    507		STR(PTR_WD)"\t1b, 4b\n\t"           \
    508		STR(PTR_WD)"\t2b, 4b\n\t"           \
    509		".previous"                         \
    510		: "=&r" (value), "=r" (res)         \
    511		: "r" (addr), "i" (-EFAULT));       \
    512} while (0)
    513
    514#define  _LoadDW(addr, value, res)  \
    515do {                                                \
    516	__asm__ __volatile__ (                      \
    517		"1:\tldl\t%0, 7(%2)\n"              \
    518		"2:\tldr\t%0, (%2)\n\t"             \
    519		"li\t%1, 0\n"                       \
    520		"3:\n\t"                            \
    521		".insn\n\t"                         \
    522		"\t.section\t.fixup,\"ax\"\n\t"     \
    523		"4:\tli\t%1, %3\n\t"                \
    524		"j\t3b\n\t"                         \
    525		".previous\n\t"                     \
    526		".section\t__ex_table,\"a\"\n\t"    \
    527		STR(PTR_WD)"\t1b, 4b\n\t"           \
    528		STR(PTR_WD)"\t2b, 4b\n\t"           \
    529		".previous"                         \
    530		: "=&r" (value), "=r" (res)         \
    531		: "r" (addr), "i" (-EFAULT));       \
    532} while (0)
    533
    534#else /* CONFIG_CPU_NO_LOAD_STORE_LR */
    535/* For CPUs without lwl and ldl instructions */
    536#define  _LoadWU(addr, value, res, type) \
    537do {                                                \
    538	__asm__ __volatile__ (			    \
    539		".set\tpush\n\t"		    \
    540		".set\tnoat\n\t"		    \
    541		"1:"type##_lbu("%0", "3(%2)")"\n\t" \
    542		"2:"type##_lbu("$1", "2(%2)")"\n\t" \
    543		"sll\t%0, 0x8\n\t"		    \
    544		"or\t%0, $1\n\t"		    \
    545		"3:"type##_lbu("$1", "1(%2)")"\n\t" \
    546		"sll\t%0, 0x8\n\t"		    \
    547		"or\t%0, $1\n\t"		    \
    548		"4:"type##_lbu("$1", "0(%2)")"\n\t" \
    549		"sll\t%0, 0x8\n\t"		    \
    550		"or\t%0, $1\n\t"		    \
    551		"li\t%1, 0\n"			    \
    552		".set\tpop\n"			    \
    553		"10:\n\t"			    \
    554		".insn\n\t"			    \
    555		".section\t.fixup,\"ax\"\n\t"	    \
    556		"11:\tli\t%1, %3\n\t"		    \
    557		"j\t10b\n\t"			    \
    558		".previous\n\t"			    \
    559		".section\t__ex_table,\"a\"\n\t"    \
    560		STR(PTR_WD)"\t1b, 11b\n\t"	    \
    561		STR(PTR_WD)"\t2b, 11b\n\t"	    \
    562		STR(PTR_WD)"\t3b, 11b\n\t"	    \
    563		STR(PTR_WD)"\t4b, 11b\n\t"	    \
    564		".previous"			    \
    565		: "=&r" (value), "=r" (res)	    \
    566		: "r" (addr), "i" (-EFAULT));       \
    567} while (0)
    568
    569#define  _LoadDW(addr, value, res)  \
    570do {                                                \
    571	__asm__ __volatile__ (			    \
    572		".set\tpush\n\t"		    \
    573		".set\tnoat\n\t"		    \
    574		"1:lb\t%0, 7(%2)\n\t"		    \
    575		"2:lbu\t$1, 6(%2)\n\t"		    \
    576		"dsll\t%0, 0x8\n\t"		    \
    577		"or\t%0, $1\n\t"		    \
    578		"3:lbu\t$1, 5(%2)\n\t"		    \
    579		"dsll\t%0, 0x8\n\t"		    \
    580		"or\t%0, $1\n\t"		    \
    581		"4:lbu\t$1, 4(%2)\n\t"		    \
    582		"dsll\t%0, 0x8\n\t"		    \
    583		"or\t%0, $1\n\t"		    \
    584		"5:lbu\t$1, 3(%2)\n\t"		    \
    585		"dsll\t%0, 0x8\n\t"		    \
    586		"or\t%0, $1\n\t"		    \
    587		"6:lbu\t$1, 2(%2)\n\t"		    \
    588		"dsll\t%0, 0x8\n\t"		    \
    589		"or\t%0, $1\n\t"		    \
    590		"7:lbu\t$1, 1(%2)\n\t"		    \
    591		"dsll\t%0, 0x8\n\t"		    \
    592		"or\t%0, $1\n\t"		    \
    593		"8:lbu\t$1, 0(%2)\n\t"		    \
    594		"dsll\t%0, 0x8\n\t"		    \
    595		"or\t%0, $1\n\t"		    \
    596		"li\t%1, 0\n"			    \
    597		".set\tpop\n\t"			    \
    598		"10:\n\t"			    \
    599		".insn\n\t"			    \
    600		".section\t.fixup,\"ax\"\n\t"	    \
    601		"11:\tli\t%1, %3\n\t"		    \
    602		"j\t10b\n\t"			    \
    603		".previous\n\t"			    \
    604		".section\t__ex_table,\"a\"\n\t"    \
    605		STR(PTR_WD)"\t1b, 11b\n\t"	    \
    606		STR(PTR_WD)"\t2b, 11b\n\t"	    \
    607		STR(PTR_WD)"\t3b, 11b\n\t"	    \
    608		STR(PTR_WD)"\t4b, 11b\n\t"	    \
    609		STR(PTR_WD)"\t5b, 11b\n\t"	    \
    610		STR(PTR_WD)"\t6b, 11b\n\t"	    \
    611		STR(PTR_WD)"\t7b, 11b\n\t"	    \
    612		STR(PTR_WD)"\t8b, 11b\n\t"	    \
    613		".previous"			    \
    614		: "=&r" (value), "=r" (res)	    \
    615		: "r" (addr), "i" (-EFAULT));       \
    616} while (0)
    617#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
    618
    619#define  _StoreHW(addr, value, res, type) \
    620do {                                                 \
    621	__asm__ __volatile__ (                      \
    622		".set\tnoat\n"                      \
    623		"1:\t"type##_sb("%1", "0(%2)")"\n"  \
    624		"srl\t$1,%1, 0x8\n"                 \
    625		"2:\t"type##_sb("$1", "1(%2)")"\n"  \
    626		".set\tat\n\t"                      \
    627		"li\t%0, 0\n"                       \
    628		"3:\n\t"                            \
    629		".insn\n\t"                         \
    630		".section\t.fixup,\"ax\"\n\t"       \
    631		"4:\tli\t%0, %3\n\t"                \
    632		"j\t3b\n\t"                         \
    633		".previous\n\t"                     \
    634		".section\t__ex_table,\"a\"\n\t"    \
    635		STR(PTR_WD)"\t1b, 4b\n\t"           \
    636		STR(PTR_WD)"\t2b, 4b\n\t"           \
    637		".previous"                         \
    638		: "=r" (res)                        \
    639		: "r" (value), "r" (addr), "i" (-EFAULT));\
    640} while (0)
    641
    642#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
    643#define  _StoreW(addr, value, res, type)  \
    644do {                                                \
    645	__asm__ __volatile__ (                      \
    646		"1:\t"type##_swl("%1", "3(%2)")"\n" \
    647		"2:\t"type##_swr("%1", "(%2)")"\n\t"\
    648		"li\t%0, 0\n"                       \
    649		"3:\n\t"                            \
    650		".insn\n\t"                         \
    651		".section\t.fixup,\"ax\"\n\t"       \
    652		"4:\tli\t%0, %3\n\t"                \
    653		"j\t3b\n\t"                         \
    654		".previous\n\t"                     \
    655		".section\t__ex_table,\"a\"\n\t"    \
    656		STR(PTR_WD)"\t1b, 4b\n\t"           \
    657		STR(PTR_WD)"\t2b, 4b\n\t"           \
    658		".previous"                         \
    659		: "=r" (res)                                \
    660		: "r" (value), "r" (addr), "i" (-EFAULT));  \
    661} while (0)
    662
    663#define  _StoreDW(addr, value, res) \
    664do {                                                \
    665	__asm__ __volatile__ (                      \
    666		"1:\tsdl\t%1, 7(%2)\n"              \
    667		"2:\tsdr\t%1, (%2)\n\t"             \
    668		"li\t%0, 0\n"                       \
    669		"3:\n\t"                            \
    670		".insn\n\t"                         \
    671		".section\t.fixup,\"ax\"\n\t"       \
    672		"4:\tli\t%0, %3\n\t"                \
    673		"j\t3b\n\t"                         \
    674		".previous\n\t"                     \
    675		".section\t__ex_table,\"a\"\n\t"    \
    676		STR(PTR_WD)"\t1b, 4b\n\t"           \
    677		STR(PTR_WD)"\t2b, 4b\n\t"           \
    678		".previous"                         \
    679		: "=r" (res)                                \
    680		: "r" (value), "r" (addr), "i" (-EFAULT));  \
    681} while (0)
    682
    683#else /* CONFIG_CPU_NO_LOAD_STORE_LR */
    684/* For CPUs without swl and sdl instructions */
    685#define  _StoreW(addr, value, res, type)  \
    686do {                                                \
    687	__asm__ __volatile__ (                      \
    688		".set\tpush\n\t"		    \
    689		".set\tnoat\n\t"		    \
    690		"1:"type##_sb("%1", "0(%2)")"\n\t"  \
    691		"srl\t$1, %1, 0x8\n\t"		    \
    692		"2:"type##_sb("$1", "1(%2)")"\n\t"  \
    693		"srl\t$1, $1,  0x8\n\t"		    \
    694		"3:"type##_sb("$1", "2(%2)")"\n\t"  \
    695		"srl\t$1, $1, 0x8\n\t"		    \
    696		"4:"type##_sb("$1", "3(%2)")"\n\t"  \
    697		".set\tpop\n\t"			    \
    698		"li\t%0, 0\n"			    \
    699		"10:\n\t"			    \
    700		".insn\n\t"			    \
    701		".section\t.fixup,\"ax\"\n\t"	    \
    702		"11:\tli\t%0, %3\n\t"		    \
    703		"j\t10b\n\t"			    \
    704		".previous\n\t"			    \
    705		".section\t__ex_table,\"a\"\n\t"    \
    706		STR(PTR_WD)"\t1b, 11b\n\t"	    \
    707		STR(PTR_WD)"\t2b, 11b\n\t"	    \
    708		STR(PTR_WD)"\t3b, 11b\n\t"	    \
    709		STR(PTR_WD)"\t4b, 11b\n\t"	    \
    710		".previous"			    \
    711		: "=&r" (res)				    \
    712		: "r" (value), "r" (addr), "i" (-EFAULT)    \
    713		: "memory");                                \
    714} while (0)
    715
    716#define  _StoreDW(addr, value, res) \
    717do {                                                \
    718	__asm__ __volatile__ (                      \
    719		".set\tpush\n\t"		    \
    720		".set\tnoat\n\t"		    \
    721		"1:sb\t%1, 0(%2)\n\t"		    \
    722		"dsrl\t$1, %1, 0x8\n\t"		    \
    723		"2:sb\t$1, 1(%2)\n\t"		    \
    724		"dsrl\t$1, $1, 0x8\n\t"		    \
    725		"3:sb\t$1, 2(%2)\n\t"		    \
    726		"dsrl\t$1, $1, 0x8\n\t"		    \
    727		"4:sb\t$1, 3(%2)\n\t"		    \
    728		"dsrl\t$1, $1, 0x8\n\t"		    \
    729		"5:sb\t$1, 4(%2)\n\t"		    \
    730		"dsrl\t$1, $1, 0x8\n\t"		    \
    731		"6:sb\t$1, 5(%2)\n\t"		    \
    732		"dsrl\t$1, $1, 0x8\n\t"		    \
    733		"7:sb\t$1, 6(%2)\n\t"		    \
    734		"dsrl\t$1, $1, 0x8\n\t"		    \
    735		"8:sb\t$1, 7(%2)\n\t"		    \
    736		"dsrl\t$1, $1, 0x8\n\t"		    \
    737		".set\tpop\n\t"			    \
    738		"li\t%0, 0\n"			    \
    739		"10:\n\t"			    \
    740		".insn\n\t"			    \
    741		".section\t.fixup,\"ax\"\n\t"	    \
    742		"11:\tli\t%0, %3\n\t"		    \
    743		"j\t10b\n\t"			    \
    744		".previous\n\t"			    \
    745		".section\t__ex_table,\"a\"\n\t"    \
    746		STR(PTR_WD)"\t1b, 11b\n\t"	    \
    747		STR(PTR_WD)"\t2b, 11b\n\t"	    \
    748		STR(PTR_WD)"\t3b, 11b\n\t"	    \
    749		STR(PTR_WD)"\t4b, 11b\n\t"	    \
    750		STR(PTR_WD)"\t5b, 11b\n\t"	    \
    751		STR(PTR_WD)"\t6b, 11b\n\t"	    \
    752		STR(PTR_WD)"\t7b, 11b\n\t"	    \
    753		STR(PTR_WD)"\t8b, 11b\n\t"	    \
    754		".previous"			    \
    755		: "=&r" (res)				    \
    756		: "r" (value), "r" (addr), "i" (-EFAULT)    \
    757		: "memory");                                \
    758} while (0)
    759
    760#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
    761#endif
    762
    763#define LoadHWU(addr, value, res)	_LoadHWU(addr, value, res, kernel)
    764#define LoadHWUE(addr, value, res)	_LoadHWU(addr, value, res, user)
    765#define LoadWU(addr, value, res)	_LoadWU(addr, value, res, kernel)
    766#define LoadWUE(addr, value, res)	_LoadWU(addr, value, res, user)
    767#define LoadHW(addr, value, res)	_LoadHW(addr, value, res, kernel)
    768#define LoadHWE(addr, value, res)	_LoadHW(addr, value, res, user)
    769#define LoadW(addr, value, res)		_LoadW(addr, value, res, kernel)
    770#define LoadWE(addr, value, res)	_LoadW(addr, value, res, user)
    771#define LoadDW(addr, value, res)	_LoadDW(addr, value, res)
    772
    773#define StoreHW(addr, value, res)	_StoreHW(addr, value, res, kernel)
    774#define StoreHWE(addr, value, res)	_StoreHW(addr, value, res, user)
    775#define StoreW(addr, value, res)	_StoreW(addr, value, res, kernel)
    776#define StoreWE(addr, value, res)	_StoreW(addr, value, res, user)
    777#define StoreDW(addr, value, res)	_StoreDW(addr, value, res)
    778
    779#endif /* _ASM_MIPS_UNALIGNED_EMUL_H */