From 2c416833554e3fa3712f5c4c311b99c35937b35b Mon Sep 17 00:00:00 2001 From: Dave Thaler Date: Sun, 4 Feb 2024 18:54:38 -0800 Subject: [PATCH] Add conformance test for callx instruction Signed-off-by: Dave Thaler --- include/bpf_conformance.h | 1 + src/bpf_assembler.cc | 11 +++++++++-- src/bpf_conformance.cc | 2 +- src/opcode_names.h | 1 + src/runner.cc | 2 ++ tests/callx.data | 12 ++++++++++++ 6 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 tests/callx.data diff --git a/include/bpf_conformance.h b/include/bpf_conformance.h index 75065f4..ffb7cc0 100644 --- a/include/bpf_conformance.h +++ b/include/bpf_conformance.h @@ -23,6 +23,7 @@ typedef enum class _bpf_conformance_test_cpu_version v2 = 2, v3 = 3, v4 = 4, + vnext = 100, unknown = -1, } bpf_conformance_test_cpu_version_t; diff --git a/src/bpf_assembler.cc b/src/bpf_assembler.cc index aa7761f..a0e793e 100644 --- a/src/bpf_assembler.cc +++ b/src/bpf_assembler.cc @@ -309,8 +309,15 @@ typedef class _bpf_assembler auto target = operands[1]; // Mode determines if this is a helper function, a local call, or a call to a runtime function. if (mode == "helper") { - inst.imm = _decode_imm32(target); - inst.src = 0; + if (target.starts_with('%')) { + inst.opcode |= EBPF_SRC_REG; + inst.imm = 0; + inst.src = _decode_register(target); + } else { + inst.opcode |= EBPF_SRC_IMM; + inst.imm = _decode_imm32(target); + inst.src = 0; + } } else if (mode == "local") { inst.imm = _decode_jump_target(target); inst.src = 1; diff --git a/src/bpf_conformance.cc b/src/bpf_conformance.cc index 9cc19f5..ac495b2 100644 --- a/src/bpf_conformance.cc +++ b/src/bpf_conformance.cc @@ -213,7 +213,7 @@ bpf_conformance_options( instructions_used.insert(bpf_conformance_instruction_t(required_cpu_version, inst)); } - // If the caller requires this as a XDP program, then add the prolog instructions. + // If the caller requires this as an XDP program, then add the prolog instructions. if (options.xdp_prolog && input_memory.size() > 0) { auto prolog_instructions = _generate_xdp_prolog(input_memory.size()); byte_code.insert(byte_code.begin(), prolog_instructions.begin(), prolog_instructions.end()); diff --git a/src/opcode_names.h b/src/opcode_names.h index 1dcdd86..b50a011 100644 --- a/src/opcode_names.h +++ b/src/opcode_names.h @@ -291,6 +291,7 @@ static const std::set instructions_from_ {bpf_conformance_test_cpu_version_t::v3, 0x85, 0x01}, {bpf_conformance_test_cpu_version_t::v3, 0x85, 0x02}, {bpf_conformance_test_cpu_version_t::v1, 0x87}, + {bpf_conformance_test_cpu_version_t::vnext, 0x8d, 0x00}, {bpf_conformance_test_cpu_version_t::v1, 0x94, 0x00, 0x00, 0x00}, {bpf_conformance_test_cpu_version_t::v4, 0x94, 0x00, 0x00, 0x01}, {bpf_conformance_test_cpu_version_t::v1, 0x95}, diff --git a/src/runner.cc b/src/runner.cc index c03777a..fbb6202 100644 --- a/src/runner.cc +++ b/src/runner.cc @@ -123,6 +123,8 @@ main(int argc, char** argv) cpu_version = bpf_conformance_test_cpu_version_t::v3; } else if (cpu_version_string == "v4") { cpu_version = bpf_conformance_test_cpu_version_t::v4; + } else if (cpu_version_string == "vnext") { + cpu_version = bpf_conformance_test_cpu_version_t::vnext; } else { std::cout << "Invalid CPU version" << std::endl; return 1; diff --git a/tests/callx.data b/tests/callx.data new file mode 100644 index 0000000..7d83a23 --- /dev/null +++ b/tests/callx.data @@ -0,0 +1,12 @@ +# Copyright (c) Big Switch Networks, Inc +# SPDX-License-Identifier: Apache-2.0 +-- asm +mov %r1, -1 +mov %r2, 5 +call %r2 +mov %r0, 2 +exit +-- result +0x2 +-- no register offset +call instruction