static int
 mem_op_stack(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
-            unsigned int size, unsigned int ptr_off, u8 gpr, bool clr_gpr,
-            lmem_step step)
+            unsigned int size, unsigned int ptr_off, u8 gpr, u8 ptr_gpr,
+            bool clr_gpr, lmem_step step)
 {
        s32 off = nfp_prog->stack_depth + meta->insn.off + ptr_off;
        bool first = true, last;
        bool lm3 = true;
        int ret;
 
-       if (off + size <= 64) {
+       if (meta->ptr_not_const) {
+               /* Use of the last encountered ptr_off is OK, they all have
+                * the same alignment.  Depend on low bits of value being
+                * discarded when written to LMaddr register.
+                */
+               stack_off_reg = ur_load_imm_any(nfp_prog, meta->insn.off,
+                                               stack_imm(nfp_prog));
+
+               emit_alu(nfp_prog, imm_b(nfp_prog),
+                        reg_a(ptr_gpr), ALU_OP_ADD, stack_off_reg);
+
+               needs_inc = true;
+       } else if (off + size <= 64) {
                /* We can reach bottom 64B with LMaddr0 */
                lm3 = false;
        } else if (round_down(off, 32) == round_down(off + size - 1, 32)) {
 static int mov_reg64(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
 {
        const struct bpf_insn *insn = &meta->insn;
+       u8 dst = insn->dst_reg * 2;
+       u8 src = insn->src_reg * 2;
+
+       if (insn->src_reg == BPF_REG_10) {
+               swreg stack_depth_reg;
 
-       wrp_reg_mov(nfp_prog, insn->dst_reg * 2, insn->src_reg * 2);
-       wrp_reg_mov(nfp_prog, insn->dst_reg * 2 + 1, insn->src_reg * 2 + 1);
+               stack_depth_reg = ur_load_imm_any(nfp_prog,
+                                                 nfp_prog->stack_depth,
+                                                 stack_imm(nfp_prog));
+               emit_alu(nfp_prog, reg_both(dst),
+                        stack_reg(nfp_prog), ALU_OP_ADD, stack_depth_reg);
+               wrp_immed(nfp_prog, reg_both(dst + 1), 0);
+       } else {
+               wrp_reg_mov(nfp_prog, dst, src);
+               wrp_reg_mov(nfp_prog, dst + 1, src + 1);
+       }
 
        return 0;
 }
              unsigned int size, unsigned int ptr_off)
 {
        return mem_op_stack(nfp_prog, meta, size, ptr_off,
-                           meta->insn.dst_reg * 2, true, wrp_lmem_load);
+                           meta->insn.dst_reg * 2, meta->insn.src_reg * 2,
+                           true, wrp_lmem_load);
 }
 
 static int mem_ldx_skb(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
              unsigned int size, unsigned int ptr_off)
 {
        return mem_op_stack(nfp_prog, meta, size, ptr_off,
-                           meta->insn.src_reg * 2, false, wrp_lmem_store);
+                           meta->insn.src_reg * 2, meta->insn.dst_reg * 2,
+                           false, wrp_lmem_store);
 }
 
 static int
 
 }
 
 static int
-nfp_bpf_check_stack_access(struct nfp_insn_meta *meta,
+nfp_bpf_check_stack_access(struct nfp_prog *nfp_prog,
+                          struct nfp_insn_meta *meta,
                           const struct bpf_reg_state *reg)
 {
        s32 old_off, new_off;
        old_off = meta->ptr.off + meta->ptr.var_off.value;
        new_off = reg->off + reg->var_off.value;
 
-       if (old_off == new_off)
+       meta->ptr_not_const |= old_off != new_off;
+
+       if (!meta->ptr_not_const)
+               return 0;
+
+       if (old_off % 4 == new_off % 4)
                return 0;
 
        pr_info("stack access changed location was:%d is:%d\n",
        }
 
        if (reg->type == PTR_TO_STACK) {
-               err = nfp_bpf_check_stack_access(meta, reg);
+               err = nfp_bpf_check_stack_access(nfp_prog, meta, reg);
                if (err)
                        return err;
        }