s390/bpf,jit: improve code generation
Make use of new immediate instructions that came with the extended immediate and general instruction extension facilities. Reviewed-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
committed by
Martin Schwidefsky
parent
c10302efe5
commit
68d9884dbc
@ -10,6 +10,7 @@
|
|||||||
#include <linux/filter.h>
|
#include <linux/filter.h>
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
|
#include <asm/facility.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Conventions:
|
* Conventions:
|
||||||
@ -114,6 +115,12 @@ struct bpf_jit {
|
|||||||
EMIT6(op1 | __disp, op2); \
|
EMIT6(op1 | __disp, op2); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define EMIT6_IMM(op, imm) \
|
||||||
|
({ \
|
||||||
|
unsigned int __imm = (imm); \
|
||||||
|
EMIT6(op | (__imm >> 16), __imm & 0xffff); \
|
||||||
|
})
|
||||||
|
|
||||||
#define EMIT_CONST(val) \
|
#define EMIT_CONST(val) \
|
||||||
({ \
|
({ \
|
||||||
unsigned int ret; \
|
unsigned int ret; \
|
||||||
@ -276,6 +283,9 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
|
|||||||
if (K <= 16383)
|
if (K <= 16383)
|
||||||
/* ahi %r5,<K> */
|
/* ahi %r5,<K> */
|
||||||
EMIT4_IMM(0xa75a0000, K);
|
EMIT4_IMM(0xa75a0000, K);
|
||||||
|
else if (test_facility(21))
|
||||||
|
/* alfi %r5,<K> */
|
||||||
|
EMIT6_IMM(0xc25b0000, K);
|
||||||
else
|
else
|
||||||
/* a %r5,<d(K)>(%r13) */
|
/* a %r5,<d(K)>(%r13) */
|
||||||
EMIT4_DISP(0x5a50d000, EMIT_CONST(K));
|
EMIT4_DISP(0x5a50d000, EMIT_CONST(K));
|
||||||
@ -291,6 +301,9 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
|
|||||||
if (K <= 16384)
|
if (K <= 16384)
|
||||||
/* ahi %r5,-K */
|
/* ahi %r5,-K */
|
||||||
EMIT4_IMM(0xa75a0000, -K);
|
EMIT4_IMM(0xa75a0000, -K);
|
||||||
|
else if (test_facility(21))
|
||||||
|
/* alfi %r5,-K */
|
||||||
|
EMIT6_IMM(0xc25b0000, -K);
|
||||||
else
|
else
|
||||||
/* s %r5,<d(K)>(%r13) */
|
/* s %r5,<d(K)>(%r13) */
|
||||||
EMIT4_DISP(0x5b50d000, EMIT_CONST(K));
|
EMIT4_DISP(0x5b50d000, EMIT_CONST(K));
|
||||||
@ -304,6 +317,9 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
|
|||||||
if (K <= 16383)
|
if (K <= 16383)
|
||||||
/* mhi %r5,K */
|
/* mhi %r5,K */
|
||||||
EMIT4_IMM(0xa75c0000, K);
|
EMIT4_IMM(0xa75c0000, K);
|
||||||
|
else if (test_facility(34))
|
||||||
|
/* msfi %r5,<K> */
|
||||||
|
EMIT6_IMM(0xc2510000, K);
|
||||||
else
|
else
|
||||||
/* ms %r5,<d(K)>(%r13) */
|
/* ms %r5,<d(K)>(%r13) */
|
||||||
EMIT4_DISP(0x7150d000, EMIT_CONST(K));
|
EMIT4_DISP(0x7150d000, EMIT_CONST(K));
|
||||||
@ -331,8 +347,12 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
|
|||||||
EMIT2(0x145c);
|
EMIT2(0x145c);
|
||||||
break;
|
break;
|
||||||
case BPF_S_ALU_AND_K: /* A &= K */
|
case BPF_S_ALU_AND_K: /* A &= K */
|
||||||
/* n %r5,<d(K)>(%r13) */
|
if (test_facility(21))
|
||||||
EMIT4_DISP(0x5450d000, EMIT_CONST(K));
|
/* nilf %r5,<K> */
|
||||||
|
EMIT6_IMM(0xc05b0000, K);
|
||||||
|
else
|
||||||
|
/* n %r5,<d(K)>(%r13) */
|
||||||
|
EMIT4_DISP(0x5450d000, EMIT_CONST(K));
|
||||||
break;
|
break;
|
||||||
case BPF_S_ALU_OR_X: /* A |= X */
|
case BPF_S_ALU_OR_X: /* A |= X */
|
||||||
jit->seen |= SEEN_XREG;
|
jit->seen |= SEEN_XREG;
|
||||||
@ -340,8 +360,12 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter,
|
|||||||
EMIT2(0x165c);
|
EMIT2(0x165c);
|
||||||
break;
|
break;
|
||||||
case BPF_S_ALU_OR_K: /* A |= K */
|
case BPF_S_ALU_OR_K: /* A |= K */
|
||||||
/* o %r5,<d(K)>(%r13) */
|
if (test_facility(21))
|
||||||
EMIT4_DISP(0x5650d000, EMIT_CONST(K));
|
/* oilf %r5,<K> */
|
||||||
|
EMIT6_IMM(0xc05d0000, K);
|
||||||
|
else
|
||||||
|
/* o %r5,<d(K)>(%r13) */
|
||||||
|
EMIT4_DISP(0x5650d000, EMIT_CONST(K));
|
||||||
break;
|
break;
|
||||||
case BPF_S_ALU_LSH_X: /* A <<= X; */
|
case BPF_S_ALU_LSH_X: /* A <<= X; */
|
||||||
jit->seen |= SEEN_XREG;
|
jit->seen |= SEEN_XREG;
|
||||||
@ -386,6 +410,9 @@ kbranch: /* Emit compare if the branch targets are different */
|
|||||||
if (K <= 16383)
|
if (K <= 16383)
|
||||||
/* chi %r5,<K> */
|
/* chi %r5,<K> */
|
||||||
EMIT4_IMM(0xa75e0000, K);
|
EMIT4_IMM(0xa75e0000, K);
|
||||||
|
else if (test_facility(21))
|
||||||
|
/* clfi %r5,<K> */
|
||||||
|
EMIT6_IMM(0xc25f0000, K);
|
||||||
else
|
else
|
||||||
/* c %r5,<d(K)>(%r13) */
|
/* c %r5,<d(K)>(%r13) */
|
||||||
EMIT4_DISP(0x5950d000, EMIT_CONST(K));
|
EMIT4_DISP(0x5950d000, EMIT_CONST(K));
|
||||||
@ -508,6 +535,9 @@ call_fn: /* lg %r1,<d(function)>(%r13) */
|
|||||||
if (K <= 16383)
|
if (K <= 16383)
|
||||||
/* lhi %r5,K */
|
/* lhi %r5,K */
|
||||||
EMIT4_IMM(0xa7580000, K);
|
EMIT4_IMM(0xa7580000, K);
|
||||||
|
else if (test_facility(21))
|
||||||
|
/* llilf %r5,<K> */
|
||||||
|
EMIT6_IMM(0xc05f0000, K);
|
||||||
else
|
else
|
||||||
/* l %r5,<d(K)>(%r13) */
|
/* l %r5,<d(K)>(%r13) */
|
||||||
EMIT4_DISP(0x5850d000, EMIT_CONST(K));
|
EMIT4_DISP(0x5850d000, EMIT_CONST(K));
|
||||||
@ -517,6 +547,9 @@ call_fn: /* lg %r1,<d(function)>(%r13) */
|
|||||||
if (K <= 16383)
|
if (K <= 16383)
|
||||||
/* lhi %r12,<K> */
|
/* lhi %r12,<K> */
|
||||||
EMIT4_IMM(0xa7c80000, K);
|
EMIT4_IMM(0xa7c80000, K);
|
||||||
|
else if (test_facility(21))
|
||||||
|
/* llilf %r12,<K> */
|
||||||
|
EMIT6_IMM(0xc0cf0000, K);
|
||||||
else
|
else
|
||||||
/* l %r12,<d(K)>(%r13) */
|
/* l %r12,<d(K)>(%r13) */
|
||||||
EMIT4_DISP(0x58c0d000, EMIT_CONST(K));
|
EMIT4_DISP(0x58c0d000, EMIT_CONST(K));
|
||||||
|
Reference in New Issue
Block a user