arch/parisc/net/bpf_jit_comp32.c
Source file repositories/reference/linux-study-clean/arch/parisc/net/bpf_jit_comp32.c
File Facts
- System
- Linux kernel
- Corpus path
arch/parisc/net/bpf_jit_comp32.c- Extension
.c- Size
- 44841 bytes
- Lines
- 1616
- Domain
- Architecture Layer
- Bucket
- arch/parisc
- Inferred role
- Architecture Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bpf.hlinux/filter.hlinux/libgcc.hbpf_jit.h
Detected Declarations
function hifunction lofunction emit_hppa_copyfunction emit_hppa_xorfunction emit_immfunction emit_imm32function emit_imm64function __build_epiloguefunction is_stackedfunction bpf_put_reg64function bpf_save_R0function bpf_restore_R0function bpf_put_reg32function emit_call_millicodefunction emit_call_libgcc_llfunction emit_jumpfunction emit_alu_i64function emit_alu_i32function emit_alu_r64function emit_alu_r32function emit_branch_r64function emit_bccfunction emit_branch_r32function emit_callfunction emit_bpf_tail_callfunction emit_load_r64function emit_store_r64function emit_rev16function emit_rev32function emit_zext64function bpf_jit_emit_insnfunction bpf_jit_build_prologuefunction bpf_jit_build_epilogue
Annotated Snippet
if (1 && !ctx->prog->aux->verifier_zext) {
REG_SET_SEEN(ctx, hi(reg));
emit(hppa_stw(HPPA_REG_ZERO, REG_SIZE * hi(reg), HPPA_REG_SP), ctx);
}
} else if (1 && !ctx->prog->aux->verifier_zext) {
REG_SET_SEEN(ctx, hi(reg));
emit_hppa_copy(HPPA_REG_ZERO, hi(reg), ctx);
}
}
/* extern hppa millicode functions */
extern void $$mulI(void);
extern void $$divU(void);
extern void $$remU(void);
static void emit_call_millicode(void *func, const s8 arg0,
const s8 arg1, u8 opcode, struct hppa_jit_context *ctx)
{
u32 func_addr;
emit_hppa_copy(arg0, HPPA_REG_ARG0, ctx);
emit_hppa_copy(arg1, HPPA_REG_ARG1, ctx);
/* libcgcc overwrites HPPA_REG_RET0/1, save temp. in dest. */
if (arg0 != HPPA_REG_RET1)
bpf_save_R0(ctx);
func_addr = (uintptr_t) dereference_function_descriptor(func);
emit(hppa_ldil(func_addr, HPPA_REG_R31), ctx);
/* skip the following be_l instruction if divisor is zero. */
if (BPF_OP(opcode) == BPF_DIV || BPF_OP(opcode) == BPF_MOD) {
if (BPF_OP(opcode) == BPF_DIV)
emit_hppa_copy(HPPA_REG_ZERO, HPPA_REG_RET1, ctx);
else
emit_hppa_copy(HPPA_REG_ARG0, HPPA_REG_RET1, ctx);
emit(hppa_or_cond(HPPA_REG_ARG1, HPPA_REG_ZERO, 1, 0, HPPA_REG_ZERO), ctx);
}
/* Note: millicode functions use r31 as return pointer instead of rp */
emit(hppa_be_l(im11(func_addr) >> 2, HPPA_REG_R31, NOP_NEXT_INSTR), ctx);
emit(hppa_nop(), ctx); /* this nop is needed here for delay slot */
/* Note: millicode functions return result in RET1, not RET0 */
emit_hppa_copy(HPPA_REG_RET1, arg0, ctx);
/* restore HPPA_REG_RET0/1, temp. save in dest. */
if (arg0 != HPPA_REG_RET1)
bpf_restore_R0(ctx);
}
static void emit_call_libgcc_ll(void *func, const s8 *arg0,
const s8 *arg1, u8 opcode, struct hppa_jit_context *ctx)
{
u32 func_addr;
emit_hppa_copy(lo(arg0), HPPA_REG_ARG0, ctx);
emit_hppa_copy(hi(arg0), HPPA_REG_ARG1, ctx);
emit_hppa_copy(lo(arg1), HPPA_REG_ARG2, ctx);
emit_hppa_copy(hi(arg1), HPPA_REG_ARG3, ctx);
/* libcgcc overwrites HPPA_REG_RET0/_RET1, so keep copy of R0 on stack */
if (hi(arg0) != HPPA_REG_RET0)
bpf_save_R0(ctx);
/* prepare stack */
emit(hppa_ldo(2 * FRAME_SIZE, HPPA_REG_SP, HPPA_REG_SP), ctx);
func_addr = (uintptr_t) dereference_function_descriptor(func);
emit(hppa_ldil(func_addr, HPPA_REG_R31), ctx);
/* zero out the following be_l instruction if divisor is 0 (and set default values) */
if (BPF_OP(opcode) == BPF_DIV || BPF_OP(opcode) == BPF_MOD) {
emit_hppa_copy(HPPA_REG_ZERO, HPPA_REG_RET0, ctx);
if (BPF_OP(opcode) == BPF_DIV)
emit_hppa_copy(HPPA_REG_ZERO, HPPA_REG_RET1, ctx);
else
emit_hppa_copy(HPPA_REG_ARG0, HPPA_REG_RET1, ctx);
emit(hppa_or_cond(HPPA_REG_ARG2, HPPA_REG_ARG3, 1, 0, HPPA_REG_ZERO), ctx);
}
emit(hppa_be_l(im11(func_addr) >> 2, HPPA_REG_R31, EXEC_NEXT_INSTR), ctx);
emit_hppa_copy(HPPA_REG_R31, HPPA_REG_RP, ctx);
/* restore stack */
emit(hppa_ldo(-2 * FRAME_SIZE, HPPA_REG_SP, HPPA_REG_SP), ctx);
emit_hppa_copy(HPPA_REG_RET0, hi(arg0), ctx);
emit_hppa_copy(HPPA_REG_RET1, lo(arg0), ctx);
/* restore HPPA_REG_RET0/_RET1 */
if (hi(arg0) != HPPA_REG_RET0)
bpf_restore_R0(ctx);
}
Annotation
- Immediate include surface: `linux/bpf.h`, `linux/filter.h`, `linux/libgcc.h`, `bpf_jit.h`.
- Detected declarations: `function hi`, `function lo`, `function emit_hppa_copy`, `function emit_hppa_xor`, `function emit_imm`, `function emit_imm32`, `function emit_imm64`, `function __build_epilogue`, `function is_stacked`, `function bpf_put_reg64`.
- Atlas domain: Architecture Layer / arch/parisc.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.