]>
Witch of Git - jade-rose/blob - toolchain/src/inst/decode.rs
1 use super::{AddImm
, AluI
, Data
, Inst
, Op1
, OpI3
, OpR
, Reg
, Special
, Target
, U3
};
2 use std
::io
::{self, Read
};
4 pub trait Decode
: Sized
{
5 fn decode(reader
: &mut impl Read
) -> io
::Result
<Self>;
9 Reg
::new(x
& 0x7).unwrap
()
12 fn special(x
: u8) -> io
::Result
<Special
> {
14 0b000 => Ok(Special
::Data(Data
::D1
)),
15 0b001 => Ok(Special
::Data(Data
::D2
)),
16 0b010 => Ok(Special
::Code
),
17 0b011 => Err(io
::Error
::new(
19 "Reserved special register",
21 _
=> Err(io
::Error
::new(
23 "Invalid special register",
28 fn op1(x
: u8) -> Op1
{
42 fn op_r(x
: u8) -> OpR
{
56 fn flag(x
: u8) -> bool
{
60 fn op_compact(x
: u8) -> OpI3
{
74 impl Decode
for Inst
{
75 fn decode(reader
: &mut impl Read
) -> io
::Result
<Self> {
77 let mut op_byte
= [0];
78 reader
.read_exact(&mut op_byte
)?
;
79 Ok(match (op_byte
[0] >> 3, op_byte
[0] & 7) {
80 (0b0000_0, 0..=2) => Inst
::Trap
,
81 (0b0000_0, 0b100) => Inst
::Jump(Target
::Abs
),
82 (0b0000_0, 0b101) => Inst
::Call(Target
::Abs
),
83 (0b0000_0, 0b110) => Inst
::Jump(Target
::Off
),
84 (0b0000_0, 0b111) => Inst
::Call(Target
::Off
),
85 (0b0000_1, r
) => Inst
::Swap(reg(r
)),
86 (0b0001_0, r
) => Inst
::GetR(reg(r
)),
87 (0b0001_1, r
) => Inst
::SetR(reg(r
)),
88 (0b0010_0, s
) => Inst
::Get(special(s
)?
),
89 (0b0010_1, s
) => Inst
::Set(special(s
)?
),
90 (0b0011_0, o
) => Inst
::Alu1(op1(o
)),
91 (0b0011_1, r
) => Inst
::IsLt(reg(r
)),
92 (o @
0b0100_0..=0b0111_1, r
) => Inst
::AluR(op_r(o
), reg(r
)),
93 (o @
0b1000_0, r
) | (o @
0b1001_0, r
) => Inst
::LdD(D1
, reg(r
), flag(o
)),
94 (o @
0b1000_1, r
) | (o @
0b1001_1, r
) => Inst
::StD(D1
, reg(r
), flag(o
)),
95 (o @
0b1010_0, r
) | (o @
0b1011_0, r
) => Inst
::LdD(D2
, reg(r
), flag(o
)),
96 (o @
0b1010_1, r
) | (o @
0b1011_1, r
) => Inst
::StD(D2
, reg(r
), flag(o
)),
97 (0b1111_0..=0b1111_1, _
) => {
98 let mut imm_byte
= [0];
99 reader
.read_exact(&mut imm_byte
)?
;
100 let imm
= imm_byte
[0];
101 match op_byte
[0] & 0xf {
102 0b0000 => Inst
::AluI(AluI
::And(imm
)),
103 0b0001 => Inst
::AluI(AluI
::Ior(imm
)),
104 0b0010 => Inst
::AluI(AluI
::Xor(imm
)),
105 0b0011 => match imm
>> 6 {
106 0b00 | 0b01 | 0b11 => {
107 Inst
::AluI(AluI
::Add(AddImm
::new(imm
as i8).unwrap
()))
110 let imm3
= U3
::new(imm
& 7).unwrap
();
111 Inst
::AluI(AluI
::Compact(op_compact(imm
), imm3
))
115 0b0100 => Inst
::BEzI(imm
as i8),
116 0b0101 => Inst
::Trap
, /* reserved branch */
117 0b0110 => Inst
::Jump(Target
::OffImm(imm
as i8)),
118 0b0111 => Inst
::Call(Target
::OffImm(imm
as i8)),
119 _
=> Inst
::Trap
, /* reserved with immediate */