diff --git a/src/bpf_assembler.cc b/src/bpf_assembler.cc index c06c1ca..8aa2e34 100644 --- a/src/bpf_assembler.cc +++ b/src/bpf_assembler.cc @@ -58,6 +58,7 @@ typedef class _bpf_assembler {"arsh", 0xc}, {"le", 0xd}, {"be", 0xd}, + {"swap", 0xd}, }; const std::unordered_map _bpf_encode_jmp_ops{ @@ -246,6 +247,11 @@ typedef class _bpf_assembler inst.dst = _decode_register(operands[0]); inst.imm = _decode_imm32(mnemonic.substr(2)); return inst; + } else if (mnemonic.starts_with("swap")) { + inst.opcode = EBPF_OP_SWAP; + inst.dst = _decode_register(operands[0]); + inst.imm = _decode_imm32(mnemonic.substr(4)); + return inst; } if (mnemonic.starts_with("sdiv") || mnemonic.starts_with("smod")) { inst.offset = 1; @@ -479,7 +485,9 @@ typedef class _bpf_assembler {"stxb", {&_bpf_assembler::_encode_stx, 2}}, {"stxdw", {&_bpf_assembler::_encode_stx, 2}}, {"stxh", {&_bpf_assembler::_encode_stx, 2}}, {"stxw", {&_bpf_assembler::_encode_stx, 2}}, {"sub", {&_bpf_assembler::_encode_alu, 2}}, {"sub32", {&_bpf_assembler::_encode_alu, 2}}, - {"xor", {&_bpf_assembler::_encode_alu, 2}}, {"xor32", {&_bpf_assembler::_encode_alu, 2}}, + {"swap16", {&_bpf_assembler::_encode_alu, 1}},{"swap32", {&_bpf_assembler::_encode_alu, 1}}, + {"swap64", {&_bpf_assembler::_encode_alu, 1}},{"xor", {&_bpf_assembler::_encode_alu, 2}}, + {"xor32", {&_bpf_assembler::_encode_alu, 2}}, }; const std::unordered_map> _bpf_encode_atomic_ops{ diff --git a/src/ebpf.h b/src/ebpf.h index 0c176ae..dff7514 100644 --- a/src/ebpf.h +++ b/src/ebpf.h @@ -135,6 +135,7 @@ typedef struct ebpf_inst #define EBPF_OP_MOV64_REG (EBPF_CLS_ALU64 | EBPF_SRC_REG | EBPF_ALU_OP_MOV) #define EBPF_OP_ARSH64_IMM (EBPF_CLS_ALU64 | EBPF_SRC_IMM | EBPF_ALU_OP_ARSH) #define EBPF_OP_ARSH64_REG (EBPF_CLS_ALU64 | EBPF_SRC_REG | EBPF_ALU_OP_ARSH) +#define EBPF_OP_SWAP (EBPF_CLS_ALU64 | EBPF_SRC_IMM | EBPF_ALU_OP_END) #define EBPF_OP_LDXW (EBPF_CLS_LDX | EBPF_MODE_MEM | EBPF_SIZE_W) #define EBPF_OP_LDXH (EBPF_CLS_LDX | EBPF_MODE_MEM | EBPF_SIZE_H) diff --git a/src/opcode_names.h b/src/opcode_names.h index ca45824..d276a5a 100644 --- a/src/opcode_names.h +++ b/src/opcode_names.h @@ -338,6 +338,9 @@ static const std::set instructions_from_ {bpf_conformance_test_cpu_version_t::v1, 0xd4, 0x00, 0x40}, {bpf_conformance_test_cpu_version_t::v2, 0xd5}, {bpf_conformance_test_cpu_version_t::v3, 0xd6}, + {bpf_conformance_test_cpu_version_t::v4, 0xd7, 0x00, 0x10}, + {bpf_conformance_test_cpu_version_t::v4, 0xd7, 0x00, 0x20}, + {bpf_conformance_test_cpu_version_t::v4, 0xd7, 0x00, 0x40}, {bpf_conformance_test_cpu_version_t::v3, 0xdb, 0x00, 0x00}, {bpf_conformance_test_cpu_version_t::v3, 0xdb, 0x00, 0x01}, {bpf_conformance_test_cpu_version_t::v3, 0xdb, 0x00, 0x40}, diff --git a/tests/swap16.data b/tests/swap16.data new file mode 100644 index 0000000..6eb57c3 --- /dev/null +++ b/tests/swap16.data @@ -0,0 +1,8 @@ +# Copyright (c) Big Switch Networks, Inc +# SPDX-License-Identifier: Apache-2.0 +-- asm +lddw %r0, 0x8877665544332211 +swap16 %r0 +exit +-- result +0x1122 diff --git a/tests/swap32.data b/tests/swap32.data new file mode 100644 index 0000000..fb0d2b9 --- /dev/null +++ b/tests/swap32.data @@ -0,0 +1,8 @@ +# Copyright (c) Big Switch Networks, Inc +# SPDX-License-Identifier: Apache-2.0 +-- asm +lddw %r0, 0x8877665544332211 +swap32 %r0 +exit +-- result +0x11223344 diff --git a/tests/swap64.data b/tests/swap64.data new file mode 100644 index 0000000..1e2fec9 --- /dev/null +++ b/tests/swap64.data @@ -0,0 +1,8 @@ +# Copyright (c) Big Switch Networks, Inc +# SPDX-License-Identifier: Apache-2.0 +-- asm +lddw %r0, 0x8877665544332211 +swap64 %r0 +exit +-- result +0x1122334455667788