]>
Witch of Git - jade-mouse/blob - toolchain/src/inst/encode.rs
1 use crate::inst
::{Addr
, Cond
, Inst
, Reg
, I7
, U4
};
2 use std
::io
::{self, Write
};
5 fn encode(&self, out
: &mut impl Write
) -> io
::Result
<()>;
8 fn unpack_cond(c
: Cond
) -> (u8, u8, Reg
, Reg
) {
10 let (o2
, o1
, ra
, rb
) = match c
{
11 Eql(ra
, rb
) => (0, 0, ra
.min(rb
), ra
.max(rb
)),
12 Neq(ra
, rb
) => (0, 0, ra
.max(rb
), ra
.min(rb
)),
13 Test(ra
, rb
) => (0, 1, ra
.min(rb
), ra
.max(rb
)),
14 TestNot(ra
, rb
) => (0, 1, ra
.min(rb
), ra
.max(rb
)),
15 Lt(ra
, rb
) => (1, 0, ra
, rb
),
16 Ult(ra
, rb
) => (1, 1, ra
, rb
),
18 debug_assert_ne
!(ra
, rb
, "ra == rb reserved for fixed addressing");
22 impl Encode
for Inst
{
23 fn encode(&self, out
: &mut impl Write
) -> io
::Result
<()> {
26 Halt
=> out
.write_all(&[0x00])?
,
27 Nope
=> out
.write_all(&[0x01])?
,
29 out
.write_all(&[0x00 | (op
as u8) << 4 | (rd
as u8) << 2 | r2
as u8])?
31 Jalr(r
) => out
.write_all(&[0x80 | (r
as u8) << 2 | r
as u8])?
,
33 debug_assert_ne
!(rd
, r2
, "Can't move to self");
34 out
.write_all(&[0x00, (rd
as u8) << 2 | r2
as u8])?
36 Alu1(r
, op
) => out
.write_all(&[0x90 | (r
as u8) << 2 | op
as u8])?
,
37 Mem(op
, r_data
, Addr
::Reg(r_addr
)) => {
38 out
.write_all(&[0xa0 | (op
as u8) << 4 | (r_data
as u8) << 2 | r_addr
as u8])?
40 Branch(cond
, I7(off
)) => {
41 let (o2
, o1
, ra
, rb
) = unpack_cond(cond
);
43 0xc0 | o2
<< 4 | (ra
as u8) << 2 | rb
as u8,
47 JumpI(off
) => out
.write_all(&[0xc0, off
as u8])?
,
48 Mem(op
, rd
, Addr
::Fixed(addr
)) => out
.write_all(&[])?
,
49 AddI(rd
, imm
) => out
.write_all(&[0xe0 | (rd
as u8) << 2, imm
as u8])?
,
50 AluCompact(rd
, op
, U4(imm
)) => {
51 out
.write_all(&[0xe1 | (rd
as u8) << 2, (op
as u8) << 4 | imm
as u8])?
53 LdImm(h
, rd
, imm
) => out
.write_all(&[0xe2 | (h
as u8) << 1, imm
])?
,
63 ) => out
.write_all(&[])?
,