Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _ASM_EXTABLE_H
0003 #define _ASM_EXTABLE_H
0004 
0005 /*
0006  * About the exception table:
0007  *
0008  * - insn is a 32-bit pc-relative offset from the faulting insn.
0009  * - nextinsn is a 16-bit offset off of the faulting instruction
0010  *   (not off of the *next* instruction as branches are).
0011  * - errreg is the register in which to place -EFAULT.
0012  * - valreg is the final target register for the load sequence
0013  *   and will be zeroed.
0014  *
0015  * Either errreg or valreg may be $31, in which case nothing happens.
0016  *
0017  * The exception fixup information "just so happens" to be arranged
0018  * as in a MEM format instruction.  This lets us emit our three
0019  * values like so:
0020  *
0021  *      lda valreg, nextinsn(errreg)
0022  *
0023  */
0024 
0025 struct exception_table_entry
0026 {
0027     signed int insn;
0028     union exception_fixup {
0029         unsigned unit;
0030         struct {
0031             signed int nextinsn : 16;
0032             unsigned int errreg : 5;
0033             unsigned int valreg : 5;
0034         } bits;
0035     } fixup;
0036 };
0037 
0038 /* Returns the new pc */
0039 #define fixup_exception(map_reg, _fixup, pc)            \
0040 ({                              \
0041     if ((_fixup)->fixup.bits.valreg != 31)          \
0042         map_reg((_fixup)->fixup.bits.valreg) = 0;   \
0043     if ((_fixup)->fixup.bits.errreg != 31)          \
0044         map_reg((_fixup)->fixup.bits.errreg) = -EFAULT; \
0045     (pc) + (_fixup)->fixup.bits.nextinsn;           \
0046 })
0047 
0048 #define ARCH_HAS_RELATIVE_EXTABLE
0049 
0050 #define swap_ex_entry_fixup(a, b, tmp, delta)           \
0051     do {                            \
0052         (a)->fixup.unit = (b)->fixup.unit;      \
0053         (b)->fixup.unit = (tmp).fixup.unit;     \
0054     } while (0)
0055 
0056 #endif