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