// Copyright 2017 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package arm64asm import ( "strings" "testing" ) func TestObjdumpARM64TestDecodeGNUSyntaxdata(t *testing.T) { testObjdumpARM64(t, testdataCases(t, "gnu")) } func TestObjdumpARM64TestDecodeGoSyntaxdata(t *testing.T) { testObjdumpARM64(t, testdataCases(t, "plan9")) } func TestObjdumpARM64Manual(t *testing.T) { testObjdumpARM64(t, hexCases(t, objdumpManualTests)) } func TestObjdumpARM64Cond(t *testing.T) { testObjdumpARM64(t, condCases(t)) } func TestObjdumpARM64(t *testing.T) { testObjdumpARM64(t, JSONCases(t)) } // objdumpManualTests holds test cases that will be run by TestObjdumpARMManual. // If you are debugging a few cases that turned up in a longer run, it can be useful // to list them here and then use -run=Manual, particularly with tracing enabled. // Note that these are byte sequences, so they must be reversed from the usual // word presentation. var objdumpManualTests = ` bf2003d5 9f2003d5 7f2003d5 5f2003d5 3f2003d5 1f2003d5 df4d03d5 ff4d03d5 28d91b14 da6cb530 15e5e514 ff4603d5 df4803d5 bf4100d5 9f3f03d5 9f3e03d5 9f3d03d5 9f3b03d5 9f3a03d5 9f3903d5 9f3703d5 9f3603d5 9f3503d5 9f3303d5 9f3203d5 9f3103d5 ff4603d5 df4803d5 bf4100d5 a3681b53 47dc78d3 0500a012 0500e092 0500a052 0500a0d2 cd5a206e cd5a202e 743d050e 743d0a0e 743d0c0e 743d084e ` // allowedMismatchObjdump reports whether the mismatch between text and dec // should be allowed by the test. func allowedMismatchObjdump(text string, inst *Inst, dec ExtInst) bool { // Skip unsupported instructions if hasPrefix(dec.text, todo...) { return true } // GNU objdump has incorrect alias conditions for following instructions if inst.Enc&0x000003ff == 0x000003ff && hasPrefix(dec.text, "negs") && hasPrefix(text, "cmp") { return true } // GNU objdump "NV" is equal to our "AL" if strings.HasSuffix(dec.text, " nv") && strings.HasSuffix(text, " al") { return true } if strings.HasPrefix(dec.text, "b.nv") && strings.HasPrefix(text, "b.al") { return true } // GNU objdump recognizes invalid binaries as following instructions if hasPrefix(dec.text, "hint", "mrs", "msr", "bfc", "orr", "mov") { return true } if strings.HasPrefix(text, "hint") { return true } // GNU objdump recognizes reserved valuse as valid ones if strings.Contains(text, "unknown instruction") && hasPrefix(dec.text, "fmla", "fmul", "fmulx", "fcvtzs", "fcvtzu", "fmls", "fmov", "scvtf", "ucvtf") { return true } // Some old objdump recognizes ldur*/stur*/prfum as ldr*/str*/prfm for k, v := range oldObjdumpMismatch { if strings.HasPrefix(dec.text, k) && strings.Replace(dec.text, k, v, 1) == text { return true } } // New objdump supports some newer mnemonics than this package. This // package should be updated to support the new mnemonics and the sense // of this reversed to continue passing with older objdumps but that // requires internal ARM tooling. if newForm, ok := newMnemonics[text]; ok && newForm == dec.text { return true } // GNU objdump misses spaces between operands for some instructions (e.g., "ld1 {v10.2s, v11.2s}, [x23],#16") if strings.Replace(text, " ", "", -1) == strings.Replace(dec.text, " ", "", -1) { return true } return false } // TODO: system instruction. var todo = strings.Fields(` sys at ic hvc smc `) // Following instructions can't be covered because they are just aliases to another instructions which are always preferred var Ncover = strings.Fields(` sbfm asrv bfm ubfm lslv lsrv rorv ins dup `) // Some old objdump wrongly decodes following instructions and allow their mismatches to avoid false alarm var oldObjdumpMismatch = map[string]string{ //oldObjValue correctValue "ldr": "ldur", "ldrb": "ldurb", "ldrh": "ldurh", "ldrsb": "ldursb", "ldrsh": "ldursh", "ldrsw": "ldursw", "str": "stur", "strb": "sturb", "strh": "sturh", "prfm": "prfum", } var newMnemonics = map[string]string{ "dsb #0x00": "ssbb", "dsb #0x04": "pssbb", }