arch/riscv/net/bpf_jit_comp64.c

Source file repositories/reference/linux-study-clean/arch/riscv/net/bpf_jit_comp64.c

File Facts

System
Linux kernel
Corpus path
arch/riscv/net/bpf_jit_comp64.c
Extension
.c
Size
57915 bytes
Lines
2160
Domain
Architecture Layer
Bucket
arch/riscv
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!upper) {
			emit_li(rd, lower, ctx);
			return;
		}

		emit_addiw(rd, rd, lower, ctx);
		return;
	}

	shift = __ffs(upper);
	upper >>= shift;
	shift += 12;

	emit_imm(rd, upper, ctx);

	emit_slli(rd, rd, shift, ctx);
	if (lower)
		emit_addi(rd, rd, lower, ctx);
}

static void __build_epilogue(bool is_tail_call, struct rv_jit_context *ctx)
{
	int stack_adjust = ctx->stack_size, store_offset = stack_adjust - 8;

	if (seen_reg(RV_REG_RA, ctx)) {
		emit_ld(RV_REG_RA, store_offset, RV_REG_SP, ctx);
		store_offset -= 8;
	}
	emit_ld(RV_REG_FP, store_offset, RV_REG_SP, ctx);
	store_offset -= 8;
	if (seen_reg(RV_REG_S1, ctx)) {
		emit_ld(RV_REG_S1, store_offset, RV_REG_SP, ctx);
		store_offset -= 8;
	}
	if (seen_reg(RV_REG_S2, ctx)) {
		emit_ld(RV_REG_S2, store_offset, RV_REG_SP, ctx);
		store_offset -= 8;
	}
	if (seen_reg(RV_REG_S3, ctx)) {
		emit_ld(RV_REG_S3, store_offset, RV_REG_SP, ctx);
		store_offset -= 8;
	}
	if (seen_reg(RV_REG_S4, ctx)) {
		emit_ld(RV_REG_S4, store_offset, RV_REG_SP, ctx);
		store_offset -= 8;
	}
	if (seen_reg(RV_REG_S5, ctx)) {
		emit_ld(RV_REG_S5, store_offset, RV_REG_SP, ctx);
		store_offset -= 8;
	}
	if (seen_reg(RV_REG_S6, ctx)) {
		emit_ld(RV_REG_S6, store_offset, RV_REG_SP, ctx);
		store_offset -= 8;
	}
	if (ctx->arena_vm_start) {
		emit_ld(RV_REG_ARENA, store_offset, RV_REG_SP, ctx);
		store_offset -= 8;
	}

	emit_addi(RV_REG_SP, RV_REG_SP, stack_adjust, ctx);
	/* Set return value. */
	if (!is_tail_call)
		emit_addiw(RV_REG_A0, RV_REG_A5, 0, ctx);
	emit_jalr(RV_REG_ZERO, is_tail_call ? RV_REG_T3 : RV_REG_RA,
		  /* kcfi, fentry and TCC init insns will be skipped on tailcall */
		  is_tail_call ? (RV_KCFI_NINSNS + RV_FENTRY_NINSNS + 1) * 4 : 0,
		  ctx);
}

static void emit_bcc(u8 cond, u8 rd, u8 rs, int rvoff,
		     struct rv_jit_context *ctx)
{
	switch (cond) {
	case BPF_JEQ:
		emit(rv_beq(rd, rs, rvoff >> 1), ctx);
		return;
	case BPF_JGT:
		emit(rv_bltu(rs, rd, rvoff >> 1), ctx);
		return;
	case BPF_JLT:
		emit(rv_bltu(rd, rs, rvoff >> 1), ctx);
		return;
	case BPF_JGE:
		emit(rv_bgeu(rd, rs, rvoff >> 1), ctx);
		return;
	case BPF_JLE:
		emit(rv_bgeu(rs, rd, rvoff >> 1), ctx);
		return;
	case BPF_JNE:
		emit(rv_bne(rd, rs, rvoff >> 1), ctx);

Annotation

Implementation Notes