diff --git a/README.md b/README.md index d644988..3b4168f 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Linux Kernel is treated as the authorative eBPF implementation. ### Ubuntu ``` -sudo apt-get install -y libboost-dev libboost-filesystem-dev libboost-program-options-dev libelf-dev lcov +sudo apt-get install -y libboost-dev libboost-filesystem-dev libboost-program-options-dev libelf-dev lcov libbpf-dev ``` ### MacOS diff --git a/include/bpf_conformance.h b/include/bpf_conformance.h index 868b02c..81f291f 100644 --- a/include/bpf_conformance.h +++ b/include/bpf_conformance.h @@ -22,6 +22,7 @@ typedef enum class _bpf_conformance_test_cpu_version v1 = 1, v2 = 2, v3 = 3, + v4 = 4, } bpf_conformance_test_cpu_version_t; // Add typedef for backwards compatibility. diff --git a/src/bpf_assembler.cc b/src/bpf_assembler.cc index d8eac72..693d282 100644 --- a/src/bpf_assembler.cc +++ b/src/bpf_assembler.cc @@ -45,6 +45,7 @@ typedef class _bpf_assembler {"sub", 0x1}, {"mul", 0x2}, {"div", 0x3}, + {"sdiv", 0x3}, {"or", 0x4}, {"and", 0x5}, {"lsh", 0x6}, @@ -245,6 +246,9 @@ typedef class _bpf_assembler inst.imm = _decode_imm32(mnemonic.substr(2)); return inst; } + if (mnemonic.starts_with("sdiv")) { + inst.offset = 1; + } if (mnemonic.ends_with("32")) { inst.opcode |= EBPF_CLS_ALU; @@ -444,6 +448,7 @@ typedef class _bpf_assembler {"be16", {&_bpf_assembler::_encode_alu, 1}}, {"be32", {&_bpf_assembler::_encode_alu, 1}}, {"be64", {&_bpf_assembler::_encode_alu, 1}}, {"call", {&_bpf_assembler::_encode_jmp, 2}}, {"div", {&_bpf_assembler::_encode_alu, 2}}, {"div32", {&_bpf_assembler::_encode_alu, 2}}, + {"sdiv", {&_bpf_assembler::_encode_alu, 2}}, {"sdiv32", {&_bpf_assembler::_encode_alu, 2}}, {"exit", {&_bpf_assembler::_encode_jmp, 0}}, {"ja", {&_bpf_assembler::_encode_jmp, 1}}, {"jeq", {&_bpf_assembler::_encode_jmp, 3}}, {"jeq32", {&_bpf_assembler::_encode_jmp, 3}}, {"jge", {&_bpf_assembler::_encode_jmp, 3}}, {"jge32", {&_bpf_assembler::_encode_jmp, 3}}, diff --git a/src/bpf_conformance.cc b/src/bpf_conformance.cc index 46c2fec..a76adba 100644 --- a/src/bpf_conformance.cc +++ b/src/bpf_conformance.cc @@ -130,6 +130,18 @@ _generate_xdp_prolog(size_t size) }; } +bpf_conformance_test_cpu_version_t +get_instruction_cpu_version(ebpf_inst inst) +{ + auto instruction = std::find_if(instructions_from_spec.begin(), instructions_from_spec.end(), [&](const auto &instruction) { + return (instruction.opcode == inst.opcode) && + (!needs_src(inst.opcode) || instruction.src == inst.src) && + (!needs_imm(inst.opcode) || instruction.imm == inst.imm) && + (!needs_offset(inst.opcode) || instruction.offset == inst.offset); + }); + return instruction->cpu_version; +} + std::map> bpf_conformance_options( const std::vector& test_files, @@ -178,28 +190,8 @@ bpf_conformance_options( // Determine the required CPU version for the test. for (size_t i = 0; i < byte_code.size(); i++) { auto inst = byte_code[i]; - // If this is an atomic store, then the test requires CPU version 3. - if (((inst.opcode & EBPF_CLS_MASK) == EBPF_CLS_STX) && - (((inst.opcode & EBPF_MODE_ATOMIC) == EBPF_MODE_ATOMIC))) { - required_cpu_version = std::max(required_cpu_version, bpf_conformance_test_cpu_version_t::v3); - } - // If this is a EBPF_CLS_JMP32, then we know this is v3. - else if ((inst.opcode & EBPF_CLS_MASK) == EBPF_CLS_JMP32) { - required_cpu_version = std::max(required_cpu_version, bpf_conformance_test_cpu_version_t::v3); - } else if ((inst.opcode & EBPF_CLS_MASK) == EBPF_CLS_JMP) { - // If this is a EBPF_CLS_JMP, then check if it is a less than operation. - if ((inst.opcode & EBPF_ALU_OP_MASK) >= (EBPF_OP_JLT_IMM & EBPF_ALU_OP_MASK)) { - // It his is a less than operation, then we know this is v2. - required_cpu_version = std::max(required_cpu_version, bpf_conformance_test_cpu_version_t::v2); - } - } - // If the program uses local or runtime calls then this is v3 of the ABI. - // inst.src == 0 means helper function call. - // inst.src == 1 means local function call. - // inst.src == 2 means runtime function call. - if (inst.opcode == EBPF_OP_CALL && inst.src != 0) { - required_cpu_version = std::max(required_cpu_version, bpf_conformance_test_cpu_version_t::v3); - } + bpf_conformance_test_cpu_version_t cpu_version = get_instruction_cpu_version(inst); + required_cpu_version = std::max(required_cpu_version, cpu_version); if (inst.opcode == EBPF_OP_LDDW) { // Instruction has a 64-bit immediate and takes two instructions slots. i++; @@ -215,7 +207,7 @@ bpf_conformance_options( } for (const auto& inst : byte_code) { - instructions_used.insert(bpf_conformance_instruction_t(inst)); + 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. @@ -302,7 +294,7 @@ bpf_conformance_options( } if (expected_error_string.empty()) { test_results[test] = { - bpf_conformance_test_result_t::TEST_RESULT_FAIL, + bpf_conformance_test_result_t::TEST_RESULT_ERROR, "Plugin returned error code " + std::to_string(c.exit_code()) + " and output " + return_value_string}; } else { diff --git a/src/opcode_names.h b/src/opcode_names.h index 6470d6d..179b8ba 100644 --- a/src/opcode_names.h +++ b/src/opcode_names.h @@ -21,24 +21,41 @@ needs_imm(uint8_t opcode) return opcode == 0xc3 || opcode == 0xd4 || opcode == 0xdb || opcode == 0xdc; } +inline bool +needs_offset(uint8_t opcode) +{ + return opcode == 0x34 || opcode == 0x37 || opcode == 0x3c || opcode == 0x3f; +} + class bpf_conformance_instruction_t { public: - bpf_conformance_instruction_t(uint8_t opcode, uint8_t src = 0, uint32_t imm = 0) + bpf_conformance_instruction_t( + bpf_conformance_test_cpu_version_t cpu_version, + uint8_t opcode, + uint8_t src = 0, + uint32_t imm = 0, + int16_t offset = 0) { + this->cpu_version = cpu_version; this->opcode = opcode; this->src = src; this->imm = imm; + this->offset = offset; } - bpf_conformance_instruction_t(ebpf_inst inst) + bpf_conformance_instruction_t(bpf_conformance_test_cpu_version_t cpu_version, ebpf_inst inst) { opcode = inst.opcode; + this->cpu_version = cpu_version; src = needs_src(opcode) ? inst.src : 0; imm = needs_imm(opcode) ? inst.imm : 0; + offset = needs_offset(opcode) ? inst.offset : 0; } + bpf_conformance_test_cpu_version_t cpu_version; uint8_t opcode; uint8_t src = {}; uint32_t imm = {}; + int16_t offset = {}; }; struct InstCmp @@ -52,6 +69,9 @@ struct InstCmp if (a.src != b.src) { return a.src < b.src; } + if (a.offset != b.offset) { + return a.offset < b.offset; + } return a.imm < b.imm; } }; @@ -178,151 +198,157 @@ static const std::map opcode_names = { // List of opcodes from the BPF ISA spec. static const std::set instructions_from_spec = { - 0x00, - 0x04, - 0x05, - 0x07, - 0x0c, - 0x0f, - 0x14, - 0x15, - 0x16, - 0x17, - {0x18, 0x00}, - {0x18, 0x01}, - {0x18, 0x02}, - {0x18, 0x03}, - {0x18, 0x04}, - {0x18, 0x05}, - {0x18, 0x06}, - 0x1c, - 0x1d, - 0x1e, - 0x1f, - 0x24, - 0x25, - 0x26, - 0x27, - 0x2c, - 0x2d, - 0x2e, - 0x2f, - 0x34, - 0x35, - 0x36, - 0x37, - 0x3c, - 0x3d, - 0x3e, - 0x3f, - 0x44, - 0x45, - 0x46, - 0x47, - 0x4c, - 0x4d, - 0x4e, - 0x4f, - 0x54, - 0x55, - 0x56, - 0x57, - 0x5c, - 0x5d, - 0x5e, - 0x5f, - 0x61, - 0x62, - 0x63, - 0x64, - 0x65, - 0x66, - 0x67, - 0x69, - 0x6a, - 0x6b, - 0x6c, - 0x6d, - 0x6e, - 0x6f, - 0x71, - 0x72, - 0x73, - 0x74, - 0x75, - 0x76, - 0x77, - 0x79, - 0x7a, - 0x7b, - 0x7c, - 0x7d, - 0x7e, - 0x7f, - 0x84, - {0x85, 0x00}, - {0x85, 0x01}, - {0x85, 0x02}, - 0x87, - 0x94, - 0x95, - 0x97, - 0x9c, - 0x9f, - 0xa4, - 0xa5, - 0xa6, - 0xa7, - 0xac, - 0xad, - 0xae, - 0xaf, - 0xb4, - 0xb5, - 0xb7, - 0xbc, - 0xbd, - 0xbe, - 0xbf, - {0xc3, 0x00, 0x00}, - {0xc3, 0x00, 0x01}, - {0xc3, 0x00, 0x40}, - {0xc3, 0x00, 0x41}, - {0xc3, 0x00, 0x50}, - {0xc3, 0x00, 0x51}, - {0xc3, 0x00, 0xa0}, - {0xc3, 0x00, 0xa1}, - {0xc3, 0x00, 0xe1}, - {0xc3, 0x00, 0xf1}, - 0xc4, - 0xc5, - 0xc6, - 0xc7, - 0xcc, - 0xcd, - 0xce, - 0xcf, - {0xd4, 0x00, 0x10}, - {0xd4, 0x00, 0x20}, - {0xd4, 0x00, 0x40}, - 0xd5, - 0xd6, - {0xdb, 0x00, 0x00}, - {0xdb, 0x00, 0x01}, - {0xdb, 0x00, 0x40}, - {0xdb, 0x00, 0x41}, - {0xdb, 0x00, 0x50}, - {0xdb, 0x00, 0x51}, - {0xdb, 0x00, 0x50}, - {0xdb, 0x00, 0xa0}, - {0xdb, 0x00, 0xa1}, - {0xdb, 0x00, 0xe1}, - {0xdb, 0x00, 0xf1}, - {0xdc, 0x00, 0x10}, - {0xdc, 0x00, 0x20}, - {0xdc, 0x00, 0x40}, - 0xdd, - 0xde, + {bpf_conformance_test_cpu_version_t::v1, 0x00}, + {bpf_conformance_test_cpu_version_t::v1, 0x04}, + {bpf_conformance_test_cpu_version_t::v1, 0x05}, + {bpf_conformance_test_cpu_version_t::v3, 0x06}, + {bpf_conformance_test_cpu_version_t::v1, 0x07}, + {bpf_conformance_test_cpu_version_t::v1, 0x0c}, + {bpf_conformance_test_cpu_version_t::v1, 0x0f}, + {bpf_conformance_test_cpu_version_t::v1, 0x14}, + {bpf_conformance_test_cpu_version_t::v1, 0x15}, + {bpf_conformance_test_cpu_version_t::v3, 0x16}, + {bpf_conformance_test_cpu_version_t::v1, 0x17}, + {bpf_conformance_test_cpu_version_t::v1, 0x18, 0x00}, + {bpf_conformance_test_cpu_version_t::v1, 0x18, 0x01}, + {bpf_conformance_test_cpu_version_t::v1, 0x18, 0x02}, + {bpf_conformance_test_cpu_version_t::v1, 0x18, 0x03}, + {bpf_conformance_test_cpu_version_t::v1, 0x18, 0x04}, + {bpf_conformance_test_cpu_version_t::v1, 0x18, 0x05}, + {bpf_conformance_test_cpu_version_t::v1, 0x18, 0x06}, + {bpf_conformance_test_cpu_version_t::v1, 0x1c}, + {bpf_conformance_test_cpu_version_t::v1, 0x1d}, + {bpf_conformance_test_cpu_version_t::v3, 0x1e}, + {bpf_conformance_test_cpu_version_t::v1, 0x1f}, + {bpf_conformance_test_cpu_version_t::v1, 0x24}, + {bpf_conformance_test_cpu_version_t::v1, 0x25}, + {bpf_conformance_test_cpu_version_t::v3, 0x26}, + {bpf_conformance_test_cpu_version_t::v1, 0x27}, + {bpf_conformance_test_cpu_version_t::v1, 0x2c}, + {bpf_conformance_test_cpu_version_t::v1, 0x2d}, + {bpf_conformance_test_cpu_version_t::v3, 0x2e}, + {bpf_conformance_test_cpu_version_t::v1, 0x2f}, + {bpf_conformance_test_cpu_version_t::v1, 0x34, 0x00, 0x00, 0x00}, + {bpf_conformance_test_cpu_version_t::v4, 0x34, 0x00, 0x00, 0x01}, + {bpf_conformance_test_cpu_version_t::v1, 0x35}, + {bpf_conformance_test_cpu_version_t::v3, 0x36}, + {bpf_conformance_test_cpu_version_t::v1, 0x37, 0x00, 0x00, 0x00}, + {bpf_conformance_test_cpu_version_t::v4, 0x37, 0x00, 0x00, 0x01}, + {bpf_conformance_test_cpu_version_t::v1, 0x3c, 0x00, 0x00, 0x00}, + {bpf_conformance_test_cpu_version_t::v4, 0x3c, 0x00, 0x00, 0x01}, + {bpf_conformance_test_cpu_version_t::v1, 0x3d}, + {bpf_conformance_test_cpu_version_t::v3, 0x3e}, + {bpf_conformance_test_cpu_version_t::v1, 0x3f, 0x00, 0x00, 0x00}, + {bpf_conformance_test_cpu_version_t::v4, 0x3f, 0x00, 0x00, 0x01}, + {bpf_conformance_test_cpu_version_t::v1, 0x44}, + {bpf_conformance_test_cpu_version_t::v1, 0x45}, + {bpf_conformance_test_cpu_version_t::v3, 0x46}, + {bpf_conformance_test_cpu_version_t::v1, 0x47}, + {bpf_conformance_test_cpu_version_t::v1, 0x4c}, + {bpf_conformance_test_cpu_version_t::v1, 0x4d}, + {bpf_conformance_test_cpu_version_t::v3, 0x4e}, + {bpf_conformance_test_cpu_version_t::v1, 0x4f}, + {bpf_conformance_test_cpu_version_t::v1, 0x54}, + {bpf_conformance_test_cpu_version_t::v1, 0x55}, + {bpf_conformance_test_cpu_version_t::v3, 0x56}, + {bpf_conformance_test_cpu_version_t::v1, 0x57}, + {bpf_conformance_test_cpu_version_t::v1, 0x5c}, + {bpf_conformance_test_cpu_version_t::v1, 0x5d}, + {bpf_conformance_test_cpu_version_t::v3, 0x5e}, + {bpf_conformance_test_cpu_version_t::v1, 0x5f}, + {bpf_conformance_test_cpu_version_t::v1, 0x61}, + {bpf_conformance_test_cpu_version_t::v1, 0x62}, + {bpf_conformance_test_cpu_version_t::v1, 0x63}, + {bpf_conformance_test_cpu_version_t::v1, 0x64}, + {bpf_conformance_test_cpu_version_t::v1, 0x65}, + {bpf_conformance_test_cpu_version_t::v3, 0x66}, + {bpf_conformance_test_cpu_version_t::v1, 0x67}, + {bpf_conformance_test_cpu_version_t::v1, 0x69}, + {bpf_conformance_test_cpu_version_t::v1, 0x6a}, + {bpf_conformance_test_cpu_version_t::v1, 0x6b}, + {bpf_conformance_test_cpu_version_t::v1, 0x6c}, + {bpf_conformance_test_cpu_version_t::v1, 0x6d}, + {bpf_conformance_test_cpu_version_t::v3, 0x6e}, + {bpf_conformance_test_cpu_version_t::v1, 0x6f}, + {bpf_conformance_test_cpu_version_t::v1, 0x71}, + {bpf_conformance_test_cpu_version_t::v1, 0x72}, + {bpf_conformance_test_cpu_version_t::v1, 0x73}, + {bpf_conformance_test_cpu_version_t::v1, 0x74}, + {bpf_conformance_test_cpu_version_t::v1, 0x75}, + {bpf_conformance_test_cpu_version_t::v3, 0x76}, + {bpf_conformance_test_cpu_version_t::v1, 0x77}, + {bpf_conformance_test_cpu_version_t::v1, 0x79}, + {bpf_conformance_test_cpu_version_t::v1, 0x7a}, + {bpf_conformance_test_cpu_version_t::v1, 0x7b}, + {bpf_conformance_test_cpu_version_t::v1, 0x7c}, + {bpf_conformance_test_cpu_version_t::v1, 0x7d}, + {bpf_conformance_test_cpu_version_t::v3, 0x7e}, + {bpf_conformance_test_cpu_version_t::v1, 0x7f}, + {bpf_conformance_test_cpu_version_t::v1, 0x84}, + {bpf_conformance_test_cpu_version_t::v1, 0x85, 0x00}, + {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::v1, 0x94}, + {bpf_conformance_test_cpu_version_t::v1, 0x95}, + {bpf_conformance_test_cpu_version_t::v1, 0x97}, + {bpf_conformance_test_cpu_version_t::v1, 0x9c}, + {bpf_conformance_test_cpu_version_t::v1, 0x9f}, + {bpf_conformance_test_cpu_version_t::v1, 0xa4}, + {bpf_conformance_test_cpu_version_t::v2, 0xa5}, + {bpf_conformance_test_cpu_version_t::v3, 0xa6}, + {bpf_conformance_test_cpu_version_t::v1, 0xa7}, + {bpf_conformance_test_cpu_version_t::v1, 0xac}, + {bpf_conformance_test_cpu_version_t::v2, 0xad}, + {bpf_conformance_test_cpu_version_t::v3, 0xae}, + {bpf_conformance_test_cpu_version_t::v1, 0xaf}, + {bpf_conformance_test_cpu_version_t::v1, 0xb4}, + {bpf_conformance_test_cpu_version_t::v2, 0xb5}, + {bpf_conformance_test_cpu_version_t::v3, 0xb6}, + {bpf_conformance_test_cpu_version_t::v1, 0xb7}, + {bpf_conformance_test_cpu_version_t::v1, 0xbc}, + {bpf_conformance_test_cpu_version_t::v2, 0xbd}, + {bpf_conformance_test_cpu_version_t::v3, 0xbe}, + {bpf_conformance_test_cpu_version_t::v1, 0xbf}, + {bpf_conformance_test_cpu_version_t::v3, 0xc3, 0x00, 0x00}, + {bpf_conformance_test_cpu_version_t::v3, 0xc3, 0x00, 0x01}, + {bpf_conformance_test_cpu_version_t::v3, 0xc3, 0x00, 0x40}, + {bpf_conformance_test_cpu_version_t::v3, 0xc3, 0x00, 0x41}, + {bpf_conformance_test_cpu_version_t::v3, 0xc3, 0x00, 0x50}, + {bpf_conformance_test_cpu_version_t::v3, 0xc3, 0x00, 0x51}, + {bpf_conformance_test_cpu_version_t::v3, 0xc3, 0x00, 0xa0}, + {bpf_conformance_test_cpu_version_t::v3, 0xc3, 0x00, 0xa1}, + {bpf_conformance_test_cpu_version_t::v3, 0xc3, 0x00, 0xe1}, + {bpf_conformance_test_cpu_version_t::v3, 0xc3, 0x00, 0xf1}, + {bpf_conformance_test_cpu_version_t::v1, 0xc4}, + {bpf_conformance_test_cpu_version_t::v2, 0xc5}, + {bpf_conformance_test_cpu_version_t::v3, 0xc6}, + {bpf_conformance_test_cpu_version_t::v1, 0xc7}, + {bpf_conformance_test_cpu_version_t::v1, 0xcc}, + {bpf_conformance_test_cpu_version_t::v2, 0xcd}, + {bpf_conformance_test_cpu_version_t::v3, 0xce}, + {bpf_conformance_test_cpu_version_t::v1, 0xcf}, + {bpf_conformance_test_cpu_version_t::v1, 0xd4, 0x00, 0x10}, + {bpf_conformance_test_cpu_version_t::v1, 0xd4, 0x00, 0x20}, + {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::v3, 0xdb, 0x00, 0x00}, + {bpf_conformance_test_cpu_version_t::v3, 0xdb, 0x00, 0x01}, + {bpf_conformance_test_cpu_version_t::v3, 0xdb, 0x00, 0x40}, + {bpf_conformance_test_cpu_version_t::v3, 0xdb, 0x00, 0x41}, + {bpf_conformance_test_cpu_version_t::v3, 0xdb, 0x00, 0x50}, + {bpf_conformance_test_cpu_version_t::v3, 0xdb, 0x00, 0x51}, + {bpf_conformance_test_cpu_version_t::v3, 0xdb, 0x00, 0x50}, + {bpf_conformance_test_cpu_version_t::v3, 0xdb, 0x00, 0xa0}, + {bpf_conformance_test_cpu_version_t::v3, 0xdb, 0x00, 0xa1}, + {bpf_conformance_test_cpu_version_t::v3, 0xdb, 0x00, 0xe1}, + {bpf_conformance_test_cpu_version_t::v3, 0xdb, 0x00, 0xf1}, + {bpf_conformance_test_cpu_version_t::v1, 0xdc, 0x00, 0x10}, + {bpf_conformance_test_cpu_version_t::v1, 0xdc, 0x00, 0x20}, + {bpf_conformance_test_cpu_version_t::v1, 0xdc, 0x00, 0x40}, + {bpf_conformance_test_cpu_version_t::v2, 0xdd}, + {bpf_conformance_test_cpu_version_t::v3, 0xde}, }; /** diff --git a/src/runner.cc b/src/runner.cc index 0895f4f..c03777a 100644 --- a/src/runner.cc +++ b/src/runner.cc @@ -111,7 +111,7 @@ main(int argc, char** argv) plugin_options.push_back(option); } - // Assume latest version if not specified. + // Assume version 3 if not specified. bpf_conformance_test_cpu_version_t cpu_version = bpf_conformance_test_cpu_version_t::v3; if (vm.count("cpu_version")) { std::string cpu_version_string = vm["cpu_version"].as(); @@ -121,6 +121,8 @@ main(int argc, char** argv) cpu_version = bpf_conformance_test_cpu_version_t::v2; } else if (cpu_version_string == "v3") { 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 { std::cout << "Invalid CPU version" << std::endl; return 1; diff --git a/tests/div-by-zero-reg.data b/tests/div32-by-zero-reg.data similarity index 100% rename from tests/div-by-zero-reg.data rename to tests/div32-by-zero-reg.data diff --git a/tests/sdiv32-by-zero-reg.data b/tests/sdiv32-by-zero-reg.data new file mode 100644 index 0000000..8013574 --- /dev/null +++ b/tests/sdiv32-by-zero-reg.data @@ -0,0 +1,9 @@ +# Copyright (c) Big Switch Networks, Inc +# SPDX-License-Identifier: Apache-2.0 +-- asm +mov32 %r0, 1 +mov32 %r1, 0 +sdiv32 %r0, %r1 +exit +-- result +0x0 diff --git a/tests/sdiv32-imm.data b/tests/sdiv32-imm.data new file mode 100644 index 0000000..ca425bd --- /dev/null +++ b/tests/sdiv32-imm.data @@ -0,0 +1,8 @@ +# Copyright (c) Big Switch Networks, Inc +# SPDX-License-Identifier: Apache-2.0 +-- asm +lddw %r0, 0x10000000c +sdiv32 %r0, -4 +exit +-- result +0xfffffffd diff --git a/tests/sdiv32-reg.data b/tests/sdiv32-reg.data new file mode 100644 index 0000000..182a9c0 --- /dev/null +++ b/tests/sdiv32-reg.data @@ -0,0 +1,9 @@ +# Copyright (c) Big Switch Networks, Inc +# SPDX-License-Identifier: Apache-2.0 +-- asm +lddw %r0, 0x10000000c +mov %r1, -4 +sdiv32 %r0, %r1 +exit +-- result +0xfffffffd diff --git a/tests/sdiv64-by-zero-reg.data b/tests/sdiv64-by-zero-reg.data new file mode 100644 index 0000000..8011f38 --- /dev/null +++ b/tests/sdiv64-by-zero-reg.data @@ -0,0 +1,9 @@ +# Copyright (c) Big Switch Networks, Inc +# SPDX-License-Identifier: Apache-2.0 +-- asm +mov32 %r0, 1 +mov32 %r1, 0 +sdiv %r0, %r1 +exit +-- result +0x0 diff --git a/tests/sdiv64-imm.data b/tests/sdiv64-imm.data new file mode 100644 index 0000000..0451680 --- /dev/null +++ b/tests/sdiv64-imm.data @@ -0,0 +1,9 @@ +# Copyright (c) Big Switch Networks, Inc +# SPDX-License-Identifier: Apache-2.0 +-- asm +mov %r0, 0xc +lsh %r0, 32 +sdiv %r0, -4 +exit +-- result +0xfffffffd00000000 diff --git a/tests/sdiv64-reg.data b/tests/sdiv64-reg.data new file mode 100644 index 0000000..09ea66a --- /dev/null +++ b/tests/sdiv64-reg.data @@ -0,0 +1,10 @@ +# Copyright (c) Big Switch Networks, Inc +# SPDX-License-Identifier: Apache-2.0 +-- asm +mov %r0, 0xc +lsh %r0, 32 +mov %r1, -4 +sdiv %r0, %r1 +exit +-- result +0xfffffffd00000000