diff options
| -rw-r--r-- | src/long_mode/display.rs | 119 | 
1 files changed, 55 insertions, 64 deletions
| diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index 644bd82..b6cca48 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -3681,72 +3681,63 @@ fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors:          instr.visit_operand(0 as u8, &mut displayer)?;          for i in 1..instr.operand_count { -            match instr.opcode { -                _ => { -                    match &instr.operands[i as usize] { -                        &OperandSpec::Nothing => { -                            return Ok(()); -                        }, -                        _ => { -                            out.write_str(", ")?; -                            let mut displayer = ColorizingOperandVisitor { -                                instr, -                                op_nr: i, -                                f: out, -                                colors, -                            }; -                            instr.visit_operand(i as u8, &mut displayer)?; -                            if let Some(evex) = instr.prefixes.evex() { -                                let x = Operand::from_spec(instr, instr.operands[i as usize]); -                                if evex.broadcast() && x.is_memory() { -                                    let scale = if instr.opcode == Opcode::VCVTPD2PS || instr.opcode == Opcode::VCVTTPD2UDQ || instr.opcode == Opcode::VCVTPD2UDQ || instr.opcode == Opcode::VCVTUDQ2PD || instr.opcode == Opcode::VCVTPS2PD || instr.opcode == Opcode::VCVTQQ2PS || instr.opcode == Opcode::VCVTDQ2PD || instr.opcode == Opcode::VCVTTPD2DQ || instr.opcode == Opcode::VFPCLASSPS || instr.opcode == Opcode::VFPCLASSPD || instr.opcode == Opcode::VCVTNEPS2BF16 || instr.opcode == Opcode::VCVTUQQ2PS || instr.opcode == Opcode::VCVTPD2DQ || instr.opcode == Opcode::VCVTTPS2UQQ || instr.opcode == Opcode::VCVTPS2UQQ || instr.opcode == Opcode::VCVTTPS2QQ || instr.opcode == Opcode::VCVTPS2QQ { -                                        if instr.opcode == Opcode::VFPCLASSPS || instr.opcode ==  Opcode::VCVTNEPS2BF16 { -                                            if evex.vex().l() { -                                                8 -                                            } else if evex.lp() { -                                                16 -                                            } else { -                                                4 -                                            } -                                        } else if instr.opcode == Opcode::VFPCLASSPD { -                                            if evex.vex().l() { -                                                4 -                                            } else if evex.lp() { -                                                8 -                                            } else { -                                                2 -                                            } -                                        } else { -                                            // vcvtpd2ps is "cool": in broadcast mode, it can read a -                                            // double-precision float (qword), resize to single-precision, -                                            // then broadcast that to the whole destination register. this -                                            // means we need to show `xmm, qword [addr]{1to4}` if vector -                                            // size is 256. likewise, scale of 8 for the same truncation -                                            // reason if vector size is 512. -                                            // vcvtudq2pd is the same story. -                                            // vfpclassp{s,d} is a mystery to me. -                                            if evex.vex().l() { -                                                4 -                                            } else if evex.lp() { -                                                8 -                                            } else { -                                                2 -                                            } -                                        } -                                    } else { -                                        // this should never be `None` - that would imply two -                                        // memory operands for a broadcasted operation. -                                        if let Some(width) = Operand::from_spec(instr, instr.operands[i as usize - 1]).width() { -                                            width / instr.mem_size -                                        } else { -                                            0 -                                        } -                                    }; -                                    write!(out, "{{1to{}}}", scale)?; -                                } +            // don't worry about checking for `instr.operands[i] != Nothing`, it would be a bug to +            // reach that while iterating only to `operand_count`.. +            out.write_str(", ")?; +            let mut displayer = ColorizingOperandVisitor { +                instr, +                op_nr: i, +                f: out, +                colors, +            }; +            instr.visit_operand(i as u8, &mut displayer)?; +            if let Some(evex) = instr.prefixes.evex() { +                let x = Operand::from_spec(instr, instr.operands[i as usize]); +                if evex.broadcast() && x.is_memory() { +                    let scale = if instr.opcode == Opcode::VCVTPD2PS || instr.opcode == Opcode::VCVTTPD2UDQ || instr.opcode == Opcode::VCVTPD2UDQ || instr.opcode == Opcode::VCVTUDQ2PD || instr.opcode == Opcode::VCVTPS2PD || instr.opcode == Opcode::VCVTQQ2PS || instr.opcode == Opcode::VCVTDQ2PD || instr.opcode == Opcode::VCVTTPD2DQ || instr.opcode == Opcode::VFPCLASSPS || instr.opcode == Opcode::VFPCLASSPD || instr.opcode == Opcode::VCVTNEPS2BF16 || instr.opcode == Opcode::VCVTUQQ2PS || instr.opcode == Opcode::VCVTPD2DQ || instr.opcode == Opcode::VCVTTPS2UQQ || instr.opcode == Opcode::VCVTPS2UQQ || instr.opcode == Opcode::VCVTTPS2QQ || instr.opcode == Opcode::VCVTPS2QQ { +                        if instr.opcode == Opcode::VFPCLASSPS || instr.opcode ==  Opcode::VCVTNEPS2BF16 { +                            if evex.vex().l() { +                                8 +                            } else if evex.lp() { +                                16 +                            } else { +                                4 +                            } +                        } else if instr.opcode == Opcode::VFPCLASSPD { +                            if evex.vex().l() { +                                4 +                            } else if evex.lp() { +                                8 +                            } else { +                                2 +                            } +                        } else { +                            // vcvtpd2ps is "cool": in broadcast mode, it can read a +                            // double-precision float (qword), resize to single-precision, +                            // then broadcast that to the whole destination register. this +                            // means we need to show `xmm, qword [addr]{1to4}` if vector +                            // size is 256. likewise, scale of 8 for the same truncation +                            // reason if vector size is 512. +                            // vcvtudq2pd is the same story. +                            // vfpclassp{s,d} is a mystery to me. +                            if evex.vex().l() { +                                4 +                            } else if evex.lp() { +                                8 +                            } else { +                                2                              }                          } -                    } +                    } else { +                        // this should never be `None` - that would imply two +                        // memory operands for a broadcasted operation. +                        if let Some(width) = Operand::from_spec(instr, instr.operands[i as usize - 1]).width() { +                            width / instr.mem_size +                        } else { +                            0 +                        } +                    }; +                    write!(out, "{{1to{}}}", scale)?;                  }              }          } | 
