diff options
Diffstat (limited to 'src/display.rs')
-rw-r--r-- | src/display.rs | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/display.rs b/src/display.rs index 9a584a5..86de297 100644 --- a/src/display.rs +++ b/src/display.rs @@ -24,6 +24,35 @@ impl fmt::Display for InstructionPacket { impl fmt::Display for Instruction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // handle cmp+jump first; this includes elements that would be misformatted below (like + // predication) + static COMPARE_JUMPS: &[Opcode] = &[ + Opcode::CmpEqJump, Opcode::CmpGtJump, + Opcode::CmpGtuJump, Opcode::TestClrJump, + ]; + if COMPARE_JUMPS.contains(&self.opcode) { + let predicate = self.flags.predicate.as_ref().unwrap(); + let preg = Operand::pred(predicate.num()); + + use crate::BranchHint; + let hint_label = match self.flags.branch_hint.unwrap() { + BranchHint::Taken => { "t" }, + BranchHint::NotTaken => { "nt" }, + }; + + write!(f, "{} = {}({}, {}); if ({}{}.new) jump:{} {}", + preg, + self.opcode.cmp_str().unwrap(), + self.sources[0], + self.sources[1], + if predicate.negated() { "!" } else { "" }, + preg, + hint_label, + self.dest.as_ref().unwrap(), + )?; + return Ok(()); + } + if let Some(predication) = self.flags.predicate { write!(f, "if ({}P{}{}) ", if predication.negated() { "!" } else { "" }, @@ -56,6 +85,16 @@ impl fmt::Display for Instruction { return Ok(()); } + // TransferRegisterJump and TransferImmediateJump also have special display rules... + if self.opcode == Opcode::TransferRegisterJump || self.opcode == Opcode::TransferImmediateJump { + write!(f, "{} = {}; jump {}", + self.alt_dest.as_ref().unwrap(), + self.sources[0], + self.dest.as_ref().unwrap(), + )?; + return Ok(()); + } + static JUMPS: &[Opcode] = &[ Opcode::JumpEq, Opcode::JumpNeq, Opcode::JumpGt, Opcode::JumpLe, Opcode::JumpGtu, Opcode::JumpLeu, Opcode::JumpBitSet, Opcode::JumpBitClear, @@ -102,6 +141,9 @@ impl fmt::Display for Instruction { if let Some(mode) = self.flags.rounded { write!(f, "{}", mode.as_label())?; } + if self.flags.chop { + f.write_str(":chop")?; + } if self.flags.saturate { f.write_str(":sat")?; } @@ -167,6 +209,11 @@ impl fmt::Display for Opcode { Opcode::JumpBitSet => { f.write_str("tstbit+jump") }, Opcode::JumpBitClear => { f.write_str("!tstbit+jump") }, + Opcode::CmpEqJump => { f.write_str("p=cmp.eq+if(p.new)jump") }, + Opcode::CmpGtJump => { f.write_str("p=cmp.gt+if(p.new)jump") }, + Opcode::CmpGtuJump => { f.write_str("p=cmp.gtu+if(p.new)jump") }, + Opcode::TestClrJump => { f.write_str("p=tstbit+if(p.new)jump") }, + Opcode::Tlbw => { f.write_str("tlbw") }, Opcode::Tlbr => { f.write_str("tlbr") }, Opcode::Tlbp => { f.write_str("tlbp") }, @@ -188,7 +235,29 @@ impl fmt::Display for Opcode { Opcode::Vabsw => { f.write_str("vabsw") }, Opcode::Vasrw => { f.write_str("vasrw") }, Opcode::Vlsrw => { f.write_str("vlsrw") }, + Opcode::Vlsrh => { f.write_str("vlsrh") }, Opcode::Vaslw => { f.write_str("vaslw") }, + Opcode::Vaslh => { f.write_str("vaslh") }, + + Opcode::Not => { f.write_str("not") }, + Opcode::Neg => { f.write_str("neg") }, + Opcode::Abs => { f.write_str("abs") }, + Opcode::Vconj => { f.write_str("vconj") }, + + Opcode::Deinterleave => { f.write_str("deinterleave") }, + Opcode::Interleave => { f.write_str("interleave") }, + Opcode::Brev => { f.write_str("brev") }, + + Opcode::ConvertDf2d => { f.write_str("convert_df2d") }, + Opcode::ConvertDf2ud => { f.write_str("convert_df2ud") }, + Opcode::ConvertUd2df => { f.write_str("convert_ud2df") }, + Opcode::ConvertD2df => { f.write_str("convert_d2df") }, + + Opcode::Extractu => { f.write_str("extractu") }, + Opcode::Insert => { f.write_str("insert") }, + + Opcode::TransferRegisterJump => { f.write_str("transferregisterjump") } + Opcode::TransferImmediateJump => { f.write_str("transferimmediatejump") } } } } |