arch/riscv/net/bpf_jit_comp32.c

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

File Facts

System
Linux kernel
Corpus path
arch/riscv/net/bpf_jit_comp32.c
Extension
.c
Size
36573 bytes
Lines
1357
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 (is_12b_int(imm)) {
			emit(rv_andi(lo(rd), lo(rd), imm), ctx);
		} else {
			emit_imm(RV_REG_T0, imm, ctx);
			emit(rv_and(lo(rd), lo(rd), RV_REG_T0), ctx);
		}
		if (imm >= 0)
			emit(rv_addi(hi(rd), RV_REG_ZERO, 0), ctx);
		break;
	case BPF_OR:
		if (is_12b_int(imm)) {
			emit(rv_ori(lo(rd), lo(rd), imm), ctx);
		} else {
			emit_imm(RV_REG_T0, imm, ctx);
			emit(rv_or(lo(rd), lo(rd), RV_REG_T0), ctx);
		}
		if (imm < 0)
			emit(rv_ori(hi(rd), RV_REG_ZERO, -1), ctx);
		break;
	case BPF_XOR:
		if (is_12b_int(imm)) {
			emit(rv_xori(lo(rd), lo(rd), imm), ctx);
		} else {
			emit_imm(RV_REG_T0, imm, ctx);
			emit(rv_xor(lo(rd), lo(rd), RV_REG_T0), ctx);
		}
		if (imm < 0)
			emit(rv_xori(hi(rd), hi(rd), -1), ctx);
		break;
	case BPF_LSH:
		if (imm >= 32) {
			emit(rv_slli(hi(rd), lo(rd), imm - 32), ctx);
			emit(rv_addi(lo(rd), RV_REG_ZERO, 0), ctx);
		} else if (imm == 0) {
			/* Do nothing. */
		} else {
			emit(rv_srli(RV_REG_T0, lo(rd), 32 - imm), ctx);
			emit(rv_slli(hi(rd), hi(rd), imm), ctx);
			emit(rv_or(hi(rd), RV_REG_T0, hi(rd)), ctx);
			emit(rv_slli(lo(rd), lo(rd), imm), ctx);
		}
		break;
	case BPF_RSH:
		if (imm >= 32) {
			emit(rv_srli(lo(rd), hi(rd), imm - 32), ctx);
			emit(rv_addi(hi(rd), RV_REG_ZERO, 0), ctx);
		} else if (imm == 0) {
			/* Do nothing. */
		} else {
			emit(rv_slli(RV_REG_T0, hi(rd), 32 - imm), ctx);
			emit(rv_srli(lo(rd), lo(rd), imm), ctx);
			emit(rv_or(lo(rd), RV_REG_T0, lo(rd)), ctx);
			emit(rv_srli(hi(rd), hi(rd), imm), ctx);
		}
		break;
	case BPF_ARSH:
		if (imm >= 32) {
			emit(rv_srai(lo(rd), hi(rd), imm - 32), ctx);
			emit(rv_srai(hi(rd), hi(rd), 31), ctx);
		} else if (imm == 0) {
			/* Do nothing. */
		} else {
			emit(rv_slli(RV_REG_T0, hi(rd), 32 - imm), ctx);
			emit(rv_srli(lo(rd), lo(rd), imm), ctx);
			emit(rv_or(lo(rd), RV_REG_T0, lo(rd)), ctx);
			emit(rv_srai(hi(rd), hi(rd), imm), ctx);
		}
		break;
	}

	bpf_put_reg64(dst, rd, ctx);
}

static void emit_alu_i32(const s8 *dst, s32 imm,
			 struct rv_jit_context *ctx, const u8 op)
{
	const s8 *tmp1 = bpf2rv32[TMP_REG_1];
	const s8 *rd = bpf_get_reg32(dst, tmp1, ctx);

	switch (op) {
	case BPF_MOV:
		emit_imm(lo(rd), imm, ctx);
		break;
	case BPF_ADD:
		if (is_12b_int(imm)) {
			emit(rv_addi(lo(rd), lo(rd), imm), ctx);
		} else {
			emit_imm(RV_REG_T0, imm, ctx);
			emit(rv_add(lo(rd), lo(rd), RV_REG_T0), ctx);
		}

Annotation

Implementation Notes