1 //
2 // disass.c - disassembly routines for Xtensa
3 //
4 // $Id: //depot/rel/Foxhill/dot.8/Xtensa/OS/hal/disass.c#1 $
5 
6 // Copyright (c) 2004-2013 Tensilica Inc.
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be included
17 // in all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 
27 #include <xtensa/hal.h>
28 #include <xtensa/config/core.h>
29 
30 #ifdef XCHAL_OP0_FORMAT_LENGTHS
31 extern const unsigned char Xthal_op0_format_lengths[16];
32 #endif
33 extern const unsigned char Xthal_byte0_format_lengths[256];
34 
35 
36 
37 /*  Instruction length in bytes as function of its op0 field (first nibble):  */
38 #ifdef XCHAL_OP0_FORMAT_LENGTHS
39 const unsigned char Xthal_op0_format_lengths[16] = {
40   XCHAL_OP0_FORMAT_LENGTHS
41 };
42 #endif
43 
44 
45 
46 /*  Instruction length in bytes as function of its first byte:  */
47 const unsigned char Xthal_byte0_format_lengths[256] = {
48   XCHAL_BYTE0_FORMAT_LENGTHS
49 };
50 
51 
52 
53 //
54 // Disassembly is currently not supported in xtensa hal.
55 //
56 
xthal_disassemble_size(unsigned char * instr_buf)57 int xthal_disassemble_size( unsigned char *instr_buf )
58 {
59 #ifdef XCHAL_OP0_FORMAT_LENGTHS
60     /*  Extract op0 field of instruction (first nibble used for decoding):  */
61 # if XCHAL_HAVE_BE
62     int op0 = ((*instr_buf >> 4) & 0xF);
63 # else
64     int op0 = (*instr_buf & 0xF);
65 # endif
66     /*return (op0 & 8) ? 2 : 3;*/	/* simple case only works consistently on older hardware */
67     return Xthal_op0_format_lengths[op0];
68 #else
69     return Xthal_byte0_format_lengths[*instr_buf];
70 #endif
71 }
72 
73 
74 
75 /*
76  *  Note:  we make sure to avoid the use of library functions,
77  *  to minimize dependencies.
78  */
xthal_disassemble(unsigned char * instr_buffer,void * tgt_address,char * buffer,unsigned buflen,unsigned options)79 int xthal_disassemble(
80     unsigned char *instr_buffer, /* the address of the instructions */
81     void *tgt_address,		 /* where the instruction is to be */
82     char *buffer,		 /* where the result goes */
83     unsigned buflen,		 /* size of buffer */
84     unsigned options		 /* what to display */
85     )
86 {
87 #define OUTC(c)	do{ if( p < endp ) *p = c; p++; }while(0)
88     int i, n;
89     char *p = buffer, *endp = buffer + buflen - 1;
90     /*static char *ret = " decoding not supported";*/
91     static const char _hexc[16] = "0123456789ABCDEF";
92 
93     n = xthal_disassemble_size( instr_buffer );
94 
95     if( options & XTHAL_DISASM_OPT_ADDR ) {
96 	unsigned addr = (unsigned)tgt_address;
97 	for( i = 0; i < 8; i++ ) {
98 	    OUTC( _hexc[(addr >> 28) & 0xF] );
99 	    addr <<= 4;
100 	}
101     }
102 
103     if( options & XTHAL_DISASM_OPT_OPHEX ) {
104 	if( p > buffer )
105 	    OUTC( ' ' );
106 	for( i = 0; i < 3; i++ ) {
107 	    if( i < n ) {
108 		OUTC( _hexc[(*instr_buffer >> 4) & 0xF] );
109 		OUTC( _hexc[*instr_buffer++ & 0xF] );
110 	    } else {
111 		OUTC( ' ' );
112 		OUTC( ' ' );
113 	    }
114 	    OUTC( ' ' );
115 	}
116     }
117 
118     if( options & XTHAL_DISASM_OPT_OPCODE ) {
119 	if( p > buffer )
120 	    OUTC( ' ' );
121 	OUTC( '?' );
122 	OUTC( '?' );
123 	OUTC( '?' );
124 	OUTC( ' ' );
125 	OUTC( ' ' );
126 	OUTC( ' ' );
127 	OUTC( ' ' );
128     }
129 
130     if( options & XTHAL_DISASM_OPT_PARMS ) {
131 	if( p > buffer )
132 	    OUTC( ' ' );
133 	OUTC( '?' );
134 	OUTC( '?' );
135 	OUTC( '?' );
136     }
137 
138     if( p < endp )
139 	*p = 0;
140     else if( buflen > 0 )
141 	*endp = 0;
142 
143     return p - buffer;	/* return length needed, even if longer than buflen */
144 }
145 
146 #undef OUTC
147 
148 
149