]>
Witch of Git - jade-rose/blob - toolchain/src/inst/decode.rs
1 use super::{AddImm
, AluI
, Data
, Inst
, LdSt
, Op1
, OpI3
, OpR
, Reg
, Special
, 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(
18 io
::ErrorKind
::InvalidInput
,
19 "Reserved special register",
21 _
=> Err(io
::Error
::new(
22 io
::ErrorKind
::InvalidInput
,
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 fn ldst(o
: u8) -> LdSt
{
82 fn data(o
: u8) -> Data
{
90 impl Decode
for Inst
{
91 fn decode(reader
: &mut impl Read
) -> io
::Result
<Self> {
92 let mut op_byte
= [0];
93 reader
.read_exact(&mut op_byte
)?
;
94 Ok(match (op_byte
[0] >> 3, op_byte
[0] & 7) {
95 (0b0000_0, 0b000) => Inst
::Trap
,
96 (0b0000_0, 0b001) => Inst
::Nope
,
97 (0b0000_0, 0b010) => Inst
::Prnt
,
98 (0b0000_0, 0b110) => Inst
::CAbA
,
99 (0b0000_0, 0b111) => Inst
::COfA
,
100 (0b0000_1, o
) => Inst
::Alu1(op1(o
)),
101 (0b0001_0, s
) => Inst
::Get(special(s
)?
),
102 (0b0001_1, s
) => Inst
::Set(special(s
)?
),
103 (0b0010_0, r
) => Inst
::GetR(reg(r
)),
104 (0b0010_1, r
) => Inst
::SetR(reg(r
)),
105 (0b0011_0, r
) => Inst
::Swap(reg(r
)),
106 (0b0011_1, r
) => Inst
::IsLt(reg(r
)),
107 (o @
0b0100_0..=0b0111_1, r
) => Inst
::AluR(op_r(o
), reg(r
)),
108 (o @
0b1000_0..=0b1011_1, r
) => Inst
::Mem(ldst(o
), data(o
), reg(r
), flag(o
)),
109 (0b1111_0..=0b1111_1, _
) => {
110 let mut imm_byte
= [0];
112 .read_exact(&mut imm_byte
)
113 .map_err(|e
| match e
.kind() {
114 io
::ErrorKind
::UnexpectedEof
=> io
::Error
::new(
115 io
::ErrorKind
::InvalidInput
,
116 "Extended instruction missing operand",
120 let imm
= imm_byte
[0];
121 match op_byte
[0] & 0xf {
122 0b0000 => Inst
::AluI(AluI
::And(imm
)),
123 0b0001 => Inst
::AluI(AluI
::Ior(imm
)),
124 0b0010 => Inst
::AluI(AluI
::Xor(imm
)),
125 0b0011 => match imm
>> 6 {
126 0b00 | 0b01 | 0b11 => {
127 Inst
::AluI(AluI
::Add(AddImm
::new(imm
as i8).unwrap
()))
130 let imm3
= U3
::new(imm
& 7).unwrap
();
131 Inst
::AluI(AluI
::Compact(op_compact(imm
), imm3
))
135 0b0100 => Inst
::BEzI(imm
as i8),
136 0b0101 => Inst
::JOfI(imm
as i8), /* reserved branch */
137 0b0110 => Inst
::CAbI(imm
),
138 0b0111 => Inst
::COfI(imm
as i8),
139 0b1110 => Inst
::GetI(imm
),
141 return Err(io
::Error
::new(
142 io
::ErrorKind
::InvalidInput
,
143 "reserved extended EXT1",
145 } /* reserved with immediate */
147 return Err(io
::Error
::new(
148 io
::ErrorKind
::InvalidInput
,
149 "reseved with immediate",
151 } /* reserved with immediate */
155 return Err(io
::Error
::new(
156 io
::ErrorKind
::InvalidInput
,
157 "invalid instruction",