1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include <asm/cputable.h>
23#include "nonstdio.h"
24#include "ansidecl.h"
25#include "ppc.h"
26#include "dis-asm.h"
27
28
29
30int
31print_insn_powerpc (unsigned long insn, unsigned long memaddr)
32{
33 const struct powerpc_opcode *opcode;
34 const struct powerpc_opcode *opcode_end;
35 unsigned long op;
36 int dialect;
37
38 dialect = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_COMMON
39 | PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_ALTIVEC;
40
41 if (cpu_has_feature(CPU_FTRS_POWER5))
42 dialect |= PPC_OPCODE_POWER5;
43
44 if (cpu_has_feature(CPU_FTRS_CELL))
45 dialect |= PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC;
46
47 if (cpu_has_feature(CPU_FTRS_POWER6))
48 dialect |= PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC;
49
50
51 op = PPC_OP (insn);
52
53
54
55 opcode_end = powerpc_opcodes + powerpc_num_opcodes;
56 again:
57 for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++)
58 {
59 unsigned long table_op;
60 const unsigned char *opindex;
61 const struct powerpc_operand *operand;
62 int invalid;
63 int need_comma;
64 int need_paren;
65
66 table_op = PPC_OP (opcode->opcode);
67 if (op < table_op)
68 break;
69 if (op > table_op)
70 continue;
71
72 if ((insn & opcode->mask) != opcode->opcode
73 || (opcode->flags & dialect) == 0)
74 continue;
75
76
77
78
79 invalid = 0;
80 for (opindex = opcode->operands; *opindex != 0; opindex++)
81 {
82 operand = powerpc_operands + *opindex;
83 if (operand->extract)
84 (*operand->extract) (insn, dialect, &invalid);
85 }
86 if (invalid)
87 continue;
88
89
90 printf("%s", opcode->name);
91 if (opcode->operands[0] != 0)
92 printf("\t");
93
94
95 need_comma = 0;
96 need_paren = 0;
97 for (opindex = opcode->operands; *opindex != 0; opindex++)
98 {
99 long value;
100
101 operand = powerpc_operands + *opindex;
102
103
104
105
106 if ((operand->flags & PPC_OPERAND_FAKE) != 0)
107 continue;
108
109
110 if (operand->extract)
111 value = (*operand->extract) (insn, dialect, &invalid);
112 else
113 {
114 value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
115 if ((operand->flags & PPC_OPERAND_SIGNED) != 0
116 && (value & (1 << (operand->bits - 1))) != 0)
117 value -= 1 << operand->bits;
118 }
119
120
121
122 if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
123 && (operand->flags & PPC_OPERAND_NEXT) == 0
124 && value == 0)
125 continue;
126
127 if (need_comma)
128 {
129 printf(",");
130 need_comma = 0;
131 }
132
133
134 if ((operand->flags & PPC_OPERAND_GPR) != 0
135 || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
136 printf("r%ld", value);
137 else if ((operand->flags & PPC_OPERAND_FPR) != 0)
138 printf("f%ld", value);
139 else if ((operand->flags & PPC_OPERAND_VR) != 0)
140 printf("v%ld", value);
141 else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
142 print_address (memaddr + value);
143 else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
144 print_address (value & 0xffffffff);
145 else if ((operand->flags & PPC_OPERAND_CR) == 0
146 || (dialect & PPC_OPCODE_PPC) == 0)
147 printf("%ld", value);
148 else
149 {
150 if (operand->bits == 3)
151 printf("cr%ld", value);
152 else
153 {
154 static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
155 int cr;
156 int cc;
157
158 cr = value >> 2;
159 if (cr != 0)
160 printf("4*cr%d+", cr);
161 cc = value & 3;
162 printf("%s", cbnames[cc]);
163 }
164 }
165
166 if (need_paren)
167 {
168 printf(")");
169 need_paren = 0;
170 }
171
172 if ((operand->flags & PPC_OPERAND_PARENS) == 0)
173 need_comma = 1;
174 else
175 {
176 printf("(");
177 need_paren = 1;
178 }
179 }
180
181
182 return 4;
183 }
184
185 if ((dialect & PPC_OPCODE_ANY) != 0)
186 {
187 dialect = ~PPC_OPCODE_ANY;
188 goto again;
189 }
190
191
192 printf(".long 0x%lx", insn);
193
194 return 4;
195}
196