// AVM ISA v1 — C++ Test Harness #include #include #include "avm.hpp" using namespace avm; #define QS Q16_SCALE void test_basic_add() { auto prog = std::vector{ {Op::PushQ16, 5 * QS}, {Op::PushQ16, 3 * QS}, {Op::Primitive, static_cast(Prim::AddSatQ16)}, {Op::Halt}}; auto s = run(init_state(), prog, 100); assert(s->stack[0].val == 8 * QS); std::cout << " ✅ basic_add: 5 + 3 = 8\n"; } void test_div_q16() { auto prog = std::vector{ {Op::PushQ16, 3 * QS}, {Op::PushQ16, 5 * QS}, {Op::Primitive, static_cast(Prim::DivSatQ16)}, {Op::Halt}}; auto s = run(init_state(), prog, 100); int exp = (3 * QS) / 5; assert(std::get(s->stack[0].val) == exp); std::cout << " ✅ div_q16: 3/5 = 0.6\n"; } void test_saturation() { auto prog = std::vector{ {Op::PushQ16, AVM_CLAMP_MAX - 1}, {Op::PushQ16, 2}, {Op::Primitive, static_cast(Prim::AddSatQ16)}, {Op::Halt}}; auto s = run(init_state(), prog, 100); assert(std::get(s->stack[0].val) == AVM_CLAMP_MAX); std::cout << " ✅ saturation: max-1+2 = max\n"; } void test_v6_lt() { struct Case { int32_t a, b; bool exp; } cases[] = { {-5*QS, -3*QS, true}, {-3*QS, -5*QS, false}, {5*QS, 3*QS, false}, {3*QS, 5*QS, true}, {-1*QS, 2*QS, true}}; for (auto c : cases) { auto prog = std::vector{ {Op::PushQ16, c.a}, {Op::PushQ16, c.b}, {Op::Primitive, static_cast(Prim::LtQ16)}, {Op::Halt}}; auto s = run(init_state(), prog, 100); assert(std::get(s->stack[0].val) == c.exp); } std::cout << " ✅ v6_lt: 5 cases pass\n"; } void test_type_mismatch() { auto prog = std::vector{ {Op::PushBool, 0, true}, {Op::PushQ16, QS}, {Op::Primitive, static_cast(Prim::AddSatQ16)}}; auto s = run(init_state(), prog, 100); assert(!s.has_value()); std::cout << " ✅ type_mismatch: rejected\n"; } void test_div_by_zero() { auto prog = std::vector{ {Op::PushQ16, QS}, {Op::PushQ16, 0}, {Op::Primitive, static_cast(Prim::DivSatQ16)}}; auto s = run(init_state(), prog, 100); assert(!s.has_value()); std::cout << " ✅ div_by_zero: rejected\n"; } void test_stack_overflow() { auto prog = std::vector(AVM_MAX_STACK + 1, Instr{Op::PushQ16, 0}); auto s = run(init_state(), prog, 10000); assert(!s.has_value()); std::cout << " ✅ stack_overflow: rejected\n"; } void test_control_flow() { auto prog = std::vector{ {Op::PushBool, 0, true}, {Op::JumpIf, 4}, {Op::PushQ16, 0}, {Op::Halt}, {Op::PushQ16, QS}, {Op::Halt}}; auto s = run(init_state(), prog, 100); assert(std::get(s->stack[0].val) == QS); std::cout << " ✅ control_flow: jump_if true\n"; } void test_locals() { auto prog = std::vector{ {Op::PushQ16, 42 * QS}, {Op::Store, 0}, {Op::Load, 0}, {Op::Halt}}; auto s = run(init_state(1), prog, 100); assert(std::get(s->stack[0].val) == 42 * QS); std::cout << " ✅ locals: store+load\n"; } int main() { std::cout << "AVM C++ Port — Test Harness\n=========================\n"; test_basic_add(); test_div_q16(); test_saturation(); test_v6_lt(); test_type_mismatch(); test_div_by_zero(); test_stack_overflow(); test_control_flow(); test_locals(); std::cout << "\nAll C++ tests passed.\n"; return 0; }