...

Source file src/golang.org/x/arch/arm/armasm/objdump_test.go

Documentation: golang.org/x/arch/arm/armasm

     1  // Copyright 2014 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package armasm
     6  
     7  import (
     8  	"encoding/binary"
     9  	"strings"
    10  	"testing"
    11  )
    12  
    13  func TestObjdumpARMTestdata(t *testing.T) { testObjdumpARM(t, testdataCases(t)) }
    14  func TestObjdumpARMManual(t *testing.T)   { testObjdumpARM(t, hexCases(t, objdumpManualTests)) }
    15  func TestObjdumpARMCond(t *testing.T)     { testObjdumpARM(t, condCases(t)) }
    16  func TestObjdumpARMUncond(t *testing.T)   { testObjdumpARM(t, uncondCases(t)) }
    17  func TestObjdumpARMVFP(t *testing.T)      { testObjdumpARM(t, vfpCases(t)) }
    18  
    19  // objdumpManualTests holds test cases that will be run by TestObjdumpARMManual.
    20  // If you are debugging a few cases that turned up in a longer run, it can be useful
    21  // to list them here and then use -run=Manual, particularly with tracing enabled.
    22  // Note that these are byte sequences, so they must be reversed from the usual
    23  // word presentation.
    24  var objdumpManualTests = `
    25  002a9b1d
    26  001b9bed
    27  020b8ded
    28  003a9b1d
    29  060b8ded
    30  fcde1100
    31  b4de1100
    32  bc480000
    33  0b008de7
    34  0b00ade7
    35  fdbcfaf7
    36  `
    37  
    38  // allowedMismatchObjdump reports whether the mismatch between text and dec
    39  // should be allowed by the test.
    40  func allowedMismatchObjdump(text string, size int, inst *Inst, dec ExtInst) bool {
    41  	if hasPrefix(text, "error:") {
    42  		if hasPrefix(dec.text, unsupported...) || strings.Contains(dec.text, "invalid:") || strings.HasSuffix(dec.text, "^") || strings.Contains(dec.text, "f16.f64") || strings.Contains(dec.text, "f64.f16") {
    43  			return true
    44  		}
    45  		// word 4320F02C: libopcodes says 'nopmi {44}'.
    46  		if hasPrefix(dec.text, "nop") && strings.Contains(dec.text, "{") {
    47  			return true
    48  		}
    49  	}
    50  
    51  	if hasPrefix(dec.text, "error:") && text == "undef" && inst.Enc == 0xf7fabcfd {
    52  		return true
    53  	}
    54  
    55  	// word 00f02053: libopcodes says 'noppl {0}'.
    56  	if hasPrefix(dec.text, "nop") && hasPrefix(text, "nop") && dec.text == text+" {0}" {
    57  		return true
    58  	}
    59  
    60  	// word F57FF04F. we say 'dsb #15', libopcodes says 'dsb sy'.
    61  	if hasPrefix(text, "dsb") && hasPrefix(dec.text, "dsb") {
    62  		return true
    63  	}
    64  	// word F57FF06F. we say 'isb #15', libopcodes says 'isb sy'.
    65  	if hasPrefix(text, "isb") && hasPrefix(dec.text, "isb") {
    66  		return true
    67  	}
    68  	// word F57FF053. we say 'dmb #3', libopcodes says 'dmb osh'.
    69  	if hasPrefix(text, "dmb") && hasPrefix(dec.text, "dmb") {
    70  		return true
    71  	}
    72  
    73  	// word 992D0000. push/stmdb with no registers (undefined).
    74  	// we say 'stmdbls sp!, {}', libopcodes says 'pushls {}'.
    75  	if hasPrefix(text, "stmdb") && hasPrefix(dec.text, "push") && strings.Contains(text, "{}") && strings.Contains(dec.text, "{}") {
    76  		return true
    77  	}
    78  
    79  	// word 28BD0000. pop/ldm with no registers (undefined).
    80  	// we say 'ldmcs sp!, {}', libopcodes says 'popcs {}'.
    81  	if hasPrefix(text, "ldm") && hasPrefix(dec.text, "pop") && strings.Contains(text, "{}") && strings.Contains(dec.text, "{}") {
    82  		return true
    83  	}
    84  
    85  	// word 014640F0.
    86  	// libopcodes emits #-0 for negative zero; we don't.
    87  	if strings.Replace(dec.text, "#-0", "#0", -1) == text || strings.Replace(dec.text, ", #-0", "", -1) == text {
    88  		return true
    89  	}
    90  
    91  	// word 91EF90F0. we say 'strdls r9, [pc, #0]!' but libopcodes says 'strdls r9, [pc]'.
    92  	// word D16F60F0. we say 'strdle r6, [pc, #0]!' but libopcodes says 'strdle r6, [pc, #-0]'.
    93  	if strings.Replace(text, ", #0]!", "]", -1) == strings.Replace(dec.text, ", #-0]", "]", -1) {
    94  		return true
    95  	}
    96  
    97  	// word 510F4000. we say apsr, libopcodes says CPSR.
    98  	if strings.Replace(dec.text, "CPSR", "apsr", -1) == text {
    99  		return true
   100  	}
   101  
   102  	// word 06A4B059.
   103  	// for ssat and usat, libopcodes decodes asr #0 as asr #0 but the manual seems to say it should be asr #32.
   104  	// There is never an asr #0.
   105  	if strings.Replace(dec.text, ", asr #0", ", asr #32", -1) == text {
   106  		return true
   107  	}
   108  
   109  	if len(dec.enc) >= 4 {
   110  		raw := binary.LittleEndian.Uint32(dec.enc[:4])
   111  
   112  		// word 21FFF0B5.
   113  		// the manual is clear that this is pre-indexed mode (with !) but libopcodes generates post-index (without !).
   114  		if raw&0x01200000 == 0x01200000 && strings.Replace(text, "!", "", -1) == dec.text {
   115  			return true
   116  		}
   117  
   118  		// word C100543E: libopcodes says tst, but no evidence for that.
   119  		if strings.HasPrefix(dec.text, "tst") && raw&0x0ff00000 != 0x03100000 && raw&0x0ff00000 != 0x01100000 {
   120  			return true
   121  		}
   122  
   123  		// word C3203CE8: libopcodes says teq, but no evidence for that.
   124  		if strings.HasPrefix(dec.text, "teq") && raw&0x0ff00000 != 0x03300000 && raw&0x0ff00000 != 0x01300000 {
   125  			return true
   126  		}
   127  
   128  		// word D14C552E: libopcodes says cmp but no evidence for that.
   129  		if strings.HasPrefix(dec.text, "cmp") && raw&0x0ff00000 != 0x03500000 && raw&0x0ff00000 != 0x01500000 {
   130  			return true
   131  		}
   132  
   133  		// word 2166AA4A: libopcodes says cmn but no evidence for that.
   134  		if strings.HasPrefix(dec.text, "cmn") && raw&0x0ff00000 != 0x03700000 && raw&0x0ff00000 != 0x01700000 {
   135  			return true
   136  		}
   137  
   138  		// word E70AEEEF: libopcodes says str but no evidence for that.
   139  		if strings.HasPrefix(dec.text, "str") && len(dec.text) >= 5 && (dec.text[3] == ' ' || dec.text[5] == ' ') && raw&0x0e500018 != 0x06000000 && raw&0x0e500000 != 0x0400000 {
   140  			return true
   141  		}
   142  
   143  		// word B0AF48F4: libopcodes says strd but P=0,W=1 which is unpredictable.
   144  		if hasPrefix(dec.text, "ldr", "str") && raw&0x01200000 == 0x00200000 {
   145  			return true
   146  		}
   147  
   148  		// word B6CC1C76: libopcodes inexplicably says 'uxtab16lt r1, ip, r6, ROR #24' instead of 'uxtab16lt r1, ip, r6, ror #24'
   149  		if strings.ToLower(dec.text) == text {
   150  			return true
   151  		}
   152  
   153  		// word F410FDA1: libopcodes says PLDW but the manual is clear that PLDW is F5/F7, not F4.
   154  		// word F7D0FB17: libopcodes says PLDW but the manual is clear that PLDW has 0x10 clear
   155  		if hasPrefix(dec.text, "pld") && raw&0xfd000010 != 0xf5000000 {
   156  			return true
   157  		}
   158  
   159  		// word F650FE14: libopcodes says PLI but the manual is clear that PLI has 0x10 clear
   160  		if hasPrefix(dec.text, "pli") && raw&0xff000010 != 0xf6000000 {
   161  			return true
   162  		}
   163  	}
   164  
   165  	return false
   166  }
   167  
   168  // Instructions known to libopcodes (or xed) but not to us.
   169  // Most of these are floating point coprocessor instructions.
   170  var unsupported = strings.Fields(`
   171  	abs
   172  	acs
   173  	adf
   174  	aes
   175  	asn
   176  	atn
   177  	cdp
   178  	cf
   179  	cmf
   180  	cnf
   181  	cos
   182  	cps
   183  	crc32
   184  	dvf
   185  	eret
   186  	exp
   187  	fadd
   188  	fcmp
   189  	fcpy
   190  	fcvt
   191  	fdiv
   192  	fdv
   193  	fix
   194  	fld
   195  	flt
   196  	fmac
   197  	fmd
   198  	fml
   199  	fmr
   200  	fms
   201  	fmul
   202  	fmx
   203  	fneg
   204  	fnm
   205  	frd
   206  	fsit
   207  	fsq
   208  	fst
   209  	fsu
   210  	fto
   211  	fui
   212  	hlt
   213  	hvc
   214  	lda
   215  	ldc
   216  	ldf
   217  	lfm
   218  	lgn
   219  	log
   220  	mar
   221  	mcr
   222  	mcrr
   223  	mia
   224  	mnf
   225  	mra
   226  	mrc
   227  	mrrc
   228  	mrs
   229  	msr
   230  	msr
   231  	muf
   232  	mvf
   233  	nrm
   234  	pol
   235  	pow
   236  	rdf
   237  	rfc
   238  	rfe
   239  	rfs
   240  	rmf
   241  	rnd
   242  	rpw
   243  	rsf
   244  	sdiv
   245  	sev
   246  	sfm
   247  	sha1
   248  	sha256
   249  	sin
   250  	smc
   251  	sqt
   252  	srs
   253  	stc
   254  	stf
   255  	stl
   256  	suf
   257  	tan
   258  	udf
   259  	udiv
   260  	urd
   261  	vfma
   262  	vfms
   263  	vfnma
   264  	vfnms
   265  	vrint
   266  	wfc
   267  	wfs
   268  `)
   269  

View as plain text