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