use unarm::{arm, thumb, ParseFlags}; macro_rules! assert_arm { ($code:literal, $flags:expr, $disasm:literal) => {{ let ins = arm::Ins::new($code, $flags); let parsed = ins.parse($flags); assert_eq!(parsed.display(Default::default()).to_string(), $disasm) }}; } macro_rules! assert_thumb { ($code:literal, $flags:expr, $disasm:literal) => {{ let ins = thumb::Ins::new($code, $flags); let parsed = ins.parse($flags); assert_eq!(parsed.display(Default::default()).to_string(), $disasm) }}; } #[test] fn test_data() { let unified = ParseFlags { ual: true, ..Default::default() }; let divided = ParseFlags { ual: false, ..Default::default() }; assert_arm!(0x00912003, &unified, "addseq r2, r1, r3"); assert_arm!(0x00912003, ÷d, "addeqs r2, r1, r3"); assert_thumb!(0x1cca, &unified, "adds r2, r1, #0x3"); assert_thumb!(0x1cca, ÷d, "add r2, r1, #0x3"); assert_thumb!(0xa1ff, &unified, "adr r1, #0x3fc"); assert_thumb!(0xa1ff, ÷d, "add r1, pc, #0x3fc"); assert_thumb!(0x400a, &unified, "ands r2, r2, r1"); assert_thumb!(0x400a, ÷d, "and r2, r1"); assert_thumb!(0x1c0a, &unified, "adds r2, r1, #0x0"); assert_thumb!(0x1c0a, ÷d, "mov r2, r1"); assert_thumb!(0x000a, &unified, "movs r2, r1"); assert_thumb!(0x000a, ÷d, "lsl r2, r1, #0x0"); assert_thumb!(0x424a, &unified, "rsbs r2, r1, #0x0"); assert_thumb!(0x424a, ÷d, "neg r2, r1"); } #[test] fn test_shift() { let unified = ParseFlags { ual: true, ..Default::default() }; let divided = ParseFlags { ual: false, ..Default::default() }; assert_arm!(0xe1a011c2, &unified, "asr r1, r2, #0x3"); assert_arm!(0xe1a011c2, ÷d, "mov r1, r2, asr #0x3"); assert_arm!(0xe1a01182, &unified, "lsl r1, r2, #0x3"); assert_arm!(0xe1a01182, ÷d, "mov r1, r2, lsl #0x3"); assert_arm!(0xe1a011a2, &unified, "lsr r1, r2, #0x3"); assert_arm!(0xe1a011a2, ÷d, "mov r1, r2, lsr #0x3"); assert_arm!(0xe1a011e2, &unified, "ror r1, r2, #0x3"); assert_arm!(0xe1a011e2, ÷d, "mov r1, r2, ror #0x3"); assert_arm!(0xe1a01062, &unified, "rrx r1, r2"); assert_arm!(0xe1a01062, ÷d, "mov r1, r2, rrx"); } #[test] fn test_ldm_stm() { let unified = ParseFlags { ual: true, ..Default::default() }; let divided = ParseFlags { ual: false, ..Default::default() }; assert_arm!(0xe8900011, &unified, "ldm r0, {r0, r4}"); assert_arm!(0xe8900011, ÷d, "ldmia r0, {r0, r4}"); assert_arm!(0x09100011, &unified, "ldmdbeq r0, {r0, r4}"); assert_arm!(0x09100011, ÷d, "ldmeqdb r0, {r0, r4}"); assert_arm!(0xe8800011, &unified, "stm r0, {r0, r4}"); assert_arm!(0xe8800011, ÷d, "stmia r0, {r0, r4}"); assert_arm!(0x09000011, &unified, "stmdbeq r0, {r0, r4}"); assert_arm!(0x09000011, ÷d, "stmeqdb r0, {r0, r4}"); assert_thumb!(0xc811, &unified, "ldm r0, {r0, r4}"); assert_thumb!(0xc811, ÷d, "ldmia r0!, {r0, r4}"); assert_thumb!(0xc822, &unified, "ldm r0!, {r1, r5}"); assert_thumb!(0xc822, ÷d, "ldmia r0!, {r1, r5}"); assert_thumb!(0xc011, &unified, "stm r0!, {r0, r4}"); assert_thumb!(0xc011, ÷d, "stmia r0!, {r0, r4}"); } #[test] fn test_ldr_str() { let unified = ParseFlags { ual: true, ..Default::default() }; let divided = ParseFlags { ual: false, ..Default::default() }; assert_arm!(0x01d120b4, &unified, "ldrheq r2, [r1, #0x4]"); assert_arm!(0x01d120b4, ÷d, "ldreqh r2, [r1, #0x4]"); assert_arm!(0x01d120d4, &unified, "ldrsbeq r2, [r1, #0x4]"); assert_arm!(0x01d120d4, ÷d, "ldreqsb r2, [r1, #0x4]"); assert_arm!(0x01c120d4, &unified, "ldrdeq r2, r3, [r1, #0x4]"); assert_arm!(0x01c120d4, ÷d, "ldreqd r2, [r1, #0x4]"); assert_arm!(0x01c120b4, &unified, "strheq r2, [r1, #0x4]"); assert_arm!(0x01c120b4, ÷d, "streqh r2, [r1, #0x4]"); assert_arm!(0x04e12004, &unified, "strbteq r2, [r1], #0x4"); assert_arm!(0x04e12004, ÷d, "streqbt r2, [r1], #0x4"); assert_arm!(0x01c120f4, &unified, "strdeq r2, r3, [r1, #0x4]"); assert_arm!(0x01c120f4, ÷d, "streqd r2, [r1, #0x4]"); } #[test] fn test_push_pop() { let unified = ParseFlags { ual: true, ..Default::default() }; let divided = ParseFlags { ual: false, ..Default::default() }; assert_arm!(0xe92d0011, &unified, "push {r0, r4}"); assert_arm!(0xe92d0011, ÷d, "stmdb sp!, {r0, r4}"); assert_arm!(0xe52d3004, &unified, "push {r3}"); assert_arm!(0xe52d3004, ÷d, "str r3, [sp, #-0x4]!"); assert_arm!(0xe8bd0011, &unified, "pop {r0, r4}"); assert_arm!(0xe8bd0011, ÷d, "ldmia sp!, {r0, r4}"); assert_arm!(0xe49d3004, &unified, "pop {r3}"); assert_arm!(0xe49d3004, ÷d, "ldr r3, [sp], #0x4"); } #[test] fn test_svc_swi() { let unified = ParseFlags { ual: true, ..Default::default() }; let divided = ParseFlags { ual: false, ..Default::default() }; assert_arm!(0xef000123, &unified, "svc #0x123"); assert_arm!(0xef000123, ÷d, "swi #0x123"); }