Source: https://github.com/iximeow/yaxpeax-arm/blob/716a6e3fc621f5fe3300f3309e56943b8e1e65ad/src/armv8/a64.rs#L317 License: 0BSD Reworked for more structured output. The library only gives us a Display impl, and no way to capture any of this information, so it needs to be reimplemented here.
(args: &mut Cb, ins: &Instruction, ctx: &mut DisplayCtx)
| 186 | // Reworked for more structured output. The library only gives us a Display impl, and no way to |
| 187 | // capture any of this information, so it needs to be reimplemented here. |
| 188 | fn display_instruction<Cb>(args: &mut Cb, ins: &Instruction, ctx: &mut DisplayCtx) -> &'static str |
| 189 | where Cb: FnMut(InstructionPart<'static>) { |
| 190 | let mnemonic = match ins.opcode { |
| 191 | Opcode::Invalid => return "<invalid>", |
| 192 | Opcode::UDF => "udf", |
| 193 | Opcode::MOVN => { |
| 194 | let imm = if let Operand::ImmShift(imm, shift) = ins.operands[1] { |
| 195 | !((imm as u64) << shift) |
| 196 | } else { |
| 197 | unreachable!("movn operand 1 is always ImmShift"); |
| 198 | }; |
| 199 | let imm = if let Operand::Register(size, _) = ins.operands[0] { |
| 200 | if size == SizeCode::W { imm as u32 as u64 } else { imm } |
| 201 | } else { |
| 202 | unreachable!("movn operand 0 is always Register"); |
| 203 | }; |
| 204 | push_operand(args, &ins.operands[0], ctx); |
| 205 | push_separator(args); |
| 206 | push_unsigned(args, imm); |
| 207 | return "mov"; |
| 208 | } |
| 209 | Opcode::MOVK => "movk", |
| 210 | Opcode::MOVZ => { |
| 211 | let imm = if let Operand::ImmShift(imm, shift) = ins.operands[1] { |
| 212 | (imm as u64) << shift |
| 213 | } else { |
| 214 | unreachable!("movz operand is always ImmShift"); |
| 215 | }; |
| 216 | let imm = if let Operand::Register(size, _) = ins.operands[0] { |
| 217 | if size == SizeCode::W { imm as u32 as u64 } else { imm } |
| 218 | } else { |
| 219 | unreachable!("movz operand 0 is always Register"); |
| 220 | }; |
| 221 | push_operand(args, &ins.operands[0], ctx); |
| 222 | push_separator(args); |
| 223 | push_unsigned(args, imm); |
| 224 | return "mov"; |
| 225 | } |
| 226 | Opcode::ADC => "adc", |
| 227 | Opcode::ADCS => "adcs", |
| 228 | Opcode::SBC => { |
| 229 | if let Operand::Register(_, 31) = ins.operands[1] { |
| 230 | push_operand(args, &ins.operands[0], ctx); |
| 231 | push_separator(args); |
| 232 | push_operand(args, &ins.operands[2], ctx); |
| 233 | return "ngc"; |
| 234 | } else { |
| 235 | "sbc" |
| 236 | } |
| 237 | } |
| 238 | Opcode::SBCS => { |
| 239 | if let Operand::Register(_, 31) = ins.operands[1] { |
| 240 | push_operand(args, &ins.operands[0], ctx); |
| 241 | push_separator(args); |
| 242 | push_operand(args, &ins.operands[2], ctx); |
| 243 | return "ngcs"; |
| 244 | } else { |
| 245 | "sbcs" |
no test coverage detected