1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Just-In-Time compiler for BPF filters on MIPS 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (c) 2014 Imagination Technologies Ltd. 6*4882a593Smuzhiyun * Author: Markos Chandras <markos.chandras@imgtec.com> 7*4882a593Smuzhiyun */ 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #ifndef BPF_JIT_MIPS_OP_H 10*4882a593Smuzhiyun #define BPF_JIT_MIPS_OP_H 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun /* Registers used by JIT */ 13*4882a593Smuzhiyun #define MIPS_R_ZERO 0 14*4882a593Smuzhiyun #define MIPS_R_V0 2 15*4882a593Smuzhiyun #define MIPS_R_A0 4 16*4882a593Smuzhiyun #define MIPS_R_A1 5 17*4882a593Smuzhiyun #define MIPS_R_T4 12 18*4882a593Smuzhiyun #define MIPS_R_T5 13 19*4882a593Smuzhiyun #define MIPS_R_T6 14 20*4882a593Smuzhiyun #define MIPS_R_T7 15 21*4882a593Smuzhiyun #define MIPS_R_S0 16 22*4882a593Smuzhiyun #define MIPS_R_S1 17 23*4882a593Smuzhiyun #define MIPS_R_S2 18 24*4882a593Smuzhiyun #define MIPS_R_S3 19 25*4882a593Smuzhiyun #define MIPS_R_S4 20 26*4882a593Smuzhiyun #define MIPS_R_S5 21 27*4882a593Smuzhiyun #define MIPS_R_S6 22 28*4882a593Smuzhiyun #define MIPS_R_S7 23 29*4882a593Smuzhiyun #define MIPS_R_SP 29 30*4882a593Smuzhiyun #define MIPS_R_RA 31 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun /* Conditional codes */ 33*4882a593Smuzhiyun #define MIPS_COND_EQ 0x1 34*4882a593Smuzhiyun #define MIPS_COND_GE (0x1 << 1) 35*4882a593Smuzhiyun #define MIPS_COND_GT (0x1 << 2) 36*4882a593Smuzhiyun #define MIPS_COND_NE (0x1 << 3) 37*4882a593Smuzhiyun #define MIPS_COND_ALL (0x1 << 4) 38*4882a593Smuzhiyun /* Conditionals on X register or K immediate */ 39*4882a593Smuzhiyun #define MIPS_COND_X (0x1 << 5) 40*4882a593Smuzhiyun #define MIPS_COND_K (0x1 << 6) 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun #define r_ret MIPS_R_V0 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun /* 45*4882a593Smuzhiyun * Use 2 scratch registers to avoid pipeline interlocks. 46*4882a593Smuzhiyun * There is no overhead during epilogue and prologue since 47*4882a593Smuzhiyun * any of the $s0-$s6 registers will only be preserved if 48*4882a593Smuzhiyun * they are going to actually be used. 49*4882a593Smuzhiyun */ 50*4882a593Smuzhiyun #define r_skb_hl MIPS_R_S0 /* skb header length */ 51*4882a593Smuzhiyun #define r_skb_data MIPS_R_S1 /* skb actual data */ 52*4882a593Smuzhiyun #define r_off MIPS_R_S2 53*4882a593Smuzhiyun #define r_A MIPS_R_S3 54*4882a593Smuzhiyun #define r_X MIPS_R_S4 55*4882a593Smuzhiyun #define r_skb MIPS_R_S5 56*4882a593Smuzhiyun #define r_M MIPS_R_S6 57*4882a593Smuzhiyun #define r_skb_len MIPS_R_S7 58*4882a593Smuzhiyun #define r_s0 MIPS_R_T4 /* scratch reg 1 */ 59*4882a593Smuzhiyun #define r_s1 MIPS_R_T5 /* scratch reg 2 */ 60*4882a593Smuzhiyun #define r_tmp_imm MIPS_R_T6 /* No need to preserve this */ 61*4882a593Smuzhiyun #define r_tmp MIPS_R_T7 /* No need to preserve this */ 62*4882a593Smuzhiyun #define r_zero MIPS_R_ZERO 63*4882a593Smuzhiyun #define r_sp MIPS_R_SP 64*4882a593Smuzhiyun #define r_ra MIPS_R_RA 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun #ifndef __ASSEMBLY__ 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun /* Declare ASM helpers */ 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun #define DECLARE_LOAD_FUNC(func) \ 71*4882a593Smuzhiyun extern u8 func(unsigned long *skb, int offset); \ 72*4882a593Smuzhiyun extern u8 func##_negative(unsigned long *skb, int offset); \ 73*4882a593Smuzhiyun extern u8 func##_positive(unsigned long *skb, int offset) 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun DECLARE_LOAD_FUNC(sk_load_word); 76*4882a593Smuzhiyun DECLARE_LOAD_FUNC(sk_load_half); 77*4882a593Smuzhiyun DECLARE_LOAD_FUNC(sk_load_byte); 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun #endif 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun #endif /* BPF_JIT_MIPS_OP_H */ 82