From e9041072e95330c23e69a492eddab3187862bcfc Mon Sep 17 00:00:00 2001 From: Richard Patel Date: Thu, 7 Apr 2022 01:17:31 +0200 Subject: [PATCH] support simplified mnemonic conditions --- disasm/src/generated.rs | 473 +++++++++++++++++++++++++++++++++++----- disasm/src/lib.rs | 5 +- genisa/src/main.rs | 81 +++++-- isa.yaml | 50 ++--- 4 files changed, 515 insertions(+), 94 deletions(-) diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index df5963e..41c9e71 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -6967,7 +6967,14 @@ impl Ins { return SimplifiedIns { mnemonic: "li", modifiers: Modifiers::default(), - args: vec![], + args: vec![ + Argument::GPR(GPR( + (((self.code) >> (32 - 11u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::Simm(Simm( + (((self.code) >> (32 - 32u8)) & ((1 << 16usize) - 1)) as _, + )), + ], ins: self, }; } @@ -6977,7 +6984,14 @@ impl Ins { return SimplifiedIns { mnemonic: "lis", modifiers: Modifiers::default(), - args: vec![], + args: vec![ + Argument::GPR(GPR( + (((self.code) >> (32 - 11u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::Uimm(Uimm( + (((self.code) >> (32 - 32u8)) & ((1 << 16usize) - 1)) as _, + )), + ], ins: self, }; } @@ -6992,7 +7006,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7005,7 +7026,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7018,7 +7046,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7031,7 +7066,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7044,7 +7086,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7057,7 +7106,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7070,7 +7126,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7083,7 +7146,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7098,7 +7168,9 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + ))], ins: self, }; } @@ -7113,7 +7185,9 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + ))], ins: self, }; } @@ -7127,7 +7201,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7139,7 +7220,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7151,7 +7239,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7163,7 +7258,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7175,7 +7277,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7187,7 +7296,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7199,7 +7315,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7211,7 +7334,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7235,7 +7365,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7247,7 +7384,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7259,7 +7403,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7271,7 +7422,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7283,7 +7441,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7295,7 +7460,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7307,7 +7479,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7319,7 +7498,14 @@ impl Ins { m.lk = self.bit(31); m }, - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 14u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::BranchDest(BranchDest( + (((self.code) >> (32 - 30u8)) & ((1 << 14usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7329,7 +7515,14 @@ impl Ins { return SimplifiedIns { mnemonic: "cmpw", modifiers: Modifiers::default(), - args: vec![], + args: vec![ + Argument::GPR(GPR( + (((self.code) >> (32 - 16u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::GPR(GPR( + (((self.code) >> (32 - 21u8)) & ((1 << 5usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7339,7 +7532,14 @@ impl Ins { return SimplifiedIns { mnemonic: "cmpwi", modifiers: Modifiers::default(), - args: vec![], + args: vec![ + Argument::GPR(GPR( + (((self.code) >> (32 - 16u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::Simm(Simm( + (((self.code) >> (32 - 32u8)) & ((1 << 16usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7347,7 +7547,17 @@ impl Ins { return SimplifiedIns { mnemonic: "cmpwi", modifiers: Modifiers::default(), - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 9u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::GPR(GPR( + (((self.code) >> (32 - 16u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::Simm(Simm( + (((self.code) >> (32 - 32u8)) & ((1 << 16usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7357,7 +7567,14 @@ impl Ins { return SimplifiedIns { mnemonic: "cmplw", modifiers: Modifiers::default(), - args: vec![], + args: vec![ + Argument::GPR(GPR( + (((self.code) >> (32 - 16u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::GPR(GPR( + (((self.code) >> (32 - 21u8)) & ((1 << 5usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7367,7 +7584,14 @@ impl Ins { return SimplifiedIns { mnemonic: "cmplwi", modifiers: Modifiers::default(), - args: vec![], + args: vec![ + Argument::GPR(GPR( + (((self.code) >> (32 - 16u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::Uimm(Uimm( + (((self.code) >> (32 - 32u8)) & ((1 << 16usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7375,7 +7599,17 @@ impl Ins { return SimplifiedIns { mnemonic: "cmplwi", modifiers: Modifiers::default(), - args: vec![], + args: vec![ + Argument::CRBit(CRBit( + (((self.code) >> (32 - 9u8)) & ((1 << 3usize) - 1)) as _, + )), + Argument::GPR(GPR( + (((self.code) >> (32 - 16u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::Uimm(Uimm( + (((self.code) >> (32 - 32u8)) & ((1 << 16usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7385,7 +7619,9 @@ impl Ins { return SimplifiedIns { mnemonic: "mfxer", modifiers: Modifiers::default(), - args: vec![], + args: vec![Argument::GPR(GPR((((self.code) >> (32 - 11u8)) + & ((1 << 5usize) - 1)) + as _))], ins: self, }; } @@ -7393,7 +7629,9 @@ impl Ins { return SimplifiedIns { mnemonic: "mflr", modifiers: Modifiers::default(), - args: vec![], + args: vec![Argument::GPR(GPR((((self.code) >> (32 - 11u8)) + & ((1 << 5usize) - 1)) + as _))], ins: self, }; } @@ -7401,7 +7639,9 @@ impl Ins { return SimplifiedIns { mnemonic: "mfctr", modifiers: Modifiers::default(), - args: vec![], + args: vec![Argument::GPR(GPR((((self.code) >> (32 - 11u8)) + & ((1 << 5usize) - 1)) + as _))], ins: self, }; } @@ -7409,7 +7649,9 @@ impl Ins { return SimplifiedIns { mnemonic: "mfdsisr", modifiers: Modifiers::default(), - args: vec![], + args: vec![Argument::GPR(GPR((((self.code) >> (32 - 11u8)) + & ((1 << 5usize) - 1)) + as _))], ins: self, }; } @@ -7417,7 +7659,9 @@ impl Ins { return SimplifiedIns { mnemonic: "mfdbatu", modifiers: Modifiers::default(), - args: vec![], + args: vec![Argument::GPR(GPR((((self.code) >> (32 - 11u8)) + & ((1 << 5usize) - 1)) + as _))], ins: self, }; } @@ -7425,7 +7669,9 @@ impl Ins { return SimplifiedIns { mnemonic: "mftdu", modifiers: Modifiers::default(), - args: vec![], + args: vec![Argument::GPR(GPR((((self.code) >> (32 - 11u8)) + & ((1 << 5usize) - 1)) + as _))], ins: self, }; } @@ -7435,7 +7681,9 @@ impl Ins { return SimplifiedIns { mnemonic: "mtxer", modifiers: Modifiers::default(), - args: vec![], + args: vec![Argument::GPR(GPR((((self.code) >> (32 - 11u8)) + & ((1 << 5usize) - 1)) + as _))], ins: self, }; } @@ -7443,7 +7691,9 @@ impl Ins { return SimplifiedIns { mnemonic: "mtlr", modifiers: Modifiers::default(), - args: vec![], + args: vec![Argument::GPR(GPR((((self.code) >> (32 - 11u8)) + & ((1 << 5usize) - 1)) + as _))], ins: self, }; } @@ -7451,7 +7701,9 @@ impl Ins { return SimplifiedIns { mnemonic: "mtctr", modifiers: Modifiers::default(), - args: vec![], + args: vec![Argument::GPR(GPR((((self.code) >> (32 - 11u8)) + & ((1 << 5usize) - 1)) + as _))], ins: self, }; } @@ -7459,7 +7711,9 @@ impl Ins { return SimplifiedIns { mnemonic: "mtdsisr", modifiers: Modifiers::default(), - args: vec![], + args: vec![Argument::GPR(GPR((((self.code) >> (32 - 11u8)) + & ((1 << 5usize) - 1)) + as _))], ins: self, }; } @@ -7467,7 +7721,9 @@ impl Ins { return SimplifiedIns { mnemonic: "mtdbatu", modifiers: Modifiers::default(), - args: vec![], + args: vec![Argument::GPR(GPR((((self.code) >> (32 - 11u8)) + & ((1 << 5usize) - 1)) + as _))], ins: self, }; } @@ -7475,12 +7731,32 @@ impl Ins { return SimplifiedIns { mnemonic: "mttdu", modifiers: Modifiers::default(), - args: vec![], + args: vec![Argument::GPR(GPR((((self.code) >> (32 - 11u8)) + & ((1 << 5usize) - 1)) + as _))], + ins: self, + }; + } + } + Opcode::Or => { + if (((self.code) >> (32 - 11u8)) & ((1 << 5usize) - 1)) + == (((self.code) >> (32 - 21u8)) & ((1 << 5usize) - 1)) + { + return SimplifiedIns { + mnemonic: "mr", + modifiers: Modifiers::default(), + args: vec![ + Argument::GPR(GPR( + (((self.code) >> (32 - 16u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::GPR(GPR( + (((self.code) >> (32 - 11u8)) & ((1 << 5usize) - 1)) as _, + )), + ], ins: self, }; } } - Opcode::Or => {} Opcode::Ori => { if (((self.code) >> (32 - 16u8)) & ((1 << 5usize) - 1)) == 0 && (((self.code) >> (32 - 11u8)) & ((1 << 5usize) - 1)) == 0 @@ -7494,13 +7770,103 @@ impl Ins { }; } } - Opcode::Rlwinm => {} + Opcode::Rlwinm => { + if (((self.code) >> (32 - 21u8)) & ((1 << 5usize) - 1)) == 0 + && (((self.code) >> (32 - 31u8)) & ((1 << 5usize) - 1)) == 31 + { + return SimplifiedIns { + mnemonic: "clrlwi", + modifiers: Modifiers::default(), + args: vec![ + Argument::GPR(GPR( + (((self.code) >> (32 - 16u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::GPR(GPR( + (((self.code) >> (32 - 11u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::OpaqueU(OpaqueU( + (((self.code) >> (32 - 26u8)) & ((1 << 5usize) - 1)) as _, + )), + ], + ins: self, + }; + } + if (((self.code) >> (32 - 26u8)) & ((1 << 5usize) - 1)) == 0 + && (((self.code) >> (32 - 31u8)) & ((1 << 5usize) - 1)) == 31 + { + return SimplifiedIns { + mnemonic: "rotlwi", + modifiers: Modifiers::default(), + args: vec![ + Argument::GPR(GPR( + (((self.code) >> (32 - 16u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::GPR(GPR( + (((self.code) >> (32 - 11u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::OpaqueU(OpaqueU( + (((self.code) >> (32 - 21u8)) & ((1 << 5usize) - 1)) as _, + )), + ], + ins: self, + }; + } + if (((self.code) >> (32 - 26u8)) & ((1 << 5usize) - 1)) == 0 + && 31 - (((self.code) >> (32 - 21u8)) & ((1 << 5usize) - 1)) + == (((self.code) >> (32 - 31u8)) & ((1 << 5usize) - 1)) + { + return SimplifiedIns { + mnemonic: "slwi", + modifiers: Modifiers::default(), + args: vec![ + Argument::GPR(GPR( + (((self.code) >> (32 - 16u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::GPR(GPR( + (((self.code) >> (32 - 11u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::OpaqueU(OpaqueU( + (((self.code) >> (32 - 31u8)) & ((1 << 5usize) - 1)) as _, + )), + ], + ins: self, + }; + } + if (((self.code) >> (32 - 31u8)) & ((1 << 5usize) - 1)) == 31 + && 32 - (((self.code) >> (32 - 26u8)) & ((1 << 5usize) - 1)) + == (((self.code) >> (32 - 21u8)) & ((1 << 5usize) - 1)) + { + return SimplifiedIns { + mnemonic: "srwi", + modifiers: Modifiers::default(), + args: vec![ + Argument::GPR(GPR( + (((self.code) >> (32 - 16u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::GPR(GPR( + (((self.code) >> (32 - 11u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::OpaqueU(OpaqueU( + (((self.code) >> (32 - 26u8)) & ((1 << 5usize) - 1)) as _, + )), + ], + ins: self, + }; + } + } Opcode::Twi => { if (((self.code) >> (32 - 11u8)) & ((1 << 5usize) - 1)) == 8 { return SimplifiedIns { mnemonic: "twgti", modifiers: Modifiers::default(), - args: vec![], + args: vec![ + Argument::GPR(GPR( + (((self.code) >> (32 - 16u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::Simm(Simm( + (((self.code) >> (32 - 32u8)) & ((1 << 16usize) - 1)) as _, + )), + ], ins: self, }; } @@ -7508,7 +7874,14 @@ impl Ins { return SimplifiedIns { mnemonic: "twllei", modifiers: Modifiers::default(), - args: vec![], + args: vec![ + Argument::GPR(GPR( + (((self.code) >> (32 - 16u8)) & ((1 << 5usize) - 1)) as _, + )), + Argument::Simm(Simm( + (((self.code) >> (32 - 32u8)) & ((1 << 16usize) - 1)) as _, + )), + ], ins: self, }; } diff --git a/disasm/src/lib.rs b/disasm/src/lib.rs index f36a651..2eff918 100644 --- a/disasm/src/lib.rs +++ b/disasm/src/lib.rs @@ -6,16 +6,17 @@ use num_traits::{AsPrimitive, PrimInt}; pub use crate::iter::{disasm_iter, DisasmIterator}; pub mod formatter; -mod iter; mod generated; +mod iter; use generated::*; pub mod prelude { pub use crate::formatter::FormattedIns; + pub use crate::Argument; pub use crate::Field::*; pub use crate::Ins; - pub use crate::Opcode::*; pub use crate::Modifiers; + pub use crate::Opcode::*; pub use crate::SimplifiedIns; pub use crate::{ Bit, BranchDest, CRBit, CRField, Offset, OpaqueU, Simm, Uimm, FPR, GPR, GQR, SPR, SR, diff --git a/genisa/src/main.rs b/genisa/src/main.rs index 6601266..9c94b19 100644 --- a/genisa/src/main.rs +++ b/genisa/src/main.rs @@ -3,6 +3,7 @@ use std::fs::File; use std::io::Write; use std::ops::Range; use std::process::{Command, Stdio}; +use std::str::FromStr; use itertools::Itertools; use proc_macro2::{Ident, Literal, Span, TokenStream, TokenTree}; @@ -30,16 +31,19 @@ fn _main() -> Result<()> { let isa = load_isa()?; let mut unformatted_code = Vec::::new(); - writeln!(&mut unformatted_code, "{}", quote! { - use crate::prelude::*; - })?; + writeln!( + &mut unformatted_code, + "{}", + quote! { + use crate::prelude::*; + } + )?; writeln!(&mut unformatted_code, "{}", isa.gen_opcode_enum()?)?; writeln!(&mut unformatted_code, "{}", isa.gen_field_enum()?)?; writeln!(&mut unformatted_code, "{}", isa.gen_ins_impl()?)?; let formatted_code = rustfmt(unformatted_code); - File::create("./disasm/src/generated.rs")? - .write_all(&formatted_code)?; + File::create("./disasm/src/generated.rs")?.write_all(&formatted_code)?; Ok(()) } @@ -69,8 +73,8 @@ pub(crate) struct BitRange(Range); impl<'de> Deserialize<'de> for BitRange { fn deserialize(deserializer: D) -> std::result::Result - where - D: Deserializer<'de>, + where + D: Deserializer<'de>, { let range_str: String = Deserialize::deserialize(deserializer)?; if let Some((start_str, stop_str)) = range_str.split_once("..") { @@ -321,7 +325,6 @@ impl Isa { Ok(field_enum) } - pub(crate) fn gen_ins_impl(&self) -> Result { // Map fields by name. let mut field_by_name = HashMap::::new(); @@ -331,7 +334,10 @@ impl Isa { // Map mnemonics by opcode. let mut mnemonics_by_opcode = HashMap::<&String, Vec<&Mnemonic>>::new(); for simple in &self.mnemonics { - mnemonics_by_opcode.entry(&simple.opcode).or_insert_with(|| Vec::new()).push(simple) + mnemonics_by_opcode + .entry(&simple.opcode) + .or_insert_with(|| Vec::new()) + .push(simple) } // Generate match arms for each opcode. let mut field_match_arms = Vec::new(); @@ -343,9 +349,9 @@ impl Isa { // Generate fields of opcode. let mut fields = Vec::new(); for arg in &opcode.args { - let field: &Field = field_by_name.get(arg).ok_or_else(|| { - Error::from(format!("undefined field {}", arg)) - })?; + let field: &Field = field_by_name + .get(arg) + .ok_or_else(|| Error::from(format!("undefined field {}", arg)))?; let variant = field.construct_variant_self(); fields.extend(quote! { #variant, }) } @@ -360,7 +366,8 @@ impl Isa { let modifiers = ModifiersExpr { modifiers: opcode.modifiers.clone(), side_effects: opcode.side_effects.clone(), - }.build()?; + } + .build()?; modifier_match_arms.push(quote! { Opcode::#ident => #modifiers, }); @@ -424,7 +431,7 @@ impl Isa { if let Some(mnemonics) = mnemonics_by_opcode.get(&opcode.name) { let mut simplified_conditions = Vec::new(); for mnemonic in mnemonics { - if mnemonic.matcher.is_empty() { + if mnemonic.matcher.is_empty() && mnemonic.condition.is_empty() { continue; // TODO else branch } // Emit if condition. @@ -439,21 +446,44 @@ impl Isa { })?; simplified_conditions.push(field.express_value_self()); // Equate with literal. - let lit_int = LitInt::new(&format!("{}", condition.value), Span::call_site()); + let lit_int = + LitInt::new(&format!("{}", condition.value), Span::call_site()); simplified_conditions.push(quote!(== #lit_int)); } + if !mnemonic.condition.is_empty() { + if mnemonic.matcher.len() > 0 { + simplified_conditions.push(quote!(&&)); + } + simplified_conditions.push(compile_mnemonic_condition( + &field_by_name, + &mnemonic.condition, + )?); + } // Emit branch. let mnemonic_lit = LitStr::new(&mnemonic.name, Span::call_site()); + // Extract modifier bits. let modifiers = ModifiersExpr { modifiers: mnemonic.modifiers.clone(), side_effects: vec![], - }.build()?; + } + .build()?; + // Extract arguments. + let mut args = Vec::new(); + for arg in &mnemonic.args { + let field = field_by_name + .get(arg) + .expect(&format!("field not found: {}", arg)); + let variant = Ident::new(field.arg.as_ref().unwrap(), Span::call_site()); + let value = field.express_value_self(); + args.push(quote!(Argument::#variant(#variant(#value as _)),)); + } + let args = token_stream!(args); simplified_conditions.push(quote! { { return SimplifiedIns { mnemonic: #mnemonic_lit, modifiers: #modifiers, - args: vec![], + args: vec![#args], ins: self, }; } @@ -622,3 +652,20 @@ impl ModifiersExpr { quote!(Modifiers::default()) } } + +/// Compiles conditions such as `S == B` into valid Rust expressions on a PowerPC instruction. +fn compile_mnemonic_condition( + field_by_name: &HashMap, + code: &str, +) -> Result { + let src_stream = TokenStream::from_str(code)?; + let token_iter = src_stream.into_iter().flat_map(|token| { + if let TokenTree::Ident(ref ident) = token { + if let Some(field) = field_by_name.get(&ident.to_string()) { + return field.express_value_self(); + } + } + token.into() + }); + Ok(TokenStream::from_iter(token_iter)) +} diff --git a/isa.yaml b/isa.yaml index 5074eb9..452e90c 100644 --- a/isa.yaml +++ b/isa.yaml @@ -1968,7 +1968,7 @@ mnemonics: - name: "mr" opcode: "or" args: [ "rA", "rS" ] - condition: "S == B" + condition: "rS == rB" - name: "nop" opcode: "ori" match: @@ -2148,56 +2148,56 @@ mnemonics: - name: "blt" opcode: "bc" modifiers: [ "AA", "LK" ] - args: [ "crS.LT", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 12 - name: "ble" opcode: "bc" modifiers: [ "AA", "LK" ] - args: [ "crS.GT", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 4 - name: "beq" opcode: "bc" modifiers: [ "AA", "LK" ] - args: [ "crS.EQ", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 12 - name: "bge" opcode: "bc" modifiers: [ "AA", "LK" ] - args: [ "crS.LT", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 4 - name: "bgt" opcode: "bc" modifiers: [ "AA", "LK" ] - args: [ "crS.GT", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 12 - name: "bne" opcode: "bc" modifiers: [ "AA", "LK" ] - args: [ "crS.EQ", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 4 - name: "bso" opcode: "bc" modifiers: [ "AA", "LK" ] - args: [ "crS.SO", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 12 - name: "bns" opcode: "bc" modifiers: [ "AA", "LK" ] - args: [ "crS.SO", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 4 @@ -2225,56 +2225,56 @@ mnemonics: - name: "bltctr" opcode: "bcctr" modifiers: [ "LK" ] - args: [ "crS.LT", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 12 - name: "blectr" opcode: "bcctr" modifiers: [ "LK" ] - args: [ "crS.GT", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 4 - name: "beqctr" opcode: "bcctr" modifiers: [ "LK" ] - args: [ "crS.EQ", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 12 - name: "bgectr" opcode: "bcctr" modifiers: [ "LK" ] - args: [ "crS.LT", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 4 - name: "bgtctr" opcode: "bcctr" modifiers: [ "LK" ] - args: [ "crS.GT", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 12 - name: "bnectr" opcode: "bcctr" modifiers: [ "LK" ] - args: [ "crS.EQ", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 4 - name: "bsoctr" opcode: "bcctr" modifiers: [ "LK" ] - args: [ "crS.SO", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 12 - name: "bnsctr" opcode: "bcctr" modifiers: [ "LK" ] - args: [ "crS.SO", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 4 @@ -2283,56 +2283,56 @@ mnemonics: - name: "bltlr" opcode: "bclr" modifiers: [ "LK" ] - args: [ "crS.LT", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 12 - name: "blelr" opcode: "bclr" modifiers: [ "LK" ] - args: [ "crS.GT", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 4 - name: "beqlr" opcode: "bclr" modifiers: [ "LK" ] - args: [ "crS.EQ", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 12 - name: "bgelr" opcode: "bclr" modifiers: [ "LK" ] - args: [ "crS.LT", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 4 - name: "bgtlr" opcode: "bclr" modifiers: [ "LK" ] - args: [ "crS.GT", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 12 - name: "bnelr" opcode: "bclr" modifiers: [ "LK" ] - args: [ "crS.EQ", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 4 - name: "bsolr" opcode: "bclr" modifiers: [ "LK" ] - args: [ "crS.SO", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 12 - name: "bnslr" opcode: "bclr" modifiers: [ "LK" ] - args: [ "crS.SO", "BD" ] + args: [ "crfS", "BD" ] match: - arg: BO value: 4