Merge remote-tracking branch 'airlied/drm-next' into drm-misc-next
[sfrench/cifs-2.6.git] / arch / alpha / include / asm / extable.h
1 #ifndef _ASM_EXTABLE_H
2 #define _ASM_EXTABLE_H
3
4 /*
5  * About the exception table:
6  *
7  * - insn is a 32-bit pc-relative offset from the faulting insn.
8  * - nextinsn is a 16-bit offset off of the faulting instruction
9  *   (not off of the *next* instruction as branches are).
10  * - errreg is the register in which to place -EFAULT.
11  * - valreg is the final target register for the load sequence
12  *   and will be zeroed.
13  *
14  * Either errreg or valreg may be $31, in which case nothing happens.
15  *
16  * The exception fixup information "just so happens" to be arranged
17  * as in a MEM format instruction.  This lets us emit our three
18  * values like so:
19  *
20  *      lda valreg, nextinsn(errreg)
21  *
22  */
23
24 struct exception_table_entry
25 {
26         signed int insn;
27         union exception_fixup {
28                 unsigned unit;
29                 struct {
30                         signed int nextinsn : 16;
31                         unsigned int errreg : 5;
32                         unsigned int valreg : 5;
33                 } bits;
34         } fixup;
35 };
36
37 /* Returns the new pc */
38 #define fixup_exception(map_reg, _fixup, pc)                    \
39 ({                                                              \
40         if ((_fixup)->fixup.bits.valreg != 31)                  \
41                 map_reg((_fixup)->fixup.bits.valreg) = 0;       \
42         if ((_fixup)->fixup.bits.errreg != 31)                  \
43                 map_reg((_fixup)->fixup.bits.errreg) = -EFAULT; \
44         (pc) + (_fixup)->fixup.bits.nextinsn;                   \
45 })
46
47 #define ARCH_HAS_RELATIVE_EXTABLE
48
49 #define swap_ex_entry_fixup(a, b, tmp, delta)                   \
50         do {                                                    \
51                 (a)->fixup.unit = (b)->fixup.unit;              \
52                 (b)->fixup.unit = (tmp).fixup.unit;             \
53         } while (0)
54
55 #endif