linux/arch/powerpc/net/bpf_jit32.h
<<
>>
Prefs
   1/*
   2 * bpf_jit32.h: BPF JIT compiler for PPC
   3 *
   4 * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation
   5 *
   6 * Split from bpf_jit.h
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License
  10 * as published by the Free Software Foundation; version 2
  11 * of the License.
  12 */
  13#ifndef _BPF_JIT32_H
  14#define _BPF_JIT32_H
  15
  16#include "bpf_jit.h"
  17
  18#ifdef CONFIG_PPC64
  19#define BPF_PPC_STACK_R3_OFF    48
  20#define BPF_PPC_STACK_LOCALS    32
  21#define BPF_PPC_STACK_BASIC     (48+64)
  22#define BPF_PPC_STACK_SAVE      (18*8)
  23#define BPF_PPC_STACKFRAME      (BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \
  24                                 BPF_PPC_STACK_SAVE)
  25#define BPF_PPC_SLOWPATH_FRAME  (48+64)
  26#else
  27#define BPF_PPC_STACK_R3_OFF    24
  28#define BPF_PPC_STACK_LOCALS    16
  29#define BPF_PPC_STACK_BASIC     (24+32)
  30#define BPF_PPC_STACK_SAVE      (18*4)
  31#define BPF_PPC_STACKFRAME      (BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \
  32                                 BPF_PPC_STACK_SAVE)
  33#define BPF_PPC_SLOWPATH_FRAME  (24+32)
  34#endif
  35
  36#define REG_SZ         (BITS_PER_LONG/8)
  37
  38/*
  39 * Generated code register usage:
  40 *
  41 * As normal PPC C ABI (e.g. r1=sp, r2=TOC), with:
  42 *
  43 * skb          r3      (Entry parameter)
  44 * A register   r4
  45 * X register   r5
  46 * addr param   r6
  47 * r7-r10       scratch
  48 * skb->data    r14
  49 * skb headlen  r15     (skb->len - skb->data_len)
  50 * m[0]         r16
  51 * m[...]       ...
  52 * m[15]        r31
  53 */
  54#define r_skb           3
  55#define r_ret           3
  56#define r_A             4
  57#define r_X             5
  58#define r_addr          6
  59#define r_scratch1      7
  60#define r_scratch2      8
  61#define r_D             14
  62#define r_HL            15
  63#define r_M             16
  64
  65#ifndef __ASSEMBLY__
  66
  67/*
  68 * Assembly helpers from arch/powerpc/net/bpf_jit.S:
  69 */
  70#define DECLARE_LOAD_FUNC(func) \
  71        extern u8 func[], func##_negative_offset[], func##_positive_offset[]
  72
  73DECLARE_LOAD_FUNC(sk_load_word);
  74DECLARE_LOAD_FUNC(sk_load_half);
  75DECLARE_LOAD_FUNC(sk_load_byte);
  76DECLARE_LOAD_FUNC(sk_load_byte_msh);
  77
  78#define PPC_LBZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LBZ(r, base, i);   \
  79                else {  PPC_ADDIS(r, base, IMM_HA(i));                        \
  80                        PPC_LBZ(r, r, IMM_L(i)); } } while(0)
  81
  82#define PPC_LD_OFFS(r, base, i) do { if ((i) < 32768) PPC_LD(r, base, i);     \
  83                else {  PPC_ADDIS(r, base, IMM_HA(i));                        \
  84                        PPC_LD(r, r, IMM_L(i)); } } while(0)
  85
  86#define PPC_LWZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LWZ(r, base, i);   \
  87                else {  PPC_ADDIS(r, base, IMM_HA(i));                        \
  88                        PPC_LWZ(r, r, IMM_L(i)); } } while(0)
  89
  90#define PPC_LHZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LHZ(r, base, i);   \
  91                else {  PPC_ADDIS(r, base, IMM_HA(i));                        \
  92                        PPC_LHZ(r, r, IMM_L(i)); } } while(0)
  93
  94#ifdef CONFIG_PPC64
  95#define PPC_LL_OFFS(r, base, i) do { PPC_LD_OFFS(r, base, i); } while(0)
  96#else
  97#define PPC_LL_OFFS(r, base, i) do { PPC_LWZ_OFFS(r, base, i); } while(0)
  98#endif
  99
 100#ifdef CONFIG_SMP
 101#ifdef CONFIG_PPC64
 102#define PPC_BPF_LOAD_CPU(r)             \
 103        do { BUILD_BUG_ON(FIELD_SIZEOF(struct paca_struct, paca_index) != 2);   \
 104                PPC_LHZ_OFFS(r, 13, offsetof(struct paca_struct, paca_index));  \
 105        } while (0)
 106#else
 107#define PPC_BPF_LOAD_CPU(r)     \
 108        do { BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, cpu) != 4);          \
 109                PPC_LHZ_OFFS(r, (1 & ~(THREAD_SIZE - 1)),                       \
 110                                offsetof(struct thread_info, cpu));             \
 111        } while(0)
 112#endif
 113#else
 114#define PPC_BPF_LOAD_CPU(r) do { PPC_LI(r, 0); } while(0)
 115#endif
 116
 117#define PPC_LHBRX_OFFS(r, base, i) \
 118                do { PPC_LI32(r, i); PPC_LHBRX(r, r, base); } while(0)
 119#ifdef __LITTLE_ENDIAN__
 120#define PPC_NTOHS_OFFS(r, base, i)      PPC_LHBRX_OFFS(r, base, i)
 121#else
 122#define PPC_NTOHS_OFFS(r, base, i)      PPC_LHZ_OFFS(r, base, i)
 123#endif
 124
 125#define SEEN_DATAREF 0x10000 /* might call external helpers */
 126#define SEEN_XREG    0x20000 /* X reg is used */
 127#define SEEN_MEM     0x40000 /* SEEN_MEM+(1<<n) = use mem[n] for temporary
 128                              * storage */
 129#define SEEN_MEM_MSK 0x0ffff
 130
 131struct codegen_context {
 132        unsigned int seen;
 133        unsigned int idx;
 134        int pc_ret0; /* bpf index of first RET #0 instruction (if any) */
 135};
 136
 137#endif
 138
 139#endif
 140