Opcode table via procedural macro
This commit is contained in:
parent
ecd06bf524
commit
f3aa97b365
|
@ -64,6 +64,7 @@ name = "ppc750cl"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"ppc750cl-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -74,6 +75,14 @@ dependencies = [
|
|||
"ppc750cl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppc750cl-macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppc750cl-rand"
|
||||
version = "0.1.0"
|
||||
|
@ -89,6 +98,24 @@ version = "0.2.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
|
@ -140,6 +167,23 @@ dependencies = [
|
|||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"lib",
|
||||
"macros",
|
||||
"fuzz",
|
||||
"rand",
|
||||
]
|
||||
|
|
|
@ -6,3 +6,4 @@ authors = ["Richard Patel <me@terorie.dev>"]
|
|||
|
||||
[dependencies]
|
||||
num-traits = "0.2.14"
|
||||
ppc750cl-macros = { path = "../macros" }
|
||||
|
|
452
lib/src/lib.rs
452
lib/src/lib.rs
|
@ -5,233 +5,231 @@ use std::ops::Range;
|
|||
|
||||
use num_traits::AsPrimitive;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum Opcode {
|
||||
Illegal = -1,
|
||||
// 750CL extensions
|
||||
Twi,
|
||||
PsCmpu0,
|
||||
PsqLx,
|
||||
PsqStx,
|
||||
PsSum0,
|
||||
PsSum1,
|
||||
PsMuls0,
|
||||
PsMuls1,
|
||||
PsMadds0,
|
||||
PsMadds1,
|
||||
PsDiv,
|
||||
PsSub,
|
||||
PsAdd,
|
||||
PsSel,
|
||||
PsRes,
|
||||
PsMul,
|
||||
PsRsqrte,
|
||||
PsMsub,
|
||||
PsMadd,
|
||||
PsNmsub,
|
||||
PsNmadd,
|
||||
PsCmpo0,
|
||||
PsqLux,
|
||||
PsqStux,
|
||||
PsNeg,
|
||||
PsCmpu1,
|
||||
PsMr,
|
||||
PsCmpo1,
|
||||
PsNabs,
|
||||
PsAbs,
|
||||
PsMerge00,
|
||||
PsMerge01,
|
||||
PsMerge10,
|
||||
PsMerge11,
|
||||
DcbzL,
|
||||
Mulli,
|
||||
Subfic,
|
||||
Cmpli,
|
||||
Cmpi,
|
||||
Addic,
|
||||
Addic_,
|
||||
Addi,
|
||||
Addis,
|
||||
Bc,
|
||||
Sc,
|
||||
B,
|
||||
Mcrf,
|
||||
Bclr,
|
||||
Crnor,
|
||||
Rfi,
|
||||
Crandc,
|
||||
Isync,
|
||||
Crxor,
|
||||
Crnand,
|
||||
Crand,
|
||||
Creqv,
|
||||
Crorc,
|
||||
Cror,
|
||||
Bcctr,
|
||||
Rlwimi,
|
||||
Rlwinm,
|
||||
Rlwnm,
|
||||
Ori,
|
||||
Oris,
|
||||
Xori,
|
||||
Xoris,
|
||||
Andi_,
|
||||
Andis_,
|
||||
Cmp,
|
||||
Tw,
|
||||
Subfc,
|
||||
Addc,
|
||||
Mulhwu,
|
||||
Mfcr,
|
||||
Lwarx,
|
||||
Lwzx,
|
||||
Slw,
|
||||
Cntlzw,
|
||||
And,
|
||||
Cmpl,
|
||||
Subf,
|
||||
Dcbst,
|
||||
Lwzux,
|
||||
Andc,
|
||||
Mulhw,
|
||||
Mfmsr,
|
||||
Dcbf,
|
||||
Lbzx,
|
||||
Neg,
|
||||
Lbzux,
|
||||
Nor,
|
||||
Subfe,
|
||||
Adde,
|
||||
Mtcrf,
|
||||
Mtmsr,
|
||||
Stwcx_,
|
||||
Stwx,
|
||||
Stwux,
|
||||
Subfze,
|
||||
Addze,
|
||||
Mtsr,
|
||||
Stbx,
|
||||
Subfme,
|
||||
Addme,
|
||||
Mullw,
|
||||
Mtsrin,
|
||||
Dcbtst,
|
||||
Stbux,
|
||||
Add,
|
||||
Dcbt,
|
||||
Lhzx,
|
||||
Eqv,
|
||||
Tlbie,
|
||||
Eciwx,
|
||||
Lhzux,
|
||||
Xor,
|
||||
Mfspr,
|
||||
Lhax,
|
||||
Mftb,
|
||||
Lhaux,
|
||||
Sthx,
|
||||
Orc,
|
||||
Ecowx,
|
||||
Sthux,
|
||||
Or,
|
||||
Divwu,
|
||||
Mtspr,
|
||||
Dcbi,
|
||||
Nand,
|
||||
Divw,
|
||||
Mcrxr,
|
||||
Lswx,
|
||||
Lwbrx,
|
||||
Lfsx,
|
||||
Srw,
|
||||
Tlbsync,
|
||||
Lfsux,
|
||||
Mfsr,
|
||||
Lswi,
|
||||
Sync,
|
||||
Lfdx,
|
||||
Lfdux,
|
||||
Mfsrin,
|
||||
Stswx,
|
||||
Stwbrx,
|
||||
Stfsx,
|
||||
Stfsux,
|
||||
Stswi,
|
||||
Stfdx,
|
||||
Stfdux,
|
||||
Lhbrx,
|
||||
Sraw,
|
||||
Srawi,
|
||||
Eieio,
|
||||
Sthbrx,
|
||||
Extsh,
|
||||
Extsb,
|
||||
Icbi,
|
||||
Stfiwx,
|
||||
Dcbz,
|
||||
Lwz,
|
||||
Lwzu,
|
||||
Lbz,
|
||||
Lbzu,
|
||||
Stw,
|
||||
Stwu,
|
||||
Stb,
|
||||
Stbu,
|
||||
Lhz,
|
||||
Lhzu,
|
||||
Lha,
|
||||
Lhau,
|
||||
Sth,
|
||||
Sthu,
|
||||
Lmw,
|
||||
Stmw,
|
||||
Lfs,
|
||||
Lfsu,
|
||||
Lfd,
|
||||
Lfdu,
|
||||
Stfs,
|
||||
Stfsu,
|
||||
Stfd,
|
||||
Stfdu,
|
||||
PsqL,
|
||||
PsqLu,
|
||||
Fdivs,
|
||||
Fsubs,
|
||||
Fadds,
|
||||
Fres,
|
||||
Fmuls,
|
||||
Fmsubs,
|
||||
Fmadds,
|
||||
Fnmsubs,
|
||||
Fnmadds,
|
||||
PsqSt,
|
||||
PsqStu,
|
||||
Fcmpu,
|
||||
Frsp,
|
||||
Fctiw,
|
||||
Fctiwz,
|
||||
Fdiv,
|
||||
Fsub,
|
||||
Fadd,
|
||||
Fsel,
|
||||
Fmul,
|
||||
Frsqrte,
|
||||
Fmsub,
|
||||
Fmadd,
|
||||
Fnmsub,
|
||||
Fnmadd,
|
||||
Fcmpo,
|
||||
Mtfsb1,
|
||||
Fneg,
|
||||
Mcrfs,
|
||||
Mtfsb0,
|
||||
Fmr,
|
||||
Mtfsfi,
|
||||
Fnabs,
|
||||
Fabs,
|
||||
Mffs,
|
||||
Mtfsf,
|
||||
// Basic instructions
|
||||
use ppc750cl_macros::isa;
|
||||
|
||||
isa! {
|
||||
"add" & 0xfc0007fe == 0x7c000214;
|
||||
"addc" & 0xfc0007fe == 0x7c00002a;
|
||||
"adde" & 0xfc0007fe == 0x7c000114;
|
||||
"addi" & 0xfc000000 == 0x38000000;
|
||||
"addic" & 0xfc000000 == 0x30000000;
|
||||
"addic." & 0xfc000000 == 0x34000000;
|
||||
"addis" & 0xfc000000 == 0x3c000000;
|
||||
"addme" & 0xfc00fbfe == 0x7c0001d4;
|
||||
"addze" & 0xfc00fbfe == 0x7c000194;
|
||||
"and" & 0xfc0007fe == 0x7c000038;
|
||||
"andc" & 0xfc0007fe == 0x7c000078;
|
||||
"andi." & 0xfc000000 == 0x70000000;
|
||||
"andis." & 0xfc000000 == 0x74000000;
|
||||
"b" & 0xfc000000 == 0x48000000;
|
||||
"bc" & 0xfc000000 == 0x40000000;
|
||||
"bcctr" & 0xfc00ffff == 0x4c000210;
|
||||
"bclr" & 0xfc00fffe == 0x4c000020;
|
||||
"cmp" & 0xfc4007ff == 0x7c000000;
|
||||
"cmpi" & 0xfc400000 == 0x2c000000;
|
||||
"cmpl" & 0xfc4007ff == 0x7c000040;
|
||||
"cmpli" & 0xfc400000 == 0x28000000;
|
||||
"cntlzw" & 0xfc00fffe == 0x7c000034;
|
||||
"crand" & 0xfc0007ff == 0x4c000202;
|
||||
"crandc" & 0xfc0007ff == 0x4c000102;
|
||||
"creqv" & 0xfc0007ff == 0x4c000242;
|
||||
"crnand" & 0xfc0007ff == 0x4c0001c2;
|
||||
"crnor" & 0xfc0007ff == 0x4c000042;
|
||||
"cror" & 0xfc0007ff == 0x4c000382;
|
||||
"crorc" & 0xfc0007ff == 0x4c000342;
|
||||
"crxor" & 0xfc0007ff == 0x4c000182;
|
||||
"dcbf" & 0xffe007ff == 0x7c0000ac;
|
||||
"dcbi" & 0xffe007ff == 0x7c0003ac;
|
||||
"dcbst" & 0xffe007ff == 0x7c00006c;
|
||||
"dcbt" & 0xffe007ff == 0x7c00022c;
|
||||
"dcbtst" & 0xffe007ff == 0x7c0001ec;
|
||||
"dcbz" & 0xffe007ff == 0x7c0007ec;
|
||||
"dcbz_l" & 0xffe007ff == 0x100007ec;
|
||||
"divw" & 0xfc0003fe == 0x7c0003d6;
|
||||
"divwu" & 0xfc0003fe == 0x7c000396;
|
||||
"eciwx" & 0xfc0003ff == 0x7c00026c;
|
||||
"ecowx" & 0xfc0003ff == 0x7c00036c;
|
||||
"eieio" & 0xffffffff == 0x7c0006ac;
|
||||
"eqv" & 0xfc0003fe == 0x7c000238;
|
||||
"extsb" & 0xfc00fffe == 0x7c000774;
|
||||
"extsh" & 0xfc00fffe == 0x7c000734;
|
||||
"fabs" & 0xfc1f07fe == 0xfc000734;
|
||||
"fadd" & 0xfc0007fe == 0xfc00002a;
|
||||
"fadds" & 0xfc0007fe == 0xec00002a;
|
||||
"fcmpo" & 0xfc6007ff == 0xfc000040;
|
||||
"fcmpu" & 0xfc6007ff == 0xfc000000;
|
||||
"fctiw" & 0xfc1f07fe == 0xfc00001c;
|
||||
"fctiwz" & 0xfc1f07fe == 0xfc00001e;
|
||||
"fdiv" & 0xfc0007fe == 0xfc000024;
|
||||
"fdivs" & 0xfc0007fe == 0xec000024;
|
||||
"fmadd" & 0xfc00003e == 0xfc00003a;
|
||||
"fmadds" & 0xfc00003e == 0xec00003a;
|
||||
"fmr" & 0xfc1f07fe == 0xfc000090;
|
||||
"fmsub" & 0xfc00003e == 0xfc000038;
|
||||
"fmsubs" & 0xfc00003e == 0xec000038;
|
||||
"fmul" & 0xfc00f83e == 0xfc000032;
|
||||
"fmuls" & 0xfc00f83e == 0xec000032;
|
||||
"fnabs" & 0xfc1f07fe == 0xfc000110;
|
||||
"fneg" & 0xfc1f07fe == 0xfc000050;
|
||||
"fnmadd" & 0xfc00003e == 0xfc00003e;
|
||||
"fnmadds" & 0xfc00003e == 0xec00003e;
|
||||
"fnmsub" & 0xfc00003e == 0xfc00003c;
|
||||
"fnmsubs" & 0xfc00003e == 0xec00003c;
|
||||
"fres" & 0xfc1f07fe == 0xec000030;
|
||||
"frsp" & 0xfc1f07fe == 0xfc000018;
|
||||
"frsqrte" & 0xfc1f07fe == 0xfc000034;
|
||||
"fsel" & 0xfc00003e == 0xfc00002e;
|
||||
"fsub" & 0xfc0007fe == 0xfc000028;
|
||||
"fsubs" & 0xfc0007fe == 0xec000028;
|
||||
"icbi" & 0xffe007ff == 0x7c0007ac;
|
||||
"isync" & 0xffffffff == 0x4c00012c;
|
||||
"lbz" & 0xfc000000 == 0x88000000;
|
||||
"lbzu" & 0xfc000000 == 0x8c000000;
|
||||
"lbzux" & 0xfc0007ff == 0x7c0000ee;
|
||||
"lbzx" & 0xfc0007ff == 0x7c0000ae;
|
||||
"lfd" & 0xfc000000 == 0xc8000000;
|
||||
"lfdu" & 0xfc000000 == 0xcc000000;
|
||||
"lfdux" & 0xfc0007ff == 0x7c0004ee;
|
||||
"lfdx" & 0xfc0007ff == 0x7c00045e;
|
||||
"lfs" & 0xfc000000 == 0xc0000000;
|
||||
"lfsu" & 0xfc000000 == 0xc4000000;
|
||||
"lfsux" & 0xfc0007ff == 0x7c00046e;
|
||||
"lfsx" & 0xfc0007ff == 0x7c00042e;
|
||||
"lha" & 0xfc000000 == 0xa8000000;
|
||||
"lhau" & 0xfc000000 == 0xac000000;
|
||||
"lhaux" & 0xfc0007ff == 0x7c0002ee;
|
||||
"lhax" & 0xfc0007ff == 0x7c0002ae;
|
||||
"lhbrx" & 0xfc0007ff == 0x7c00062c;
|
||||
"lhz" & 0xfc000000 == 0xa0000000;
|
||||
"lhzu" & 0xfc000000 == 0xa4000000;
|
||||
"lhzux" & 0xfc0007ff == 0x7c00026e;
|
||||
"lhzx" & 0xfc0007ff == 0x7c00022e;
|
||||
"lmw" & 0xfc000000 == 0xb8000000;
|
||||
"lswi" & 0xfc0007ff == 0x7c0004aa;
|
||||
"lswx" & 0xfc0007ff == 0x7c00042a;
|
||||
"lwarx" & 0xfc0007ff == 0x7c000028;
|
||||
"lwbrx" & 0xfc0007ff == 0x7c00042c;
|
||||
"lwz" & 0xfc000000 == 0x80000000;
|
||||
"lwzu" & 0xfc000000 == 0x84000000;
|
||||
"lwzux" & 0xfc0007ff == 0x7c00006e;
|
||||
"lwzx" & 0xfc0007ff == 0x7c00002e;
|
||||
"mcrf" & 0xfc300fff == 0x4c000000;
|
||||
"mcrfs" & 0xfc30ffff == 0xfc000080;
|
||||
"mcrxr" & 0xfc30ffff == 0x7c000400;
|
||||
"mfcr" & 0xfc1fffff == 0x7c000026;
|
||||
"mffs" & 0xfc1ffffe == 0x7c00048e;
|
||||
"mfmsr" & 0xfc1fffff == 0x7c0000a6;
|
||||
"mfspr" & 0xfc0007ff == 0x7c0002a6;
|
||||
"mfsr" & 0xfc10ffff == 0x7c0004a6;
|
||||
"mfsrin" & 0xfc1f07ff == 0x7c000526;
|
||||
"mftb" & 0xfc0007ff == 0x7c0002e6;
|
||||
"mtcrf" & 0xfc100fff == 0x7c000120;
|
||||
"mtfsb0" & 0xfc1ffffe == 0xfc00008c;
|
||||
"mtfsb1" & 0xfc1ffffe == 0xfc00004c;
|
||||
"mtfsf" & 0xfe0107fe == 0xfc00058e;
|
||||
"mtfsfi" & 0xfc7f0ffe == 0xfc00010c;
|
||||
"mtmsr" & 0xfc1fffff == 0x7c000124;
|
||||
"mtspr" & 0xfc0007ff == 0x7c0003a6;
|
||||
"mtsr" & 0xfc10ffff == 0x7c0001a4;
|
||||
"mtsrin" & 0xfc1f07ff == 0x7c0001e4;
|
||||
"mulhw" & 0xfc0007fe == 0x7c000096;
|
||||
"mulhwu" & 0xfc0007fe == 0x7c000016;
|
||||
"mulli" & 0xfc000000 == 0x1c000000;
|
||||
"mullw" & 0xfc0003fe == 0x7c0001d6;
|
||||
"nand" & 0xfc0007fe == 0x7c0003b8;
|
||||
"neg" & 0xfc00fffe == 0x7c0000d0;
|
||||
"nor" & 0xfc0007fe == 0x7c0000f8;
|
||||
"or" & 0xfc0007fe == 0x7c000378;
|
||||
"orc" & 0xfc0007fe == 0x7c000338;
|
||||
"ori" & 0xfc000000 == 0x60000000;
|
||||
"oris" & 0xfc000000 == 0x64000000;
|
||||
"psq_l" & 0xfc000000 == 0xe0000000;
|
||||
"psq_lu" & 0xfc000000 == 0xe4000000;
|
||||
"psq_lux" & 0xfc00007f == 0x1000004c;
|
||||
"psq_lx" & 0xfc00007f == 0x1000000c;
|
||||
"psq_st" & 0xfc000000 == 0xf0000000;
|
||||
"psq_stu" & 0xfc000000 == 0xf4000000;
|
||||
"psq_stux" & 0xfc00007f == 0x1000004e;
|
||||
"psq_stx" & 0xfc00007f == 0x1000000e;
|
||||
"ps_abs" & 0xfc1f07fe == 0x10000210;
|
||||
"ps_add" & 0xfc0007fe == 0x1000002a;
|
||||
"ps_cmpo0" & 0xfc6007ff == 0x10000040;
|
||||
"ps_cmpo1" & 0xfc6007ff == 0x100000c0;
|
||||
"ps_cmpu0" & 0xfc6007ff == 0x10000000;
|
||||
"ps_cmpu1" & 0xfc6007ff == 0x10000080;
|
||||
"ps_div" & 0xfc0007fe == 0x10000024;
|
||||
"ps_madd" & 0xfc00003e == 0x1000003a;
|
||||
"ps_madds0" & 0xfc00003e == 0x1000001c;
|
||||
"ps_madds1" & 0xfc00003e == 0x1000001e;
|
||||
"ps_merge00" & 0xfc0007fe == 0x10000420;
|
||||
"ps_merge01" & 0xfc0007fe == 0x10000460;
|
||||
"ps_merge10" & 0xfc0007fe == 0x100004a0;
|
||||
"ps_merge11" & 0xfc0007fe == 0x100004e0;
|
||||
"ps_mr" & 0xfc1f07fe == 0x10000090;
|
||||
"ps_msub" & 0xfc00003e == 0x10000038;
|
||||
"ps_mul" & 0xfc00f83e == 0x10000032;
|
||||
"ps_muls0" & 0xfc00f83e == 0x10000018;
|
||||
"ps_muls1" & 0xfc00f83e == 0x1000001a;
|
||||
"ps_nabs" & 0xfc1f07fe == 0x10000110;
|
||||
"ps_neg" & 0xfc1f07fe == 0x10000050;
|
||||
"ps_nmadd" & 0xfc00003e == 0x1000003e;
|
||||
"ps_nmsub" & 0xfc00003e == 0x1000003c;
|
||||
"ps_res" & 0xfc1f07fe == 0x10000030;
|
||||
"ps_rsqrte" & 0xfc1f07fe == 0x10000034;
|
||||
"ps_sel" & 0xfc00003e == 0x1000002e;
|
||||
"ps_sub" & 0xfc0007fe == 0x10000028;
|
||||
"ps_sum0" & 0xfc00003e == 0x10000014;
|
||||
"ps_sum1" & 0xfc00003e == 0x10000016;
|
||||
"rfi" & 0xfffff801 == 0x4c000000;
|
||||
"rlwimi" & 0xfc000000 == 0x50000000;
|
||||
"rlwinm" & 0xfc000000 == 0x54000000;
|
||||
"rlwnm" & 0xfc000000 == 0x5c000000;
|
||||
"sc" & 0xffffffff == 0x44000002;
|
||||
"slw" & 0xfc0007fe == 0x7c000030;
|
||||
"sraw" & 0xfc0007fe == 0x7c000630;
|
||||
"srawi" & 0xfc0007fe == 0x7c000670;
|
||||
"srw" & 0xfc0007fe == 0x7c000430;
|
||||
"stb" & 0xfc000000 == 0x98000000;
|
||||
"stbu" & 0xfc000000 == 0x9c000000;
|
||||
"stbux" & 0xfc0003ff == 0x7c0001ee;
|
||||
"stbx" & 0xfc0003ff == 0x7c0001ae;
|
||||
"stfd" & 0xfc000000 == 0xd8000000;
|
||||
"stfdu" & 0xfc000000 == 0xdc000000;
|
||||
"stfdux" & 0xfc0003ff == 0x7c0005ee;
|
||||
"stfdx" & 0xfc0003ff == 0x7c0005ae;
|
||||
"stfiwx" & 0xfc0007ff == 0x7c0007ae;
|
||||
"stfs" & 0xfc000000 == 0xd0000000;
|
||||
"stfsu" & 0xfc000000 == 0xd4000000;
|
||||
"stfsux" & 0xfc0003ff == 0x7c00056e;
|
||||
"stfsx" & 0xfc0003ff == 0x7c00052e;
|
||||
"sth" & 0xfc000000 == 0xb0000000;
|
||||
"sthbrx" & 0xfc0007ff == 0x7c00072c;
|
||||
"sthu" & 0xfc000000 == 0xb4000000;
|
||||
"sthux" & 0xfc0003ff == 0x7c00036e;
|
||||
"sthx" & 0xfc0003ff == 0x7c00032e;
|
||||
"stmw" & 0xfc000000 == 0xbc000000;
|
||||
"stswi" & 0xfc0007ff == 0x7c0005aa;
|
||||
"stswx" & 0xfc0007ff == 0x7c00052a;
|
||||
"stw" & 0xfc000000 == 0x90000000;
|
||||
"stwbrx" & 0xfc0007ff == 0x7c00052c;
|
||||
"stwcx." & 0xfc0007ff == 0x7c00012d;
|
||||
"stwu" & 0xfc000000 == 0x94000000;
|
||||
"stwux" & 0xfc0003ff == 0x7c00016e;
|
||||
"stwx" & 0xfc0003ff == 0x7c00012e;
|
||||
"subf" & 0xfc0003fe == 0x7c000050;
|
||||
"subfc" & 0xfc0003fe == 0x7c000010;
|
||||
"subfe" & 0xfc0003fe == 0x7c000110;
|
||||
"subfic" & 0xfc000000 == 0x20000000;
|
||||
"subfme" & 0xfc00fbfe == 0x7c0001d0;
|
||||
"subfze" & 0xfc00fbfe == 0x7c000190;
|
||||
"sync" & 0xffffffff == 0x7c0004ac;
|
||||
"tlbie" & 0xffff07ff == 0x7c000264;
|
||||
"tlbsync" & 0xffffffff == 0x7c00046c;
|
||||
"tw" & 0xfc0007ff == 0x7c000008;
|
||||
"twi" & 0xfc000000 == 0xc000000;
|
||||
"xor" & 0xfc0007fe == 0x7c000278;
|
||||
"xori" & 0xfc000000 == 0x68000000;
|
||||
"xoris" & 0xfc000000 == 0x6c000000;
|
||||
}
|
||||
|
||||
impl Default for Opcode {
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "ppc750cl-macros"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
authors = ["Richard Patel <me@terorie.dev>"]
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0.28"
|
||||
syn = { version = "1.0.74", features = ["full"] }
|
|
@ -0,0 +1,144 @@
|
|||
use proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
|
||||
use std::iter::FromIterator;
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::token::{And, EqEq};
|
||||
use syn::{LitInt, LitStr, Token};
|
||||
|
||||
struct Opcodes {
|
||||
opcodes: Punctuated<Opcode, Token![;]>,
|
||||
}
|
||||
|
||||
impl Parse for Opcodes {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
Ok(Self {
|
||||
opcodes: Punctuated::parse_terminated(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Opcode {
|
||||
name: String,
|
||||
variant_name: String,
|
||||
mask: u32,
|
||||
bits: u32,
|
||||
}
|
||||
|
||||
impl Parse for Opcode {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let name = input.parse::<LitStr>()?;
|
||||
input.parse::<And>()?;
|
||||
let mask = input.parse::<LitInt>()?;
|
||||
input.parse::<EqEq>()?;
|
||||
let bits = input.parse::<LitInt>()?;
|
||||
Ok(Self {
|
||||
name: name.value(),
|
||||
variant_name: opcode_to_variant_name(&name)?,
|
||||
mask: hex_from_lit_int(&mask)?,
|
||||
bits: hex_from_lit_int(&bits)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn hex_from_lit_int(int: &LitInt) -> syn::Result<u32> {
|
||||
let str = int.to_string();
|
||||
let hex = match str.strip_prefix("0x") {
|
||||
None => return Err(syn::Error::new(int.span(), "not a hex integer")),
|
||||
Some(x) => x,
|
||||
};
|
||||
u32::from_str_radix(hex, 16).map_err(|e| syn::Error::new(int.span(), e))
|
||||
}
|
||||
|
||||
fn opcode_to_variant_name(opcode: &LitStr) -> syn::Result<String> {
|
||||
let mut s = String::new();
|
||||
let opcode_value = opcode.value();
|
||||
let mut chars = opcode_value.chars();
|
||||
loop {
|
||||
// Make first char uppercase.
|
||||
let c = match chars.next() {
|
||||
None => return Ok(s),
|
||||
Some(c) => c,
|
||||
};
|
||||
match c {
|
||||
'a'..='z' => s.push(c.to_ascii_uppercase()),
|
||||
_ => return Err(syn::Error::new(opcode.span(), "invalid opcode name")),
|
||||
}
|
||||
loop {
|
||||
let c = match chars.next() {
|
||||
None => return Ok(s),
|
||||
Some(c) => c,
|
||||
};
|
||||
match c {
|
||||
'0'..='9' | 'a'..='z' => s.push(c),
|
||||
'_' => break,
|
||||
'.' => {
|
||||
s.push('_');
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
return Err(syn::Error::new(
|
||||
opcode.span(),
|
||||
"invalid character in opcode name",
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn isa(input: TokenStream) -> TokenStream {
|
||||
let opcodes = syn::parse_macro_input!(input as Opcodes);
|
||||
|
||||
// Assemble root stream.
|
||||
let mut root = Vec::<TokenTree>::new();
|
||||
|
||||
// Define enum derives and header.
|
||||
let derives: TokenStream = "#[derive(Debug, Copy, Clone, Eq, PartialEq)]"
|
||||
.parse()
|
||||
.unwrap();
|
||||
root.append(&mut derives.into_iter().collect());
|
||||
let enum_header: TokenStream = "pub enum Opcode".parse().unwrap();
|
||||
root.append(&mut enum_header.into_iter().collect());
|
||||
|
||||
// Create entries.
|
||||
// First entry is going to be the illegal entry.
|
||||
let mut enum_entries = Vec::<TokenTree>::new();
|
||||
enum_entries.append(
|
||||
&mut "Illegal = -1,"
|
||||
.parse::<TokenStream>()
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.collect(),
|
||||
);
|
||||
// Append the actual opcodes.
|
||||
for opcode in opcodes.opcodes {
|
||||
enum_entries.push(TokenTree::Ident(Ident::new(
|
||||
&opcode.variant_name,
|
||||
Span::call_site(),
|
||||
)));
|
||||
enum_entries.push(TokenTree::Punct(Punct::new(',', Spacing::Alone)));
|
||||
}
|
||||
|
||||
// Create body.
|
||||
let enum_body = Group::new(Delimiter::Brace, TokenStream::from_iter(enum_entries));
|
||||
root.push(TokenTree::Group(enum_body));
|
||||
|
||||
TokenStream::from_iter(root)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn _opcode_to_variant_name(input: &str) -> String {
|
||||
opcode_to_variant_name(&LitStr::new(input, proc_macro2::Span::call_site())).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_opcode_to_variant_name() {
|
||||
assert_eq!(_opcode_to_variant_name("lol_lel."), "LolLel_");
|
||||
assert_eq!(_opcode_to_variant_name("ps_nmsub"), "PsNmsub");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue