linux/arch/sparc/net/bpf_jit_asm.S
<<
>>
Prefs
   1#include <asm/ptrace.h>
   2
   3#include "bpf_jit.h"
   4
   5#ifdef CONFIG_SPARC64
   6#define SAVE_SZ         176
   7#define SCRATCH_OFF     STACK_BIAS + 128
   8#define BE_PTR(label)   be,pn %xcc, label
   9#define SIGN_EXTEND(reg)        sra reg, 0, reg
  10#else
  11#define SAVE_SZ         96
  12#define SCRATCH_OFF     72
  13#define BE_PTR(label)   be label
  14#define SIGN_EXTEND(reg)
  15#endif
  16
  17#define SKF_MAX_NEG_OFF (-0x200000) /* SKF_LL_OFF from filter.h */
  18
  19        .text
  20        .globl  bpf_jit_load_word
  21bpf_jit_load_word:
  22        cmp     r_OFF, 0
  23        bl      bpf_slow_path_word_neg
  24         nop
  25        .globl  bpf_jit_load_word_positive_offset
  26bpf_jit_load_word_positive_offset:
  27        sub     r_HEADLEN, r_OFF, r_TMP
  28        cmp     r_TMP, 3
  29        ble     bpf_slow_path_word
  30         add    r_SKB_DATA, r_OFF, r_TMP
  31        andcc   r_TMP, 3, %g0
  32        bne     load_word_unaligned
  33         nop
  34        retl
  35         ld     [r_TMP], r_A
  36load_word_unaligned:
  37        ldub    [r_TMP + 0x0], r_OFF
  38        ldub    [r_TMP + 0x1], r_TMP2
  39        sll     r_OFF, 8, r_OFF
  40        or      r_OFF, r_TMP2, r_OFF
  41        ldub    [r_TMP + 0x2], r_TMP2
  42        sll     r_OFF, 8, r_OFF
  43        or      r_OFF, r_TMP2, r_OFF
  44        ldub    [r_TMP + 0x3], r_TMP2
  45        sll     r_OFF, 8, r_OFF
  46        retl
  47         or     r_OFF, r_TMP2, r_A
  48
  49        .globl  bpf_jit_load_half
  50bpf_jit_load_half:
  51        cmp     r_OFF, 0
  52        bl      bpf_slow_path_half_neg
  53         nop
  54        .globl  bpf_jit_load_half_positive_offset
  55bpf_jit_load_half_positive_offset:
  56        sub     r_HEADLEN, r_OFF, r_TMP
  57        cmp     r_TMP, 1
  58        ble     bpf_slow_path_half
  59         add    r_SKB_DATA, r_OFF, r_TMP
  60        andcc   r_TMP, 1, %g0
  61        bne     load_half_unaligned
  62         nop
  63        retl
  64         lduh   [r_TMP], r_A
  65load_half_unaligned:
  66        ldub    [r_TMP + 0x0], r_OFF
  67        ldub    [r_TMP + 0x1], r_TMP2
  68        sll     r_OFF, 8, r_OFF
  69        retl
  70         or     r_OFF, r_TMP2, r_A
  71
  72        .globl  bpf_jit_load_byte
  73bpf_jit_load_byte:
  74        cmp     r_OFF, 0
  75        bl      bpf_slow_path_byte_neg
  76         nop
  77        .globl  bpf_jit_load_byte_positive_offset
  78bpf_jit_load_byte_positive_offset:
  79        cmp     r_OFF, r_HEADLEN
  80        bge     bpf_slow_path_byte
  81         nop
  82        retl
  83         ldub   [r_SKB_DATA + r_OFF], r_A
  84
  85        .globl  bpf_jit_load_byte_msh
  86bpf_jit_load_byte_msh:
  87        cmp     r_OFF, 0
  88        bl      bpf_slow_path_byte_msh_neg
  89         nop
  90        .globl  bpf_jit_load_byte_msh_positive_offset
  91bpf_jit_load_byte_msh_positive_offset:
  92        cmp     r_OFF, r_HEADLEN
  93        bge     bpf_slow_path_byte_msh
  94         nop
  95        ldub    [r_SKB_DATA + r_OFF], r_OFF
  96        and     r_OFF, 0xf, r_OFF
  97        retl
  98         sll    r_OFF, 2, r_X
  99
 100#define bpf_slow_path_common(LEN)       \
 101        save    %sp, -SAVE_SZ, %sp;     \
 102        mov     %i0, %o0;               \
 103        mov     r_OFF, %o1;             \
 104        add     %fp, SCRATCH_OFF, %o2;  \
 105        call    skb_copy_bits;          \
 106         mov    (LEN), %o3;             \
 107        cmp     %o0, 0;                 \
 108        restore;
 109
 110bpf_slow_path_word:
 111        bpf_slow_path_common(4)
 112        bl      bpf_error
 113         ld     [%sp + SCRATCH_OFF], r_A
 114        retl
 115         nop
 116bpf_slow_path_half:
 117        bpf_slow_path_common(2)
 118        bl      bpf_error
 119         lduh   [%sp + SCRATCH_OFF], r_A
 120        retl
 121         nop
 122bpf_slow_path_byte:
 123        bpf_slow_path_common(1)
 124        bl      bpf_error
 125         ldub   [%sp + SCRATCH_OFF], r_A
 126        retl
 127         nop
 128bpf_slow_path_byte_msh:
 129        bpf_slow_path_common(1)
 130        bl      bpf_error
 131         ldub   [%sp + SCRATCH_OFF], r_A
 132        and     r_OFF, 0xf, r_OFF
 133        retl
 134         sll    r_OFF, 2, r_X
 135
 136#define bpf_negative_common(LEN)                        \
 137        save    %sp, -SAVE_SZ, %sp;                     \
 138        mov     %i0, %o0;                               \
 139        mov     r_OFF, %o1;                             \
 140        SIGN_EXTEND(%o1);                               \
 141        call    bpf_internal_load_pointer_neg_helper;   \
 142         mov    (LEN), %o2;                             \
 143        mov     %o0, r_TMP;                             \
 144        cmp     %o0, 0;                                 \
 145        BE_PTR(bpf_error);                              \
 146         restore;
 147
 148bpf_slow_path_word_neg:
 149        sethi   %hi(SKF_MAX_NEG_OFF), r_TMP
 150        cmp     r_OFF, r_TMP
 151        bl      bpf_error
 152         nop
 153        .globl  bpf_jit_load_word_negative_offset
 154bpf_jit_load_word_negative_offset:
 155        bpf_negative_common(4)
 156        andcc   r_TMP, 3, %g0
 157        bne     load_word_unaligned
 158         nop
 159        retl
 160         ld     [r_TMP], r_A
 161
 162bpf_slow_path_half_neg:
 163        sethi   %hi(SKF_MAX_NEG_OFF), r_TMP
 164        cmp     r_OFF, r_TMP
 165        bl      bpf_error
 166         nop
 167        .globl  bpf_jit_load_half_negative_offset
 168bpf_jit_load_half_negative_offset:
 169        bpf_negative_common(2)
 170        andcc   r_TMP, 1, %g0
 171        bne     load_half_unaligned
 172         nop
 173        retl
 174         lduh   [r_TMP], r_A
 175
 176bpf_slow_path_byte_neg:
 177        sethi   %hi(SKF_MAX_NEG_OFF), r_TMP
 178        cmp     r_OFF, r_TMP
 179        bl      bpf_error
 180         nop
 181        .globl  bpf_jit_load_byte_negative_offset
 182bpf_jit_load_byte_negative_offset:
 183        bpf_negative_common(1)
 184        retl
 185         ldub   [r_TMP], r_A
 186
 187bpf_slow_path_byte_msh_neg:
 188        sethi   %hi(SKF_MAX_NEG_OFF), r_TMP
 189        cmp     r_OFF, r_TMP
 190        bl      bpf_error
 191         nop
 192        .globl  bpf_jit_load_byte_msh_negative_offset
 193bpf_jit_load_byte_msh_negative_offset:
 194        bpf_negative_common(1)
 195        ldub    [r_TMP], r_OFF
 196        and     r_OFF, 0xf, r_OFF
 197        retl
 198         sll    r_OFF, 2, r_X
 199
 200bpf_error:
 201        /* Make the JIT program return zero.  The JIT epilogue
 202         * stores away the original %o7 into r_saved_O7.  The
 203         * normal leaf function return is to use "retl" which
 204         * would evalute to "jmpl %o7 + 8, %g0" but we want to
 205         * use the saved value thus the sequence you see here.
 206         */
 207        jmpl    r_saved_O7 + 8, %g0
 208         clr    %o0
 209