lib/std/lang/il/tests.rad 3.8 KiB raw
1
//! Tests for RIL source register iteration.
2
3
use std::testing;
4
5
/// Require exact source-register order and stable exhaustion.
6
unsafe fn check(instr: super::Instr, expected: &[u32]) throws (testing::TestError) {
7
    let mut cursor = super::registers(&instr);
8
    for value in expected {
9
        let reg = super::nextReg(&mut cursor, &instr) else panic;
10
        try testing::expect(reg.n == value);
11
    }
12
    try testing::expect(super::nextReg(&mut cursor, &instr) == nil);
13
    try testing::expect(super::nextReg(&mut cursor, &instr) == nil);
14
}
15
16
@test unsafe fn testRegisterIteration() throws (testing::TestError) {
17
    let dst = super::Reg { n: 99 };
18
    let r1 = super::Reg { n: 1 };
19
    let r2 = super::Reg { n: 2 };
20
    let a = super::Val::Reg(r1);
21
    let b = super::Val::Reg(r2);
22
    let imm = super::Val::Imm(7);
23
    try check(super::Instr::Reserve { dst, size: a, alignment: 8 }, &[1]);
24
    try check(super::Instr::Reserve { dst, size: imm, alignment: 8 }, &[]);
25
    try check(super::Instr::Load { typ: super::Type::W64, dst, src: r1, offset: 0 }, &[1]);
26
    try check(super::Instr::Sload { typ: super::Type::W32, dst, src: r2, offset: 0 }, &[2]);
27
    try check(super::Instr::Store { typ: super::Type::W64, src: a, dst: r2, offset: 0 }, &[1, 2]);
28
    try check(super::Instr::Store { typ: super::Type::W64, src: imm, dst: r2, offset: 0 }, &[2]);
29
    try check(super::Instr::Blit { dst: r1, src: r2, size: a }, &[1, 2, 1]);
30
    try check(super::Instr::Blit { dst: r1, src: r2, size: imm }, &[1, 2]);
31
    try check(super::Instr::Copy { dst, val: a }, &[1]);
32
    try check(super::Instr::Copy { dst, val: imm }, &[]);
33
    try check(super::Instr::Copy { dst, val: super::Val::DataSym("data") }, &[]);
34
    try check(super::Instr::Copy { dst, val: super::Val::Undef }, &[]);
35
    try check(super::Instr::BinOp { op: super::BinOp::Add, typ: super::Type::W64, dst, a: imm, b }, &[2]);
36
    try check(super::Instr::BinOp { op: super::BinOp::Add, typ: super::Type::W64, dst, a, b: a }, &[1, 1]);
37
    try check(super::Instr::UnOp { op: super::UnOp::Neg, typ: super::Type::W64, dst, a }, &[1]);
38
    try check(super::Instr::Zext { typ: super::Type::W8, dst, val: a }, &[1]);
39
    try check(super::Instr::Sext { typ: super::Type::W8, dst, val: b }, &[2]);
40
    let mut args = [imm, a, b, a];
41
    try check(super::Instr::Call { retTy: super::Type::W64, dst, func: b, args: &args[..] }, &[2, 1, 2, 1]);
42
    try check(super::Instr::Call { retTy: super::Type::W64, dst: nil, func: super::Val::FnAddr("callee"), args: &[] }, &[]);
43
    try check(super::Instr::Ret { val: a }, &[1]);
44
    try check(super::Instr::Ret { val: nil }, &[]);
45
    try check(super::Instr::Jmp { target: 0, args: &mut args[..] }, &[1, 2, 1]);
46
    let mut other = [b, imm];
47
    try check(super::Instr::Br { op: super::CmpOp::Eq, typ: super::Type::W64, a, b,
48
        thenTarget: 0, thenArgs: &mut args[..], elseTarget: 1, elseArgs: &mut other[..] }, &[1, 2, 1, 2, 1, 2]);
49
    let mut cases = [
50
        super::SwitchCase { value: 0, target: 0, args: &mut [] },
51
        super::SwitchCase { value: 1, target: 1, args: &mut args[..] },
52
        super::SwitchCase { value: 2, target: 2, args: &mut [] },
53
        super::SwitchCase { value: 3, target: 3, args: &mut other[..] },
54
    ];
55
    try check(super::Instr::Switch { val: b, defaultTarget: 0, defaultArgs: &mut [], cases: &mut cases[..] }, &[2, 1, 2, 1, 2]);
56
    try check(super::Instr::Switch { val: imm, defaultTarget: 0, defaultArgs: &mut args[..], cases: &mut [] }, &[1, 2, 1]);
57
    try check(super::Instr::Switch { val: imm, defaultTarget: 0, defaultArgs: &mut [], cases: &mut [] }, &[]);
58
    try check(super::Instr::Ecall { dst, num: a, a0: imm, a1: b, a2: a, a3: imm }, &[1, 2, 1]);
59
    try check(super::Instr::Ecall { dst, num: a, a0: b, a1: a, a2: b, a3: a }, &[1, 2, 1, 2, 1]);
60
    try check(super::Instr::Unreachable, &[]);
61
    try check(super::Instr::Ebreak, &[]);
62
    try check(super::Instr::MemoryFence, &[]);
63
64
}