Commit 3e2a33cf authored by Jiong Wang's avatar Jiong Wang Committed by Alexei Starovoitov
Browse files

sparc: bpf: eliminate zero extension code-gen



Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: default avatarJiong Wang <jiong.wang@netronome.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 591006b9
Loading
Loading
Loading
Loading
+27 −2
Original line number Diff line number Diff line
@@ -908,6 +908,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
	/* dst = src */
	case BPF_ALU | BPF_MOV | BPF_X:
		emit_alu3_K(SRL, src, 0, dst, ctx);
		if (insn_is_zext(&insn[1]))
			return 1;
		break;
	case BPF_ALU64 | BPF_MOV | BPF_X:
		emit_reg_move(src, dst, ctx);
@@ -942,6 +944,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
	case BPF_ALU | BPF_DIV | BPF_X:
		emit_write_y(G0, ctx);
		emit_alu(DIV, src, dst, ctx);
		if (insn_is_zext(&insn[1]))
			return 1;
		break;
	case BPF_ALU64 | BPF_DIV | BPF_X:
		emit_alu(UDIVX, src, dst, ctx);
@@ -975,6 +979,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
		break;
	case BPF_ALU | BPF_RSH | BPF_X:
		emit_alu(SRL, src, dst, ctx);
		if (insn_is_zext(&insn[1]))
			return 1;
		break;
	case BPF_ALU64 | BPF_RSH | BPF_X:
		emit_alu(SRLX, src, dst, ctx);
@@ -997,8 +1003,11 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
		case 16:
			emit_alu_K(SLL, dst, 16, ctx);
			emit_alu_K(SRL, dst, 16, ctx);
			if (insn_is_zext(&insn[1]))
				return 1;
			break;
		case 32:
			if (!ctx->prog->aux->verifier_zext)
				emit_alu_K(SRL, dst, 0, ctx);
			break;
		case 64:
@@ -1021,6 +1030,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
			emit_alu3_K(AND, dst, 0xff, dst, ctx);
			emit_alu3_K(SLL, tmp, 8, tmp, ctx);
			emit_alu(OR, tmp, dst, ctx);
			if (insn_is_zext(&insn[1]))
				return 1;
			break;

		case 32:
@@ -1037,6 +1048,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
			emit_alu3_K(AND, dst, 0xff, dst, ctx);	/* dst	= dst & 0xff */
			emit_alu3_K(SLL, dst, 24, dst, ctx);	/* dst  = dst << 24 */
			emit_alu(OR, tmp, dst, ctx);		/* dst  = dst | tmp */
			if (insn_is_zext(&insn[1]))
				return 1;
			break;

		case 64:
@@ -1050,6 +1063,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
	/* dst = imm */
	case BPF_ALU | BPF_MOV | BPF_K:
		emit_loadimm32(imm, dst, ctx);
		if (insn_is_zext(&insn[1]))
			return 1;
		break;
	case BPF_ALU64 | BPF_MOV | BPF_K:
		emit_loadimm_sext(imm, dst, ctx);
@@ -1132,6 +1147,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
		break;
	case BPF_ALU | BPF_RSH | BPF_K:
		emit_alu_K(SRL, dst, imm, ctx);
		if (insn_is_zext(&insn[1]))
			return 1;
		break;
	case BPF_ALU64 | BPF_RSH | BPF_K:
		emit_alu_K(SRLX, dst, imm, ctx);
@@ -1144,7 +1161,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
		break;

	do_alu32_trunc:
		if (BPF_CLASS(code) == BPF_ALU)
		if (BPF_CLASS(code) == BPF_ALU &&
		    !ctx->prog->aux->verifier_zext)
			emit_alu_K(SRL, dst, 0, ctx);
		break;

@@ -1265,6 +1283,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
			rs2 = RS2(tmp);
		}
		emit(opcode | RS1(src) | rs2 | RD(dst), ctx);
		if (opcode != LD64 && insn_is_zext(&insn[1]))
			return 1;
		break;
	}
	/* ST: *(size *)(dst + off) = imm */
@@ -1432,6 +1452,11 @@ static void jit_fill_hole(void *area, unsigned int size)
		*ptr++ = 0x91d02005; /* ta 5 */
}

bool bpf_jit_needs_zext(void)
{
	return true;
}

struct sparc64_jit_data {
	struct bpf_binary_header *header;
	u8 *image;