├── src ├── machine │ ├── behavior │ │ ├── mod.rs │ │ ├── is │ │ │ ├── interrupt │ │ │ │ ├── mod.rs │ │ │ │ ├── trip.rs │ │ │ │ ├── resume.rs │ │ │ │ └── trap.rs │ │ │ ├── other │ │ │ │ ├── mod.rs │ │ │ │ ├── swym.rs │ │ │ │ ├── get.rs │ │ │ │ ├── geta.rs │ │ │ │ ├── getab.rs │ │ │ │ ├── puti.rs │ │ │ │ └── put.rs │ │ │ ├── float │ │ │ │ ├── fix.rs │ │ │ │ ├── fixu.rs │ │ │ │ ├── sflot.rs │ │ │ │ ├── sfloti.rs │ │ │ │ ├── sflotu.rs │ │ │ │ ├── sflotui.rs │ │ │ │ ├── fadd.rs │ │ │ │ ├── fdiv.rs │ │ │ │ ├── fmul.rs │ │ │ │ ├── frem.rs │ │ │ │ ├── fsub.rs │ │ │ │ ├── feql.rs │ │ │ │ ├── stsfi.rs │ │ │ │ ├── ldsfi.rs │ │ │ │ ├── mod.rs │ │ │ │ ├── fcmp.rs │ │ │ │ ├── feqle.rs │ │ │ │ ├── stsf.rs │ │ │ │ ├── fsqrt.rs │ │ │ │ ├── fun.rs │ │ │ │ ├── ldsf.rs │ │ │ │ ├── floti.rs │ │ │ │ ├── flotui.rs │ │ │ │ ├── flot.rs │ │ │ │ ├── flotu.rs │ │ │ │ ├── fcmpe.rs │ │ │ │ ├── fint.rs │ │ │ │ └── fune.rs │ │ │ ├── subroutine │ │ │ │ ├── pop.rs │ │ │ │ ├── save.rs │ │ │ │ ├── pushgo.rs │ │ │ │ ├── pushgoi.rs │ │ │ │ ├── pushj.rs │ │ │ │ ├── pushjb.rs │ │ │ │ ├── unsave.rs │ │ │ │ └── mod.rs │ │ │ ├── system │ │ │ │ ├── preld.rs │ │ │ │ ├── sync.rs │ │ │ │ ├── prego.rs │ │ │ │ ├── pregoi.rs │ │ │ │ ├── prest.rs │ │ │ │ ├── presti.rs │ │ │ │ ├── syncd.rs │ │ │ │ ├── preldi.rs │ │ │ │ ├── ldvts.rs │ │ │ │ ├── syncdi.rs │ │ │ │ ├── syncid.rs │ │ │ │ ├── ldvtsi.rs │ │ │ │ ├── syncidi.rs │ │ │ │ ├── ldunc.rs │ │ │ │ ├── stunc.rs │ │ │ │ ├── ldunci.rs │ │ │ │ ├── stunci.rs │ │ │ │ ├── mod.rs │ │ │ │ ├── cswapi.rs │ │ │ │ └── cswap.rs │ │ │ ├── control │ │ │ │ ├── pbev.rs │ │ │ │ ├── pbn.rs │ │ │ │ ├── pbnb.rs │ │ │ │ ├── pbnn.rs │ │ │ │ ├── pbnp.rs │ │ │ │ ├── pbnz.rs │ │ │ │ ├── pbod.rs │ │ │ │ ├── pbp.rs │ │ │ │ ├── pbpb.rs │ │ │ │ ├── pbz.rs │ │ │ │ ├── pbzb.rs │ │ │ │ ├── pbevb.rs │ │ │ │ ├── pbnnb.rs │ │ │ │ ├── pbnpb.rs │ │ │ │ ├── pbnzb.rs │ │ │ │ ├── pbodb.rs │ │ │ │ ├── goi.rs │ │ │ │ ├── go.rs │ │ │ │ ├── jmp.rs │ │ │ │ ├── jmpb.rs │ │ │ │ ├── bn.rs │ │ │ │ ├── bnn.rs │ │ │ │ ├── bnp.rs │ │ │ │ ├── bnz.rs │ │ │ │ ├── bp.rs │ │ │ │ ├── bz.rs │ │ │ │ ├── bev.rs │ │ │ │ ├── bod.rs │ │ │ │ ├── bnb.rs │ │ │ │ ├── bpb.rs │ │ │ │ ├── bzb.rs │ │ │ │ ├── bevb.rs │ │ │ │ ├── bnnb.rs │ │ │ │ ├── bnpb.rs │ │ │ │ ├── bnzb.rs │ │ │ │ ├── bodb.rs │ │ │ │ └── mod.rs │ │ │ ├── memory │ │ │ │ ├── lda.rs │ │ │ │ ├── ldou.rs │ │ │ │ ├── stbu.rs │ │ │ │ ├── stou.rs │ │ │ │ ├── sttu.rs │ │ │ │ ├── stwu.rs │ │ │ │ ├── ldoui.rs │ │ │ │ ├── stbui.rs │ │ │ │ ├── stoui.rs │ │ │ │ ├── stwui.rs │ │ │ │ ├── sttui.rs │ │ │ │ ├── ldoi.rs │ │ │ │ ├── stoi.rs │ │ │ │ ├── stcoi.rs │ │ │ │ ├── ldo.rs │ │ │ │ ├── sto.rs │ │ │ │ ├── stco.rs │ │ │ │ ├── stbi.rs │ │ │ │ ├── stti.rs │ │ │ │ ├── stwi.rs │ │ │ │ ├── ldbi.rs │ │ │ │ ├── ldwi.rs │ │ │ │ ├── ldti.rs │ │ │ │ ├── ldbui.rs │ │ │ │ ├── ldwui.rs │ │ │ │ ├── sthti.rs │ │ │ │ ├── ldtui.rs │ │ │ │ ├── stb.rs │ │ │ │ ├── stw.rs │ │ │ │ ├── ldb.rs │ │ │ │ ├── ldhti.rs │ │ │ │ ├── stt.rs │ │ │ │ ├── ldt.rs │ │ │ │ ├── ldw.rs │ │ │ │ ├── ldbu.rs │ │ │ │ ├── ldtu.rs │ │ │ │ ├── ldwu.rs │ │ │ │ ├── stht.rs │ │ │ │ ├── ldht.rs │ │ │ │ └── mod.rs │ │ │ ├── arithmetic │ │ │ │ ├── negi.rs │ │ │ │ ├── negui.rs │ │ │ │ ├── muli.rs │ │ │ │ ├── neg.rs │ │ │ │ ├── addi.rs │ │ │ │ ├── addui.rs │ │ │ │ ├── cmpi.rs │ │ │ │ ├── negu.rs │ │ │ │ ├── sli.rs │ │ │ │ ├── slui.rs │ │ │ │ ├── sri.rs │ │ │ │ ├── srui.rs │ │ │ │ ├── subi.rs │ │ │ │ ├── subui.rs │ │ │ │ ├── cmpui.rs │ │ │ │ ├── addu16i.rs │ │ │ │ ├── addu2i.rs │ │ │ │ ├── addu4i.rs │ │ │ │ ├── addu8i.rs │ │ │ │ ├── add.rs │ │ │ │ ├── addu.rs │ │ │ │ ├── mul.rs │ │ │ │ ├── sub.rs │ │ │ │ ├── subu.rs │ │ │ │ ├── cmp.rs │ │ │ │ ├── cmpu.rs │ │ │ │ ├── slu.rs │ │ │ │ ├── sl.rs │ │ │ │ ├── sr.rs │ │ │ │ ├── sru.rs │ │ │ │ ├── addu2.rs │ │ │ │ ├── addu4.rs │ │ │ │ ├── addu8.rs │ │ │ │ ├── addu16.rs │ │ │ │ ├── divi.rs │ │ │ │ ├── div.rs │ │ │ │ ├── mod.rs │ │ │ │ ├── mului.rs │ │ │ │ ├── divui.rs │ │ │ │ ├── divu.rs │ │ │ │ └── mulu.rs │ │ │ ├── immediate │ │ │ │ ├── mod.rs │ │ │ │ ├── setl.rs │ │ │ │ ├── seth.rs │ │ │ │ ├── setml.rs │ │ │ │ ├── setmh.rs │ │ │ │ ├── orl.rs │ │ │ │ ├── andnl.rs │ │ │ │ ├── incl.rs │ │ │ │ ├── orh.rs │ │ │ │ ├── andnh.rs │ │ │ │ ├── inch.rs │ │ │ │ ├── orml.rs │ │ │ │ ├── andnml.rs │ │ │ │ ├── ormh.rs │ │ │ │ ├── andnmh.rs │ │ │ │ ├── incmh.rs │ │ │ │ └── incml.rs │ │ │ ├── conditional │ │ │ │ ├── csz.rs │ │ │ │ ├── csev.rs │ │ │ │ ├── csn.rs │ │ │ │ ├── csnz.rs │ │ │ │ ├── csod.rs │ │ │ │ ├── csp.rs │ │ │ │ ├── csnn.rs │ │ │ │ ├── csnp.rs │ │ │ │ ├── cszi.rs │ │ │ │ ├── csni.rs │ │ │ │ ├── csnzi.rs │ │ │ │ ├── csodi.rs │ │ │ │ ├── cspi.rs │ │ │ │ ├── csevi.rs │ │ │ │ ├── csnni.rs │ │ │ │ ├── csnpi.rs │ │ │ │ ├── zsz.rs │ │ │ │ ├── zsev.rs │ │ │ │ ├── zsn.rs │ │ │ │ ├── zsnz.rs │ │ │ │ ├── zsod.rs │ │ │ │ ├── zsp.rs │ │ │ │ ├── zsnn.rs │ │ │ │ ├── zsnp.rs │ │ │ │ ├── zszi.rs │ │ │ │ ├── zsni.rs │ │ │ │ ├── zsnzi.rs │ │ │ │ ├── zsodi.rs │ │ │ │ ├── zspi.rs │ │ │ │ ├── zsevi.rs │ │ │ │ ├── zsnni.rs │ │ │ │ ├── zsnpi.rs │ │ │ │ └── mod.rs │ │ │ ├── bitwise │ │ │ │ ├── mod.rs │ │ │ │ ├── ori.rs │ │ │ │ ├── andi.rs │ │ │ │ ├── orni.rs │ │ │ │ ├── andni.rs │ │ │ │ ├── nandi.rs │ │ │ │ ├── nori.rs │ │ │ │ ├── xori.rs │ │ │ │ ├── nxori.rs │ │ │ │ ├── and.rs │ │ │ │ ├── or.rs │ │ │ │ ├── nor.rs │ │ │ │ ├── orn.rs │ │ │ │ ├── andn.rs │ │ │ │ ├── nand.rs │ │ │ │ ├── xor.rs │ │ │ │ ├── nxor.rs │ │ │ │ ├── muxi.rs │ │ │ │ ├── mux.rs │ │ │ │ ├── sadd.rs │ │ │ │ └── saddi.rs │ │ │ ├── bytewise │ │ │ │ ├── odifi.rs │ │ │ │ ├── odif.rs │ │ │ │ ├── mod.rs │ │ │ │ ├── bdifi.rs │ │ │ │ ├── tdifi.rs │ │ │ │ ├── wdifi.rs │ │ │ │ ├── bdif.rs │ │ │ │ ├── wdif.rs │ │ │ │ ├── tdif.rs │ │ │ │ ├── mor.rs │ │ │ │ ├── mxor.rs │ │ │ │ ├── mori.rs │ │ │ │ └── mxori.rs │ │ │ └── mod.rs │ │ └── cu.rs │ ├── state │ │ ├── gpr.rs │ │ ├── sr.rs │ │ ├── types.rs │ │ ├── mod.rs │ │ └── mem.rs │ └── mod.rs ├── lib.rs ├── main.rs └── cli.rs ├── res ├── prime113.mmo └── prime119.mmo ├── .travis.yml ├── ci ├── 60-build.sh ├── 70-test.sh ├── 80-doc.sh ├── run.sh ├── 30-line_endings.sh ├── 40-indentation.sh ├── 10-trailing_whitespaces.sh ├── 50-line_length.sh └── 20-trailing_newline.sh ├── .gitignore ├── README.md ├── Cargo.toml └── LICENSE /src/machine/behavior/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod cu; 2 | pub mod is; 3 | -------------------------------------------------------------------------------- /res/prime113.mmo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MMXVII/mmix/HEAD/res/prime113.mmo -------------------------------------------------------------------------------- /res/prime119.mmo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MMXVII/mmix/HEAD/res/prime119.mmo -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate clap; 2 | extern crate extprim; 3 | 4 | pub mod cli; 5 | pub mod machine; 6 | -------------------------------------------------------------------------------- /src/machine/behavior/is/interrupt/mod.rs: -------------------------------------------------------------------------------- 1 | mod_def_reexport!{ 2 | resume, 3 | trap, 4 | trip, 5 | } 6 | 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | rust: stable 3 | cache: cargo 4 | sudo: false 5 | git: 6 | depth: 1 7 | script: 8 | - ci/run.sh 9 | -------------------------------------------------------------------------------- /src/machine/behavior/is/other/mod.rs: -------------------------------------------------------------------------------- 1 | mod_def_reexport!{ 2 | getab, 3 | geta, 4 | get, 5 | puti, 6 | put, 7 | swym, 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/machine/behavior/is/other/swym.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn swym(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | // nothing to do 5 | } 6 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/fix.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn fix(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | unimplemented!(); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/fixu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn fixu(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | unimplemented!(); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/sflot.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn sflot(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | unimplemented!(); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/sfloti.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn sfloti(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | unimplemented!(); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/sflotu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn sflotu(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | unimplemented!(); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/sflotui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn sflotui(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | unimplemented!(); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/interrupt/trip.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn trip(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | unimplemented!(); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/subroutine/pop.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn pop(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | unimplemented!(); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/subroutine/save.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn save(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | unimplemented!(); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/interrupt/resume.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn resume(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | unimplemented!(); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/subroutine/pushgo.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn pushgo(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | unimplemented!(); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/subroutine/pushgoi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn pushgoi(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | unimplemented!(); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/subroutine/pushj.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn pushj(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | unimplemented!(); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/subroutine/pushjb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn pushjb(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | unimplemented!(); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/subroutine/unsave.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn unsave(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | unimplemented!(); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/subroutine/mod.rs: -------------------------------------------------------------------------------- 1 | mod_def_reexport!{ 2 | pop, 3 | pushgoi, 4 | pushgo, 5 | pushjb, 6 | pushj, 7 | save, 8 | unsave, 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/preld.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// preload data 4 | pub fn preld(_state: &mut State, _x: u8, _y: u8, _z: u8) { 5 | // Nothing to do here :) 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/sync.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// synchronize 4 | pub fn sync(_state: &mut State, _x: u8, _y: u8, _z: u8) { 5 | // Nothing to do here :) 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/prego.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// prefetch to go 4 | pub fn prego(_state: &mut State, _x: u8, _y: u8, _z: u8) { 5 | // Nothing to do here :) 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/pregoi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// prefetch to go 4 | pub fn pregoi(_state: &mut State, _x: u8, _y: u8, _z: u8) { 5 | // Nothing to do here :) 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/prest.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// prestore data 4 | pub fn prest(_state: &mut State, _x: u8, _y: u8, _z: u8) { 5 | // Nothing to do here :) 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/presti.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// prestore data 4 | pub fn presti(_state: &mut State, _x: u8, _y: u8, _z: u8) { 5 | // Nothing to do here :) 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/syncd.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// synchronize data 4 | pub fn syncd(_state: &mut State, _x: u8, _y: u8, _z: u8) { 5 | // Nothing to do here :) 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbev.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bev; 3 | 4 | pub fn pbev(state: &mut State, x: u8, y: u8, z: u8) { 5 | bev(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbn.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bn; 3 | 4 | pub fn pbn(state: &mut State, x: u8, y: u8, z: u8) { 5 | bn(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbnb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bnb; 3 | 4 | pub fn pbnb(state: &mut State, x: u8, y: u8, z: u8) { 5 | bnb(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbnn.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bnn; 3 | 4 | pub fn pbnn(state: &mut State, x: u8, y: u8, z: u8) { 5 | bnn(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbnp.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bnp; 3 | 4 | pub fn pbnp(state: &mut State, x: u8, y: u8, z: u8) { 5 | bnp(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbnz.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bnz; 3 | 4 | pub fn pbnz(state: &mut State, x: u8, y: u8, z: u8) { 5 | bnz(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbod.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bod; 3 | 4 | pub fn pbod(state: &mut State, x: u8, y: u8, z: u8) { 5 | bod(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbp.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bp; 3 | 4 | pub fn pbp(state: &mut State, x: u8, y: u8, z: u8) { 5 | bp(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbpb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bpb; 3 | 4 | pub fn pbpb(state: &mut State, x: u8, y: u8, z: u8) { 5 | bpb(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbz.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bz; 3 | 4 | pub fn pbz(state: &mut State, x: u8, y: u8, z: u8) { 5 | bz(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbzb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bzb; 3 | 4 | pub fn pbzb(state: &mut State, x: u8, y: u8, z: u8) { 5 | bzb(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/preldi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// preload data immediate 4 | pub fn preldi(_state: &mut State, _x: u8, _y: u8, _z: u8) { 5 | // Nothing to do here :) 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbevb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bevb; 3 | 4 | pub fn pbevb(state: &mut State, x: u8, y: u8, z: u8) { 5 | bevb(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbnnb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bnnb; 3 | 4 | pub fn pbnnb(state: &mut State, x: u8, y: u8, z: u8) { 5 | bnnb(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbnpb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bnpb; 3 | 4 | pub fn pbnpb(state: &mut State, x: u8, y: u8, z: u8) { 5 | bnpb(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbnzb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bnzb; 3 | 4 | pub fn pbnzb(state: &mut State, x: u8, y: u8, z: u8) { 5 | bnzb(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/pbodb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::control::bodb; 3 | 4 | pub fn pbodb(state: &mut State, x: u8, y: u8, z: u8) { 5 | bodb(state, x, y, z); 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/ldvts.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// load virtual translation status 4 | pub fn ldvts(_state: &mut State, _x: u8, _y: u8, _z: u8) { 5 | // Nothing to do here :) 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/syncdi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// synchronize data immediate 4 | pub fn syncdi(_state: &mut State, _x: u8, _y: u8, _z: u8) { 5 | // Nothing to do here :) 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/syncid.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// synchronized instructions and data 4 | pub fn syncid(_state: &mut State, _x: u8, _y: u8, _z: u8) { 5 | // Nothing to do here :) 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/ldvtsi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | // load virtual translation status immediate 4 | pub fn ldvtsi(_state: &mut State, _x: u8, _y: u8, _z: u8) { 5 | // Nothing to do here :) 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/syncidi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// synchronized instructions and data 4 | pub fn syncidi(_state: &mut State, _x: u8, _y: u8, _z: u8) { 5 | // Nothing to do here :) 6 | } 7 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/lda.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::arithmetic::addu; 3 | 4 | /// load address 5 | pub fn lda(state: &mut State, x: u8, y: u8, z: u8) { 6 | addu(state, x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldou.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::memory::ldo; 3 | 4 | /// load octa unsigned 5 | pub fn ldou(state: &mut State, x: u8, y: u8, z: u8) { 6 | ldo(state, x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stbu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::memory::stb; 3 | 4 | /// store byte unsigned 5 | pub fn stbu(state: &mut State, x: u8, y: u8, z: u8) { 6 | stb(state, x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stou.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::memory::sto; 3 | 4 | /// store octa unsigned 5 | pub fn stou(state: &mut State, x: u8, y: u8, z: u8) { 6 | sto(state, x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/sttu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::memory::stt; 3 | 4 | /// store tetra unsigned 5 | pub fn sttu(state: &mut State, x: u8, y: u8, z: u8) { 6 | stt(state, x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stwu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::memory::stw; 3 | 4 | /// store wyde unsigned 5 | pub fn stwu(state: &mut State, x: u8, y: u8, z: u8) { 6 | stw(state, x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/ldunc.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::memory::ldo; 3 | 4 | /// load octa uncached 5 | pub fn ldunc(state: &mut State, x: u8, y: u8, z: u8) { 6 | ldo(state, x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/stunc.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::memory::sto; 3 | 4 | /// store octa uncached 5 | pub fn stunc(state: &mut State, x: u8, y: u8, z: u8) { 6 | sto(state, x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /ci/60-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Exit script on first error 4 | set -o errexit -o nounset 5 | 6 | # Explain what we do 7 | echo ">>> Building..." 8 | 9 | # Build the project 10 | export RUSTFLAGS="--deny warnings" 11 | cargo build 12 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldoui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::memory::ldoi; 3 | 4 | /// load octa unsigned immediate 5 | pub fn ldoui(state: &mut State, x: u8, y: u8, z: u8) { 6 | ldoi(state, x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stbui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::memory::stbi; 3 | 4 | /// store byte unsigned immediate 5 | pub fn stbui(state: &mut State, x: u8, y: u8, z: u8) { 6 | stbi(state, x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stoui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::memory::stoi; 3 | 4 | /// store octa unsigned immediate 5 | pub fn stoui(state: &mut State, x: u8, y: u8, z: u8) { 6 | stoi(state, x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stwui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::memory::stwi; 3 | 4 | /// store wyde unsigned immediate 5 | pub fn stwui(state: &mut State, x: u8, y: u8, z: u8) { 6 | stwi(state, x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /ci/70-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Exit script on first error 4 | set -o errexit -o nounset 5 | 6 | # Explain what we do 7 | echo ">>> Running the tests..." 8 | 9 | # Build the project 10 | export RUSTFLAGS="--deny warnings" 11 | cargo test 12 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/sttui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::memory::stti; 3 | 4 | /// store tetra unsigned immediate 5 | pub fn sttui(state: &mut State, x: u8, y: u8, z: u8) { 6 | stti(state, x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/ldunci.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::memory::ldoi; 3 | 4 | /// load octa uncached immediate 5 | pub fn ldunci(state: &mut State, x: u8, y: u8, z: u8) { 6 | ldoi(state, x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/stunci.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::behavior::is::memory::stoi; 3 | 4 | /// store octa uncached immediate 5 | pub fn stunci(state: &mut State, x: u8, y: u8, z: u8) { 6 | stoi(state, x, y, z); 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore temporary Cargo files 2 | Cargo.lock 3 | target/ 4 | 5 | # Ignore Sublime files 6 | *.sublime-* 7 | 8 | # Ignore OS config files 9 | *.bak 10 | *.directory 11 | *Desktop.ini 12 | *desktop.ini 13 | *Thumbs.db 14 | *thumbs.db 15 | -------------------------------------------------------------------------------- /ci/80-doc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Exit script on first error 4 | set -o errexit -o nounset 5 | 6 | # Explain what we do 7 | echo ">>> Checking the documentation..." 8 | 9 | # Build the project 10 | export RUSTFLAGS="--deny warnings" 11 | cargo doc 12 | -------------------------------------------------------------------------------- /ci/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Exit script on first error 4 | set -o errexit -o nounset 5 | 6 | # Compute the current directory 7 | DIR="`dirname \"$0\"`" 8 | 9 | # Run each test 10 | for TEST in $(find $DIR/*-* -type f); do 11 | $TEST 12 | done 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/interrupt/trap.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn trap(_state: &mut State, _x: u8, _y: u8, _z: u8) { 4 | // FIXME For the moment, TRAP halts the machine 5 | println!("Goodbye!"); 6 | ::std::process::exit(0); 7 | } 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mmix 2 | An MMIX virtual machine written in Rust 3 | 4 | ## Project status 5 | This work was as student project that has since been discontinued. 6 | Thus, You may not expect new features or bug fixes. 7 | However, do not hesitate to submit issues or pull requests. 8 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/negi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn negi(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Execute 5 | let res = (y as i64).wrapping_sub(z as i64); 6 | 7 | // Store result 8 | state.gpr[x] = res.into(); 9 | } 10 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/negui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn negui(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Execute 5 | let res = (y as u64).wrapping_sub(z as u64); 6 | 7 | // Store result 8 | state.gpr[x] = res.into(); 9 | } 10 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/mod.rs: -------------------------------------------------------------------------------- 1 | mod_def_reexport!{ 2 | andnh, 3 | andnl, 4 | andnmh, 5 | andnml, 6 | inch, 7 | incl, 8 | incmh, 9 | incml, 10 | orh, 11 | orl, 12 | ormh, 13 | orml, 14 | seth, 15 | setl, 16 | setmh, 17 | setml, 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/machine/behavior/is/other/get.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::sr::R; 3 | 4 | pub fn get(state: &mut State, x: u8, _y: u8, z: u8) { 5 | // Execute 6 | let sr: R = (z as u8).into(); 7 | let res: u64 = state.sr[sr].into(); 8 | 9 | // Store result 10 | state.gpr[x] = res.into(); 11 | } 12 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/csz.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if zero 4 | pub fn csz(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 == 0 { 10 | state.gpr[x] = state.gpr[z]; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/muli.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn muli(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: i64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res = op1.wrapping_mul(z as i64); 9 | 10 | // Store result 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/neg.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn neg(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op2: i64 = state.gpr[z].into(); 6 | 7 | // Execute 8 | let res = (y as i64).wrapping_sub(op2); 9 | 10 | // Store result 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/csev.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if even 4 | pub fn csev(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 % 2 == 0 { 10 | state.gpr[x] = state.gpr[z]; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/csn.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if negative 4 | pub fn csn(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 < 0 { 10 | state.gpr[x] = state.gpr[z]; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/csnz.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if nonzero 4 | pub fn csnz(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 != 0 { 10 | state.gpr[x] = state.gpr[z]; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/csod.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if odd 4 | pub fn csod(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 % 2 == 1 { 10 | state.gpr[x] = state.gpr[z]; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/csp.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if positive 4 | pub fn csp(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 > 0 { 10 | state.gpr[x] = state.gpr[z]; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/setl.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// set low wyde 4 | pub fn setl(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Shift y 6 | let y = (y as u64) << 8; 7 | 8 | // Execute 9 | let result = y + (z as u64); 10 | 11 | // Store result 12 | state.gpr[x] = result.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/addi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn addi(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: i64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res = (z as i64).wrapping_add(op1); 9 | 10 | // Store result 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/addui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn addui(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: u64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res = (z as u64).wrapping_add(op1); 9 | 10 | // Store result 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/cmpi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn cmpi(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: i64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res: i64 = (z as i64).cmp(&op1) as i64; 9 | 10 | // Store result 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/negu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn negu(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op2: u64 = state.gpr[z].into(); 6 | 7 | // Execute 8 | let res = (y as u64).wrapping_sub(op2); 9 | 10 | // Store result 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/sli.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn sli(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: i64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res = op1.overflowing_shl(z as u32).0; 9 | 10 | // Store result 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/slui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn slui(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: u64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res = op1.wrapping_shl(z as u32); 9 | 10 | // Store result 11 | state.gpr[x] = res.into(); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/sri.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn sri(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: i64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res = op1.overflowing_shr(z as u32).0; 9 | 10 | // Store results 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/srui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn srui(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: u64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res = op1.overflowing_shr(z as u32).0; 9 | 10 | // Store results 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/subi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn subi(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: i64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res = (z as i64).wrapping_sub(op1); 9 | 10 | // Store result 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/subui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn subui(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: u64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res = (z as u64).wrapping_sub(op1); 9 | 10 | // Store result 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/csnn.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if nonnegative 4 | pub fn csnn(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 >= 0 { 10 | state.gpr[x] = state.gpr[z]; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/csnp.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if nonpositive 4 | pub fn csnp(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 <= 0 { 10 | state.gpr[x] = state.gpr[z]; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/cmpui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn cmpui(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: u64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res: i64 = (z as u64).cmp(&op1) as i64; 9 | 10 | // Store result 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/cszi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if zero immediate 4 | pub fn cszi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 == 0 { 10 | state.gpr[x] = (z as u64).into(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/mod.rs: -------------------------------------------------------------------------------- 1 | mod_def_reexport!{ 2 | andi, 3 | andni, 4 | andn, 5 | and, 6 | muxi, 7 | mux, 8 | nandi, 9 | nand, 10 | nori, 11 | nor, 12 | nxori, 13 | nxor, 14 | ori, 15 | orni, 16 | orn, 17 | or, 18 | saddi, 19 | sadd, 20 | xori, 21 | xor, 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/csni.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if negative immediate 4 | pub fn csni(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 < 0 { 10 | state.gpr[x] = (z as u64).into(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/csnzi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if nonzero immediate 4 | pub fn csnzi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 != 0 { 10 | state.gpr[x] = (z as u64).into(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/csodi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if odd immediate 4 | pub fn csodi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 % 2 == 1 { 10 | state.gpr[x] = (z as u64).into(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/cspi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if positive immediate 4 | pub fn cspi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 > 0 { 10 | state.gpr[x] = (z as u64).into(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/ori.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise or immediate 4 | pub fn ori(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | let res = op1 | z as u64; 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/csevi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if even immediate 4 | pub fn csevi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 % 2 == 0 { 10 | state.gpr[x] = (z as u64).into(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/csnni.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if nonnegative immediate 4 | pub fn csnni(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 >= 0 { 10 | state.gpr[x] = (z as u64).into(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/csnpi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// conditional set if nonpositive immediate 4 | pub fn csnpi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 <= 0 { 10 | state.gpr[x] = (z as u64).into(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/addu16i.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn addu16i(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: u64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res = (op1.wrapping_mul(16)).wrapping_add(z as u64); 9 | 10 | // Store result 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/addu2i.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn addu2i(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: u64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res = (op1.wrapping_mul(2)).wrapping_add(z as u64); 9 | 10 | // Store result 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/addu4i.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn addu4i(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: u64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res = (op1.wrapping_mul(4)).wrapping_add(z as u64); 9 | 10 | // Store result 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/addu8i.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn addu8i(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: u64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res = (op1.wrapping_mul(8)).wrapping_add(z as u64); 9 | 10 | // Store result 11 | state.gpr[x] = res.into(); 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/andi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise and immediate 4 | pub fn andi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | let res = op1 & z as u64; 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/orni.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise or-not immediate 4 | pub fn orni(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | let res = op1 | !z as u64; 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/fadd.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn fadd(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: f64 = state.gpr[y].into(); 6 | let op2: f64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = op1 + op2; 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/fdiv.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn fdiv(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: f64 = state.gpr[y].into(); 6 | let op2: f64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = op1 / op2; 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/fmul.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn fmul(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: f64 = state.gpr[y].into(); 6 | let op2: f64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = op1 * op2; 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/frem.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn frem(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: f64 = state.gpr[y].into(); 6 | let op2: f64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = op1 % op2; 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/fsub.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn fsub(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: f64 = state.gpr[y].into(); 6 | let op2: f64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = op1 - op2; 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/andni.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise and-not immediate 4 | pub fn andni(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | let res = op1 & !z as u64; 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/nandi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise not-and immediate 4 | pub fn nandi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | let res = !(op1 & z as u64); 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/nori.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise not-or immediate 4 | pub fn nori(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | let res = !(op1 | z as u64); 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/xori.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise exclusive-or immediate 4 | pub fn xori(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | let res = op1 ^ z as u64; 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/feql.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn feql(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: f64 = state.gpr[y].into(); 6 | let op2: f64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = (op1 == op2) as i64; 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/seth.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// set high wyde 4 | pub fn seth(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Shift y and z 6 | let y = (y as u64) << 56; 7 | let z = (z as u64) << 48; 8 | 9 | // Execute 10 | let result = y + z; 11 | 12 | // Store result 13 | state.gpr[x] = result.into(); 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/other/geta.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn geta(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let ra: u64 = ((y as u64) << 8) + (z as u64); 6 | let at: u64 = state.pc.into(); 7 | 8 | // Execute 9 | let res: u64 = at + 4 * ra; 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/mod.rs: -------------------------------------------------------------------------------- 1 | mod_def_reexport!{ 2 | cswapi, 3 | cswap, 4 | ldunci, 5 | ldunc, 6 | ldvtsi, 7 | ldvts, 8 | pregoi, 9 | prego, 10 | preldi, 11 | preld, 12 | presti, 13 | prest, 14 | stunci, 15 | stunc, 16 | syncdi, 17 | syncd, 18 | syncidi, 19 | syncid, 20 | sync, 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/add.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn add(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[y].into(); 6 | let op2: i64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = op1.wrapping_add(op2); 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/addu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn addu(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: u64 = state.gpr[y].into(); 6 | let op2: u64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = op1.wrapping_add(op2); 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/mul.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn mul(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[y].into(); 6 | let op2: i64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = op1.wrapping_mul(op2); 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/sub.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn sub(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[y].into(); 6 | let op2: i64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = op1.wrapping_sub(op2); 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/subu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn subu(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: u64 = state.gpr[y].into(); 6 | let op2: u64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = op1.wrapping_sub(op2); 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/nxori.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise not-exclusive-or immediate 4 | pub fn nxori(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | let res = !(op1 ^ z as u64); 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/goi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn goi(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: u64 = state.gpr[y].into(); 6 | 7 | // Execute 8 | let res = op1.wrapping_add(z as u64); 9 | 10 | // Store result 11 | state.gpr[x] = (state.pc + 4).into(); 12 | state.pc = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/setml.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// set medium low wyde 4 | pub fn setml(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Shift y and z 6 | let y = (y as u64) << 24; 7 | let z = (z as u64) << 16; 8 | 9 | // Execute 10 | let result = y + z; 11 | 12 | // Store result 13 | state.gpr[x] = result.into(); 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/cmp.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn cmp(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[y].into(); 6 | let op2: i64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res : i64 = op1.cmp(&op2) as i64; 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/cmpu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn cmpu(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: u64 = state.gpr[y].into(); 6 | let op2: u64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res: i64 = op1.cmp(&op2) as i64; 10 | 11 | // Store results 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/slu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn slu(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: u64 = state.gpr[y].into(); 6 | let op2: u64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = op1.wrapping_shl(op2 as u32); 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/and.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise and 4 | pub fn and(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let op1: u64 = state.gpr[y].into(); 7 | let op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let res = op1 & op2; 11 | 12 | // Store result 13 | state.gpr[x] = res.into(); 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/or.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise or 4 | pub fn or(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let op1: u64 = state.gpr[y].into(); 7 | let op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let res = op1 | op2; 11 | 12 | // Store result 13 | state.gpr[x] = res.into(); 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/setmh.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// set medium high wyde 4 | pub fn setmh(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Shift y and z 6 | let y = (y as u64) << 40; 7 | let z = (z as u64) << 32; 8 | 9 | // Execute 10 | let result = y + z; 11 | 12 | // Store result 13 | state.gpr[x] = result.into(); 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/sl.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn sl(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: i64 = state.gpr[y].into(); 6 | let op2: i64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = op1.overflowing_shl(op2 as u32).0; 10 | 11 | // Store results 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/sr.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn sr(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: i64 = state.gpr[y].into(); 6 | let op2: i64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = op1.overflowing_shr(op2 as u32).0; 10 | 11 | // Store results 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/sru.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn sru(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: u64 = state.gpr[y].into(); 6 | let op2: u64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = op1.overflowing_shr(op2 as u32).0; 10 | 11 | // Store results 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/nor.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise not-or 4 | pub fn nor(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let op1: u64 = state.gpr[y].into(); 7 | let op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let res = !(op1 | op2); 11 | 12 | // Store result 13 | state.gpr[x] = res.into(); 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/orn.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise or-not 4 | pub fn orn(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let op1: u64 = state.gpr[y].into(); 7 | let op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let res = op1 | !op2; 11 | 12 | // Store result 13 | state.gpr[x] = res.into(); 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bytewise/odifi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// octa difference immediate 4 | pub fn odifi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | let result = op1.saturating_sub(z as u64); 10 | 11 | // Store result 12 | state.gpr[x] = result.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zsz.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if zero 4 | pub fn zsz(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 == 0 { 10 | state.gpr[x] = state.gpr[z]; 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mmix" 3 | version = "0.1.0" 4 | authors = ["Janina Born ", 5 | "Barbara Butz ", 6 | "Karoline Plum ", 7 | "Tobias Stolzmann "] 8 | 9 | [[bin]] 10 | name = "mmixvm" 11 | 12 | [dependencies] 13 | clap = "2" 14 | extprim = "1" 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/andn.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise and-not 4 | pub fn andn(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let op1: u64 = state.gpr[y].into(); 7 | let op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let res = op1 & !op2; 11 | 12 | // Store result 13 | state.gpr[x] = res.into(); 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/nand.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise not-and 4 | pub fn nand(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let op1: u64 = state.gpr[y].into(); 7 | let op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let res = !(op1 & op2); 11 | 12 | // Store result 13 | state.gpr[x] = res.into(); 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/xor.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise exclusive-or 4 | pub fn xor(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let op1: u64 = state.gpr[y].into(); 7 | let op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let res = op1 ^ op2; 11 | 12 | // Store result 13 | state.gpr[x] = res.into(); 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zsev.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if even 4 | pub fn zsev(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 % 2 == 0 { 10 | state.gpr[x] = state.gpr[z]; 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zsn.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if negative 4 | pub fn zsn(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 < 0 { 10 | state.gpr[x] = state.gpr[z]; 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zsnz.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if nonzero 4 | pub fn zsnz(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 != 0 { 10 | state.gpr[x] = state.gpr[z]; 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zsod.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if odd 4 | pub fn zsod(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 % 2 == 1 { 10 | state.gpr[x] = state.gpr[z]; 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zsp.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if positive 4 | pub fn zsp(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 > 0 { 10 | state.gpr[x] = state.gpr[z]; 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/addu2.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn addu2(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: u64 = state.gpr[y].into(); 6 | let op2: u64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = (op1.wrapping_mul(2)).wrapping_add(op2); 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/addu4.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn addu4(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: u64 = state.gpr[y].into(); 6 | let op2: u64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = (op1.wrapping_mul(4)).wrapping_add(op2); 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/addu8.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn addu8(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: u64 = state.gpr[y].into(); 6 | let op2: u64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = (op1.wrapping_mul(8)).wrapping_add(op2); 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zsnn.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if nonnegative 4 | pub fn zsnn(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 >= 0 { 10 | state.gpr[x] = state.gpr[z]; 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zsnp.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if nonpositive 4 | pub fn zsnp(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 <= 0 { 10 | state.gpr[x] = state.gpr[z]; 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/other/getab.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn getab(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let ra: u64 = ((y as u64) << 8) + (z as u64); 6 | let at: u64 = state.pc.into(); 7 | 8 | // Execute 9 | let res: u64 = at + 4 * (ra - 2u64.pow(16u32)); 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/addu16.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn addu16(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: u64 = state.gpr[y].into(); 6 | let op2: u64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = (op1.wrapping_mul(16)).wrapping_add(op2); 10 | 11 | // Store result 12 | state.gpr[x] = res.into(); 13 | } 14 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/nxor.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | ///bitwise not-exclusive-or 4 | pub fn nxor(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let op1: u64 = state.gpr[y].into(); 7 | let op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let res = !(op1 ^ op2); 11 | 12 | // Store result 13 | state.gpr[x] = res.into(); 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zszi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if zero immediate 4 | pub fn zszi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 == 0 { 10 | state.gpr[x] = (z as u64).into(); 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zsni.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if negative immediate 4 | pub fn zsni(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 < 0 { 10 | state.gpr[x] = (z as u64).into(); 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zsnzi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if nonzero immediate 4 | pub fn zsnzi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 != 0 { 10 | state.gpr[x] = (z as u64).into(); 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zsodi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if odd immediate 4 | pub fn zsodi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 % 2 == 1 { 10 | state.gpr[x] = (z as u64).into(); 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zspi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if positive immediate 4 | pub fn zspi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 > 0 { 10 | state.gpr[x] = (z as u64).into(); 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/other/puti.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::sr::R; 3 | 4 | pub fn puti(state: &mut State, x: u8, _y: u8, z: u8) { 5 | // Store result 6 | let sr: R = match x { 7 | 8 | 12 | 15 | 9 | 10 | 11 | 13 | 17 | 18 | 14 8 | => panic!("Putting isn't allowed"), 9 | _ => x.into(), 10 | }; 11 | state.sr[sr] = (z as u64).into() 12 | } 13 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bytewise/odif.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// octa difference 4 | pub fn odif(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let op1: u64 = state.gpr[y].into(); 7 | let op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let result = op1.saturating_sub(op2); 11 | 12 | // Store result 13 | state.gpr[x] = result.into(); 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zsevi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if even immediate 4 | pub fn zsevi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 % 2 == 0 { 10 | state.gpr[x] = (z as u64).into(); 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zsnni.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if nonnegative immediate 4 | pub fn zsnni(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 >= 0 { 10 | state.gpr[x] = (z as u64).into(); 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/zsnpi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// zero or set if nonpositive immediate 4 | pub fn zsnpi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | if op1 <= 0 { 10 | state.gpr[x] = (z as u64).into(); 11 | } else { 12 | state.gpr[x] = 0u64.into(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/go.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn go(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: u64 = state.gpr[y].into(); 6 | let op2: u64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res = op1.wrapping_add(op2); 10 | 11 | // Store result 12 | state.gpr[x] = (state.pc + 4).into(); 13 | state.pc = res.into(); 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldoi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::OctaAt; 3 | 4 | /// load octa immediate 5 | pub fn ldoi(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load first operand 7 | let op1: u64 = state.gpr[y].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(z as u64); 11 | 12 | // Load from memory 13 | state.gpr[x] = state.mem[OctaAt(a)]; 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stoi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::OctaAt; 3 | 4 | /// store octa immediate 5 | pub fn stoi(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load first operand 7 | let op1: u64 = state.gpr[y].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(z as u64); 11 | 12 | // Store in memory 13 | state.mem[OctaAt(a)] = state.gpr[x]; 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/jmp.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn jmp(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let x: u64 = (x as u64) << 16; 6 | let y: u64 = (y as u64) << 8; 7 | let xyz: u64 = x + y + (z as u64); 8 | let at: u64 = state.pc.into(); 9 | 10 | // Execute 11 | let ra: u64 = at + 4 * xyz; 12 | 13 | // Store result 14 | state.pc = ra.into(); 15 | } 16 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/orl.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise or with low wyde 4 | pub fn orl(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[x].into(); 7 | 8 | // Shift y 9 | let y = (y as u64) << 8; 10 | 11 | // Execute 12 | let result = op1 | (y + (z as u64)); 13 | 14 | // Store result 15 | state.gpr[x] = result.into(); 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stcoi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::OctaAt; 3 | 4 | /// store constant octabyte immediate 5 | pub fn stcoi(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load first operand 7 | let op1: u64 = state.gpr[y].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(z as u64); 11 | 12 | // Store in memory 13 | state.mem[OctaAt(a)] = (x as u64).into(); 14 | } 15 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/jmpb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn jmpb(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let x: u64 = (x as u64) << 16; 6 | let y: u64 = (y as u64) << 8; 7 | let xyz: u64 = x + y + (z as u64); 8 | let at: u64 = state.pc.into(); 9 | 10 | // Execute 11 | let ra: u64 = at - 4 * xyz; 12 | 13 | // Store result 14 | state.pc = ra.into(); 15 | } 16 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/andnl.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise and-not low wyde 4 | pub fn andnl(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[x].into(); 7 | 8 | // Shift y 9 | let y = (y as u64) << 8; 10 | 11 | // Execute 12 | let result = op1 & !(y + (z as u64)); 13 | 14 | // Store result 15 | state.gpr[x] = result.into(); 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldo.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::OctaAt; 3 | 4 | /// load octa 5 | pub fn ldo(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op2: u64 = state.gpr[z].into(); 9 | 10 | // Execute 11 | let a = op1.wrapping_add(op2); 12 | 13 | // Load from memory 14 | state.gpr[x] = state.mem[OctaAt(a)]; 15 | } 16 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/sto.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::OctaAt; 3 | 4 | /// store octa 5 | pub fn sto(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op2: u64 = state.gpr[z].into(); 9 | 10 | // Execute 11 | let a = op1.wrapping_add(op2); 12 | 13 | // Store in memory 14 | state.mem[OctaAt(a)] = state.gpr[x]; 15 | } 16 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bytewise/mod.rs: -------------------------------------------------------------------------------- 1 | mod_def_reexport!{ 2 | bdifi, 3 | bdif, 4 | mori, 5 | mor, 6 | mxori, 7 | mxor, 8 | odifi, 9 | odif, 10 | tdifi, 11 | tdif, 12 | wdifi, 13 | wdif, 14 | } 15 | 16 | fn get_byte(bits: u64) -> u8 { 17 | bits as u8 18 | } 19 | 20 | fn get_wyde(bits: u64) -> u16 { 21 | bits as u16 22 | } 23 | 24 | fn get_tetra(bits: u64) -> u32 { 25 | bits as u32 26 | } 27 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/incl.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// increase by low wyde 4 | pub fn incl(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[x].into(); 7 | 8 | // Shift y 9 | let y = (y as u64) << 8; 10 | 11 | // Execute 12 | let result = op1.wrapping_add(y + (z as u64)); 13 | 14 | // Store result 15 | state.gpr[x] = result.into(); 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bn.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bn(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * ra; 11 | 12 | // Store result 13 | if op1 < 0 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bnn.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bnn(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * ra; 11 | 12 | // Store result 13 | if op1 >= 0 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bnp.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bnp(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * ra; 11 | 12 | // Store result 13 | if op1 <= 0 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bnz.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bnz(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * ra; 11 | 12 | // Store result 13 | if op1 != 0 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bp.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bp(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * ra; 11 | 12 | // Store result 13 | if op1 > 0 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bz.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bz(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * ra; 11 | 12 | // Store result 13 | if op1 == 0 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/muxi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::sr::R; 3 | 4 | /// bitwise multiplex immediate 5 | pub fn muxi(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op3: u64 = state.sr[R::M].into(); 9 | 10 | // Execute 11 | let res = (op1 & op3) | (z as u64 & !op3); 12 | 13 | // Store result 14 | state.gpr[x] = res.into(); 15 | } 16 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bev.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bev(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * ra; 11 | 12 | // Store result 13 | if op1 % 2 == 0 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bod.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bod(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * ra; 11 | 12 | // Store result 13 | if op1 % 2 == 1 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/stsfi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::TetraAt; 3 | 4 | pub fn stsfi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: u64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | let a = op1.wrapping_add(z as u64); 10 | 11 | // Load x 12 | let res: f64 = state.gpr[x].into(); 13 | 14 | // Store in memory 15 | state.mem[TetraAt(a)] = (res as f32).into(); 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stco.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::OctaAt; 3 | 4 | /// store constant octabyte 5 | pub fn stco(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op2: u64 = state.gpr[z].into(); 9 | 10 | // Execute 11 | let a = op1.wrapping_add(op2); 12 | 13 | // Store in memory 14 | state.mem[OctaAt(a)] = (x as u64).into(); 15 | } 16 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bnb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bnb(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * (ra - 2u64.pow(16u32)); 11 | 12 | // Store result 13 | if op1 < 0 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bpb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bpb(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * (ra - 2u64.pow(16u32)); 11 | 12 | // Store result 13 | if op1 > 0 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bzb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bzb(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * (ra - 2u64.pow(16u32)); 11 | 12 | // Store result 13 | if op1 == 0 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/ldsfi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::TetraAt; 3 | 4 | pub fn ldsfi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: u64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | let a = op1.wrapping_add(z as u64); 10 | 11 | // Load from memory 12 | let res: f32 = state.mem[TetraAt(a)].into(); 13 | 14 | // Store result 15 | state.gpr[x] = (res as f64).into(); 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/orh.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise or with high wyde 4 | pub fn orh(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[x].into(); 7 | 8 | // Shift y and z 9 | let y = (y as u64) << 56; 10 | let z = (z as u64) << 48; 11 | 12 | // Execute 13 | let result = op1 | (y + z); 14 | 15 | // Store result 16 | state.gpr[x] = result.into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/other/put.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::sr::R; 3 | 4 | pub fn put(state: &mut State, x: u8, _y: u8, z: u8) { 5 | // Load operands 6 | let op1: u64 = state.gpr[z].into(); 7 | 8 | // Store result 9 | let sr: R = match x { 10 | 8 | 12 | 15 | 9 | 10 | 11 | 13 | 17 | 18 | 14 11 | => panic!("Putting isn't allowed"), 12 | _ => x.into(), 13 | }; 14 | state.sr[sr] = op1.into() 15 | } 16 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bevb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bevb(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * (ra - 2u64.pow(16u32)); 11 | 12 | // Store result 13 | if op1 % 2 == 0 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bnnb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bnnb(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * (ra - 2u64.pow(16u32)); 11 | 12 | // Store result 13 | if op1 >= 0 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bnpb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bnpb(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * (ra - 2u64.pow(16u32)); 11 | 12 | // Store result 13 | if op1 <= 0 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bnzb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bnzb(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * (ra - 2u64.pow(16u32)); 11 | 12 | // Store result 13 | if op1 != 0 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/bodb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn bodb(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: i64 = state.gpr[x].into(); 6 | let ra: u64 = ((y as u64) << 8) + (z as u64); 7 | let at: u64 = state.pc.into(); 8 | 9 | // Execute 10 | let res: u64 = at + 4 * (ra - 2u64.pow(16u32)); 11 | 12 | // Store result 13 | if op1 % 2 == 1 { 14 | state.pc = res.into(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/mod.rs: -------------------------------------------------------------------------------- 1 | mod_def_reexport!{ 2 | fadd, 3 | fcmpe, 4 | fcmp, 5 | fdiv, 6 | feqle, 7 | feql, 8 | fint, 9 | fix, 10 | fixu, 11 | floti, 12 | flot, 13 | flotui, 14 | flotu, 15 | fmul, 16 | frem, 17 | fsqrt, 18 | fsub, 19 | fune, 20 | fun, 21 | ldsfi, 22 | ldsf, 23 | sfloti, 24 | sflot, 25 | sflotui, 26 | sflotu, 27 | stsfi, 28 | stsf, 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/andnh.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise and-not high wyde 4 | pub fn andnh(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[x].into(); 7 | 8 | // Shift y and z 9 | let y = (y as u64) << 56; 10 | let z = (z as u64) << 48; 11 | 12 | // Execute 13 | let result = op1 & !(y + z); 14 | 15 | // Store result 16 | state.gpr[x] = result.into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/inch.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// increase by high wyde 4 | pub fn inch(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[x].into(); 7 | 8 | // Shift y and z 9 | let y = (y as u64) << 56; 10 | let z = (z as u64) << 48; 11 | 12 | // Execute 13 | let result = op1.wrapping_add(y + z); 14 | 15 | // Store result 16 | state.gpr[x] = result.into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/orml.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise or with medium low wyde 4 | pub fn orml(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[x].into(); 7 | 8 | // Shift y and z 9 | let y = (y as u64) << 24; 10 | let z = (z as u64) << 16; 11 | 12 | // Execute 13 | let result = op1 | (y + z); 14 | 15 | // Store result 16 | state.gpr[x] = result.into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/andnml.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise and-not medium low wyde 4 | pub fn andnml(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[x].into(); 7 | 8 | // Shift y and z 9 | let y = (y as u64) << 24; 10 | let z = (z as u64) << 16; 11 | 12 | // Execute 13 | let result = op1 & !(y + z); 14 | 15 | // Store result 16 | state.gpr[x] = result.into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/ormh.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise or with medium high wyde 4 | pub fn ormh(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[x].into(); 7 | 8 | // Shift y and z 9 | let y = (y as u64) << 40; 10 | let z = (z as u64) << 32; 11 | 12 | // Execute 13 | let result = op1 | (y + z); 14 | 15 | // Store result 16 | state.gpr[x] = result.into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/mux.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::sr::R; 3 | 4 | /// bitwise multiplex 5 | pub fn mux(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op2: u64 = state.gpr[z].into(); 9 | let op3: u64 = state.sr[R::M].into(); 10 | 11 | // Execute 12 | let res = (op1 & op3) | (op2 & !op3); 13 | 14 | // Store result 15 | state.gpr[x] = res.into(); 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/fcmp.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn fcmp(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: f64 = state.gpr[y].into(); 6 | let op2: f64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res: i64 = match op1 - op2 { 10 | d if d > 0.0 => 1, 11 | d if d < 0.0 => -1, 12 | _ => 0, 13 | }; 14 | 15 | // Store result 16 | state.gpr[x] = res.into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/andnmh.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// bitwise and-not medium high wyde 4 | pub fn andnmh(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[x].into(); 7 | 8 | // Shift y and z 9 | let y = (y as u64) << 40; 10 | let z = (z as u64) << 32; 11 | 12 | // Execute 13 | let result = op1 & !(y + z); 14 | 15 | // Store result 16 | state.gpr[x] = result.into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/incmh.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// increase by medium high wyde 4 | pub fn incmh(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[x].into(); 7 | 8 | // Shift y and z 9 | let y = (y as u64) << 40; 10 | let z = (z as u64) << 32; 11 | 12 | // Execute 13 | let result = op1.wrapping_add(y + z); 14 | 15 | // Store result 16 | state.gpr[x] = result.into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/immediate/incml.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// increase by medium low wyde 4 | pub fn incml(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[x].into(); 7 | 8 | // Shift y and z 9 | let y = (y as u64) << 24; 10 | let z = (z as u64) << 16; 11 | 12 | // Execute 13 | let result = op1.wrapping_add(y + z); 14 | 15 | // Store result 16 | state.gpr[x] = result.into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/sadd.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// sideways add 4 | pub fn sadd(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Calculate andn and load result 6 | super::andn(state, x, y, z); 7 | let mut bits: u64 = state.gpr[x].into(); 8 | 9 | // Execute 10 | let mut res: u64 = 0; 11 | while bits != 0 { 12 | res += bits % 2; 13 | bits /= 2; 14 | } 15 | 16 | // Store result 17 | state.gpr[x] = res.into(); 18 | } 19 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/feqle.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::sr::R; 3 | 4 | pub fn feqle(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let op1: f64 = state.gpr[y].into(); 7 | let op2: f64 = state.gpr[z].into(); 8 | let eps: f64 = state.sr[R::E].into(); 9 | 10 | // Execute 11 | let gap = (op1 - op2).abs(); 12 | let res = (gap <= eps) as i64; 13 | 14 | // Store result 15 | state.gpr[x] = res.into(); 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stbi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::ByteAt; 3 | 4 | /// store byte immediate 5 | pub fn stbi(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load first operand 7 | let op1: u64 = state.gpr[y].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(z as u64); 11 | 12 | // Load x 13 | let res: i64 = state.gpr[x].into(); 14 | 15 | // Store in memory 16 | state.mem[ByteAt(a)] = (res as i8).into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stti.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::TetraAt; 3 | 4 | /// store tetra immediate 5 | pub fn stti(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load first operand 7 | let op1: u64 = state.gpr[y].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(z as u64); 11 | 12 | // Load x 13 | let res: i64 = state.gpr[x].into(); 14 | 15 | // Store in memory 16 | state.mem[TetraAt(a)] = (res as i32).into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stwi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::WydeAt; 3 | 4 | /// store wyde immediate 5 | pub fn stwi(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load first operand 7 | let op1: u64 = state.gpr[y].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(z as u64); 11 | 12 | // Load x 13 | let res: i64 = state.gpr[x].into(); 14 | 15 | // Store in memory 16 | state.mem[WydeAt(a)] = (res as i16).into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/stsf.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::TetraAt; 3 | 4 | pub fn stsf(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let op1: u64 = state.gpr[y].into(); 7 | let op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(op2); 11 | 12 | // Load x 13 | let res: f64 = state.gpr[x].into(); 14 | 15 | // Store in memory 16 | state.mem[TetraAt(a)] = (res as f32).into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldbi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::ByteAt; 3 | 4 | /// load byte immediate 5 | pub fn ldbi(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load first operand 7 | let op1: u64 = state.gpr[y].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(z as u64); 11 | 12 | // Load from memory 13 | let res: i8 = state.mem[ByteAt(a)].into(); 14 | 15 | // Store result 16 | state.gpr[x] = (res as i64).into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldwi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::WydeAt; 3 | 4 | /// load wyde immediate 5 | pub fn ldwi(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load first operand 7 | let op1: u64 = state.gpr[y].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(z as u64); 11 | 12 | // Load from memory 13 | let res: i16 = state.mem[WydeAt(a)].into(); 14 | 15 | // Store result 16 | state.gpr[x] = (res as i64).into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bitwise/saddi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// sideways add immediate 4 | pub fn saddi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Calculate andn and load result 6 | super::andni(state, x, y, z); 7 | let mut bits: u64 = state.gpr[x].into(); 8 | 9 | // Execute 10 | let mut res: u64 = 0; 11 | while bits != 0 { 12 | res += bits % 2; 13 | bits /= 2; 14 | } 15 | 16 | // Store result 17 | state.gpr[x] = res.into(); 18 | } 19 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bytewise/bdifi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// byte difference immediate 4 | pub fn bdifi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | let mut result = (op1 >> 8) << 8; 10 | let y_byte = super::get_byte(op1); 11 | let interim = y_byte.saturating_sub(z) as u64; 12 | result += interim; 13 | 14 | // Store result 15 | state.gpr[x] = result.into(); 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/fsqrt.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn fsqrt(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: f64 = state.gpr[z].into(); 6 | 7 | // Execute 8 | let res: f64 = match y { 9 | 1 => unimplemented!(), 10 | 2 => unimplemented!(), 11 | 3 => unimplemented!(), 12 | 4 => unimplemented!(), 13 | _ => op1.sqrt(), 14 | }; 15 | 16 | // Store result 17 | state.gpr[x] = res.into(); 18 | } 19 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/fun.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn fun(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: f64 = state.gpr[y].into(); 6 | let op2: f64 = state.gpr[z].into(); 7 | 8 | // Execute 9 | let res: i64 = if op1.is_nan() || op1 > op2 { 10 | 1 11 | } else if op2.is_nan() || op1 < op2 { 12 | -1 13 | } else { 14 | 0 15 | }; 16 | 17 | // Store result 18 | state.gpr[x] = res.into(); 19 | } 20 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/ldsf.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::TetraAt; 3 | 4 | pub fn ldsf(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: u64 = state.gpr[y].into(); 7 | let op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(op2); 11 | 12 | // Load from memory 13 | let res: f32 = state.mem[TetraAt(a)].into(); 14 | 15 | // Store result 16 | state.gpr[x] = (res as f64).into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldti.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::TetraAt; 3 | 4 | /// load tetra immediate 5 | pub fn ldti(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load first operand 7 | let op1: u64 = state.gpr[y].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(z as u64); 11 | 12 | // Load from memory 13 | let res: i32 = state.mem[TetraAt(a)].into(); 14 | 15 | // Store result 16 | state.gpr[x] = (res as i64).into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldbui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::ByteAt; 3 | 4 | /// load byte unsigned immediate 5 | pub fn ldbui(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load first operand 7 | let op1: u64 = state.gpr[y].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(z as u64); 11 | 12 | // Load from memory 13 | let res: u8 = state.mem[ByteAt(a)].into(); 14 | 15 | // Store result 16 | state.gpr[x] = (res as u64).into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldwui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::WydeAt; 3 | 4 | /// load wyde unsigned immediate 5 | pub fn ldwui(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load first operand 7 | let op1: u64 = state.gpr[y].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(z as u64); 11 | 12 | // Load from memory 13 | let res: u16 = state.mem[WydeAt(a)].into(); 14 | 15 | // Store result 16 | state.gpr[x] = (res as u64).into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/sthti.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::TetraAt; 3 | 4 | /// store high tetra immediate 5 | pub fn sthti(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load first operand 7 | let op1: u64 = state.gpr[y].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(z as u64); 11 | 12 | // Load x 13 | let res: i64 = state.gpr[x].into(); 14 | 15 | // Store in memory 16 | state.mem[TetraAt(a)] = ((res >> 32) as i32).into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bytewise/tdifi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// tetra difference immediate 4 | pub fn tdifi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | let mut result = (op1 >> 32) << 32; 10 | let y_tetra = super::get_tetra(op1); 11 | let interim = y_tetra.saturating_sub(z as u32) as u64; 12 | result += interim; 13 | 14 | // Store result 15 | state.gpr[x] = result.into(); 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bytewise/wdifi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// wyde difference immediate 4 | pub fn wdifi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let op1: u64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | let mut result = (op1 >> 16) << 16; 10 | let y_wyde = super::get_wyde(op1); 11 | let interim = y_wyde.saturating_sub(z as u16) as u64; 12 | result += interim; 13 | 14 | // Store result 15 | state.gpr[x] = result.into(); 16 | } 17 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldtui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::TetraAt; 3 | 4 | /// load tetra unsigned immediate 5 | pub fn ldtui(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load first operand 7 | let op1: u64 = state.gpr[y].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(z as u64); 11 | 12 | // Load from memory 13 | let res: u32 = state.mem[TetraAt(a)].into(); 14 | 15 | // Store result 16 | state.gpr[x] = (res as u64).into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::ByteAt; 3 | 4 | /// store byte 5 | pub fn stb(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op2: u64 = state.gpr[z].into(); 9 | 10 | // Execute 11 | let a = op1.wrapping_add(op2); 12 | 13 | // Load x 14 | let res: i64 = state.gpr[x].into(); 15 | 16 | // Store in memory 17 | state.mem[ByteAt(a)] = (res as i8).into(); 18 | } 19 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stw.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::WydeAt; 3 | 4 | /// store wyde 5 | pub fn stw(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op2: u64 = state.gpr[z].into(); 9 | 10 | // Execute 11 | let a = op1.wrapping_add(op2); 12 | 13 | // Load x 14 | let res: i64 = state.gpr[x].into(); 15 | 16 | // Store in memory 17 | state.mem[WydeAt(a)] = (res as i16).into(); 18 | } 19 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldb.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::ByteAt; 3 | 4 | /// load byte 5 | pub fn ldb(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op2: u64 = state.gpr[z].into(); 9 | 10 | // Execute 11 | let a = op1.wrapping_add(op2); 12 | 13 | // Load from memory 14 | let res: i8 = state.mem[ByteAt(a)].into(); 15 | 16 | // Store result 17 | state.gpr[x] = (res as i64).into(); 18 | } 19 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldhti.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::TetraAt; 3 | 4 | /// load high tetra immediate 5 | pub fn ldhti(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load first operand 7 | let op1: u64 = state.gpr[y].into(); 8 | 9 | // Execute 10 | let a = op1.wrapping_add(z as u64); 11 | 12 | // Load from memory 13 | let res: u32 = state.mem[TetraAt(a)].into(); 14 | 15 | // Store result 16 | state.gpr[x] = ((res as u64) << 32).into(); 17 | } 18 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stt.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::TetraAt; 3 | 4 | /// store tetra 5 | pub fn stt(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op2: u64 = state.gpr[z].into(); 9 | 10 | // Execute 11 | let a = op1.wrapping_add(op2); 12 | 13 | // Load x 14 | let res: i64 = state.gpr[x].into(); 15 | 16 | // Store in memory 17 | state.mem[TetraAt(a)] = (res as i32).into(); 18 | } 19 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldt.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::TetraAt; 3 | 4 | /// load tetra 5 | pub fn ldt(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op2: u64 = state.gpr[z].into(); 9 | 10 | // Execute 11 | let a = op1.wrapping_add(op2); 12 | 13 | // Load from memory 14 | let res: i32 = state.mem[TetraAt(a)].into(); 15 | 16 | // Store result 17 | state.gpr[x] = (res as i64).into(); 18 | } 19 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldw.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::WydeAt; 3 | 4 | /// load wyde 5 | pub fn ldw(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op2: u64 = state.gpr[z].into(); 9 | 10 | // Execute 11 | let a = op1.wrapping_add(op2); 12 | 13 | // Load from memory 14 | let res: i16 = state.mem[WydeAt(a)].into(); 15 | 16 | // Store result 17 | state.gpr[x] = (res as i64).into(); 18 | } 19 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldbu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::ByteAt; 3 | 4 | /// load byte unsigned 5 | pub fn ldbu(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op2: u64 = state.gpr[z].into(); 9 | 10 | // Execute 11 | let a = op1.wrapping_add(op2); 12 | 13 | // Load from memory 14 | let res: u8 = state.mem[ByteAt(a)].into(); 15 | 16 | // Store result 17 | state.gpr[x] = (res as u64).into(); 18 | } 19 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldtu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::TetraAt; 3 | 4 | /// load tetra unsigned 5 | pub fn ldtu(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op2: u64 = state.gpr[z].into(); 9 | 10 | // Execute 11 | let a = op1.wrapping_add(op2); 12 | 13 | // Load from memory 14 | let res: u32 = state.mem[TetraAt(a)].into(); 15 | 16 | // Store result 17 | state.gpr[x] = (res as u64).into(); 18 | } 19 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldwu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::WydeAt; 3 | 4 | /// load wyde unsigned 5 | pub fn ldwu(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op2: u64 = state.gpr[z].into(); 9 | 10 | // Execute 11 | let a = op1.wrapping_add(op2); 12 | 13 | // Load from memory 14 | let res: u16 = state.mem[WydeAt(a)].into(); 15 | 16 | // Store result 17 | state.gpr[x] = (res as u64).into(); 18 | } 19 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/stht.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::TetraAt; 3 | 4 | /// store high tetra 5 | pub fn stht(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op2: u64 = state.gpr[z].into(); 9 | 10 | // Execute 11 | let a = op1.wrapping_add(op2); 12 | 13 | // Load x 14 | let res: i64 = state.gpr[x].into(); 15 | 16 | // Store in memory 17 | state.mem[TetraAt(a)] = ((res >> 32) as i32).into(); 18 | } 19 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/ldht.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::TetraAt; 3 | 4 | /// load high tetra 5 | pub fn ldht(state: &mut State, x: u8, y: u8, z: u8) { 6 | // Load operands 7 | let op1: u64 = state.gpr[y].into(); 8 | let op2: u64 = state.gpr[z].into(); 9 | 10 | // Execute 11 | let a = op1.wrapping_add(op2); 12 | 13 | // Load from memory 14 | let res: u32 = state.mem[TetraAt(a)].into(); 15 | 16 | // Store result 17 | state.gpr[x] = ((res as u64) << 32).into(); 18 | } 19 | -------------------------------------------------------------------------------- /src/machine/behavior/is/conditional/mod.rs: -------------------------------------------------------------------------------- 1 | mod_def_reexport!{ 2 | csevi, 3 | csev, 4 | csni, 5 | csnni, 6 | csnn, 7 | csnpi, 8 | csnp, 9 | csn, 10 | csnzi, 11 | csnz, 12 | csodi, 13 | csod, 14 | cspi, 15 | csp, 16 | cszi, 17 | csz, 18 | zsevi, 19 | zsev, 20 | zsni, 21 | zsnni, 22 | zsnn, 23 | zsnpi, 24 | zsnp, 25 | zsn, 26 | zsnzi, 27 | zsnz, 28 | zsodi, 29 | zsod, 30 | zspi, 31 | zsp, 32 | zszi, 33 | zsz, 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/floti.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn floti(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: i64 = z as i64; 6 | 7 | // Execute 8 | let mut res = op1 as f64; 9 | match y { // FIXME this might be incorrect 10 | 1 => unimplemented!(), 11 | 2 => unimplemented!(), 12 | 3 => unimplemented!(), 13 | 4 => unimplemented!(), 14 | _ => res = res, 15 | } 16 | 17 | // Store result 18 | state.gpr[x] = res.into(); 19 | } 20 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/flotui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn flotui(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: u64 = z as u64; 6 | 7 | // Execute 8 | let mut res = op1 as f64; 9 | match y { // FIXME this might be incorrect 10 | 1 => unimplemented!(), 11 | 2 => unimplemented!(), 12 | 3 => unimplemented!(), 13 | 4 => unimplemented!(), 14 | _ => res = res, 15 | } 16 | 17 | // Store result 18 | state.gpr[x] = res.into(); 19 | } 20 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/flot.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn flot(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: i64 = state.gpr[z].into(); 6 | 7 | // Execute 8 | let mut res = op1 as f64; 9 | match y { // FIXME this might be incorrect 10 | 1 => unimplemented!(), 11 | 2 => unimplemented!(), 12 | 3 => unimplemented!(), 13 | 4 => unimplemented!(), 14 | _ => res = res, 15 | } 16 | 17 | // Store result 18 | state.gpr[x] = res.into(); 19 | } 20 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/flotu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn flotu(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operand 5 | let op1: u64 = state.gpr[z].into(); 6 | 7 | // Execute 8 | let mut res = op1 as f64; 9 | match y { // FIXME this might be incorrect 10 | 1 => unimplemented!(), 11 | 2 => unimplemented!(), 12 | 3 => unimplemented!(), 13 | 4 => unimplemented!(), 14 | _ => res = res, 15 | } 16 | 17 | // Store result 18 | state.gpr[x] = res.into(); 19 | } 20 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/divi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::sr::R; 3 | 4 | pub fn divi(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: i64 = state.gpr[y].into(); 7 | 8 | // Execute 9 | let res; 10 | let rem; 11 | 12 | if z == 0 { 13 | res = 0; 14 | rem = op1; 15 | } else { 16 | res = op1.wrapping_div(z as i64); 17 | rem = op1 - res; 18 | } 19 | 20 | // Store 21 | state.gpr[x] = res.into(); 22 | state.sr[R::R] = rem.into(); 23 | } 24 | -------------------------------------------------------------------------------- /src/machine/behavior/is/control/mod.rs: -------------------------------------------------------------------------------- 1 | mod_def_reexport!{ 2 | bevb, 3 | bev, 4 | bnb, 5 | bnnb, 6 | bnn, 7 | bnpb, 8 | bnp, 9 | bn, 10 | bnzb, 11 | bnz, 12 | bodb, 13 | bod, 14 | bpb, 15 | bp, 16 | bzb, 17 | bz, 18 | goi, 19 | go, 20 | jmpb, 21 | jmp, 22 | pbevb, 23 | pbev, 24 | pbnb, 25 | pbnnb, 26 | pbnn, 27 | pbnpb, 28 | pbnp, 29 | pbn, 30 | pbnzb, 31 | pbnz, 32 | pbodb, 33 | pbod, 34 | pbpb, 35 | pbp, 36 | pbzb, 37 | pbz, 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/fcmpe.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::sr::R; 3 | 4 | pub fn fcmpe(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let op1: f64 = state.gpr[y].into(); 7 | let op2: f64 = state.gpr[z].into(); 8 | let eps: f64 = state.sr[R::E].into(); 9 | 10 | // Execute 11 | let res: i64 = match op1 - op2 { 12 | d if d.abs() <= eps => 0, 13 | d if d > 0.0 => 1, 14 | _ => -1, 15 | }; 16 | 17 | // Store result 18 | state.gpr[x] = res.into(); 19 | } 20 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/fint.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | pub fn fint(state: &mut State, x: u8, y: u8, z: u8) { 4 | // Load operands 5 | let op1: f64 = state.gpr[z].into(); 6 | 7 | // Execute 8 | let res: f64 = match y { 9 | 1 => op1.round(), // round off 10 | 2 => op1.ceil(), // round up 11 | 3 => op1.floor(), // round down 12 | 4 => (op1 / 10.0).ceil() * 10.0, // round to nearest ten 13 | _ => panic!("no rounding mode"), 14 | }; 15 | 16 | // Store result 17 | state.gpr[x] = res.into(); 18 | } 19 | -------------------------------------------------------------------------------- /src/machine/behavior/is/float/fune.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::sr::R; 3 | 4 | pub fn fune(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let op1: f64 = state.gpr[y].into(); 7 | let op2: f64 = state.gpr[z].into(); 8 | let eps: f64 = state.sr[R::E].into(); 9 | 10 | // Execute 11 | let res: i64 = if op1.is_nan() || op1 - op2 > eps { 12 | 1 13 | } else if op2.is_nan() || op1 - op2 < eps { 14 | -1 15 | } else { 16 | 0 17 | }; 18 | 19 | // Store result 20 | state.gpr[x] = res.into(); 21 | } 22 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/cswapi.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::OctaAt; 3 | use machine::state::sr::R; 4 | 5 | /// compare and swap ocatbytes immediate 6 | pub fn cswapi(state: &mut State, x: u8, y: u8, z: u8) { 7 | // Load first operand 8 | let op1: u64 = state.gpr[y].into(); 9 | 10 | // Execute 11 | let a = op1.wrapping_add(z as u64); 12 | 13 | if state.mem[OctaAt(a)] == state.sr[R::P] { 14 | state.mem[OctaAt(a)] = state.gpr[x]; 15 | } else { 16 | state.sr[R::P] = state.mem[OctaAt(a)]; 17 | state.gpr[x] = 0u64.into(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/machine/behavior/is/memory/mod.rs: -------------------------------------------------------------------------------- 1 | mod_def_reexport!{ 2 | lda, 3 | ldbi, 4 | ldb, 5 | ldbui, 6 | ldbu, 7 | ldhti, 8 | ldht, 9 | ldoi, 10 | ldo, 11 | ldoui, 12 | ldou, 13 | ldti, 14 | ldt, 15 | ldtui, 16 | ldtu, 17 | ldwi, 18 | ldw, 19 | ldwui, 20 | ldwu, 21 | stbi, 22 | stb, 23 | stbui, 24 | stbu, 25 | stcoi, 26 | stco, 27 | sthti, 28 | stht, 29 | stoi, 30 | sto, 31 | stoui, 32 | stou, 33 | stti, 34 | stt, 35 | sttui, 36 | sttu, 37 | stwi, 38 | stw, 39 | stwui, 40 | stwu, 41 | } 42 | -------------------------------------------------------------------------------- /src/machine/behavior/is/system/cswap.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::OctaAt; 3 | use machine::state::sr::R; 4 | 5 | /// compare and swap ocatbytes 6 | pub fn cswap(state: &mut State, x: u8, y: u8, z: u8) { 7 | // Load operands 8 | let op1: u64 = state.gpr[y].into(); 9 | let op2: u64 = state.gpr[z].into(); 10 | 11 | // Execute 12 | let a = op1.wrapping_add(op2); 13 | 14 | if state.mem[OctaAt(a)] == state.sr[R::P] { 15 | state.mem[OctaAt(a)] = state.gpr[x]; 16 | } else { 17 | state.sr[R::P] = state.mem[OctaAt(a)]; 18 | state.gpr[x] = 0u64.into(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/div.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::sr::R; 3 | 4 | pub fn div(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let op1: i64 = state.gpr[y].into(); 7 | let op2: i64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let res; 11 | let rem; // remainder 12 | 13 | if op2 == 0 { // special case: denominator == 0 14 | res = 0; 15 | rem = op1; 16 | } else { 17 | res = op1.wrapping_div(op2); 18 | rem = op1 - res; 19 | } 20 | 21 | // Store 22 | state.gpr[x] = res.into(); 23 | state.sr[R::R] = rem.into(); 24 | } 25 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/mod.rs: -------------------------------------------------------------------------------- 1 | mod_def_reexport!{ 2 | addi, 3 | add, 4 | addu16i, 5 | addu16, 6 | addu2i, 7 | addu2, 8 | addu4i, 9 | addu4, 10 | addu8i, 11 | addu8, 12 | addui, 13 | addu, 14 | cmpi, 15 | cmp, 16 | cmpui, 17 | cmpu, 18 | divi, 19 | div, 20 | divui, 21 | divu, 22 | muli, 23 | mul, 24 | mului, 25 | mulu, 26 | negi, 27 | neg, 28 | negui, 29 | negu, 30 | sli, 31 | sl, 32 | slui, 33 | slu, 34 | sri, 35 | sr, 36 | srui, 37 | sru, 38 | subi, 39 | sub, 40 | subui, 41 | subu, 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/machine/state/gpr.rs: -------------------------------------------------------------------------------- 1 | use machine::state::types::Octa; 2 | 3 | use std::ops::{Index, IndexMut}; 4 | 5 | pub struct GPRegisters { 6 | buf: Vec, 7 | } 8 | 9 | impl GPRegisters { 10 | pub fn new() -> Self { 11 | GPRegisters { 12 | buf: vec![0u64.into(); 256], 13 | } 14 | } 15 | } 16 | 17 | impl Index for GPRegisters { 18 | type Output = Octa; 19 | fn index(&self, index: u8) -> &Self::Output { 20 | self.buf.index(index as usize) 21 | } 22 | } 23 | 24 | impl IndexMut for GPRegisters { 25 | fn index_mut(&mut self, index: u8) -> &mut Self::Output { 26 | self.buf.index_mut(index as usize) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bytewise/bdif.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// byte difference 4 | pub fn bdif(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let mut op1: u64 = state.gpr[y].into(); 7 | let mut op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let mut result: u64 = 0; 11 | for i in 0..8 { 12 | let y_byte = super::get_byte(op1); 13 | let z_byte = super::get_byte(op2); 14 | let interim = (y_byte.saturating_sub(z_byte) as u64) << (8 * i); 15 | result += interim; 16 | op1 >>= 8; 17 | op2 >>= 8; 18 | } 19 | 20 | // Store result 21 | state.gpr[x] = result.into(); 22 | } 23 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bytewise/wdif.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// wyde difference 4 | pub fn wdif(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let mut op1: u64 = state.gpr[y].into(); 7 | let mut op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let mut result: u64 = 0; 11 | for i in 0..4 { 12 | let y_wyde = super::get_wyde(op1); 13 | let z_wyde = super::get_wyde(op2); 14 | let interim = (y_wyde.saturating_sub(z_wyde) as u64) << (16 * i); 15 | result += interim; 16 | op1 >>= 16; 17 | op2 >>= 16; 18 | } 19 | 20 | // Store result 21 | state.gpr[x] = result.into(); 22 | } 23 | -------------------------------------------------------------------------------- /ci/30-line_endings.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | FOLDER="." 4 | FILES='.+\.\(md\|rs\|\sh\|toml\|txt\|yml\)' 5 | 6 | # Exit script on first error 7 | set -o errexit -o nounset 8 | 9 | # Explain what we do 10 | echo -n ">>> Seaching for files with wrong line endings..." 11 | 12 | # Check any text file 13 | FOUND=0 14 | for FILE in $(find $FOLDER -regex $FILES); do 15 | # Ignore files that are ignored by git 16 | git check-ignore -q $FILE && continue 17 | 18 | # Search wrong line endings 19 | if grep -q $'\r' $FILE; then 20 | [ $FOUND == 0 ] && echo -e "\tError." 21 | echo -e "Found: $FILE" 22 | FOUND=1 23 | fi 24 | done 25 | test $FOUND == 0 26 | echo -e "\tDone." 27 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bytewise/tdif.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// tetra difference 4 | pub fn tdif(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let mut op1: u64 = state.gpr[y].into(); 7 | let mut op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let mut result: u64 = 0; 11 | for i in 0..2 { 12 | let y_tetra = super::get_tetra(op1); 13 | let z_tetra = super::get_tetra(op2); 14 | let interim = (y_tetra.saturating_sub(z_tetra) as u64) << (32 * i); 15 | result += interim; 16 | op1 >>= 32; 17 | op2 >>= 32; 18 | } 19 | 20 | // Store result 21 | state.gpr[x] = result.into(); 22 | } 23 | -------------------------------------------------------------------------------- /ci/40-indentation.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | FOLDER="." 4 | FILES='.+\.\(md\|rs\|\sh\|toml\|txt\|yml\)' 5 | 6 | # Exit script on first error 7 | set -o errexit -o nounset 8 | 9 | # Explain what we do 10 | echo -n ">>> Seaching for files with tab characters..." 11 | 12 | # Check any text file 13 | FOUND=0 14 | for FILE in $(find $FOLDER -regex $FILES); do 15 | # Ignore files that are ignored by git 16 | git check-ignore -q $FILE && continue 17 | 18 | # Search for files with tab characters 19 | if grep -q $'\t' $FILE; then 20 | [ $FOUND == 0 ] && echo -e "\t\tError." 21 | echo -e "Found: $FILE" 22 | FOUND=1 23 | fi 24 | done 25 | test $FOUND == 0 26 | echo -e "\t\tDone." 27 | -------------------------------------------------------------------------------- /ci/10-trailing_whitespaces.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | FOLDER="." 4 | FILES='.+\.\(md\|rs\|\sh\|toml\|txt\|yml\)' 5 | 6 | # Exit script on first error 7 | set -o errexit -o nounset 8 | 9 | # Explain what we do 10 | echo -n ">>> Seaching for lines with trailing whitespaces..." 11 | 12 | # Check any text file 13 | FOUND=0 14 | for FILE in $(find $FOLDER -regex $FILES); do 15 | # Ignore files that are ignored by git 16 | git check-ignore -q $FILE && continue 17 | 18 | # Search for trailing whitespaces 19 | if egrep -q " +$" $FILE; then 20 | [ $FOUND == 0 ] && echo -e "\tError." 21 | echo -e "Found:\t$FILE" 22 | FOUND=1 23 | fi 24 | done 25 | test $FOUND == 0 26 | echo -e "\tDone." 27 | -------------------------------------------------------------------------------- /ci/50-line_length.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | FOLDER="." 4 | FILES='.+\.\(md\|rs\|\sh\|toml\|txt\|yml\)' 5 | COLS=100 6 | 7 | # Exit script on first error 8 | set -o errexit -o nounset 9 | 10 | # Explain what we do 11 | echo -n ">>> Seaching for lines exceeding the length limit..." 12 | 13 | # Check any text file 14 | FOUND=0 15 | for FILE in $(find $FOLDER -regex $FILES); do 16 | # Ignore files that are ignored by git 17 | git check-ignore -q $FILE && continue 18 | 19 | # Seach for lines that are too long 20 | if [ $(wc -L $FILE | cut -d" " -f1) -gt $COLS ]; then 21 | [ $FOUND == 0 ] && echo -e "\tError." 22 | echo -e "Found: $FILE" 23 | FOUND=1 24 | fi 25 | done 26 | test $FOUND == 0 27 | echo -e "\tDone." 28 | -------------------------------------------------------------------------------- /ci/20-trailing_newline.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | FOLDER="." 4 | FILES='.+\.\(md\|rs\|\sh\|toml\|txt\|yml\)' 5 | 6 | # Exit script on first error 7 | set -o errexit -o nounset 8 | 9 | # Explain what we do 10 | echo -n ">>> Seaching for files without a trailing newline..." 11 | 12 | # Check any text file 13 | FOUND=0 14 | for FILE in $(find $FOLDER -regex $FILES); do 15 | # Ignore files that are ignored by git 16 | git check-ignore -q $FILE && continue 17 | 18 | # Search for trailing newline 19 | LASTLINE=$(tail -n 1 $FILE; echo x) 20 | LASTLINE=${LASTLINE%x} 21 | if [ "${LASTLINE: -1}" != $'\n' ]; then 22 | [ $FOUND == 0 ] && echo -e "\tError." 23 | echo -e "Found:\t$FILE" 24 | FOUND=1 25 | fi 26 | done 27 | test $FOUND == 0 28 | echo -e "\tDone." 29 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/mului.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::sr::R; 3 | 4 | pub fn mului(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operand 6 | let op1: u64 = state.gpr[y].into(); 7 | 8 | /* 9 | * Theory: 10 | * 11 | * See instruction MULU in machine::behavior::is::arithmetic::mulu! 12 | */ 13 | 14 | // Calculate the single parts 15 | let mut h = hi(op1) * hi(z as u64); 16 | let m = hi(op1) * lo(z as u64) 17 | + lo(op1) * hi(z as u64); 18 | let mut l = lo(op1) * lo(z as u64); 19 | 20 | // Merge the single parts 21 | h += hi(m); 22 | l += lo(m) << 32; 23 | 24 | // Store results 25 | state.sr[R::H] = h.into(); 26 | state.gpr[x] = l.into(); 27 | } 28 | 29 | fn hi(x: u64) -> u64 { 30 | x >> 32 31 | } 32 | 33 | fn lo(x: u64) -> u64 { 34 | (x as u32) as u64 35 | } 36 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/divui.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::sr::R; 3 | 4 | use extprim::u128::{u128, div_rem}; 5 | 6 | /// divide unsigned 7 | pub fn divui(state: &mut State, x: u8, y: u8, z: u8) { 8 | // Load operands 9 | let num_high: u64 = state.sr[R::D].into(); 10 | let num_low: u64 = state.gpr[y].into(); 11 | let denom = z as u64; 12 | 13 | // Execute 14 | if denom != 0 { 15 | if denom > num_high { 16 | 17 | let num = u128::from_parts(num_high, num_low); 18 | let (divi, rem) = div_rem(num, u128::new(denom)); 19 | // Store result 20 | state.gpr[x] = divi.low64().into(); 21 | state.sr[R::R] = rem.low64().into(); 22 | 23 | } else { 24 | // Store results 25 | state.gpr[x] = state.sr[R::D]; 26 | state.sr[R::R] = state.gpr[y]; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/divu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::sr::R; 3 | 4 | use extprim::u128::{u128, div_rem}; 5 | 6 | /// divide unsigned 7 | pub fn divu(state: &mut State, x: u8, y: u8, z: u8) { 8 | // Load operands 9 | let num_high: u64 = state.sr[R::D].into(); 10 | let num_low: u64 = state.gpr[y].into(); 11 | let denom: u64 = state.gpr[z].into(); 12 | 13 | // Execute 14 | if denom != 0 { 15 | if denom > num_high { 16 | 17 | let num = u128::from_parts(num_high, num_low); 18 | let (divi, rem) = div_rem(num, u128::new(denom)); 19 | // Store result 20 | state.gpr[x] = divi.low64().into(); 21 | state.sr[R::R] = rem.low64().into(); 22 | 23 | } else { 24 | // Store results 25 | state.gpr[x] = state.sr[R::D]; 26 | state.sr[R::R] = state.gpr[y]; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/machine/behavior/cu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::mem::ByteAt; 3 | 4 | pub fn cycle(state: &mut State) { 5 | // The program counter in state may point to any of the four bytes in the 6 | // tetrabyte that is to be executed next. 7 | // We compute the address of the first byte of the next instruction, which stores 8 | // the instruction's opcode. 9 | let opcode_address = state.pc & !(2 + 1); 10 | 11 | // Fetch opcode and operands 12 | let opcode: u8 = state.mem[ByteAt(opcode_address )].into(); 13 | let x: u8 = state.mem[ByteAt(opcode_address + 1)].into(); 14 | let y: u8 = state.mem[ByteAt(opcode_address + 2)].into(); 15 | let z: u8 = state.mem[ByteAt(opcode_address + 3)].into(); 16 | 17 | // Get instruction implementation corresponding to opcode 18 | let instruction = super::is::get_semantics(opcode); 19 | 20 | // Execute instruction 21 | instruction(state, x, y, z); 22 | 23 | // Increase program counter 24 | state.pc += 4; 25 | } 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Janina Born, Barbara Butz, Karoline Plum, Tobias Stolzmann 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/machine/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod behavior; 2 | pub mod state; 3 | 4 | use self::state::mem::ByteAt; 5 | use self::state::State; 6 | 7 | pub struct Machine { 8 | state: State, 9 | /* TODO add more fields... */ 10 | } 11 | 12 | impl Machine { 13 | // TODO FYI: Machine uses the builder pattern. 14 | 15 | pub fn new() -> Self { 16 | Machine { 17 | state: State::new() 18 | } 19 | } 20 | 21 | pub fn load(mut self, pos: u64, data: &[u8]) -> Self { 22 | for i in (pos..).take(data.len()) { 23 | self.state.mem[ByteAt(i)] = data[i as usize].into() 24 | } 25 | self 26 | } 27 | 28 | pub fn set_breakpoint(self, _bp: u64) -> Self { 29 | unimplemented!(); 30 | } 31 | 32 | pub fn start(&mut self) { 33 | unimplemented!(); 34 | } 35 | 36 | pub fn step(&mut self) { 37 | behavior::cu::cycle(&mut self.state); 38 | } 39 | 40 | /// Display the state partially on the command line for testing purposes 41 | /// Be warned, this is only a provisional function, and should be removed later. 42 | /// Its functionality should be provided by a seperate View struct! FIXME 43 | pub fn debug_output(&self) { 44 | self.state.debug_output(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate mmix; 2 | 3 | use mmix::cli::Config; 4 | use mmix::machine::Machine; 5 | 6 | use std::fs::File; 7 | use std::io::{Error, Read}; 8 | 9 | fn main() { 10 | // Parse CLI arguments 11 | let config = Config::parse(); 12 | 13 | // Read the executable 14 | let exe = match read(config.filename()) { 15 | Ok(x) => x, 16 | Err(err) => { 17 | println!("Cannot read '{}': {}", config.filename(), err); 18 | return 19 | } 20 | }; 21 | 22 | // Build a new machine 23 | let mut mmix = 24 | Machine::new() // Create 25 | .load(0, &exe); // Load executable 26 | 27 | // Determine the execution method 28 | let run = match config.step() { 29 | true => Machine::step, 30 | false => Machine::start, 31 | }; 32 | 33 | // Start the machine 34 | loop { 35 | mmix.debug_output(); // Print the current state 36 | pause(); // Wait for the user to press enter 37 | run(&mut mmix); // Run the machine until it pauses 38 | } 39 | } 40 | 41 | fn read(name: &str) -> Result, Error> { 42 | File::open(name)?.bytes().collect() 43 | } 44 | 45 | fn pause() { 46 | std::io::stdin() 47 | .read_line(&mut String::new()) 48 | .expect("something went horribly wrong..."); 49 | } 50 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bytewise/mor.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// multiple or 4 | pub fn mor(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let mut op1: u64 = state.gpr[y].into(); 7 | let mut op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let mut matrix_op1: [[bool; 8]; 8] = [[false; 8]; 8]; 11 | let mut matrix_op2: [[bool; 8]; 8] = [[false; 8]; 8]; 12 | let mut matrix_result: [[bool; 8]; 8] = [[false; 8]; 8]; 13 | 14 | for i in 0..8 { 15 | for j in 0..8 { 16 | matrix_op1[7 - i][7 - j] = get_last_bit(op1); 17 | matrix_op2[7 - i][7 - j] = get_last_bit(op2); 18 | op1 >>= 1; 19 | op2 >>= 1; 20 | } 21 | } 22 | 23 | for i in 0..8 { 24 | for j in 0..8 { 25 | let mut entry = false; 26 | for k in 0..8 { 27 | entry = entry | (matrix_op1[i][k] & matrix_op2[k][j]); 28 | } 29 | matrix_result[i][j] = entry; 30 | } 31 | } 32 | 33 | let mut result: u64 = 0; 34 | 35 | for i in 0..8 { 36 | for j in 0..8 { 37 | result <<= 1; 38 | result += matrix_result[i][j] as u64; 39 | 40 | } 41 | } 42 | 43 | // Store result 44 | state.gpr[x] = result.into(); 45 | } 46 | 47 | fn get_last_bit(bits: u64) -> bool { 48 | bits % 2 != 0 49 | } 50 | -------------------------------------------------------------------------------- /src/machine/state/sr.rs: -------------------------------------------------------------------------------- 1 | use machine::state::types::Octa; 2 | 3 | use std::mem::transmute; 4 | use std::ops::{Index, IndexMut}; 5 | 6 | 7 | #[derive(Debug, PartialEq, Eq, Copy, Clone)] 8 | pub enum R { 9 | A = 21, B = 0, C = 8, D = 1, E = 2, F = 22, G = 19, H = 3, 10 | I = 12, J = 4, K = 15, L = 20, M = 5, N = 9, O = 10, P = 23, 11 | Q = 16, R = 6, S = 11, T = 13, U = 17, V = 18, W = 24, X = 25, 12 | Y = 26, Z = 27, BB = 7, TT = 14, WW = 28, XX = 29, YY = 30, ZZ = 31, 13 | } 14 | 15 | impl From for R { 16 | fn from(from: u8) -> Self { 17 | assert!(from < 32); 18 | unsafe { 19 | transmute::(from) 20 | } 21 | } 22 | } 23 | 24 | impl Into for R { 25 | fn into(self) -> u8 { 26 | self as u8 27 | } 28 | } 29 | 30 | 31 | pub struct SRegisters { 32 | buf: Vec, 33 | } 34 | 35 | impl SRegisters { 36 | pub fn new() -> Self { 37 | SRegisters { 38 | buf: vec![0u64.into(); 32], 39 | } 40 | } 41 | } 42 | 43 | impl Index for SRegisters { 44 | type Output = Octa; 45 | fn index(&self, index: R) -> &Self::Output { 46 | self.buf.index(index as usize) 47 | } 48 | } 49 | 50 | impl IndexMut for SRegisters { 51 | fn index_mut(&mut self, index: R) -> &mut Self::Output { 52 | self.buf.index_mut(index as usize) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bytewise/mxor.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// multiple exclusive-or 4 | pub fn mxor(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let mut op1: u64 = state.gpr[y].into(); 7 | let mut op2: u64 = state.gpr[z].into(); 8 | 9 | // Execute 10 | let mut matrix_op1: [[bool; 8]; 8] = [[false; 8]; 8]; 11 | let mut matrix_op2: [[bool; 8]; 8] = [[false; 8]; 8]; 12 | let mut matrix_result: [[bool; 8]; 8] = [[false; 8]; 8]; 13 | 14 | for i in 0..8 { 15 | for j in 0..8 { 16 | matrix_op1[7 - i][7 - j] = get_last_bit(op1); 17 | matrix_op2[7 - i][7 - j] = get_last_bit(op2); 18 | op1 >>= 1; 19 | op2 >>= 1; 20 | } 21 | } 22 | 23 | for i in 0..8 { 24 | for j in 0..8 { 25 | let mut entry = false; 26 | for k in 0..8 { 27 | entry = entry ^ (matrix_op1[i][k] & matrix_op2[k][j]); 28 | } 29 | matrix_result[i][j] = entry; 30 | } 31 | } 32 | 33 | let mut result: u64 = 0; 34 | 35 | for i in 0..8 { 36 | for j in 0..8 { 37 | result <<= 1; 38 | result += matrix_result[i][j] as u64; 39 | 40 | } 41 | } 42 | 43 | // Store result 44 | state.gpr[x] = result.into(); 45 | } 46 | 47 | fn get_last_bit(bits: u64) -> bool { 48 | bits % 2 != 0 49 | } 50 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bytewise/mori.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// multiple or immediate 4 | pub fn mori(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let mut op1: u64 = state.gpr[y].into(); 7 | 8 | // Make z mutable 9 | let mut z = z; 10 | 11 | // Execute 12 | let mut matrix_op1: [[bool; 8]; 8] = [[false; 8]; 8]; 13 | let mut matrix_z: [[bool; 8]; 8] = [[false; 8]; 8]; 14 | let mut matrix_result: [[bool; 8]; 8] = [[false; 8]; 8]; 15 | 16 | for i in 0..8 { 17 | for j in 0..8 { 18 | matrix_op1[7 - i][7 - j] = get_last_bit(op1); 19 | matrix_z[7 - i][7 - j] = get_last_bit(z as u64); 20 | op1 >>= 1; 21 | z >>= 1; 22 | } 23 | } 24 | 25 | for i in 0..8 { 26 | for j in 0..8 { 27 | let mut entry = false; 28 | for k in 0..8 { 29 | entry = entry | (matrix_op1[i][k] & matrix_z[k][j]); 30 | } 31 | matrix_result[i][j] = entry; 32 | } 33 | } 34 | 35 | let mut result: u64 = 0; 36 | 37 | for i in 0..8 { 38 | for j in 0..8 { 39 | result <<= 1; 40 | result += matrix_result[i][j] as u64; 41 | 42 | } 43 | } 44 | 45 | // Store result 46 | state.gpr[x] = result.into(); 47 | } 48 | 49 | fn get_last_bit(bits: u64) -> bool { 50 | bits % 2 != 0 51 | } 52 | -------------------------------------------------------------------------------- /src/machine/behavior/is/bytewise/mxori.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | 3 | /// multiple exclusive-or immediate 4 | pub fn mxori(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load first operand 6 | let mut op1: u64 = state.gpr[y].into(); 7 | 8 | // Make z mutable 9 | let mut z = z; 10 | 11 | // Execute 12 | let mut matrix_op1: [[bool; 8]; 8] = [[false; 8]; 8]; 13 | let mut matrix_z: [[bool; 8]; 8] = [[false; 8]; 8]; 14 | let mut matrix_result: [[bool; 8]; 8] = [[false; 8]; 8]; 15 | 16 | for i in 0..8 { 17 | for j in 0..8 { 18 | matrix_op1[7 - i][7 - j] = get_last_bit(op1); 19 | matrix_z[7 - i][7 - j] = get_last_bit(z as u64); 20 | op1 >>= 1; 21 | z >>= 1; 22 | } 23 | } 24 | 25 | for i in 0..8 { 26 | for j in 0..8 { 27 | let mut entry = false; 28 | for k in 0..8 { 29 | entry = entry ^ (matrix_op1[i][k] & matrix_z[k][j]); 30 | } 31 | matrix_result[i][j] = entry; 32 | } 33 | } 34 | 35 | let mut result: u64 = 0; 36 | 37 | for i in 0..8 { 38 | for j in 0..8 { 39 | result <<= 1; 40 | result += matrix_result[i][j] as u64; 41 | 42 | } 43 | } 44 | 45 | // Store result 46 | state.gpr[x] = result.into(); 47 | } 48 | 49 | fn get_last_bit(bits: u64) -> bool { 50 | bits % 2 != 0 51 | } 52 | -------------------------------------------------------------------------------- /src/machine/state/types.rs: -------------------------------------------------------------------------------- 1 | use std::mem::transmute; 2 | 3 | #[derive(Clone, Copy, Eq, PartialEq, Debug)] 4 | pub struct Byte(u8); 5 | 6 | #[derive(Clone, Copy, Eq, PartialEq, Debug)] 7 | pub struct Wyde(u16); 8 | 9 | #[derive(Clone, Copy, Eq, PartialEq, Debug)] 10 | pub struct Tetra(u32); 11 | 12 | #[derive(Clone, Copy, Eq, PartialEq, Debug)] 13 | pub struct Octa(u64); 14 | 15 | macro_rules! type_impl { 16 | ( $( ($outer:ident, $inner:ty) => ($( $convert:ty ),*), )* ) => { 17 | $( 18 | $( 19 | impl From<$convert> for $outer { 20 | fn from(from: $convert) -> Self { 21 | let x = unsafe { 22 | transmute::<$convert, $inner>(from) 23 | }; 24 | $outer(x) 25 | } 26 | } 27 | 28 | impl Into<$convert> for $outer { 29 | fn into(self) -> $convert { 30 | let x = self.0; 31 | unsafe { 32 | transmute::<$inner, $convert>(x) 33 | } 34 | } 35 | } 36 | )* 37 | )* 38 | } 39 | } 40 | 41 | type_impl! { 42 | (Byte, u8) => ( u8, i8 ), 43 | (Wyde, u16) => (u16, i16 ), 44 | (Tetra, u32) => (u32, i32, f32), 45 | (Octa, u64) => (u64, i64, f64), 46 | } 47 | 48 | #[cfg(test)] 49 | mod tests { 50 | use super::*; 51 | 52 | #[test] 53 | fn f32_tetra_u32() { 54 | let x: Tetra = 3.14f32.into(); 55 | let y: u32 = x.into(); 56 | assert_eq!(0x4048f5c3, y); 57 | } 58 | 59 | // TODO add more tests 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/machine/behavior/is/arithmetic/mulu.rs: -------------------------------------------------------------------------------- 1 | use machine::state::State; 2 | use machine::state::sr::R; 3 | 4 | pub fn mulu(state: &mut State, x: u8, y: u8, z: u8) { 5 | // Load operands 6 | let op1: u64 = state.gpr[y].into(); 7 | let op2: u64 = state.gpr[z].into(); 8 | 9 | /* 10 | * Theory: 11 | * 12 | * First, we split the operands into parts ("digits") of 32 bit: 13 | * 14 | * op1 == 2^32 * hi(op1) + lo(op2) 15 | * op2 == 2^32 * hi(op2) + lo(op2) 16 | * 17 | * Then, we use the multiplication algorithm from the primary school: 18 | * 19 | * op1 * op2 20 | * == (2^32 * hi(op1) + lo(op2)) * (2^32 * hi(op2) + lo(op2)) 21 | * == 2^64 * hi(op1) * hi(op2) 22 | * + 2^32 * hi(op1) * lo(op2) 23 | * + 2^32 * lo(op1) * hi(op2) 24 | * + lo(op1) * lo(op2) 25 | * 26 | * That's it! 27 | * 28 | * Notes: 29 | * - Splitting the operands can be done with simple bit operations. 30 | * - No multiplication should wrap! 31 | * - A multiplication with 2^n is a left-shift for n (binary) digits. 32 | */ 33 | 34 | // Calculate the single parts 35 | let mut h = hi(op1) * hi(op2); // XX__ 36 | let m = hi(op1) * lo(op2) // _XX_ 37 | + lo(op1) * hi(op2); 38 | let mut l = lo(op1) * lo(op2); // __XX 39 | 40 | // Merge the single parts 41 | h += hi(m); 42 | l += lo(m) << 32; 43 | 44 | 45 | // Store results 46 | state.sr[R::H] = h.into(); 47 | state.gpr[x] = l.into(); 48 | } 49 | 50 | 51 | fn hi(x: u64) -> u64 { 52 | x >> 32 53 | } 54 | 55 | 56 | fn lo(x: u64) -> u64 { 57 | (x as u32) as u64 58 | } 59 | -------------------------------------------------------------------------------- /src/cli.rs: -------------------------------------------------------------------------------- 1 | use clap::{App, AppSettings, Arg}; 2 | 3 | #[derive(Debug)] 4 | pub struct Config { 5 | filename: String, 6 | step: bool, 7 | } 8 | 9 | impl Config { 10 | pub fn parse() -> Self { 11 | // Parse the CLI arguments using clap 12 | let m = app().get_matches(); 13 | 14 | // Return a configuration 15 | Config { 16 | filename: m.value_of("filename").unwrap().into(), 17 | step: m.is_present("step"), 18 | } 19 | } 20 | 21 | pub fn filename(&self) -> &str { 22 | &self.filename 23 | } 24 | 25 | pub fn step(&self) -> bool { 26 | self.step 27 | } 28 | } 29 | 30 | fn app<'a, 'b>() -> App<'a, 'b> { 31 | App::new( "mmixvm" ) 32 | .version( "0.1.0" ) 33 | .about( "An MMIX virtual machine written in Rust" ) 34 | .setting( AppSettings::ColoredHelp ) 35 | .arg( 36 | Arg::with_name( "filename" ) 37 | .value_name( "filename" ) 38 | .help( "A binary used to initialize the main memory" ) 39 | .required( true ) 40 | .index( 1 ) 41 | ) 42 | .arg( 43 | Arg::with_name( "step" ) 44 | .help( "Specifies to execute the program step-by-step" ) 45 | .short( "s" ) 46 | .long( "step" ) 47 | ) 48 | } 49 | -------------------------------------------------------------------------------- /src/machine/state/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod gpr; 2 | pub mod mem; 3 | pub mod sr; 4 | pub mod types; 5 | 6 | use machine::behavior::is::get_symbolics; 7 | use self::sr::{R, SRegisters}; 8 | use self::gpr::GPRegisters; 9 | use self::mem::*; 10 | 11 | pub struct State { 12 | pub pc: u64, 13 | pub sr: SRegisters, 14 | pub gpr: GPRegisters, 15 | pub mem: Memory, 16 | } 17 | 18 | impl State { 19 | pub fn new() -> Self { 20 | State { 21 | pc: 0, // default bootstrap address: 0x0 22 | sr: SRegisters::new(), 23 | gpr: GPRegisters::new(), 24 | mem: Memory::new(), 25 | } 26 | } 27 | 28 | pub fn from_parts(pc: u64, sr: SRegisters, gpr: GPRegisters, mem: Memory) -> Self { 29 | State { 30 | pc: pc, 31 | sr: sr, 32 | gpr: gpr, 33 | mem: mem, 34 | } 35 | } 36 | 37 | /// Display the state partially on the command line for testing purposes 38 | /// Be warned, this is only a provisional function, and should be removed later. 39 | /// Its functionality should be provided by a seperate View struct! FIXME 40 | pub fn debug_output(&self) { 41 | // General purpose registers 42 | for i in 0..5u8 { 43 | let val: u64 = self.gpr[i].into(); 44 | 45 | let hi = (val >> 48) as u16; 46 | let mh = (val >> 32) as u16; 47 | let ml = (val >> 16) as u16; 48 | let lo = val as u16; 49 | 50 | println!("gpr[{}]:\t\t{:04x} {:04x} {:04x} {:04x}", i, hi, mh, ml, lo); 51 | } 52 | println!(); 53 | 54 | // Special registers 55 | { 56 | let val: u64 = self.sr[R::R].into(); 57 | 58 | let hi = (val >> 48) as u16; 59 | let mh = (val >> 32) as u16; 60 | let ml = (val >> 16) as u16; 61 | let lo = val as u16; 62 | 63 | println!("sr[R::R]:\t{:04x} {:04x} {:04x} {:04x}", hi, mh, ml, lo); 64 | } 65 | println!(""); 66 | 67 | // Memory 68 | for i in 0..5 { 69 | let hi: u16 = self.mem[WydeAt(i )].into(); 70 | let mh: u16 = self.mem[WydeAt(i + 2)].into(); 71 | let ml: u16 = self.mem[WydeAt(i + 4)].into(); 72 | let lo: u16 = self.mem[WydeAt(i + 6)].into(); 73 | println!("mem[OctaAt({})]:\t{:04x} {:04x} {:04x} {:04x}", i, hi, mh, ml, lo); 74 | } 75 | println!(""); 76 | 77 | // Programm counter 78 | { 79 | println!("pc:\t{}", self.pc); 80 | 81 | let op: u8 = self.mem[ByteAt(self.pc )].into(); 82 | let x: u8 = self.mem[ByteAt(self.pc + 1)].into(); 83 | let y: u8 = self.mem[ByteAt(self.pc + 2)].into(); 84 | let z: u8 = self.mem[ByteAt(self.pc + 3)].into(); 85 | let sym = get_symbolics(op); 86 | 87 | println!("next:\t{} x:{:02x} y:{:02x} z:{:02x}", sym, x, y, z); 88 | } 89 | println!(""); 90 | println!("-----------------------------------"); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/machine/behavior/is/mod.rs: -------------------------------------------------------------------------------- 1 | macro_rules! mod_def_reexport { 2 | ( $( $instr:ident, )* ) => ( 3 | $( 4 | mod $instr; 5 | pub use self::$instr::$instr; 6 | )* 7 | ) 8 | } 9 | 10 | 11 | pub mod arithmetic; 12 | pub mod bitwise; 13 | pub mod bytewise; 14 | pub mod conditional; 15 | pub mod control; 16 | pub mod float; 17 | pub mod immediate; 18 | pub mod interrupt; 19 | pub mod memory; 20 | pub mod other; 21 | pub mod subroutine; 22 | pub mod system; 23 | 24 | use machine::state::State; 25 | 26 | pub fn get_semantics(opcode: u8) -> Semantic { 27 | SEMANTICS[opcode as usize] 28 | } 29 | 30 | pub fn get_symbolics(opcode: u8) -> &'static str { 31 | SYMBOLICS[opcode as usize] 32 | } 33 | 34 | type Semantic = fn(&mut State, u8, u8, u8); 35 | 36 | const SEMANTICS: [Semantic; 256] = [ 37 | interrupt::trap, 38 | float::fcmp, 39 | float::fun, 40 | float::feql, 41 | float::fadd, 42 | float::fix, 43 | float::fsub, 44 | float::fixu, 45 | float::flot, 46 | float::floti, 47 | float::flotu, 48 | float::flotui, 49 | float::sflot, 50 | float::sfloti, 51 | float::sflotu, 52 | float::sflotui, 53 | float::fmul, 54 | float::fcmpe, 55 | float::fune, 56 | float::feqle, 57 | float::fdiv, 58 | float::fsqrt, 59 | float::frem, 60 | float::fint, 61 | arithmetic::mul, 62 | arithmetic::muli, 63 | arithmetic::mulu, 64 | arithmetic::mului, 65 | arithmetic::div, 66 | arithmetic::divi, 67 | arithmetic::divu, 68 | arithmetic::divui, 69 | arithmetic::add, 70 | arithmetic::addi, 71 | arithmetic::addu, 72 | arithmetic::addui, 73 | arithmetic::sub, 74 | arithmetic::subi, 75 | arithmetic::subu, 76 | arithmetic::subui, 77 | arithmetic::addu2, 78 | arithmetic::addu2i, 79 | arithmetic::addu4, 80 | arithmetic::addu4i, 81 | arithmetic::addu8, 82 | arithmetic::addu8i, 83 | arithmetic::addu16, 84 | arithmetic::addu16i, 85 | arithmetic::cmp, 86 | arithmetic::cmpi, 87 | arithmetic::cmpu, 88 | arithmetic::cmpui, 89 | arithmetic::neg, 90 | arithmetic::negi, 91 | arithmetic::negu, 92 | arithmetic::negui, 93 | arithmetic::sl, 94 | arithmetic::sli, 95 | arithmetic::slu, 96 | arithmetic::slui, 97 | arithmetic::sr, 98 | arithmetic::sri, 99 | arithmetic::sru, 100 | arithmetic::srui, 101 | control::bn, 102 | control::bnb, 103 | control::bz, 104 | control::bzb, 105 | control::bp, 106 | control::bpb, 107 | control::bod, 108 | control::bodb, 109 | control::bnn, 110 | control::bnnb, 111 | control::bnz, 112 | control::bnzb, 113 | control::bnp, 114 | control::bnpb, 115 | control::bev, 116 | control::bevb, 117 | control::pbn, 118 | control::pbnb, 119 | control::pbz, 120 | control::pbzb, 121 | control::pbp, 122 | control::pbpb, 123 | control::pbod, 124 | control::pbodb, 125 | control::pbnn, 126 | control::pbnnb, 127 | control::pbnz, 128 | control::pbnzb, 129 | control::pbnp, 130 | control::pbnpb, 131 | control::pbev, 132 | control::pbevb, 133 | conditional::csn, 134 | conditional::csni, 135 | conditional::csz, 136 | conditional::cszi, 137 | conditional::csp, 138 | conditional::cspi, 139 | conditional::csod, 140 | conditional::csodi, 141 | conditional::csnn, 142 | conditional::csnni, 143 | conditional::csnz, 144 | conditional::csnzi, 145 | conditional::csnp, 146 | conditional::csnpi, 147 | conditional::csev, 148 | conditional::csevi, 149 | conditional::zsn, 150 | conditional::zsni, 151 | conditional::zsz, 152 | conditional::zszi, 153 | conditional::zsp, 154 | conditional::zspi, 155 | conditional::zsod, 156 | conditional::zsodi, 157 | conditional::zsnn, 158 | conditional::zsnni, 159 | conditional::zsnz, 160 | conditional::zsnzi, 161 | conditional::zsnp, 162 | conditional::zsnpi, 163 | conditional::zsev, 164 | conditional::zsevi, 165 | memory::ldb, 166 | memory::ldbi, 167 | memory::ldbu, 168 | memory::ldbui, 169 | memory::ldw, 170 | memory::ldwi, 171 | memory::ldwu, 172 | memory::ldwui, 173 | memory::ldt, 174 | memory::ldti, 175 | memory::ldtu, 176 | memory::ldtui, 177 | memory::ldo, 178 | memory::ldoi, 179 | memory::ldou, 180 | memory::ldoui, 181 | float::ldsf, 182 | float::ldsfi, 183 | memory::ldht, 184 | memory::ldhti, 185 | system::cswap, 186 | system::cswapi, 187 | system::ldunc, 188 | system::ldunci, 189 | system::ldvts, 190 | system::ldvtsi, 191 | system::preld, 192 | system::preldi, 193 | system::prego, 194 | system::pregoi, 195 | control::go, 196 | control::goi, 197 | memory::stb, 198 | memory::stbi, 199 | memory::stbu, 200 | memory::stbui, 201 | memory::stw, 202 | memory::stwi, 203 | memory::stwu, 204 | memory::stwui, 205 | memory::stt, 206 | memory::stti, 207 | memory::sttu, 208 | memory::sttui, 209 | memory::sto, 210 | memory::stoi, 211 | memory::stou, 212 | memory::stoui, 213 | float::stsf, 214 | float::stsfi, 215 | memory::stht, 216 | memory::sthti, 217 | memory::stco, 218 | memory::stcoi, 219 | system::stunc, 220 | system::stunci, 221 | system::syncd, 222 | system::syncdi, 223 | system::prest, 224 | system::presti, 225 | system::syncid, 226 | system::syncidi, 227 | subroutine::pushgo, 228 | subroutine::pushgoi, 229 | bitwise::or, 230 | bitwise::ori, 231 | bitwise::orn, 232 | bitwise::orni, 233 | bitwise::nor, 234 | bitwise::nori, 235 | bitwise::xor, 236 | bitwise::xori, 237 | bitwise::and, 238 | bitwise::andi, 239 | bitwise::andn, 240 | bitwise::andni, 241 | bitwise::nand, 242 | bitwise::nandi, 243 | bitwise::nxor, 244 | bitwise::nxori, 245 | bytewise::bdif, 246 | bytewise::bdifi, 247 | bytewise::wdif, 248 | bytewise::wdifi, 249 | bytewise::tdif, 250 | bytewise::tdifi, 251 | bytewise::odif, 252 | bytewise::odifi, 253 | bitwise::mux, 254 | bitwise::muxi, 255 | bitwise::sadd, 256 | bitwise::saddi, 257 | bytewise::mor, 258 | bytewise::mori, 259 | bytewise::mxor, 260 | bytewise::mxori, 261 | immediate::seth, 262 | immediate::setmh, 263 | immediate::setml, 264 | immediate::setl, 265 | immediate::inch, 266 | immediate::incmh, 267 | immediate::incml, 268 | immediate::incl, 269 | immediate::orh, 270 | immediate::ormh, 271 | immediate::orml, 272 | immediate::orl, 273 | immediate::andnh, 274 | immediate::andnmh, 275 | immediate::andnml, 276 | immediate::andnl, 277 | control::jmp, 278 | control::jmpb, 279 | subroutine::pushj, 280 | subroutine::pushjb, 281 | other::geta, 282 | other::getab, 283 | other::put, 284 | other::puti, 285 | subroutine::pop, 286 | interrupt::resume, 287 | subroutine::save, 288 | subroutine::unsave, 289 | system::sync, 290 | other::swym, 291 | other::get, 292 | interrupt::trip, 293 | ]; 294 | 295 | const SYMBOLICS: [&'static str; 256] = [ 296 | "TRAP", 297 | "FCMP", 298 | "FUN", 299 | "FEQL", 300 | "FADD", 301 | "FIX", 302 | "FSUB", 303 | "FIXU", 304 | "FLOT", 305 | "FLOTI", 306 | "FLOTU", 307 | "FLOTUI", 308 | "SFLOT", 309 | "SFLOTI", 310 | "SFLOTU", 311 | "SFLOTUI", 312 | "FMUL", 313 | "FCMPE", 314 | "FUNE", 315 | "FEQLE", 316 | "FDIV", 317 | "FSQRT", 318 | "FREM", 319 | "FINT", 320 | "MUL", 321 | "MULI", 322 | "MULU", 323 | "MULUI", 324 | "DIV", 325 | "DIVI", 326 | "DIVU", 327 | "DIVUI", 328 | "ADD", 329 | "ADDI", 330 | "ADDU", 331 | "ADDUI", 332 | "SUB", 333 | "SUBI", 334 | "SUBU", 335 | "SUBUI", 336 | "2ADDU", 337 | "2ADDUI", 338 | "4ADDU", 339 | "4ADDUI", 340 | "8ADDU", 341 | "8ADDUI", 342 | "16ADDU", 343 | "16ADDUI", 344 | "CMP", 345 | "CMPI", 346 | "CMPU", 347 | "CMPUI", 348 | "NEG", 349 | "NEGI", 350 | "NEGU", 351 | "NEGUI", 352 | "SL", 353 | "SLI", 354 | "SLU", 355 | "SLUI", 356 | "SR", 357 | "SRI", 358 | "SRU", 359 | "SRUI", 360 | "BN", 361 | "BNB", 362 | "BZ", 363 | "BZB", 364 | "BP", 365 | "BPB", 366 | "BOD", 367 | "BODB", 368 | "BNN", 369 | "BNNB", 370 | "BNZ", 371 | "BNZB", 372 | "BNP", 373 | "BNPB", 374 | "BEV", 375 | "BEVB", 376 | "PBN", 377 | "PBNB", 378 | "PBZ", 379 | "PBZB", 380 | "PBP", 381 | "PBPB", 382 | "PBOD", 383 | "PBODB", 384 | "PBNN", 385 | "PBNNB", 386 | "PBNZ", 387 | "PBNZB", 388 | "PBNP", 389 | "PBNPB", 390 | "PBEV", 391 | "PBEVB", 392 | "CSN", 393 | "CSNI", 394 | "CSZ", 395 | "CSZI", 396 | "CSP", 397 | "CSPI", 398 | "CSOD", 399 | "CSODI", 400 | "CSNN", 401 | "CSNNI", 402 | "CSNZ", 403 | "CSNZI", 404 | "CSNP", 405 | "CSNPI", 406 | "CSEV", 407 | "CSEVI", 408 | "ZSN", 409 | "ZSNI", 410 | "ZSZ", 411 | "ZSZI", 412 | "ZSP", 413 | "ZSPI", 414 | "ZSOD", 415 | "ZSODI", 416 | "ZSNN", 417 | "ZSNNI", 418 | "ZSNZ", 419 | "ZSNZI", 420 | "ZSNP", 421 | "ZSNPI", 422 | "ZSEV", 423 | "ZSEVI", 424 | "LDB", 425 | "LDBI", 426 | "LDBU", 427 | "LDBUI", 428 | "LDW", 429 | "LDWI", 430 | "LDWU", 431 | "LDWUI", 432 | "LDT", 433 | "LDTI", 434 | "LDTU", 435 | "LDTUI", 436 | "LDO", 437 | "LDOI", 438 | "LDOU", 439 | "LDOUI", 440 | "LDSF", 441 | "LDSFI", 442 | "LDHT", 443 | "LDHTI", 444 | "CSWAP", 445 | "CSWAPI", 446 | "LDUNC", 447 | "LDUNCI", 448 | "LDVTS", 449 | "LDVTSI", 450 | "PRELD", 451 | "PRELDI", 452 | "PREGO", 453 | "PREGOI", 454 | "GO", 455 | "GOI", 456 | "STB", 457 | "STBI", 458 | "STBU", 459 | "STBUI", 460 | "STW", 461 | "STWI", 462 | "STWU", 463 | "STWUI", 464 | "STT", 465 | "STTI", 466 | "STTU", 467 | "STTUI", 468 | "STO", 469 | "STOI", 470 | "STOU", 471 | "STOUI", 472 | "STSF", 473 | "STSFI", 474 | "STHT", 475 | "STHTI", 476 | "STCO", 477 | "STCOI", 478 | "STUNC", 479 | "STUNCI", 480 | "SYNCD", 481 | "SYNCDI", 482 | "PREST", 483 | "PRESTI", 484 | "SYNCID", 485 | "SYNCIDI", 486 | "PUSHGO", 487 | "PUSHGOI", 488 | "OR", 489 | "ORI", 490 | "ORN", 491 | "ORNI", 492 | "NOR", 493 | "NORI", 494 | "XOR", 495 | "XORI", 496 | "AND", 497 | "ANDI", 498 | "ANDN", 499 | "ANDNI", 500 | "NAND", 501 | "NANDI", 502 | "NXOR", 503 | "NXORI", 504 | "BDIF", 505 | "BDIFI", 506 | "WDIF", 507 | "WDIFI", 508 | "TDIF", 509 | "TDIFI", 510 | "ODIF", 511 | "ODIFI", 512 | "MUX", 513 | "MUXI", 514 | "SADD", 515 | "SADDI", 516 | "MOR", 517 | "MORI", 518 | "MXOR", 519 | "MXORI", 520 | "SETH", 521 | "SETMH", 522 | "SETML", 523 | "SETL", 524 | "INCH", 525 | "INCMH", 526 | "INCML", 527 | "INCL", 528 | "ORH", 529 | "ORMH", 530 | "ORML", 531 | "ORL", 532 | "ANDNH", 533 | "ANDNMH", 534 | "ANDNML", 535 | "ANDNL", 536 | "JMP", 537 | "JMPB", 538 | "PUSHJ", 539 | "PUSHJB", 540 | "GETA", 541 | "GETAB", 542 | "PUT", 543 | "PUTI", 544 | "POP", 545 | "RESUME", 546 | "SAVE", 547 | "UNSAVE", 548 | "SYNC", 549 | "SWYM", 550 | "GET", 551 | "TRIP", 552 | ]; 553 | -------------------------------------------------------------------------------- /src/machine/state/mem.rs: -------------------------------------------------------------------------------- 1 | use machine::state::types::*; 2 | 3 | use std::ops::{Index, IndexMut}; 4 | 5 | #[derive(Copy, Clone)] 6 | pub struct ByteAt(pub u64); 7 | 8 | #[derive(Copy, Clone)] 9 | pub struct WydeAt(pub u64); 10 | 11 | #[derive(Copy, Clone)] 12 | pub struct TetraAt(pub u64); 13 | 14 | #[derive(Copy, Clone)] 15 | pub struct OctaAt(pub u64); 16 | 17 | pub struct Memory { 18 | buf: Vec, 19 | } 20 | 21 | impl Memory { 22 | pub fn new() -> Self { 23 | Memory::with_capacity(1024 * 1024) // 1 MiB 24 | } 25 | 26 | pub fn with_capacity(bytes: u64) -> Self { 27 | // Compute the number of octas needed 28 | let octas = ((bytes + 7) / 8) as usize; 29 | 30 | // Create a zero initialized vector that represents the memory 31 | let buf = vec![0u64.into(); octas]; 32 | 33 | // Build and return the memory 34 | Memory { 35 | buf: buf, 36 | } 37 | } 38 | } 39 | 40 | impl Index for Memory { 41 | type Output = Byte; 42 | fn index(&self, idx: ByteAt) -> &Self::Output { 43 | // Find the octa that holds the byte 44 | let octa: *const Octa = self.index(OctaAt(idx.0)); 45 | 46 | // Calculate the byte's position within that octa 47 | let mut pos = (idx.0 % 8 / 1) as isize; 48 | if cfg!(target_endian = "little") { 49 | pos = (8 - 1) - pos; 50 | } 51 | 52 | // Calculate a pointer to the byte 53 | let mut byte = octa as *const Byte; 54 | byte = unsafe { 55 | byte.offset(pos) 56 | }; 57 | 58 | // Return the pointer as reference 59 | unsafe { 60 | byte.as_ref() 61 | }.unwrap() 62 | } 63 | } 64 | 65 | impl IndexMut for Memory { 66 | fn index_mut(&mut self, idx: ByteAt) -> &mut Self::Output { 67 | // Find the octa that holds the byte 68 | let octa: *const Octa = self.index_mut(OctaAt(idx.0)); 69 | 70 | // Calculate the byte's position within that octa 71 | let mut pos = (idx.0 % 8 / 1) as isize; 72 | if cfg!(target_endian = "little") { 73 | pos = (8 - 1) - pos; 74 | } 75 | 76 | // Calculate a pointer to the byte 77 | let mut byte = octa as *mut Byte; 78 | byte = unsafe { 79 | byte.offset(pos) 80 | }; 81 | 82 | // Return the pointer as reference 83 | unsafe { 84 | byte.as_mut() 85 | }.unwrap() 86 | } 87 | } 88 | 89 | impl Index for Memory { 90 | type Output = Wyde; 91 | fn index(&self, idx: WydeAt) -> &Self::Output { 92 | // Find the octa that holds the wyde 93 | let octa: *const Octa = self.index(OctaAt(idx.0)); 94 | 95 | // Calculate the wyde's position within that octa 96 | let mut pos = (idx.0 % 8 / 2) as isize; 97 | if cfg!(target_endian = "little") { 98 | pos = (4 - 1) - pos; 99 | } 100 | 101 | // Calculate a pointer to the wyde 102 | let mut wyde = octa as *const Wyde; 103 | wyde = unsafe { 104 | wyde.offset(pos) 105 | }; 106 | 107 | // Return the pointer as reference 108 | unsafe { 109 | wyde.as_ref() 110 | }.unwrap() 111 | } 112 | } 113 | 114 | impl IndexMut for Memory { 115 | fn index_mut(&mut self, idx: WydeAt) -> &mut Self::Output { 116 | // Find the octa that holds the wyde 117 | let octa: *const Octa = self.index_mut(OctaAt(idx.0)); 118 | 119 | // Calculate the wyde's position within that octa 120 | let mut pos = (idx.0 % 8 / 2) as isize; 121 | if cfg!(target_endian = "little") { 122 | pos = (4 - 1) - pos; 123 | } 124 | 125 | // Calculate a pointer to the wyde 126 | let mut wyde = octa as *mut Wyde; 127 | wyde = unsafe { 128 | wyde.offset(pos) 129 | }; 130 | 131 | // Return the pointer as reference 132 | unsafe { 133 | wyde.as_mut() 134 | }.unwrap() 135 | } 136 | } 137 | 138 | impl Index for Memory { 139 | type Output = Tetra; 140 | fn index(&self, idx: TetraAt) -> &Self::Output { 141 | // Find the octa that holds the tetra 142 | let octa: *const Octa = self.index(OctaAt(idx.0)); 143 | 144 | // Calculate the tetra's position within that octa 145 | let mut pos = (idx.0 % 8 / 4) as isize; 146 | if cfg!(target_endian = "little") { 147 | pos = (2 - 1) - pos; 148 | } 149 | 150 | // Calculate a pointer to the tetra 151 | let mut tetra = octa as *const Tetra; 152 | tetra = unsafe { 153 | tetra.offset(pos) 154 | }; 155 | 156 | // Return the pointer as reference 157 | unsafe { 158 | tetra.as_ref() 159 | }.unwrap() 160 | } 161 | } 162 | 163 | impl IndexMut for Memory { 164 | fn index_mut(&mut self, idx: TetraAt) -> &mut Self::Output { 165 | // Find the octa that holds the tetra 166 | let octa: *mut Octa = self.index_mut(OctaAt(idx.0)); 167 | 168 | // Calculate the tetra's position within that octa 169 | let mut pos = (idx.0 % 8 / 4) as isize; 170 | if cfg!(target_endian = "little") { 171 | pos = (2 - 1) - pos; 172 | } 173 | 174 | // Calculate a pointer to the tetra 175 | let mut tetra = octa as *mut Tetra; 176 | tetra = unsafe { 177 | tetra.offset(pos) 178 | }; 179 | 180 | // Return the pointer as reference 181 | unsafe { 182 | tetra.as_mut() 183 | }.unwrap() 184 | } 185 | } 186 | 187 | impl Index for Memory { 188 | type Output = Octa; 189 | fn index(&self, idx: OctaAt) -> &Self::Output { 190 | let pos = (idx.0 / 8) as usize; 191 | self.buf.index(pos) 192 | } 193 | } 194 | 195 | impl IndexMut for Memory { 196 | fn index_mut(&mut self, idx: OctaAt) -> &mut Self::Output { 197 | let pos = (idx.0 / 8) as usize; 198 | self.buf.index_mut(pos) 199 | } 200 | } 201 | 202 | #[cfg(test)] 203 | mod tests { 204 | use super::*; 205 | 206 | /// Check if any byte is accessible 207 | #[test] 208 | fn undersized() { 209 | let mut mem = Memory::with_capacity(25); 210 | 211 | // 0..25: regular bytes 212 | // 25..32: "alignment" bytes 213 | for i in 0..32 { 214 | mem[ByteAt(i)] = 42u8.into(); 215 | let res: u8 = mem[ByteAt(i)].into(); 216 | assert_eq!(res, 42u8); 217 | } 218 | } 219 | 220 | /// Check if the memory is not oversized 221 | #[test] 222 | #[should_panic] 223 | fn oversized() { 224 | let mut mem = Memory::with_capacity(25); 225 | mem[ByteAt(32)] = 42u8.into(); 226 | } 227 | 228 | /// Check if the memory is initially zeroed 229 | #[test] 230 | fn zeroed() { 231 | let mem = Memory::with_capacity(24); 232 | 233 | for i in 0..24 { 234 | let zero: u8 = mem[ByteAt(i)].into(); 235 | assert_eq!(zero, 0); 236 | } 237 | } 238 | 239 | /// Check if a byte is properly accessed 240 | #[test] 241 | fn access_byte() { 242 | let mut mem = Memory::with_capacity(24); 243 | 244 | // Write 245 | mem[ByteAt(8)] = 0xFFu8.into(); 246 | 247 | // Read 248 | let byte: u8 = mem[ ByteAt(8)].into(); 249 | assert_eq!( byte, 0xFF); 250 | 251 | let wyde: u16 = mem[ WydeAt(8)].into(); 252 | assert_eq!( wyde, 0xFF00); 253 | 254 | let tetra: u32 = mem[TetraAt(8)].into(); 255 | assert_eq!(tetra, 0xFF00_0000); 256 | 257 | let octa: u64 = mem[ OctaAt(8)].into(); 258 | assert_eq!( octa, 0xFF00_0000_0000_0000); 259 | 260 | // Check if anything else is zero 261 | for i in (0..8).chain(9..24) { 262 | let zero: u8 = mem[ByteAt(i)].into(); 263 | assert_eq!(zero, 0); 264 | } 265 | } 266 | 267 | // Check if a wyde is properly accessed 268 | #[test] 269 | fn access_wyde() { 270 | let mut mem = Memory::with_capacity(24); 271 | 272 | // Write 273 | mem[WydeAt(8)] = 0xFF8Fu16.into(); 274 | 275 | // Read 276 | let byte_0: u8 = mem[ ByteAt( 8)].into(); 277 | let byte_1: u8 = mem[ ByteAt( 9)].into(); 278 | assert_eq!( byte_0, 0xFF); 279 | assert_eq!( byte_1, 0x8F); 280 | 281 | let wyde : u16 = mem[ WydeAt( 8)].into(); 282 | assert_eq!( wyde , 0xFF8F); 283 | 284 | let tetra : u32 = mem[TetraAt( 8)].into(); 285 | assert_eq!(tetra , 0xFF8F_0000); 286 | 287 | let octa : u64 = mem[ OctaAt( 8)].into(); 288 | assert_eq!( octa , 0xFF8F_0000_0000_0000); 289 | 290 | // Check if anything else is zero 291 | for i in (0..8).chain(10..24) { 292 | let zero: u8 = mem[ByteAt(i)].into(); 293 | assert_eq!(zero, 0); 294 | } 295 | } 296 | 297 | // Check if a tetra is properly accessed 298 | #[test] 299 | fn access_tetra() { 300 | let mut mem = Memory::with_capacity(24); 301 | 302 | // Write 303 | mem[TetraAt(8)] = 0xFF8F_8848u32.into(); 304 | 305 | // Read 306 | let byte_0: u8 = mem[ ByteAt( 8)].into(); 307 | let byte_1: u8 = mem[ ByteAt( 9)].into(); 308 | let byte_2: u8 = mem[ ByteAt(10)].into(); 309 | let byte_3: u8 = mem[ ByteAt(11)].into(); 310 | assert_eq!( byte_0, 0xFF); 311 | assert_eq!( byte_1, 0x8F); 312 | assert_eq!( byte_2, 0x88); 313 | assert_eq!( byte_3, 0x48); 314 | 315 | let wyde_0: u16 = mem[ WydeAt( 8)].into(); 316 | let wyde_1: u16 = mem[ WydeAt(10)].into(); 317 | assert_eq!( wyde_0, 0xFF8F); 318 | assert_eq!( wyde_1, 0x8848); 319 | 320 | let tetra : u32 = mem[TetraAt( 8)].into(); 321 | assert_eq!(tetra , 0xFF8F_8848); 322 | 323 | let octa : u64 = mem[ OctaAt( 8)].into(); 324 | assert_eq!( octa , 0xFF8F_8848_0000_0000); 325 | 326 | // Check if anything else is zero 327 | for i in (0..8).chain(12..24) { 328 | let zero: u8 = mem[ByteAt(i)].into(); 329 | assert_eq!(zero, 0); 330 | } 331 | } 332 | 333 | // Check if a octa is properly accessed 334 | #[test] 335 | fn access_octa() { 336 | let mut mem = Memory::with_capacity(24); 337 | 338 | // Write 339 | mem[OctaAt(8)] = 0xFF8F_8848_4424_2212u64.into(); 340 | 341 | // Read 342 | let byte_0: u8 = mem[ ByteAt( 8)].into(); 343 | let byte_1: u8 = mem[ ByteAt( 9)].into(); 344 | let byte_2: u8 = mem[ ByteAt(10)].into(); 345 | let byte_3: u8 = mem[ ByteAt(11)].into(); 346 | let byte_4: u8 = mem[ ByteAt(12)].into(); 347 | let byte_5: u8 = mem[ ByteAt(13)].into(); 348 | let byte_6: u8 = mem[ ByteAt(14)].into(); 349 | let byte_7: u8 = mem[ ByteAt(15)].into(); 350 | assert_eq!( byte_0, 0xFF); 351 | assert_eq!( byte_1, 0x8F); 352 | assert_eq!( byte_2, 0x88); 353 | assert_eq!( byte_3, 0x48); 354 | assert_eq!( byte_4, 0x44); 355 | assert_eq!( byte_5, 0x24); 356 | assert_eq!( byte_6, 0x22); 357 | assert_eq!( byte_7, 0x12); 358 | 359 | let wyde_0: u16 = mem[ WydeAt( 8)].into(); 360 | let wyde_1: u16 = mem[ WydeAt(10)].into(); 361 | let wyde_2: u16 = mem[ WydeAt(12)].into(); 362 | let wyde_3: u16 = mem[ WydeAt(14)].into(); 363 | assert_eq!( wyde_0, 0xFF8F); 364 | assert_eq!( wyde_1, 0x8848); 365 | assert_eq!( wyde_2, 0x4424); 366 | assert_eq!( wyde_3, 0x2212); 367 | 368 | let tetra_0: u32 = mem[TetraAt( 8)].into(); 369 | let tetra_1: u32 = mem[TetraAt(12)].into(); 370 | assert_eq!(tetra_0, 0xFF8F_8848); 371 | assert_eq!(tetra_1, 0x4424_2212); 372 | 373 | let octa : u64 = mem[ OctaAt( 8)].into(); 374 | assert_eq!( octa , 0xFF8F_8848_4424_2212); 375 | 376 | // Check if anything else is zero 377 | for i in (0..8).chain(16..24) { 378 | let zero: u8 = mem[ByteAt(i)].into(); 379 | assert_eq!(zero, 0); 380 | } 381 | } 382 | 383 | #[test] 384 | fn equivalent_indices() { 385 | let mut mem = Memory::with_capacity(16); 386 | 387 | for i in 0..16 { 388 | mem[ByteAt(i)] = (i as u8).into(); 389 | } 390 | 391 | for i in 1..8 { 392 | assert_eq!(mem[ OctaAt( 0)], mem[ OctaAt( i)]); 393 | assert_eq!(mem[ OctaAt( 8)], mem[ OctaAt( 8 + i)]); 394 | } 395 | 396 | for i in 1..4 { 397 | assert_eq!(mem[TetraAt( 0)], mem[TetraAt( i)]); 398 | assert_eq!(mem[TetraAt( 4)], mem[TetraAt( 4 + i)]); 399 | assert_eq!(mem[TetraAt( 8)], mem[TetraAt( 8 + i)]); 400 | assert_eq!(mem[TetraAt(12)], mem[TetraAt(12 + i)]); 401 | } 402 | 403 | for i in 0..8 { 404 | assert_eq!(mem[WydeAt(2 * i)], mem[WydeAt(2 * i + 1)]); 405 | } 406 | } 407 | } 408 | --------------------------------------------------------------------------------