summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/net
diff options
context:
space:
mode:
authorNaveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>2016-06-22 18:25:02 +0200
committerMichael Ellerman <mpe@ellerman.id.au>2016-06-24 07:14:45 +0200
commitaaf2f7e09932a08c1287d8e4c602bccbe98f60a6 (patch)
tree22e8ec8fcb4fc3f35950e0cdfeba542323737c42 /arch/powerpc/net
parentpowerpc/powernv: set power_save func after the idle states are initialized (diff)
downloadlinux-aaf2f7e09932a08c1287d8e4c602bccbe98f60a6.tar.xz
linux-aaf2f7e09932a08c1287d8e4c602bccbe98f60a6.zip
powerpc/bpf/jit: Fix/enhance 32-bit Load Immediate implementation
The existing LI32() macro can sometimes result in a sign-extended 32-bit load that does not clear the top 32-bits properly. As an example, loading 0x7fffffff results in the register containing 0xffffffff7fffffff. While this does not impact classic BPF JIT implementation (since that only uses the lower word for all operations), we would like to share this macro between classic BPF JIT and extended BPF JIT, wherein the entire 64-bit value in the register matters. Fix this by first doing a shifted LI followed by ORI. An additional optimization is with loading values between -32768 to -1, where we now only need a single LI. The new implementation now generates the same or less number of instructions. Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/net')
-rw-r--r--arch/powerpc/net/bpf_jit.h13
1 files changed, 10 insertions, 3 deletions
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index 889fd199a821..a9882db9ecaa 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -232,10 +232,17 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
(((cond) & 0x3ff) << 16) | \
(((dest) - (ctx->idx * 4)) & \
0xfffc))
-#define PPC_LI32(d, i) do { PPC_LI(d, IMM_L(i)); \
- if ((u32)(uintptr_t)(i) >= 32768) { \
- PPC_ADDIS(d, d, IMM_HA(i)); \
+/* Sign-extended 32-bit immediate load */
+#define PPC_LI32(d, i) do { \
+ if ((int)(uintptr_t)(i) >= -32768 && \
+ (int)(uintptr_t)(i) < 32768) \
+ PPC_LI(d, i); \
+ else { \
+ PPC_LIS(d, IMM_H(i)); \
+ if (IMM_L(i)) \
+ PPC_ORI(d, d, IMM_L(i)); \
} } while(0)
+
#define PPC_LI64(d, i) do { \
if (!((uintptr_t)(i) & 0xffffffff00000000ULL)) \
PPC_LI32(d, i); \