// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! Bind program instructions

#![allow(dead_code)]

bitfield! {
    /// Each instruction is a pair of 32 bit unsigned integers divided as
    /// follows.
    /// lsb           msb
    /// COAABBBB VVVVVVVV  Condition Opcode paramA paramB Value
    struct RawInstruction([u32]);
    u32;
    condition, set_condition: 3, 0;
    operation, set_operation: 7, 4;
    parameter_a, set_parameter_a: 15, 8;
    parameter_b, set_parameter_b: 31, 16;
    value, set_value: 63, 32;
}

/// For all conditions (except Always), the operands to the condition
/// are (parameter_b, value) pairs in the final encoding.
#[derive(PartialEq, Eq)]
pub enum Condition {
    Always,
    Equal(u32, u32),
    NotEqual(u32, u32),
    GreaterThan(u32, u32),
    LessThan(u32, u32),
    GreaterThanEqual(u32, u32),
    LessThanEqual(u32, u32),
}

pub enum Instruction {
    Abort(Condition),
    Match(Condition),
    Goto(Condition, u32),
    Label(u32),
}

fn to_raw_condition(condition: Condition) -> (u32, u32, u32) {
    match condition {
        Condition::Always => (0, 0, 0),
        Condition::Equal(b, v) => (1, b, v),
        Condition::NotEqual(b, v) => (2, b, v),
        Condition::GreaterThan(b, v) => (3, b, v),
        Condition::LessThan(b, v) => (4, b, v),
        Condition::GreaterThanEqual(b, v) => (5, b, v),
        Condition::LessThanEqual(b, v) => (6, b, v),
    }
}

fn to_raw_instruction(instruction: Instruction) -> RawInstruction<[u32; 2]> {
    let (c, o, a, b, v) = match instruction {
        Instruction::Abort(condition) => {
            let (c, b, v) = to_raw_condition(condition);
            (c, 0, 0, b, v)
        }
        Instruction::Match(condition) => {
            let (c, b, v) = to_raw_condition(condition);
            (c, 1, 0, b, v)
        }
        Instruction::Goto(condition, a) => {
            let (c, b, v) = to_raw_condition(condition);
            (c, 2, a, b, v)
        }
        Instruction::Label(a) => (0, 5, a, 0, 0),
    };
    let mut raw_instruction = RawInstruction([0, 0]);
    raw_instruction.set_condition(c);
    raw_instruction.set_operation(o);
    raw_instruction.set_parameter_a(a);
    raw_instruction.set_parameter_b(b);
    raw_instruction.set_value(v);
    raw_instruction
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_raw_instruction() {
        let mut raw = RawInstruction([0, 0]);
        assert_eq!(raw.0[0], 0);
        assert_eq!(raw.0[1], 0);
        assert_eq!(raw.condition(), 0);
        assert_eq!(raw.operation(), 0);
        assert_eq!(raw.parameter_a(), 0);
        assert_eq!(raw.parameter_b(), 0);
        assert_eq!(raw.value(), 0);

        raw.set_condition(1);
        assert_eq!(raw.0[0], 1);
        assert_eq!(raw.0[1], 0);
        assert_eq!(raw.condition(), 1);
        assert_eq!(raw.operation(), 0);
        assert_eq!(raw.parameter_a(), 0);
        assert_eq!(raw.parameter_b(), 0);
        assert_eq!(raw.value(), 0);

        raw.set_operation(2);
        assert_eq!(raw.0[0], 1 | (2 << 4));
        assert_eq!(raw.0[1], 0);
        assert_eq!(raw.condition(), 1);
        assert_eq!(raw.operation(), 2);
        assert_eq!(raw.parameter_a(), 0);
        assert_eq!(raw.parameter_b(), 0);
        assert_eq!(raw.value(), 0);

        raw.set_parameter_a(3);
        assert_eq!(raw.0[0], 1 | (2 << 4) | (3 << 8));
        assert_eq!(raw.0[1], 0);
        assert_eq!(raw.condition(), 1);
        assert_eq!(raw.operation(), 2);
        assert_eq!(raw.parameter_a(), 3);
        assert_eq!(raw.parameter_b(), 0);
        assert_eq!(raw.value(), 0);

        raw.set_parameter_b(4);
        assert_eq!(raw.0[0], 1 | (2 << 4) | (3 << 8) | (4 << 16));
        assert_eq!(raw.0[1], 0);
        assert_eq!(raw.condition(), 1);
        assert_eq!(raw.operation(), 2);
        assert_eq!(raw.parameter_a(), 3);
        assert_eq!(raw.parameter_b(), 4);
        assert_eq!(raw.value(), 0);

        raw.set_value(5);
        assert_eq!(raw.0[0], 1 | (2 << 4) | (3 << 8) | (4 << 16));
        assert_eq!(raw.0[1], 5);
        assert_eq!(raw.condition(), 1);
        assert_eq!(raw.operation(), 2);
        assert_eq!(raw.parameter_a(), 3);
        assert_eq!(raw.parameter_b(), 4);
        assert_eq!(raw.value(), 5)
    }

    #[test]
    fn test_abort_value() {
        let instruction = Instruction::Abort(Condition::Always);
        let raw_instruction = to_raw_instruction(instruction);
        assert_eq!(raw_instruction.0[0], 0 << 4);
        assert_eq!(raw_instruction.0[1], 0);
        assert_eq!(raw_instruction.operation(), 0)
    }

    #[test]
    fn test_match_value() {
        let instruction = Instruction::Match(Condition::Always);
        let raw_instruction = to_raw_instruction(instruction);
        assert_eq!(raw_instruction.0[0], 1 << 4);
        assert_eq!(raw_instruction.0[1], 0);
        assert_eq!(raw_instruction.operation(), 1)
    }

    #[test]
    fn test_goto_value() {
        let instruction = Instruction::Goto(Condition::Always, 0);
        let raw_instruction = to_raw_instruction(instruction);
        assert_eq!(raw_instruction.0[0], 2 << 4);
        assert_eq!(raw_instruction.0[1], 0);
        assert_eq!(raw_instruction.operation(), 2)
    }

    #[test]
    fn test_label_value() {
        let instruction = Instruction::Label(0);
        let raw_instruction = to_raw_instruction(instruction);
        assert_eq!(raw_instruction.0[0], 5 << 4);
        assert_eq!(raw_instruction.0[1], 0);
        assert_eq!(raw_instruction.operation(), 5)
    }

    #[test]
    fn test_complicated_value() {
        let instruction = Instruction::Goto(Condition::LessThan(23, 1234), 42);
        let raw_instruction = to_raw_instruction(instruction);
        assert_eq!(raw_instruction.0[0], 4 | (2 << 4) | (42 << 8) | (23 << 16));
        assert_eq!(raw_instruction.0[1], 1234);
        assert_eq!(raw_instruction.condition(), 4);
        assert_eq!(raw_instruction.operation(), 2);
        assert_eq!(raw_instruction.parameter_a(), 42);
        assert_eq!(raw_instruction.parameter_b(), 23);
        assert_eq!(raw_instruction.value(), 1234)
    }
}
