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 #if defined(__SPLIT__op0_format_lengths)
37 
38 /*  Instruction length in bytes as function of its op0 field (first nibble):  */
39 #ifdef XCHAL_OP0_FORMAT_LENGTHS
40 const unsigned char Xthal_op0_format_lengths[16] = {
41   XCHAL_OP0_FORMAT_LENGTHS
42 };
43 #endif
44 
45 
46 #elif defined(__SPLIT__byte0_format_lengths)
47 
48 /*  Instruction length in bytes as function of its first byte:  */
49 const unsigned char Xthal_byte0_format_lengths[256] = {
50   XCHAL_BYTE0_FORMAT_LENGTHS
51 };
52 
53 
54 #elif defined(__SPLIT__disassemble_size)
55 
56 //
57 // Disassembly is currently not supported in xtensa hal.
58 //
59 
xthal_disassemble_size(unsigned char * instr_buf)60 int xthal_disassemble_size( unsigned char *instr_buf )
61 {
62 #ifdef XCHAL_OP0_FORMAT_LENGTHS
63     /*  Extract op0 field of instruction (first nibble used for decoding):  */
64 # if XCHAL_HAVE_BE
65     int op0 = ((*instr_buf >> 4) & 0xF);
66 # else
67     int op0 = (*instr_buf & 0xF);
68 # endif
69     /*return (op0 & 8) ? 2 : 3;*/	/* simple case only works consistently on older hardware */
70     return Xthal_op0_format_lengths[op0];
71 #else
72     return Xthal_byte0_format_lengths[*instr_buf];
73 #endif
74 }
75 
76 
77 #elif defined(__SPLIT__disassemble)
78 
79 /*
80  *  Note:  we make sure to avoid the use of library functions,
81  *  to minimize dependencies.
82  */
xthal_disassemble(unsigned char * instr_buffer,void * tgt_address,char * buffer,unsigned buflen,unsigned options)83 int xthal_disassemble(
84     unsigned char *instr_buffer, /* the address of the instructions */
85     void *tgt_address,		 /* where the instruction is to be */
86     char *buffer,		 /* where the result goes */
87     unsigned buflen,		 /* size of buffer */
88     unsigned options		 /* what to display */
89     )
90 {
91 #define OUTC(c)	do{ if( p < endp ) *p = c; p++; }while(0)
92     int i, n;
93     char *p = buffer, *endp = buffer + buflen - 1;
94     /*static char *ret = " decoding not supported";*/
95     static const char _hexc[16] = "0123456789ABCDEF";
96 
97     n = xthal_disassemble_size( instr_buffer );
98 
99     if( options & XTHAL_DISASM_OPT_ADDR ) {
100 	unsigned addr = (unsigned)tgt_address;
101 	for( i = 0; i < 8; i++ ) {
102 	    OUTC( _hexc[(addr >> 28) & 0xF] );
103 	    addr <<= 4;
104 	}
105     }
106 
107     if( options & XTHAL_DISASM_OPT_OPHEX ) {
108 	if( p > buffer )
109 	    OUTC( ' ' );
110 	for( i = 0; i < 3; i++ ) {
111 	    if( i < n ) {
112 		OUTC( _hexc[(*instr_buffer >> 4) & 0xF] );
113 		OUTC( _hexc[*instr_buffer++ & 0xF] );
114 	    } else {
115 		OUTC( ' ' );
116 		OUTC( ' ' );
117 	    }
118 	    OUTC( ' ' );
119 	}
120     }
121 
122     if( options & XTHAL_DISASM_OPT_OPCODE ) {
123 	if( p > buffer )
124 	    OUTC( ' ' );
125 	OUTC( '?' );
126 	OUTC( '?' );
127 	OUTC( '?' );
128 	OUTC( ' ' );
129 	OUTC( ' ' );
130 	OUTC( ' ' );
131 	OUTC( ' ' );
132     }
133 
134     if( options & XTHAL_DISASM_OPT_PARMS ) {
135 	if( p > buffer )
136 	    OUTC( ' ' );
137 	OUTC( '?' );
138 	OUTC( '?' );
139 	OUTC( '?' );
140     }
141 
142     if( p < endp )
143 	*p = 0;
144     else if( buflen > 0 )
145 	*endp = 0;
146 
147     return p - buffer;	/* return length needed, even if longer than buflen */
148 }
149 
150 #undef OUTC
151 
152 
153 #endif /*split*/
154