aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/xmon
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc/xmon')
-rw-r--r--arch/ppc/xmon/Makefile8
-rw-r--r--arch/ppc/xmon/adb.c212
-rw-r--r--arch/ppc/xmon/ansidecl.h141
-rw-r--r--arch/ppc/xmon/nonstdio.h22
-rw-r--r--arch/ppc/xmon/ppc-dis.c190
-rw-r--r--arch/ppc/xmon/ppc-opc.c2721
-rw-r--r--arch/ppc/xmon/ppc.h240
-rw-r--r--arch/ppc/xmon/privinst.h91
-rw-r--r--arch/ppc/xmon/setjmp.c29
-rw-r--r--arch/ppc/xmon/start.c646
-rw-r--r--arch/ppc/xmon/start_8xx.c287
-rw-r--r--arch/ppc/xmon/subr_prf.c55
-rw-r--r--arch/ppc/xmon/xmon.c2008
13 files changed, 6650 insertions, 0 deletions
diff --git a/arch/ppc/xmon/Makefile b/arch/ppc/xmon/Makefile
new file mode 100644
index 000000000000..9aa260b926f5
--- /dev/null
+++ b/arch/ppc/xmon/Makefile
@@ -0,0 +1,8 @@
1# Makefile for xmon
2
3ifdef CONFIG_8xx
4obj-y := start_8xx.o
5else
6obj-y := start.o
7endif
8obj-y += xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o
diff --git a/arch/ppc/xmon/adb.c b/arch/ppc/xmon/adb.c
new file mode 100644
index 000000000000..e91384dcccac
--- /dev/null
+++ b/arch/ppc/xmon/adb.c
@@ -0,0 +1,212 @@
1/*
2 * Copyright (C) 1996 Paul Mackerras.
3 */
4#include "nonstdio.h"
5#include "privinst.h"
6
7#define scanhex xmon_scanhex
8#define skipbl xmon_skipbl
9
10#define ADB_B (*(volatile unsigned char *)0xf3016000)
11#define ADB_SR (*(volatile unsigned char *)0xf3017400)
12#define ADB_ACR (*(volatile unsigned char *)0xf3017600)
13#define ADB_IFR (*(volatile unsigned char *)0xf3017a00)
14
15static inline void eieio(void) { asm volatile ("eieio" : :); }
16
17#define N_ADB_LOG 1000
18struct adb_log {
19 unsigned char b;
20 unsigned char ifr;
21 unsigned char acr;
22 unsigned int time;
23} adb_log[N_ADB_LOG];
24int n_adb_log;
25
26void
27init_adb_log(void)
28{
29 adb_log[0].b = ADB_B;
30 adb_log[0].ifr = ADB_IFR;
31 adb_log[0].acr = ADB_ACR;
32 adb_log[0].time = get_dec();
33 n_adb_log = 0;
34}
35
36void
37dump_adb_log(void)
38{
39 unsigned t, t0;
40 struct adb_log *ap;
41 int i;
42
43 ap = adb_log;
44 t0 = ap->time;
45 for (i = 0; i <= n_adb_log; ++i, ++ap) {
46 t = t0 - ap->time;
47 printf("b=%x ifr=%x acr=%x at %d.%.7d\n", ap->b, ap->ifr, ap->acr,
48 t / 1000000000, (t % 1000000000) / 100);
49 }
50}
51
52void
53adb_chklog(void)
54{
55 struct adb_log *ap = &adb_log[n_adb_log + 1];
56
57 ap->b = ADB_B;
58 ap->ifr = ADB_IFR;
59 ap->acr = ADB_ACR;
60 if (ap->b != ap[-1].b || (ap->ifr & 4) != (ap[-1].ifr & 4)
61 || ap->acr != ap[-1].acr) {
62 ap->time = get_dec();
63 ++n_adb_log;
64 }
65}
66
67int
68adb_bitwait(int bmask, int bval, int fmask, int fval)
69{
70 int i;
71 struct adb_log *ap;
72
73 for (i = 10000; i > 0; --i) {
74 adb_chklog();
75 ap = &adb_log[n_adb_log];
76 if ((ap->b & bmask) == bval && (ap->ifr & fmask) == fval)
77 return 0;
78 }
79 return -1;
80}
81
82int
83adb_wait(void)
84{
85 if (adb_bitwait(0, 0, 4, 4) < 0) {
86 printf("adb: ready wait timeout\n");
87 return -1;
88 }
89 return 0;
90}
91
92void
93adb_readin(void)
94{
95 int i, j;
96 unsigned char d[64];
97
98 if (ADB_B & 8) {
99 printf("ADB_B: %x\n", ADB_B);
100 return;
101 }
102 i = 0;
103 adb_wait();
104 j = ADB_SR;
105 eieio();
106 ADB_B &= ~0x20;
107 eieio();
108 for (;;) {
109 if (adb_wait() < 0)
110 break;
111 d[i++] = ADB_SR;
112 eieio();
113 if (ADB_B & 8)
114 break;
115 ADB_B ^= 0x10;
116 eieio();
117 }
118 ADB_B |= 0x30;
119 if (adb_wait() == 0)
120 j = ADB_SR;
121 for (j = 0; j < i; ++j)
122 printf("%.2x ", d[j]);
123 printf("\n");
124}
125
126int
127adb_write(unsigned char *d, int i)
128{
129 int j;
130 unsigned x;
131
132 if ((ADB_B & 8) == 0) {
133 printf("r: ");
134 adb_readin();
135 }
136 for (;;) {
137 ADB_ACR = 0x1c;
138 eieio();
139 ADB_SR = d[0];
140 eieio();
141 ADB_B &= ~0x20;
142 eieio();
143 if (ADB_B & 8)
144 break;
145 ADB_ACR = 0xc;
146 eieio();
147 ADB_B |= 0x20;
148 eieio();
149 adb_readin();
150 }
151 adb_wait();
152 for (j = 1; j < i; ++j) {
153 ADB_SR = d[j];
154 eieio();
155 ADB_B ^= 0x10;
156 eieio();
157 if (adb_wait() < 0)
158 break;
159 }
160 ADB_ACR = 0xc;
161 eieio();
162 x = ADB_SR;
163 eieio();
164 ADB_B |= 0x30;
165 return j;
166}
167
168void
169adbcmds(void)
170{
171 char cmd;
172 unsigned rtcu, rtcl, dec, pdec, x;
173 int i, j;
174 unsigned char d[64];
175
176 cmd = skipbl();
177 switch (cmd) {
178 case 't':
179 for (;;) {
180 rtcl = get_rtcl();
181 rtcu = get_rtcu();
182 dec = get_dec();
183 printf("rtc u=%u l=%u dec=%x (%d = %d.%.7d)\n",
184 rtcu, rtcl, dec, pdec - dec, (pdec - dec) / 1000000000,
185 ((pdec - dec) % 1000000000) / 100);
186 pdec = dec;
187 if (cmd == 'x')
188 break;
189 while (xmon_read(stdin, &cmd, 1) != 1)
190 ;
191 }
192 break;
193 case 'r':
194 init_adb_log();
195 while (adb_bitwait(8, 0, 0, 0) == 0)
196 adb_readin();
197 break;
198 case 'w':
199 i = 0;
200 while (scanhex(&x))
201 d[i++] = x;
202 init_adb_log();
203 j = adb_write(d, i);
204 printf("sent %d bytes\n", j);
205 while (adb_bitwait(8, 0, 0, 0) == 0)
206 adb_readin();
207 break;
208 case 'l':
209 dump_adb_log();
210 break;
211 }
212}
diff --git a/arch/ppc/xmon/ansidecl.h b/arch/ppc/xmon/ansidecl.h
new file mode 100644
index 000000000000..c9b9f0929e9e
--- /dev/null
+++ b/arch/ppc/xmon/ansidecl.h
@@ -0,0 +1,141 @@
1/* ANSI and traditional C compatibility macros
2 Copyright 1991, 1992 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 2 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19/* ANSI and traditional C compatibility macros
20
21 ANSI C is assumed if __STDC__ is #defined.
22
23 Macro ANSI C definition Traditional C definition
24 ----- ---- - ---------- ----------- - ----------
25 PTR `void *' `char *'
26 LONG_DOUBLE `long double' `double'
27 VOLATILE `volatile' `'
28 SIGNED `signed' `'
29 PTRCONST `void *const' `char *'
30 ANSI_PROTOTYPES 1 not defined
31
32 CONST is also defined, but is obsolete. Just use const.
33
34 DEFUN (name, arglist, args)
35
36 Defines function NAME.
37
38 ARGLIST lists the arguments, separated by commas and enclosed in
39 parentheses. ARGLIST becomes the argument list in traditional C.
40
41 ARGS list the arguments with their types. It becomes a prototype in
42 ANSI C, and the type declarations in traditional C. Arguments should
43 be separated with `AND'. For functions with a variable number of
44 arguments, the last thing listed should be `DOTS'.
45
46 DEFUN_VOID (name)
47
48 Defines a function NAME, which takes no arguments.
49
50 obsolete -- EXFUN (name, (prototype)) -- obsolete.
51
52 Replaced by PARAMS. Do not use; will disappear someday soon.
53 Was used in external function declarations.
54 In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in
55 parentheses). In traditional C it is `NAME()'.
56 For a function that takes no arguments, PROTOTYPE should be `(void)'.
57
58 PARAMS ((args))
59
60 We could use the EXFUN macro to handle prototype declarations, but
61 the name is misleading and the result is ugly. So we just define a
62 simple macro to handle the parameter lists, as in:
63
64 static int foo PARAMS ((int, char));
65
66 This produces: `static int foo();' or `static int foo (int, char);'
67
68 EXFUN would have done it like this:
69
70 static int EXFUN (foo, (int, char));
71
72 but the function is not external...and it's hard to visually parse
73 the function name out of the mess. EXFUN should be considered
74 obsolete; new code should be written to use PARAMS.
75
76 For example:
77 extern int printf PARAMS ((CONST char *format DOTS));
78 int DEFUN(fprintf, (stream, format),
79 FILE *stream AND CONST char *format DOTS) { ... }
80 void DEFUN_VOID(abort) { ... }
81*/
82
83#ifndef _ANSIDECL_H
84
85#define _ANSIDECL_H 1
86
87
88/* Every source file includes this file,
89 so they will all get the switch for lint. */
90/* LINTLIBRARY */
91
92
93#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32)
94/* All known AIX compilers implement these things (but don't always
95 define __STDC__). The RISC/OS MIPS compiler defines these things
96 in SVR4 mode, but does not define __STDC__. */
97
98#define PTR void *
99#define PTRCONST void *CONST
100#define LONG_DOUBLE long double
101
102#define AND ,
103#define NOARGS void
104#define CONST const
105#define VOLATILE volatile
106#define SIGNED signed
107#define DOTS , ...
108
109#define EXFUN(name, proto) name proto
110#define DEFUN(name, arglist, args) name(args)
111#define DEFUN_VOID(name) name(void)
112
113#define PROTO(type, name, arglist) type name arglist
114#define PARAMS(paramlist) paramlist
115#define ANSI_PROTOTYPES 1
116
117#else /* Not ANSI C. */
118
119#define PTR char *
120#define PTRCONST PTR
121#define LONG_DOUBLE double
122
123#define AND ;
124#define NOARGS
125#define CONST
126#ifndef const /* some systems define it in header files for non-ansi mode */
127#define const
128#endif
129#define VOLATILE
130#define SIGNED
131#define DOTS
132
133#define EXFUN(name, proto) name()
134#define DEFUN(name, arglist, args) name arglist args;
135#define DEFUN_VOID(name) name()
136#define PROTO(type, name, arglist) type name ()
137#define PARAMS(paramlist) ()
138
139#endif /* ANSI C. */
140
141#endif /* ansidecl.h */
diff --git a/arch/ppc/xmon/nonstdio.h b/arch/ppc/xmon/nonstdio.h
new file mode 100644
index 000000000000..0240bc573c96
--- /dev/null
+++ b/arch/ppc/xmon/nonstdio.h
@@ -0,0 +1,22 @@
1typedef int FILE;
2extern FILE *xmon_stdin, *xmon_stdout;
3#define EOF (-1)
4#define stdin xmon_stdin
5#define stdout xmon_stdout
6#define printf xmon_printf
7#define fprintf xmon_fprintf
8#define fputs xmon_fputs
9#define fgets xmon_fgets
10#define putchar xmon_putchar
11#define getchar xmon_getchar
12#define putc xmon_putc
13#define getc xmon_getc
14#define fopen(n, m) NULL
15#define fflush(f) do {} while (0)
16#define fclose(f) do {} while (0)
17extern char *fgets(char *, int, void *);
18extern void xmon_fprintf(void *, const char *, ...);
19extern void xmon_sprintf(char *, const char *, ...);
20extern void xmon_puts(char*);
21
22#define perror(s) printf("%s: no files!\n", (s))
diff --git a/arch/ppc/xmon/ppc-dis.c b/arch/ppc/xmon/ppc-dis.c
new file mode 100644
index 000000000000..798ac1a677f6
--- /dev/null
+++ b/arch/ppc/xmon/ppc-dis.c
@@ -0,0 +1,190 @@
1/* ppc-dis.c -- Disassemble PowerPC instructions
2 Copyright 1994 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Cygnus Support
4
5This file is part of GDB, GAS, and the GNU binutils.
6
7GDB, GAS, and the GNU binutils are free software; you can redistribute
8them and/or modify them under the terms of the GNU General Public
9License as published by the Free Software Foundation; either version
102, or (at your option) any later version.
11
12GDB, GAS, and the GNU binutils are distributed in the hope that they
13will be useful, but WITHOUT ANY WARRANTY; without even the implied
14warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15the GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this file; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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/* Print a big endian PowerPC instruction. For convenience, also
31 disassemble instructions supported by the Motorola PowerPC 601. */
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/* Print a PowerPC or POWER instruction. */
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 /* Get the major opcode of the instruction. */
51 op = PPC_OP (insn);
52
53 /* Find the first match in the opcode table. We could speed this up
54 a bit by doing a binary search on the major opcode. */
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 /* Make two passes over the operands. First see if any of them
76 have extraction functions, and, if they do, make sure the
77 instruction is valid. */
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 /* The instruction is valid. */
89 fprintf(out, "%s", opcode->name);
90 if (opcode->operands[0] != 0)
91 fprintf(out, "\t");
92
93 /* Now extract and print the operands. */
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 /* Operands that are marked FAKE are simply ignored. We
103 already made sure that the extract function considered
104 the instruction to be valid. */
105 if ((operand->flags & PPC_OPERAND_FAKE) != 0)
106 continue;
107
108 /* Extract the value from the instruction. */
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 /* If the operand is optional, and the value is zero, don't
120 print anything. */
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 /* Print the operand as directed by the flags. */
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 /* We have found and printed an instruction; return. */
183 return 4;
184 }
185
186 /* We could not find a match. */
187 fprintf(out, ".long 0x%lx", insn);
188
189 return 4;
190}
diff --git a/arch/ppc/xmon/ppc-opc.c b/arch/ppc/xmon/ppc-opc.c
new file mode 100644
index 000000000000..533a6c9973d4
--- /dev/null
+++ b/arch/ppc/xmon/ppc-opc.c
@@ -0,0 +1,2721 @@
1/* ppc-opc.c -- PowerPC opcode list
2 Copyright 1994 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Cygnus Support
4
5This file is part of GDB, GAS, and the GNU binutils.
6
7GDB, GAS, and the GNU binutils are free software; you can redistribute
8them and/or modify them under the terms of the GNU General Public
9License as published by the Free Software Foundation; either version
102, or (at your option) any later version.
11
12GDB, GAS, and the GNU binutils are distributed in the hope that they
13will be useful, but WITHOUT ANY WARRANTY; without even the implied
14warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15the GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this file; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21#include <linux/posix_types.h>
22#include "ansidecl.h"
23#include "ppc.h"
24
25/* This file holds the PowerPC opcode table. The opcode table
26 includes almost all of the extended instruction mnemonics. This
27 permits the disassembler to use them, and simplifies the assembler
28 logic, at the cost of increasing the table size. The table is
29 strictly constant data, so the compiler should be able to put it in
30 the .text section.
31
32 This file also holds the operand table. All knowledge about
33 inserting operands into instructions and vice-versa is kept in this
34 file. */
35
36/* Local insertion and extraction functions. */
37
38static unsigned long insert_bat PARAMS ((unsigned long, long, const char **));
39static long extract_bat PARAMS ((unsigned long, int *));
40static unsigned long insert_bba PARAMS ((unsigned long, long, const char **));
41static long extract_bba PARAMS ((unsigned long, int *));
42static unsigned long insert_bd PARAMS ((unsigned long, long, const char **));
43static long extract_bd PARAMS ((unsigned long, int *));
44static unsigned long insert_bdm PARAMS ((unsigned long, long, const char **));
45static long extract_bdm PARAMS ((unsigned long, int *));
46static unsigned long insert_bdp PARAMS ((unsigned long, long, const char **));
47static long extract_bdp PARAMS ((unsigned long, int *));
48static unsigned long insert_bo PARAMS ((unsigned long, long, const char **));
49static long extract_bo PARAMS ((unsigned long, int *));
50static unsigned long insert_boe PARAMS ((unsigned long, long, const char **));
51static long extract_boe PARAMS ((unsigned long, int *));
52static unsigned long insert_ds PARAMS ((unsigned long, long, const char **));
53static long extract_ds PARAMS ((unsigned long, int *));
54static unsigned long insert_li PARAMS ((unsigned long, long, const char **));
55static long extract_li PARAMS ((unsigned long, int *));
56static unsigned long insert_mbe PARAMS ((unsigned long, long, const char **));
57static long extract_mbe PARAMS ((unsigned long, int *));
58static unsigned long insert_mb6 PARAMS ((unsigned long, long, const char **));
59static long extract_mb6 PARAMS ((unsigned long, int *));
60static unsigned long insert_nb PARAMS ((unsigned long, long, const char **));
61static long extract_nb PARAMS ((unsigned long, int *));
62static unsigned long insert_nsi PARAMS ((unsigned long, long, const char **));
63static long extract_nsi PARAMS ((unsigned long, int *));
64static unsigned long insert_ral PARAMS ((unsigned long, long, const char **));
65static unsigned long insert_ram PARAMS ((unsigned long, long, const char **));
66static unsigned long insert_ras PARAMS ((unsigned long, long, const char **));
67static unsigned long insert_rbs PARAMS ((unsigned long, long, const char **));
68static long extract_rbs PARAMS ((unsigned long, int *));
69static unsigned long insert_sh6 PARAMS ((unsigned long, long, const char **));
70static long extract_sh6 PARAMS ((unsigned long, int *));
71static unsigned long insert_spr PARAMS ((unsigned long, long, const char **));
72static long extract_spr PARAMS ((unsigned long, int *));
73static unsigned long insert_tbr PARAMS ((unsigned long, long, const char **));
74static long extract_tbr PARAMS ((unsigned long, int *));
75
76/* The operands table.
77
78 The fields are bits, shift, signed, insert, extract, flags. */
79
80const struct powerpc_operand powerpc_operands[] =
81{
82 /* The zero index is used to indicate the end of the list of
83 operands. */
84#define UNUSED (0)
85 { 0, 0, NULL, NULL, 0 },
86
87 /* The BA field in an XL form instruction. */
88#define BA (1)
89#define BA_MASK (0x1f << 16)
90 { 5, 16, NULL, NULL, PPC_OPERAND_CR },
91
92 /* The BA field in an XL form instruction when it must be the same
93 as the BT field in the same instruction. */
94#define BAT (2)
95 { 5, 16, insert_bat, extract_bat, PPC_OPERAND_FAKE },
96
97 /* The BB field in an XL form instruction. */
98#define BB (3)
99#define BB_MASK (0x1f << 11)
100 { 5, 11, NULL, NULL, PPC_OPERAND_CR },
101
102 /* The BB field in an XL form instruction when it must be the same
103 as the BA field in the same instruction. */
104#define BBA (4)
105 { 5, 11, insert_bba, extract_bba, PPC_OPERAND_FAKE },
106
107 /* The BD field in a B form instruction. The lower two bits are
108 forced to zero. */
109#define BD (5)
110 { 16, 0, insert_bd, extract_bd, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
111
112 /* The BD field in a B form instruction when absolute addressing is
113 used. */
114#define BDA (6)
115 { 16, 0, insert_bd, extract_bd, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
116
117 /* The BD field in a B form instruction when the - modifier is used.
118 This sets the y bit of the BO field appropriately. */
119#define BDM (7)
120 { 16, 0, insert_bdm, extract_bdm,
121 PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
122
123 /* The BD field in a B form instruction when the - modifier is used
124 and absolute address is used. */
125#define BDMA (8)
126 { 16, 0, insert_bdm, extract_bdm,
127 PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
128
129 /* The BD field in a B form instruction when the + modifier is used.
130 This sets the y bit of the BO field appropriately. */
131#define BDP (9)
132 { 16, 0, insert_bdp, extract_bdp,
133 PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
134
135 /* The BD field in a B form instruction when the + modifier is used
136 and absolute addressing is used. */
137#define BDPA (10)
138 { 16, 0, insert_bdp, extract_bdp,
139 PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
140
141 /* The BF field in an X or XL form instruction. */
142#define BF (11)
143 { 3, 23, NULL, NULL, PPC_OPERAND_CR },
144
145 /* An optional BF field. This is used for comparison instructions,
146 in which an omitted BF field is taken as zero. */
147#define OBF (12)
148 { 3, 23, NULL, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
149
150 /* The BFA field in an X or XL form instruction. */
151#define BFA (13)
152 { 3, 18, NULL, NULL, PPC_OPERAND_CR },
153
154 /* The BI field in a B form or XL form instruction. */
155#define BI (14)
156#define BI_MASK (0x1f << 16)
157 { 5, 16, NULL, NULL, PPC_OPERAND_CR },
158
159 /* The BO field in a B form instruction. Certain values are
160 illegal. */
161#define BO (15)
162#define BO_MASK (0x1f << 21)
163 { 5, 21, insert_bo, extract_bo, 0 },
164
165 /* The BO field in a B form instruction when the + or - modifier is
166 used. This is like the BO field, but it must be even. */
167#define BOE (16)
168 { 5, 21, insert_boe, extract_boe, 0 },
169
170 /* The BT field in an X or XL form instruction. */
171#define BT (17)
172 { 5, 21, NULL, NULL, PPC_OPERAND_CR },
173
174 /* The condition register number portion of the BI field in a B form
175 or XL form instruction. This is used for the extended
176 conditional branch mnemonics, which set the lower two bits of the
177 BI field. This field is optional. */
178#define CR (18)
179 { 3, 18, NULL, NULL, PPC_OPERAND_CR | PPC_OPERAND_OPTIONAL },
180
181 /* The D field in a D form instruction. This is a displacement off
182 a register, and implies that the next operand is a register in
183 parentheses. */
184#define D (19)
185 { 16, 0, NULL, NULL, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
186
187 /* The DS field in a DS form instruction. This is like D, but the
188 lower two bits are forced to zero. */
189#define DS (20)
190 { 16, 0, insert_ds, extract_ds, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
191
192 /* The FL1 field in a POWER SC form instruction. */
193#define FL1 (21)
194 { 4, 12, NULL, NULL, 0 },
195
196 /* The FL2 field in a POWER SC form instruction. */
197#define FL2 (22)
198 { 3, 2, NULL, NULL, 0 },
199
200 /* The FLM field in an XFL form instruction. */
201#define FLM (23)
202 { 8, 17, NULL, NULL, 0 },
203
204 /* The FRA field in an X or A form instruction. */
205#define FRA (24)
206#define FRA_MASK (0x1f << 16)
207 { 5, 16, NULL, NULL, PPC_OPERAND_FPR },
208
209 /* The FRB field in an X or A form instruction. */
210#define FRB (25)
211#define FRB_MASK (0x1f << 11)
212 { 5, 11, NULL, NULL, PPC_OPERAND_FPR },
213
214 /* The FRC field in an A form instruction. */
215#define FRC (26)
216#define FRC_MASK (0x1f << 6)
217 { 5, 6, NULL, NULL, PPC_OPERAND_FPR },
218
219 /* The FRS field in an X form instruction or the FRT field in a D, X
220 or A form instruction. */
221#define FRS (27)
222#define FRT (FRS)
223 { 5, 21, NULL, NULL, PPC_OPERAND_FPR },
224
225 /* The FXM field in an XFX instruction. */
226#define FXM (28)
227#define FXM_MASK (0xff << 12)
228 { 8, 12, NULL, NULL, 0 },
229
230 /* The L field in a D or X form instruction. */
231#define L (29)
232 { 1, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
233
234 /* The LEV field in a POWER SC form instruction. */
235#define LEV (30)
236 { 7, 5, NULL, NULL, 0 },
237
238 /* The LI field in an I form instruction. The lower two bits are
239 forced to zero. */
240#define LI (31)
241 { 26, 0, insert_li, extract_li, PPC_OPERAND_RELATIVE | PPC_OPERAND_SIGNED },
242
243 /* The LI field in an I form instruction when used as an absolute
244 address. */
245#define LIA (32)
246 { 26, 0, insert_li, extract_li, PPC_OPERAND_ABSOLUTE | PPC_OPERAND_SIGNED },
247
248 /* The MB field in an M form instruction. */
249#define MB (33)
250#define MB_MASK (0x1f << 6)
251 { 5, 6, NULL, NULL, 0 },
252
253 /* The ME field in an M form instruction. */
254#define ME (34)
255#define ME_MASK (0x1f << 1)
256 { 5, 1, NULL, NULL, 0 },
257
258 /* The MB and ME fields in an M form instruction expressed a single
259 operand which is a bitmask indicating which bits to select. This
260 is a two operand form using PPC_OPERAND_NEXT. See the
261 description in opcode/ppc.h for what this means. */
262#define MBE (35)
263 { 5, 6, NULL, NULL, PPC_OPERAND_OPTIONAL | PPC_OPERAND_NEXT },
264 { 32, 0, insert_mbe, extract_mbe, 0 },
265
266 /* The MB or ME field in an MD or MDS form instruction. The high
267 bit is wrapped to the low end. */
268#define MB6 (37)
269#define ME6 (MB6)
270#define MB6_MASK (0x3f << 5)
271 { 6, 5, insert_mb6, extract_mb6, 0 },
272
273 /* The NB field in an X form instruction. The value 32 is stored as
274 0. */
275#define NB (38)
276 { 6, 11, insert_nb, extract_nb, 0 },
277
278 /* The NSI field in a D form instruction. This is the same as the
279 SI field, only negated. */
280#define NSI (39)
281 { 16, 0, insert_nsi, extract_nsi,
282 PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED },
283
284 /* The RA field in an D, DS, X, XO, M, or MDS form instruction. */
285#define RA (40)
286#define RA_MASK (0x1f << 16)
287 { 5, 16, NULL, NULL, PPC_OPERAND_GPR },
288
289 /* The RA field in a D or X form instruction which is an updating
290 load, which means that the RA field may not be zero and may not
291 equal the RT field. */
292#define RAL (41)
293 { 5, 16, insert_ral, NULL, PPC_OPERAND_GPR },
294
295 /* The RA field in an lmw instruction, which has special value
296 restrictions. */
297#define RAM (42)
298 { 5, 16, insert_ram, NULL, PPC_OPERAND_GPR },
299
300 /* The RA field in a D or X form instruction which is an updating
301 store or an updating floating point load, which means that the RA
302 field may not be zero. */
303#define RAS (43)
304 { 5, 16, insert_ras, NULL, PPC_OPERAND_GPR },
305
306 /* The RB field in an X, XO, M, or MDS form instruction. */
307#define RB (44)
308#define RB_MASK (0x1f << 11)
309 { 5, 11, NULL, NULL, PPC_OPERAND_GPR },
310
311 /* The RB field in an X form instruction when it must be the same as
312 the RS field in the instruction. This is used for extended
313 mnemonics like mr. */
314#define RBS (45)
315 { 5, 1, insert_rbs, extract_rbs, PPC_OPERAND_FAKE },
316
317 /* The RS field in a D, DS, X, XFX, XS, M, MD or MDS form
318 instruction or the RT field in a D, DS, X, XFX or XO form
319 instruction. */
320#define RS (46)
321#define RT (RS)
322#define RT_MASK (0x1f << 21)
323 { 5, 21, NULL, NULL, PPC_OPERAND_GPR },
324
325 /* The SH field in an X or M form instruction. */
326#define SH (47)
327#define SH_MASK (0x1f << 11)
328 { 5, 11, NULL, NULL, 0 },
329
330 /* The SH field in an MD form instruction. This is split. */
331#define SH6 (48)
332#define SH6_MASK ((0x1f << 11) | (1 << 1))
333 { 6, 1, insert_sh6, extract_sh6, 0 },
334
335 /* The SI field in a D form instruction. */
336#define SI (49)
337 { 16, 0, NULL, NULL, PPC_OPERAND_SIGNED },
338
339 /* The SI field in a D form instruction when we accept a wide range
340 of positive values. */
341#define SISIGNOPT (50)
342 { 16, 0, NULL, NULL, PPC_OPERAND_SIGNED | PPC_OPERAND_SIGNOPT },
343
344 /* The SPR field in an XFX form instruction. This is flipped--the
345 lower 5 bits are stored in the upper 5 and vice- versa. */
346#define SPR (51)
347#define SPR_MASK (0x3ff << 11)
348 { 10, 11, insert_spr, extract_spr, 0 },
349
350 /* The BAT index number in an XFX form m[ft]ibat[lu] instruction. */
351#define SPRBAT (52)
352#define SPRBAT_MASK (0x3 << 17)
353 { 2, 17, NULL, NULL, 0 },
354
355 /* The SPRG register number in an XFX form m[ft]sprg instruction. */
356#define SPRG (53)
357#define SPRG_MASK (0x3 << 16)
358 { 2, 16, NULL, NULL, 0 },
359
360 /* The SR field in an X form instruction. */
361#define SR (54)
362 { 4, 16, NULL, NULL, 0 },
363
364 /* The SV field in a POWER SC form instruction. */
365#define SV (55)
366 { 14, 2, NULL, NULL, 0 },
367
368 /* The TBR field in an XFX form instruction. This is like the SPR
369 field, but it is optional. */
370#define TBR (56)
371 { 10, 11, insert_tbr, extract_tbr, PPC_OPERAND_OPTIONAL },
372
373 /* The TO field in a D or X form instruction. */
374#define TO (57)
375#define TO_MASK (0x1f << 21)
376 { 5, 21, NULL, NULL, 0 },
377
378 /* The U field in an X form instruction. */
379#define U (58)
380 { 4, 12, NULL, NULL, 0 },
381
382 /* The UI field in a D form instruction. */
383#define UI (59)
384 { 16, 0, NULL, NULL, 0 },
385};
386
387/* The functions used to insert and extract complicated operands. */
388
389/* The BA field in an XL form instruction when it must be the same as
390 the BT field in the same instruction. This operand is marked FAKE.
391 The insertion function just copies the BT field into the BA field,
392 and the extraction function just checks that the fields are the
393 same. */
394
395/*ARGSUSED*/
396static unsigned long
397insert_bat(unsigned long insn, long value, const char **errmsg)
398{
399 return insn | (((insn >> 21) & 0x1f) << 16);
400}
401
402static long
403extract_bat(unsigned long insn, int *invalid)
404{
405 if (invalid != (int *) NULL
406 && ((insn >> 21) & 0x1f) != ((insn >> 16) & 0x1f))
407 *invalid = 1;
408 return 0;
409}
410
411/* The BB field in an XL form instruction when it must be the same as
412 the BA field in the same instruction. This operand is marked FAKE.
413 The insertion function just copies the BA field into the BB field,
414 and the extraction function just checks that the fields are the
415 same. */
416
417/*ARGSUSED*/
418static unsigned long
419insert_bba(unsigned long insn, long value, const char **errmsg)
420{
421 return insn | (((insn >> 16) & 0x1f) << 11);
422}
423
424static long
425extract_bba(unsigned long insn, int *invalid)
426{
427 if (invalid != (int *) NULL
428 && ((insn >> 16) & 0x1f) != ((insn >> 11) & 0x1f))
429 *invalid = 1;
430 return 0;
431}
432
433/* The BD field in a B form instruction. The lower two bits are
434 forced to zero. */
435
436/*ARGSUSED*/
437static unsigned long
438insert_bd(unsigned long insn, long value, const char **errmsg)
439{
440 return insn | (value & 0xfffc);
441}
442
443/*ARGSUSED*/
444static long
445extract_bd(unsigned long insn, int *invalid)
446{
447 if ((insn & 0x8000) != 0)
448 return (insn & 0xfffc) - 0x10000;
449 else
450 return insn & 0xfffc;
451}
452
453/* The BD field in a B form instruction when the - modifier is used.
454 This modifier means that the branch is not expected to be taken.
455 We must set the y bit of the BO field to 1 if the offset is
456 negative. When extracting, we require that the y bit be 1 and that
457 the offset be positive, since if the y bit is 0 we just want to
458 print the normal form of the instruction. */
459
460/*ARGSUSED*/
461static unsigned long
462insert_bdm(unsigned long insn, long value, const char **errmsg)
463{
464 if ((value & 0x8000) != 0)
465 insn |= 1 << 21;
466 return insn | (value & 0xfffc);
467}
468
469static long
470extract_bdm(unsigned long insn, int *invalid)
471{
472 if (invalid != (int *) NULL
473 && ((insn & (1 << 21)) == 0
474 || (insn & (1 << 15)) == 0))
475 *invalid = 1;
476 if ((insn & 0x8000) != 0)
477 return (insn & 0xfffc) - 0x10000;
478 else
479 return insn & 0xfffc;
480}
481
482/* The BD field in a B form instruction when the + modifier is used.
483 This is like BDM, above, except that the branch is expected to be
484 taken. */
485
486/*ARGSUSED*/
487static unsigned long
488insert_bdp(unsigned long insn, long value, const char **errmsg)
489{
490 if ((value & 0x8000) == 0)
491 insn |= 1 << 21;
492 return insn | (value & 0xfffc);
493}
494
495static long
496extract_bdp(unsigned long insn, int *invalid)
497{
498 if (invalid != (int *) NULL
499 && ((insn & (1 << 21)) == 0
500 || (insn & (1 << 15)) != 0))
501 *invalid = 1;
502 if ((insn & 0x8000) != 0)
503 return (insn & 0xfffc) - 0x10000;
504 else
505 return insn & 0xfffc;
506}
507
508/* Check for legal values of a BO field. */
509
510static int
511valid_bo (long value)
512{
513 /* Certain encodings have bits that are required to be zero. These
514 are (z must be zero, y may be anything):
515 001zy
516 011zy
517 1z00y
518 1z01y
519 1z1zz
520 */
521 switch (value & 0x14)
522 {
523 default:
524 case 0:
525 return 1;
526 case 0x4:
527 return (value & 0x2) == 0;
528 case 0x10:
529 return (value & 0x8) == 0;
530 case 0x14:
531 return value == 0x14;
532 }
533}
534
535/* The BO field in a B form instruction. Warn about attempts to set
536 the field to an illegal value. */
537
538static unsigned long
539insert_bo(unsigned long insn, long value, const char **errmsg)
540{
541 if (errmsg != (const char **) NULL
542 && ! valid_bo (value))
543 *errmsg = "invalid conditional option";
544 return insn | ((value & 0x1f) << 21);
545}
546
547static long
548extract_bo(unsigned long insn, int *invalid)
549{
550 long value;
551
552 value = (insn >> 21) & 0x1f;
553 if (invalid != (int *) NULL
554 && ! valid_bo (value))
555 *invalid = 1;
556 return value;
557}
558
559/* The BO field in a B form instruction when the + or - modifier is
560 used. This is like the BO field, but it must be even. When
561 extracting it, we force it to be even. */
562
563static unsigned long
564insert_boe(unsigned long insn, long value, const char **errmsg)
565{
566 if (errmsg != (const char **) NULL)
567 {
568 if (! valid_bo (value))
569 *errmsg = "invalid conditional option";
570 else if ((value & 1) != 0)
571 *errmsg = "attempt to set y bit when using + or - modifier";
572 }
573 return insn | ((value & 0x1f) << 21);
574}
575
576static long
577extract_boe(unsigned long insn, int *invalid)
578{
579 long value;
580
581 value = (insn >> 21) & 0x1f;
582 if (invalid != (int *) NULL
583 && ! valid_bo (value))
584 *invalid = 1;
585 return value & 0x1e;
586}
587
588/* The DS field in a DS form instruction. This is like D, but the
589 lower two bits are forced to zero. */
590
591/*ARGSUSED*/
592static unsigned long
593insert_ds(unsigned long insn, long value, const char **errmsg)
594{
595 return insn | (value & 0xfffc);
596}
597
598/*ARGSUSED*/
599static long
600extract_ds(unsigned long insn, int *invalid)
601{
602 if ((insn & 0x8000) != 0)
603 return (insn & 0xfffc) - 0x10000;
604 else
605 return insn & 0xfffc;
606}
607
608/* The LI field in an I form instruction. The lower two bits are
609 forced to zero. */
610
611/*ARGSUSED*/
612static unsigned long
613insert_li(unsigned long insn, long value, const char **errmsg)
614{
615 return insn | (value & 0x3fffffc);
616}
617
618/*ARGSUSED*/
619static long
620extract_li(unsigned long insn, int *invalid)
621{
622 if ((insn & 0x2000000) != 0)
623 return (insn & 0x3fffffc) - 0x4000000;
624 else
625 return insn & 0x3fffffc;
626}
627
628/* The MB and ME fields in an M form instruction expressed as a single
629 operand which is itself a bitmask. The extraction function always
630 marks it as invalid, since we never want to recognize an
631 instruction which uses a field of this type. */
632
633static unsigned long
634insert_mbe(unsigned long insn, long value, const char **errmsg)
635{
636 unsigned long uval;
637 int mb, me;
638
639 uval = value;
640
641 if (uval == 0)
642 {
643 if (errmsg != (const char **) NULL)
644 *errmsg = "illegal bitmask";
645 return insn;
646 }
647
648 me = 31;
649 while ((uval & 1) == 0)
650 {
651 uval >>= 1;
652 --me;
653 }
654
655 mb = me;
656 uval >>= 1;
657 while ((uval & 1) != 0)
658 {
659 uval >>= 1;
660 --mb;
661 }
662
663 if (uval != 0)
664 {
665 if (errmsg != (const char **) NULL)
666 *errmsg = "illegal bitmask";
667 }
668
669 return insn | (mb << 6) | (me << 1);
670}
671
672static long
673extract_mbe(unsigned long insn, int *invalid)
674{
675 long ret;
676 int mb, me;
677 int i;
678
679 if (invalid != (int *) NULL)
680 *invalid = 1;
681
682 ret = 0;
683 mb = (insn >> 6) & 0x1f;
684 me = (insn >> 1) & 0x1f;
685 for (i = mb; i < me; i++)
686 ret |= 1 << (31 - i);
687 return ret;
688}
689
690/* The MB or ME field in an MD or MDS form instruction. The high bit
691 is wrapped to the low end. */
692
693/*ARGSUSED*/
694static unsigned long
695insert_mb6(unsigned long insn, long value, const char **errmsg)
696{
697 return insn | ((value & 0x1f) << 6) | (value & 0x20);
698}
699
700/*ARGSUSED*/
701static long
702extract_mb6(unsigned long insn, int *invalid)
703{
704 return ((insn >> 6) & 0x1f) | (insn & 0x20);
705}
706
707/* The NB field in an X form instruction. The value 32 is stored as
708 0. */
709
710static unsigned long
711insert_nb(unsigned long insn, long value, const char **errmsg)
712{
713 if (value < 0 || value > 32)
714 *errmsg = "value out of range";
715 if (value == 32)
716 value = 0;
717 return insn | ((value & 0x1f) << 11);
718}
719
720/*ARGSUSED*/
721static long
722extract_nb(unsigned long insn, int *invalid)
723{
724 long ret;
725
726 ret = (insn >> 11) & 0x1f;
727 if (ret == 0)
728 ret = 32;
729 return ret;
730}
731
732/* The NSI field in a D form instruction. This is the same as the SI
733 field, only negated. The extraction function always marks it as
734 invalid, since we never want to recognize an instruction which uses
735 a field of this type. */
736
737/*ARGSUSED*/
738static unsigned long
739insert_nsi(unsigned long insn, long value, const char **errmsg)
740{
741 return insn | ((- value) & 0xffff);
742}
743
744static long
745extract_nsi(unsigned long insn, int *invalid)
746{
747 if (invalid != (int *) NULL)
748 *invalid = 1;
749 if ((insn & 0x8000) != 0)
750 return - ((insn & 0xffff) - 0x10000);
751 else
752 return - (insn & 0xffff);
753}
754
755/* The RA field in a D or X form instruction which is an updating
756 load, which means that the RA field may not be zero and may not
757 equal the RT field. */
758
759static unsigned long
760insert_ral(unsigned long insn, long value, const char **errmsg)
761{
762 if (value == 0
763 || value == ((insn >> 21) & 0x1f))
764 *errmsg = "invalid register operand when updating";
765 return insn | ((value & 0x1f) << 16);
766}
767
768/* The RA field in an lmw instruction, which has special value
769 restrictions. */
770
771static unsigned long
772insert_ram(unsigned long insn, long value, const char **errmsg)
773{
774 if (value >= ((insn >> 21) & 0x1f))
775 *errmsg = "index register in load range";
776 return insn | ((value & 0x1f) << 16);
777}
778
779/* The RA field in a D or X form instruction which is an updating
780 store or an updating floating point load, which means that the RA
781 field may not be zero. */
782
783static unsigned long
784insert_ras(unsigned long insn, long value, const char **errmsg)
785{
786 if (value == 0)
787 *errmsg = "invalid register operand when updating";
788 return insn | ((value & 0x1f) << 16);
789}
790
791/* The RB field in an X form instruction when it must be the same as
792 the RS field in the instruction. This is used for extended
793 mnemonics like mr. This operand is marked FAKE. The insertion
794 function just copies the BT field into the BA field, and the
795 extraction function just checks that the fields are the same. */
796
797/*ARGSUSED*/
798static unsigned long
799insert_rbs(unsigned long insn, long value, const char **errmsg)
800{
801 return insn | (((insn >> 21) & 0x1f) << 11);
802}
803
804static long
805extract_rbs(unsigned long insn, int *invalid)
806{
807 if (invalid != (int *) NULL
808 && ((insn >> 21) & 0x1f) != ((insn >> 11) & 0x1f))
809 *invalid = 1;
810 return 0;
811}
812
813/* The SH field in an MD form instruction. This is split. */
814
815/*ARGSUSED*/
816static unsigned long
817insert_sh6(unsigned long insn, long value, const char **errmsg)
818{
819 return insn | ((value & 0x1f) << 11) | ((value & 0x20) >> 4);
820}
821
822/*ARGSUSED*/
823static long
824extract_sh6(unsigned long insn, int *invalid)
825{
826 return ((insn >> 11) & 0x1f) | ((insn << 4) & 0x20);
827}
828
829/* The SPR field in an XFX form instruction. This is flipped--the
830 lower 5 bits are stored in the upper 5 and vice- versa. */
831
832static unsigned long
833insert_spr(unsigned long insn, long value, const char **errmsg)
834{
835 return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
836}
837
838static long
839extract_spr(unsigned long insn, int *invalid)
840{
841 return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
842}
843
844/* The TBR field in an XFX instruction. This is just like SPR, but it
845 is optional. When TBR is omitted, it must be inserted as 268 (the
846 magic number of the TB register). These functions treat 0
847 (indicating an omitted optional operand) as 268. This means that
848 ``mftb 4,0'' is not handled correctly. This does not matter very
849 much, since the architecture manual does not define mftb as
850 accepting any values other than 268 or 269. */
851
852#define TB (268)
853
854static unsigned long
855insert_tbr(unsigned long insn, long value, const char **errmsg)
856{
857 if (value == 0)
858 value = TB;
859 return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);
860}
861
862static long
863extract_tbr(unsigned long insn, int *invalid)
864{
865 long ret;
866
867 ret = ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
868 if (ret == TB)
869 ret = 0;
870 return ret;
871}
872
873/* Macros used to form opcodes. */
874
875/* The main opcode. */
876#define OP(x) (((x) & 0x3f) << 26)
877#define OP_MASK OP (0x3f)
878
879/* The main opcode combined with a trap code in the TO field of a D
880 form instruction. Used for extended mnemonics for the trap
881 instructions. */
882#define OPTO(x,to) (OP (x) | (((to) & 0x1f) << 21))
883#define OPTO_MASK (OP_MASK | TO_MASK)
884
885/* The main opcode combined with a comparison size bit in the L field
886 of a D form or X form instruction. Used for extended mnemonics for
887 the comparison instructions. */
888#define OPL(x,l) (OP (x) | (((l) & 1) << 21))
889#define OPL_MASK OPL (0x3f,1)
890
891/* An A form instruction. */
892#define A(op, xop, rc) (OP (op) | (((xop) & 0x1f) << 1) | ((rc) & 1))
893#define A_MASK A (0x3f, 0x1f, 1)
894
895/* An A_MASK with the FRB field fixed. */
896#define AFRB_MASK (A_MASK | FRB_MASK)
897
898/* An A_MASK with the FRC field fixed. */
899#define AFRC_MASK (A_MASK | FRC_MASK)
900
901/* An A_MASK with the FRA and FRC fields fixed. */
902#define AFRAFRC_MASK (A_MASK | FRA_MASK | FRC_MASK)
903
904/* A B form instruction. */
905#define B(op, aa, lk) (OP (op) | (((aa) & 1) << 1) | ((lk) & 1))
906#define B_MASK B (0x3f, 1, 1)
907
908/* A B form instruction setting the BO field. */
909#define BBO(op, bo, aa, lk) (B ((op), (aa), (lk)) | (((bo) & 0x1f) << 21))
910#define BBO_MASK BBO (0x3f, 0x1f, 1, 1)
911
912/* A BBO_MASK with the y bit of the BO field removed. This permits
913 matching a conditional branch regardless of the setting of the y
914 bit. */
915#define Y_MASK (1 << 21)
916#define BBOY_MASK (BBO_MASK &~ Y_MASK)
917
918/* A B form instruction setting the BO field and the condition bits of
919 the BI field. */
920#define BBOCB(op, bo, cb, aa, lk) \
921 (BBO ((op), (bo), (aa), (lk)) | (((cb) & 0x3) << 16))
922#define BBOCB_MASK BBOCB (0x3f, 0x1f, 0x3, 1, 1)
923
924/* A BBOCB_MASK with the y bit of the BO field removed. */
925#define BBOYCB_MASK (BBOCB_MASK &~ Y_MASK)
926
927/* A BBOYCB_MASK in which the BI field is fixed. */
928#define BBOYBI_MASK (BBOYCB_MASK | BI_MASK)
929
930/* The main opcode mask with the RA field clear. */
931#define DRA_MASK (OP_MASK | RA_MASK)
932
933/* A DS form instruction. */
934#define DSO(op, xop) (OP (op) | ((xop) & 0x3))
935#define DS_MASK DSO (0x3f, 3)
936
937/* An M form instruction. */
938#define M(op, rc) (OP (op) | ((rc) & 1))
939#define M_MASK M (0x3f, 1)
940
941/* An M form instruction with the ME field specified. */
942#define MME(op, me, rc) (M ((op), (rc)) | (((me) & 0x1f) << 1))
943
944/* An M_MASK with the MB and ME fields fixed. */
945#define MMBME_MASK (M_MASK | MB_MASK | ME_MASK)
946
947/* An M_MASK with the SH and ME fields fixed. */
948#define MSHME_MASK (M_MASK | SH_MASK | ME_MASK)
949
950/* An MD form instruction. */
951#define MD(op, xop, rc) (OP (op) | (((xop) & 0x7) << 2) | ((rc) & 1))
952#define MD_MASK MD (0x3f, 0x7, 1)
953
954/* An MD_MASK with the MB field fixed. */
955#define MDMB_MASK (MD_MASK | MB6_MASK)
956
957/* An MD_MASK with the SH field fixed. */
958#define MDSH_MASK (MD_MASK | SH6_MASK)
959
960/* An MDS form instruction. */
961#define MDS(op, xop, rc) (OP (op) | (((xop) & 0xf) << 1) | ((rc) & 1))
962#define MDS_MASK MDS (0x3f, 0xf, 1)
963
964/* An MDS_MASK with the MB field fixed. */
965#define MDSMB_MASK (MDS_MASK | MB6_MASK)
966
967/* An SC form instruction. */
968#define SC(op, sa, lk) (OP (op) | (((sa) & 1) << 1) | ((lk) & 1))
969#define SC_MASK (OP_MASK | (0x3ff << 16) | (1 << 1) | 1)
970
971/* An X form instruction. */
972#define X(op, xop) (OP (op) | (((xop) & 0x3ff) << 1))
973
974/* An X form instruction with the RC bit specified. */
975#define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1))
976
977/* The mask for an X form instruction. */
978#define X_MASK XRC (0x3f, 0x3ff, 1)
979
980/* An X_MASK with the RA field fixed. */
981#define XRA_MASK (X_MASK | RA_MASK)
982
983/* An X_MASK with the RB field fixed. */
984#define XRB_MASK (X_MASK | RB_MASK)
985
986/* An X_MASK with the RT field fixed. */
987#define XRT_MASK (X_MASK | RT_MASK)
988
989/* An X_MASK with the RA and RB fields fixed. */
990#define XRARB_MASK (X_MASK | RA_MASK | RB_MASK)
991
992/* An X_MASK with the RT and RA fields fixed. */
993#define XRTRA_MASK (X_MASK | RT_MASK | RA_MASK)
994
995/* An X form comparison instruction. */
996#define XCMPL(op, xop, l) (X ((op), (xop)) | (((l) & 1) << 21))
997
998/* The mask for an X form comparison instruction. */
999#define XCMP_MASK (X_MASK | (1 << 22))
1000
1001/* The mask for an X form comparison instruction with the L field
1002 fixed. */
1003#define XCMPL_MASK (XCMP_MASK | (1 << 21))
1004
1005/* An X form trap instruction with the TO field specified. */
1006#define XTO(op, xop, to) (X ((op), (xop)) | (((to) & 0x1f) << 21))
1007#define XTO_MASK (X_MASK | TO_MASK)
1008
1009/* An XFL form instruction. */
1010#define XFL(op, xop, rc) (OP (op) | (((xop) & 0x3ff) << 1) | ((rc) & 1))
1011#define XFL_MASK (XFL (0x3f, 0x3ff, 1) | (1 << 25) | (1 << 16))
1012
1013/* An XL form instruction with the LK field set to 0. */
1014#define XL(op, xop) (OP (op) | (((xop) & 0x3ff) << 1))
1015
1016/* An XL form instruction which uses the LK field. */
1017#define XLLK(op, xop, lk) (XL ((op), (xop)) | ((lk) & 1))
1018
1019/* The mask for an XL form instruction. */
1020#define XL_MASK XLLK (0x3f, 0x3ff, 1)
1021
1022/* An XL form instruction which explicitly sets the BO field. */
1023#define XLO(op, bo, xop, lk) \
1024 (XLLK ((op), (xop), (lk)) | (((bo) & 0x1f) << 21))
1025#define XLO_MASK (XL_MASK | BO_MASK)
1026
1027/* An XL form instruction which explicitly sets the y bit of the BO
1028 field. */
1029#define XLYLK(op, xop, y, lk) (XLLK ((op), (xop), (lk)) | (((y) & 1) << 21))
1030#define XLYLK_MASK (XL_MASK | Y_MASK)
1031
1032/* An XL form instruction which sets the BO field and the condition
1033 bits of the BI field. */
1034#define XLOCB(op, bo, cb, xop, lk) \
1035 (XLO ((op), (bo), (xop), (lk)) | (((cb) & 3) << 16))
1036#define XLOCB_MASK XLOCB (0x3f, 0x1f, 0x3, 0x3ff, 1)
1037
1038/* An XL_MASK or XLYLK_MASK or XLOCB_MASK with the BB field fixed. */
1039#define XLBB_MASK (XL_MASK | BB_MASK)
1040#define XLYBB_MASK (XLYLK_MASK | BB_MASK)
1041#define XLBOCBBB_MASK (XLOCB_MASK | BB_MASK)
1042
1043/* An XL_MASK with the BO and BB fields fixed. */
1044#define XLBOBB_MASK (XL_MASK | BO_MASK | BB_MASK)
1045
1046/* An XL_MASK with the BO, BI and BB fields fixed. */
1047#define XLBOBIBB_MASK (XL_MASK | BO_MASK | BI_MASK | BB_MASK)
1048
1049/* An XO form instruction. */
1050#define XO(op, xop, oe, rc) \
1051 (OP (op) | (((xop) & 0x1ff) << 1) | (((oe) & 1) << 10) | ((rc) & 1))
1052#define XO_MASK XO (0x3f, 0x1ff, 1, 1)
1053
1054/* An XO_MASK with the RB field fixed. */
1055#define XORB_MASK (XO_MASK | RB_MASK)
1056
1057/* An XS form instruction. */
1058#define XS(op, xop, rc) (OP (op) | (((xop) & 0x1ff) << 2) | ((rc) & 1))
1059#define XS_MASK XS (0x3f, 0x1ff, 1)
1060
1061/* A mask for the FXM version of an XFX form instruction. */
1062#define XFXFXM_MASK (X_MASK | (1 << 20) | (1 << 11))
1063
1064/* An XFX form instruction with the FXM field filled in. */
1065#define XFXM(op, xop, fxm) \
1066 (X ((op), (xop)) | (((fxm) & 0xff) << 12))
1067
1068/* An XFX form instruction with the SPR field filled in. */
1069#define XSPR(op, xop, spr) \
1070 (X ((op), (xop)) | (((spr) & 0x1f) << 16) | (((spr) & 0x3e0) << 6))
1071#define XSPR_MASK (X_MASK | SPR_MASK)
1072
1073/* An XFX form instruction with the SPR field filled in except for the
1074 SPRBAT field. */
1075#define XSPRBAT_MASK (XSPR_MASK &~ SPRBAT_MASK)
1076
1077/* An XFX form instruction with the SPR field filled in except for the
1078 SPRG field. */
1079#define XSPRG_MASK (XSPR_MASK &~ SPRG_MASK)
1080
1081/* The BO encodings used in extended conditional branch mnemonics. */
1082#define BODNZF (0x0)
1083#define BODNZFP (0x1)
1084#define BODZF (0x2)
1085#define BODZFP (0x3)
1086#define BOF (0x4)
1087#define BOFP (0x5)
1088#define BODNZT (0x8)
1089#define BODNZTP (0x9)
1090#define BODZT (0xa)
1091#define BODZTP (0xb)
1092#define BOT (0xc)
1093#define BOTP (0xd)
1094#define BODNZ (0x10)
1095#define BODNZP (0x11)
1096#define BODZ (0x12)
1097#define BODZP (0x13)
1098#define BOU (0x14)
1099
1100/* The BI condition bit encodings used in extended conditional branch
1101 mnemonics. */
1102#define CBLT (0)
1103#define CBGT (1)
1104#define CBEQ (2)
1105#define CBSO (3)
1106
1107/* The TO encodings used in extended trap mnemonics. */
1108#define TOLGT (0x1)
1109#define TOLLT (0x2)
1110#define TOEQ (0x4)
1111#define TOLGE (0x5)
1112#define TOLNL (0x5)
1113#define TOLLE (0x6)
1114#define TOLNG (0x6)
1115#define TOGT (0x8)
1116#define TOGE (0xc)
1117#define TONL (0xc)
1118#define TOLT (0x10)
1119#define TOLE (0x14)
1120#define TONG (0x14)
1121#define TONE (0x18)
1122#define TOU (0x1f)
1123
1124/* Smaller names for the flags so each entry in the opcodes table will
1125 fit on a single line. */
1126#undef PPC
1127#define PPC PPC_OPCODE_PPC
1128#define POWER PPC_OPCODE_POWER
1129#define POWER2 PPC_OPCODE_POWER2
1130#define B32 PPC_OPCODE_32
1131#define B64 PPC_OPCODE_64
1132#define M601 PPC_OPCODE_601
1133
1134/* The opcode table.
1135
1136 The format of the opcode table is:
1137
1138 NAME OPCODE MASK FLAGS { OPERANDS }
1139
1140 NAME is the name of the instruction.
1141 OPCODE is the instruction opcode.
1142 MASK is the opcode mask; this is used to tell the disassembler
1143 which bits in the actual opcode must match OPCODE.
1144 FLAGS are flags indicated what processors support the instruction.
1145 OPERANDS is the list of operands.
1146
1147 The disassembler reads the table in order and prints the first
1148 instruction which matches, so this table is sorted to put more
1149 specific instructions before more general instructions. It is also
1150 sorted by major opcode. */
1151
1152const struct powerpc_opcode powerpc_opcodes[] = {
1153{ "tdlgti", OPTO(2,TOLGT), OPTO_MASK, PPC|B64, { RA, SI } },
1154{ "tdllti", OPTO(2,TOLLT), OPTO_MASK, PPC|B64, { RA, SI } },
1155{ "tdeqi", OPTO(2,TOEQ), OPTO_MASK, PPC|B64, { RA, SI } },
1156{ "tdlgei", OPTO(2,TOLGE), OPTO_MASK, PPC|B64, { RA, SI } },
1157{ "tdlnli", OPTO(2,TOLNL), OPTO_MASK, PPC|B64, { RA, SI } },
1158{ "tdllei", OPTO(2,TOLLE), OPTO_MASK, PPC|B64, { RA, SI } },
1159{ "tdlngi", OPTO(2,TOLNG), OPTO_MASK, PPC|B64, { RA, SI } },
1160{ "tdgti", OPTO(2,TOGT), OPTO_MASK, PPC|B64, { RA, SI } },
1161{ "tdgei", OPTO(2,TOGE), OPTO_MASK, PPC|B64, { RA, SI } },
1162{ "tdnli", OPTO(2,TONL), OPTO_MASK, PPC|B64, { RA, SI } },
1163{ "tdlti", OPTO(2,TOLT), OPTO_MASK, PPC|B64, { RA, SI } },
1164{ "tdlei", OPTO(2,TOLE), OPTO_MASK, PPC|B64, { RA, SI } },
1165{ "tdngi", OPTO(2,TONG), OPTO_MASK, PPC|B64, { RA, SI } },
1166{ "tdnei", OPTO(2,TONE), OPTO_MASK, PPC|B64, { RA, SI } },
1167{ "tdi", OP(2), OP_MASK, PPC|B64, { TO, RA, SI } },
1168
1169{ "twlgti", OPTO(3,TOLGT), OPTO_MASK, PPC, { RA, SI } },
1170{ "tlgti", OPTO(3,TOLGT), OPTO_MASK, POWER, { RA, SI } },
1171{ "twllti", OPTO(3,TOLLT), OPTO_MASK, PPC, { RA, SI } },
1172{ "tllti", OPTO(3,TOLLT), OPTO_MASK, POWER, { RA, SI } },
1173{ "tweqi", OPTO(3,TOEQ), OPTO_MASK, PPC, { RA, SI } },
1174{ "teqi", OPTO(3,TOEQ), OPTO_MASK, POWER, { RA, SI } },
1175{ "twlgei", OPTO(3,TOLGE), OPTO_MASK, PPC, { RA, SI } },
1176{ "tlgei", OPTO(3,TOLGE), OPTO_MASK, POWER, { RA, SI } },
1177{ "twlnli", OPTO(3,TOLNL), OPTO_MASK, PPC, { RA, SI } },
1178{ "tlnli", OPTO(3,TOLNL), OPTO_MASK, POWER, { RA, SI } },
1179{ "twllei", OPTO(3,TOLLE), OPTO_MASK, PPC, { RA, SI } },
1180{ "tllei", OPTO(3,TOLLE), OPTO_MASK, POWER, { RA, SI } },
1181{ "twlngi", OPTO(3,TOLNG), OPTO_MASK, PPC, { RA, SI } },
1182{ "tlngi", OPTO(3,TOLNG), OPTO_MASK, POWER, { RA, SI } },
1183{ "twgti", OPTO(3,TOGT), OPTO_MASK, PPC, { RA, SI } },
1184{ "tgti", OPTO(3,TOGT), OPTO_MASK, POWER, { RA, SI } },
1185{ "twgei", OPTO(3,TOGE), OPTO_MASK, PPC, { RA, SI } },
1186{ "tgei", OPTO(3,TOGE), OPTO_MASK, POWER, { RA, SI } },
1187{ "twnli", OPTO(3,TONL), OPTO_MASK, PPC, { RA, SI } },
1188{ "tnli", OPTO(3,TONL), OPTO_MASK, POWER, { RA, SI } },
1189{ "twlti", OPTO(3,TOLT), OPTO_MASK, PPC, { RA, SI } },
1190{ "tlti", OPTO(3,TOLT), OPTO_MASK, POWER, { RA, SI } },
1191{ "twlei", OPTO(3,TOLE), OPTO_MASK, PPC, { RA, SI } },
1192{ "tlei", OPTO(3,TOLE), OPTO_MASK, POWER, { RA, SI } },
1193{ "twngi", OPTO(3,TONG), OPTO_MASK, PPC, { RA, SI } },
1194{ "tngi", OPTO(3,TONG), OPTO_MASK, POWER, { RA, SI } },
1195{ "twnei", OPTO(3,TONE), OPTO_MASK, PPC, { RA, SI } },
1196{ "tnei", OPTO(3,TONE), OPTO_MASK, POWER, { RA, SI } },
1197{ "twi", OP(3), OP_MASK, PPC, { TO, RA, SI } },
1198{ "ti", OP(3), OP_MASK, POWER, { TO, RA, SI } },
1199
1200{ "mulli", OP(7), OP_MASK, PPC, { RT, RA, SI } },
1201{ "muli", OP(7), OP_MASK, POWER, { RT, RA, SI } },
1202
1203{ "subfic", OP(8), OP_MASK, PPC, { RT, RA, SI } },
1204{ "sfi", OP(8), OP_MASK, POWER, { RT, RA, SI } },
1205
1206{ "dozi", OP(9), OP_MASK, POWER|M601, { RT, RA, SI } },
1207
1208{ "cmplwi", OPL(10,0), OPL_MASK, PPC, { OBF, RA, UI } },
1209{ "cmpldi", OPL(10,1), OPL_MASK, PPC|B64, { OBF, RA, UI } },
1210{ "cmpli", OP(10), OP_MASK, PPC, { BF, L, RA, UI } },
1211{ "cmpli", OP(10), OP_MASK, POWER, { BF, RA, UI } },
1212
1213{ "cmpwi", OPL(11,0), OPL_MASK, PPC, { OBF, RA, SI } },
1214{ "cmpdi", OPL(11,1), OPL_MASK, PPC|B64, { OBF, RA, SI } },
1215{ "cmpi", OP(11), OP_MASK, PPC, { BF, L, RA, SI } },
1216{ "cmpi", OP(11), OP_MASK, POWER, { BF, RA, SI } },
1217
1218{ "addic", OP(12), OP_MASK, PPC, { RT, RA, SI } },
1219{ "ai", OP(12), OP_MASK, POWER, { RT, RA, SI } },
1220{ "subic", OP(12), OP_MASK, PPC, { RT, RA, NSI } },
1221
1222{ "addic.", OP(13), OP_MASK, PPC, { RT, RA, SI } },
1223{ "ai.", OP(13), OP_MASK, POWER, { RT, RA, SI } },
1224{ "subic.", OP(13), OP_MASK, PPC, { RT, RA, NSI } },
1225
1226{ "li", OP(14), DRA_MASK, PPC, { RT, SI } },
1227{ "lil", OP(14), DRA_MASK, POWER, { RT, SI } },
1228{ "addi", OP(14), OP_MASK, PPC, { RT, RA, SI } },
1229{ "cal", OP(14), OP_MASK, POWER, { RT, D, RA } },
1230{ "subi", OP(14), OP_MASK, PPC, { RT, RA, NSI } },
1231{ "la", OP(14), OP_MASK, PPC, { RT, D, RA } },
1232
1233{ "lis", OP(15), DRA_MASK, PPC, { RT, SISIGNOPT } },
1234{ "liu", OP(15), DRA_MASK, POWER, { RT, SISIGNOPT } },
1235{ "addis", OP(15), OP_MASK, PPC, { RT,RA,SISIGNOPT } },
1236{ "cau", OP(15), OP_MASK, POWER, { RT,RA,SISIGNOPT } },
1237{ "subis", OP(15), OP_MASK, PPC, { RT, RA, NSI } },
1238
1239{ "bdnz-", BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC, { BDM } },
1240{ "bdnz+", BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC, { BDP } },
1241{ "bdnz", BBO(16,BODNZ,0,0), BBOYBI_MASK, PPC, { BD } },
1242{ "bdn", BBO(16,BODNZ,0,0), BBOYBI_MASK, POWER, { BD } },
1243{ "bdnzl-", BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC, { BDM } },
1244{ "bdnzl+", BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC, { BDP } },
1245{ "bdnzl", BBO(16,BODNZ,0,1), BBOYBI_MASK, PPC, { BD } },
1246{ "bdnl", BBO(16,BODNZ,0,1), BBOYBI_MASK, POWER, { BD } },
1247{ "bdnza-", BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC, { BDMA } },
1248{ "bdnza+", BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC, { BDPA } },
1249{ "bdnza", BBO(16,BODNZ,1,0), BBOYBI_MASK, PPC, { BDA } },
1250{ "bdna", BBO(16,BODNZ,1,0), BBOYBI_MASK, POWER, { BDA } },
1251{ "bdnzla-", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC, { BDMA } },
1252{ "bdnzla+", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC, { BDPA } },
1253{ "bdnzla", BBO(16,BODNZ,1,1), BBOYBI_MASK, PPC, { BDA } },
1254{ "bdnla", BBO(16,BODNZ,1,1), BBOYBI_MASK, POWER, { BDA } },
1255{ "bdz-", BBO(16,BODZ,0,0), BBOYBI_MASK, PPC, { BDM } },
1256{ "bdz+", BBO(16,BODZ,0,0), BBOYBI_MASK, PPC, { BDP } },
1257{ "bdz", BBO(16,BODZ,0,0), BBOYBI_MASK, PPC|POWER, { BD } },
1258{ "bdzl-", BBO(16,BODZ,0,1), BBOYBI_MASK, PPC, { BDM } },
1259{ "bdzl+", BBO(16,BODZ,0,1), BBOYBI_MASK, PPC, { BDP } },
1260{ "bdzl", BBO(16,BODZ,0,1), BBOYBI_MASK, PPC|POWER, { BD } },
1261{ "bdza-", BBO(16,BODZ,1,0), BBOYBI_MASK, PPC, { BDMA } },
1262{ "bdza+", BBO(16,BODZ,1,0), BBOYBI_MASK, PPC, { BDPA } },
1263{ "bdza", BBO(16,BODZ,1,0), BBOYBI_MASK, PPC|POWER, { BDA } },
1264{ "bdzla-", BBO(16,BODZ,1,1), BBOYBI_MASK, PPC, { BDMA } },
1265{ "bdzla+", BBO(16,BODZ,1,1), BBOYBI_MASK, PPC, { BDPA } },
1266{ "bdzla", BBO(16,BODZ,1,1), BBOYBI_MASK, PPC|POWER, { BDA } },
1267{ "blt-", BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
1268{ "blt+", BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
1269{ "blt", BBOCB(16,BOT,CBLT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1270{ "bltl-", BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
1271{ "bltl+", BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
1272{ "bltl", BBOCB(16,BOT,CBLT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1273{ "blta-", BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
1274{ "blta+", BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
1275{ "blta", BBOCB(16,BOT,CBLT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1276{ "bltla-", BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
1277{ "bltla+", BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
1278{ "bltla", BBOCB(16,BOT,CBLT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1279{ "bgt-", BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
1280{ "bgt+", BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
1281{ "bgt", BBOCB(16,BOT,CBGT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1282{ "bgtl-", BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
1283{ "bgtl+", BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
1284{ "bgtl", BBOCB(16,BOT,CBGT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1285{ "bgta-", BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
1286{ "bgta+", BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
1287{ "bgta", BBOCB(16,BOT,CBGT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1288{ "bgtla-", BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
1289{ "bgtla+", BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
1290{ "bgtla", BBOCB(16,BOT,CBGT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1291{ "beq-", BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
1292{ "beq+", BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
1293{ "beq", BBOCB(16,BOT,CBEQ,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1294{ "beql-", BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
1295{ "beql+", BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
1296{ "beql", BBOCB(16,BOT,CBEQ,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1297{ "beqa-", BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
1298{ "beqa+", BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
1299{ "beqa", BBOCB(16,BOT,CBEQ,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1300{ "beqla-", BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
1301{ "beqla+", BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
1302{ "beqla", BBOCB(16,BOT,CBEQ,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1303{ "bso-", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
1304{ "bso+", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
1305{ "bso", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1306{ "bsol-", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
1307{ "bsol+", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
1308{ "bsol", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1309{ "bsoa-", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
1310{ "bsoa+", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
1311{ "bsoa", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1312{ "bsola-", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
1313{ "bsola+", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
1314{ "bsola", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1315{ "bun-", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
1316{ "bun+", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
1317{ "bun", BBOCB(16,BOT,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BD } },
1318{ "bunl-", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
1319{ "bunl+", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
1320{ "bunl", BBOCB(16,BOT,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BD } },
1321{ "buna-", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
1322{ "buna+", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
1323{ "buna", BBOCB(16,BOT,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDA } },
1324{ "bunla-", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
1325{ "bunla+", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
1326{ "bunla", BBOCB(16,BOT,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDA } },
1327{ "bge-", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
1328{ "bge+", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
1329{ "bge", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1330{ "bgel-", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
1331{ "bgel+", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
1332{ "bgel", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1333{ "bgea-", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
1334{ "bgea+", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
1335{ "bgea", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1336{ "bgela-", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
1337{ "bgela+", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
1338{ "bgela", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1339{ "bnl-", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
1340{ "bnl+", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
1341{ "bnl", BBOCB(16,BOF,CBLT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1342{ "bnll-", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
1343{ "bnll+", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
1344{ "bnll", BBOCB(16,BOF,CBLT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1345{ "bnla-", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
1346{ "bnla+", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
1347{ "bnla", BBOCB(16,BOF,CBLT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1348{ "bnlla-", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
1349{ "bnlla+", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
1350{ "bnlla", BBOCB(16,BOF,CBLT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1351{ "ble-", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
1352{ "ble+", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
1353{ "ble", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1354{ "blel-", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
1355{ "blel+", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
1356{ "blel", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1357{ "blea-", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
1358{ "blea+", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
1359{ "blea", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1360{ "blela-", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
1361{ "blela+", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
1362{ "blela", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1363{ "bng-", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
1364{ "bng+", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
1365{ "bng", BBOCB(16,BOF,CBGT,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1366{ "bngl-", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
1367{ "bngl+", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
1368{ "bngl", BBOCB(16,BOF,CBGT,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1369{ "bnga-", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
1370{ "bnga+", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
1371{ "bnga", BBOCB(16,BOF,CBGT,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1372{ "bngla-", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
1373{ "bngla+", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
1374{ "bngla", BBOCB(16,BOF,CBGT,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1375{ "bne-", BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
1376{ "bne+", BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
1377{ "bne", BBOCB(16,BOF,CBEQ,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1378{ "bnel-", BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
1379{ "bnel+", BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
1380{ "bnel", BBOCB(16,BOF,CBEQ,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1381{ "bnea-", BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
1382{ "bnea+", BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
1383{ "bnea", BBOCB(16,BOF,CBEQ,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1384{ "bnela-", BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
1385{ "bnela+", BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
1386{ "bnela", BBOCB(16,BOF,CBEQ,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1387{ "bns-", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
1388{ "bns+", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
1389{ "bns", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1390{ "bnsl-", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
1391{ "bnsl+", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
1392{ "bnsl", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC|POWER, { CR, BD } },
1393{ "bnsa-", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
1394{ "bnsa+", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
1395{ "bnsa", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1396{ "bnsla-", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
1397{ "bnsla+", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
1398{ "bnsla", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC|POWER, { CR, BDA } },
1399{ "bnu-", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDM } },
1400{ "bnu+", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BDP } },
1401{ "bnu", BBOCB(16,BOF,CBSO,0,0), BBOYCB_MASK, PPC, { CR, BD } },
1402{ "bnul-", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDM } },
1403{ "bnul+", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BDP } },
1404{ "bnul", BBOCB(16,BOF,CBSO,0,1), BBOYCB_MASK, PPC, { CR, BD } },
1405{ "bnua-", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDMA } },
1406{ "bnua+", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDPA } },
1407{ "bnua", BBOCB(16,BOF,CBSO,1,0), BBOYCB_MASK, PPC, { CR, BDA } },
1408{ "bnula-", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDMA } },
1409{ "bnula+", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDPA } },
1410{ "bnula", BBOCB(16,BOF,CBSO,1,1), BBOYCB_MASK, PPC, { CR, BDA } },
1411{ "bdnzt-", BBO(16,BODNZT,0,0), BBOY_MASK, PPC, { BI, BDM } },
1412{ "bdnzt+", BBO(16,BODNZT,0,0), BBOY_MASK, PPC, { BI, BDP } },
1413{ "bdnzt", BBO(16,BODNZT,0,0), BBOY_MASK, PPC, { BI, BD } },
1414{ "bdnztl-", BBO(16,BODNZT,0,1), BBOY_MASK, PPC, { BI, BDM } },
1415{ "bdnztl+", BBO(16,BODNZT,0,1), BBOY_MASK, PPC, { BI, BDP } },
1416{ "bdnztl", BBO(16,BODNZT,0,1), BBOY_MASK, PPC, { BI, BD } },
1417{ "bdnzta-", BBO(16,BODNZT,1,0), BBOY_MASK, PPC, { BI, BDMA } },
1418{ "bdnzta+", BBO(16,BODNZT,1,0), BBOY_MASK, PPC, { BI, BDPA } },
1419{ "bdnzta", BBO(16,BODNZT,1,0), BBOY_MASK, PPC, { BI, BDA } },
1420{ "bdnztla-",BBO(16,BODNZT,1,1), BBOY_MASK, PPC, { BI, BDMA } },
1421{ "bdnztla+",BBO(16,BODNZT,1,1), BBOY_MASK, PPC, { BI, BDPA } },
1422{ "bdnztla", BBO(16,BODNZT,1,1), BBOY_MASK, PPC, { BI, BDA } },
1423{ "bdnzf-", BBO(16,BODNZF,0,0), BBOY_MASK, PPC, { BI, BDM } },
1424{ "bdnzf+", BBO(16,BODNZF,0,0), BBOY_MASK, PPC, { BI, BDP } },
1425{ "bdnzf", BBO(16,BODNZF,0,0), BBOY_MASK, PPC, { BI, BD } },
1426{ "bdnzfl-", BBO(16,BODNZF,0,1), BBOY_MASK, PPC, { BI, BDM } },
1427{ "bdnzfl+", BBO(16,BODNZF,0,1), BBOY_MASK, PPC, { BI, BDP } },
1428{ "bdnzfl", BBO(16,BODNZF,0,1), BBOY_MASK, PPC, { BI, BD } },
1429{ "bdnzfa-", BBO(16,BODNZF,1,0), BBOY_MASK, PPC, { BI, BDMA } },
1430{ "bdnzfa+", BBO(16,BODNZF,1,0), BBOY_MASK, PPC, { BI, BDPA } },
1431{ "bdnzfa", BBO(16,BODNZF,1,0), BBOY_MASK, PPC, { BI, BDA } },
1432{ "bdnzfla-",BBO(16,BODNZF,1,1), BBOY_MASK, PPC, { BI, BDMA } },
1433{ "bdnzfla+",BBO(16,BODNZF,1,1), BBOY_MASK, PPC, { BI, BDPA } },
1434{ "bdnzfla", BBO(16,BODNZF,1,1), BBOY_MASK, PPC, { BI, BDA } },
1435{ "bt-", BBO(16,BOT,0,0), BBOY_MASK, PPC, { BI, BDM } },
1436{ "bt+", BBO(16,BOT,0,0), BBOY_MASK, PPC, { BI, BDP } },
1437{ "bt", BBO(16,BOT,0,0), BBOY_MASK, PPC, { BI, BD } },
1438{ "bbt", BBO(16,BOT,0,0), BBOY_MASK, POWER, { BI, BD } },
1439{ "btl-", BBO(16,BOT,0,1), BBOY_MASK, PPC, { BI, BDM } },
1440{ "btl+", BBO(16,BOT,0,1), BBOY_MASK, PPC, { BI, BDP } },
1441{ "btl", BBO(16,BOT,0,1), BBOY_MASK, PPC, { BI, BD } },
1442{ "bbtl", BBO(16,BOT,0,1), BBOY_MASK, POWER, { BI, BD } },
1443{ "bta-", BBO(16,BOT,1,0), BBOY_MASK, PPC, { BI, BDMA } },
1444{ "bta+", BBO(16,BOT,1,0), BBOY_MASK, PPC, { BI, BDPA } },
1445{ "bta", BBO(16,BOT,1,0), BBOY_MASK, PPC, { BI, BDA } },
1446{ "bbta", BBO(16,BOT,1,0), BBOY_MASK, POWER, { BI, BDA } },
1447{ "btla-", BBO(16,BOT,1,1), BBOY_MASK, PPC, { BI, BDMA } },
1448{ "btla+", BBO(16,BOT,1,1), BBOY_MASK, PPC, { BI, BDPA } },
1449{ "btla", BBO(16,BOT,1,1), BBOY_MASK, PPC, { BI, BDA } },
1450{ "bbtla", BBO(16,BOT,1,1), BBOY_MASK, POWER, { BI, BDA } },
1451{ "bf-", BBO(16,BOF,0,0), BBOY_MASK, PPC, { BI, BDM } },
1452{ "bf+", BBO(16,BOF,0,0), BBOY_MASK, PPC, { BI, BDP } },
1453{ "bf", BBO(16,BOF,0,0), BBOY_MASK, PPC, { BI, BD } },
1454{ "bbf", BBO(16,BOF,0,0), BBOY_MASK, POWER, { BI, BD } },
1455{ "bfl-", BBO(16,BOF,0,1), BBOY_MASK, PPC, { BI, BDM } },
1456{ "bfl+", BBO(16,BOF,0,1), BBOY_MASK, PPC, { BI, BDP } },
1457{ "bfl", BBO(16,BOF,0,1), BBOY_MASK, PPC, { BI, BD } },
1458{ "bbfl", BBO(16,BOF,0,1), BBOY_MASK, POWER, { BI, BD } },
1459{ "bfa-", BBO(16,BOF,1,0), BBOY_MASK, PPC, { BI, BDMA } },
1460{ "bfa+", BBO(16,BOF,1,0), BBOY_MASK, PPC, { BI, BDPA } },
1461{ "bfa", BBO(16,BOF,1,0), BBOY_MASK, PPC, { BI, BDA } },
1462{ "bbfa", BBO(16,BOF,1,0), BBOY_MASK, POWER, { BI, BDA } },
1463{ "bfla-", BBO(16,BOF,1,1), BBOY_MASK, PPC, { BI, BDMA } },
1464{ "bfla+", BBO(16,BOF,1,1), BBOY_MASK, PPC, { BI, BDPA } },
1465{ "bfla", BBO(16,BOF,1,1), BBOY_MASK, PPC, { BI, BDA } },
1466{ "bbfla", BBO(16,BOF,1,1), BBOY_MASK, POWER, { BI, BDA } },
1467{ "bdzt-", BBO(16,BODZT,0,0), BBOY_MASK, PPC, { BI, BDM } },
1468{ "bdzt+", BBO(16,BODZT,0,0), BBOY_MASK, PPC, { BI, BDP } },
1469{ "bdzt", BBO(16,BODZT,0,0), BBOY_MASK, PPC, { BI, BD } },
1470{ "bdztl-", BBO(16,BODZT,0,1), BBOY_MASK, PPC, { BI, BDM } },
1471{ "bdztl+", BBO(16,BODZT,0,1), BBOY_MASK, PPC, { BI, BDP } },
1472{ "bdztl", BBO(16,BODZT,0,1), BBOY_MASK, PPC, { BI, BD } },
1473{ "bdzta-", BBO(16,BODZT,1,0), BBOY_MASK, PPC, { BI, BDMA } },
1474{ "bdzta+", BBO(16,BODZT,1,0), BBOY_MASK, PPC, { BI, BDPA } },
1475{ "bdzta", BBO(16,BODZT,1,0), BBOY_MASK, PPC, { BI, BDA } },
1476{ "bdztla-", BBO(16,BODZT,1,1), BBOY_MASK, PPC, { BI, BDMA } },
1477{ "bdztla+", BBO(16,BODZT,1,1), BBOY_MASK, PPC, { BI, BDPA } },
1478{ "bdztla", BBO(16,BODZT,1,1), BBOY_MASK, PPC, { BI, BDA } },
1479{ "bdzf-", BBO(16,BODZF,0,0), BBOY_MASK, PPC, { BI, BDM } },
1480{ "bdzf+", BBO(16,BODZF,0,0), BBOY_MASK, PPC, { BI, BDP } },
1481{ "bdzf", BBO(16,BODZF,0,0), BBOY_MASK, PPC, { BI, BD } },
1482{ "bdzfl-", BBO(16,BODZF,0,1), BBOY_MASK, PPC, { BI, BDM } },
1483{ "bdzfl+", BBO(16,BODZF,0,1), BBOY_MASK, PPC, { BI, BDP } },
1484{ "bdzfl", BBO(16,BODZF,0,1), BBOY_MASK, PPC, { BI, BD } },
1485{ "bdzfa-", BBO(16,BODZF,1,0), BBOY_MASK, PPC, { BI, BDMA } },
1486{ "bdzfa+", BBO(16,BODZF,1,0), BBOY_MASK, PPC, { BI, BDPA } },
1487{ "bdzfa", BBO(16,BODZF,1,0), BBOY_MASK, PPC, { BI, BDA } },
1488{ "bdzfla-", BBO(16,BODZF,1,1), BBOY_MASK, PPC, { BI, BDMA } },
1489{ "bdzfla+", BBO(16,BODZF,1,1), BBOY_MASK, PPC, { BI, BDPA } },
1490{ "bdzfla", BBO(16,BODZF,1,1), BBOY_MASK, PPC, { BI, BDA } },
1491{ "bc-", B(16,0,0), B_MASK, PPC, { BOE, BI, BDM } },
1492{ "bc+", B(16,0,0), B_MASK, PPC, { BOE, BI, BDP } },
1493{ "bc", B(16,0,0), B_MASK, PPC|POWER, { BO, BI, BD } },
1494{ "bcl-", B(16,0,1), B_MASK, PPC, { BOE, BI, BDM } },
1495{ "bcl+", B(16,0,1), B_MASK, PPC, { BOE, BI, BDP } },
1496{ "bcl", B(16,0,1), B_MASK, PPC|POWER, { BO, BI, BD } },
1497{ "bca-", B(16,1,0), B_MASK, PPC, { BOE, BI, BDMA } },
1498{ "bca+", B(16,1,0), B_MASK, PPC, { BOE, BI, BDPA } },
1499{ "bca", B(16,1,0), B_MASK, PPC|POWER, { BO, BI, BDA } },
1500{ "bcla-", B(16,1,1), B_MASK, PPC, { BOE, BI, BDMA } },
1501{ "bcla+", B(16,1,1), B_MASK, PPC, { BOE, BI, BDPA } },
1502{ "bcla", B(16,1,1), B_MASK, PPC|POWER, { BO, BI, BDA } },
1503
1504{ "sc", SC(17,1,0), 0xffffffff, PPC, { 0 } },
1505{ "svc", SC(17,0,0), SC_MASK, POWER, { LEV, FL1, FL2 } },
1506{ "svcl", SC(17,0,1), SC_MASK, POWER, { LEV, FL1, FL2 } },
1507{ "svca", SC(17,1,0), SC_MASK, POWER, { SV } },
1508{ "svcla", SC(17,1,1), SC_MASK, POWER, { SV } },
1509
1510{ "b", B(18,0,0), B_MASK, PPC|POWER, { LI } },
1511{ "bl", B(18,0,1), B_MASK, PPC|POWER, { LI } },
1512{ "ba", B(18,1,0), B_MASK, PPC|POWER, { LIA } },
1513{ "bla", B(18,1,1), B_MASK, PPC|POWER, { LIA } },
1514
1515{ "mcrf", XL(19,0), XLBB_MASK|(3<<21)|(3<<16), PPC|POWER, { BF, BFA } },
1516
1517{ "blr", XLO(19,BOU,16,0), XLBOBIBB_MASK, PPC, { 0 } },
1518{ "br", XLO(19,BOU,16,0), XLBOBIBB_MASK, POWER, { 0 } },
1519{ "blrl", XLO(19,BOU,16,1), XLBOBIBB_MASK, PPC, { 0 } },
1520{ "brl", XLO(19,BOU,16,1), XLBOBIBB_MASK, POWER, { 0 } },
1521{ "bdnzlr", XLO(19,BODNZ,16,0), XLBOBIBB_MASK, PPC, { 0 } },
1522{ "bdnzlr-", XLO(19,BODNZ,16,0), XLBOBIBB_MASK, PPC, { 0 } },
1523{ "bdnzlr+", XLO(19,BODNZP,16,0), XLBOBIBB_MASK, PPC, { 0 } },
1524{ "bdnzlrl", XLO(19,BODNZ,16,1), XLBOBIBB_MASK, PPC, { 0 } },
1525{ "bdnzlrl-",XLO(19,BODNZ,16,1), XLBOBIBB_MASK, PPC, { 0 } },
1526{ "bdnzlrl+",XLO(19,BODNZP,16,1), XLBOBIBB_MASK, PPC, { 0 } },
1527{ "bdzlr", XLO(19,BODZ,16,0), XLBOBIBB_MASK, PPC, { 0 } },
1528{ "bdzlr-", XLO(19,BODZ,16,0), XLBOBIBB_MASK, PPC, { 0 } },
1529{ "bdzlr+", XLO(19,BODZP,16,0), XLBOBIBB_MASK, PPC, { 0 } },
1530{ "bdzlrl", XLO(19,BODZ,16,1), XLBOBIBB_MASK, PPC, { 0 } },
1531{ "bdzlrl-", XLO(19,BODZ,16,1), XLBOBIBB_MASK, PPC, { 0 } },
1532{ "bdzlrl+", XLO(19,BODZP,16,1), XLBOBIBB_MASK, PPC, { 0 } },
1533{ "bltlr", XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1534{ "bltlr-", XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1535{ "bltlr+", XLOCB(19,BOTP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1536{ "bltr", XLOCB(19,BOT,CBLT,16,0), XLBOCBBB_MASK, POWER, { CR } },
1537{ "bltlrl", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1538{ "bltlrl-", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1539{ "bltlrl+", XLOCB(19,BOTP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1540{ "bltrl", XLOCB(19,BOT,CBLT,16,1), XLBOCBBB_MASK, POWER, { CR } },
1541{ "bgtlr", XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1542{ "bgtlr-", XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1543{ "bgtlr+", XLOCB(19,BOTP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1544{ "bgtr", XLOCB(19,BOT,CBGT,16,0), XLBOCBBB_MASK, POWER, { CR } },
1545{ "bgtlrl", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1546{ "bgtlrl-", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1547{ "bgtlrl+", XLOCB(19,BOTP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1548{ "bgtrl", XLOCB(19,BOT,CBGT,16,1), XLBOCBBB_MASK, POWER, { CR } },
1549{ "beqlr", XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
1550{ "beqlr-", XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
1551{ "beqlr+", XLOCB(19,BOTP,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
1552{ "beqr", XLOCB(19,BOT,CBEQ,16,0), XLBOCBBB_MASK, POWER, { CR } },
1553{ "beqlrl", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
1554{ "beqlrl-", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
1555{ "beqlrl+", XLOCB(19,BOTP,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
1556{ "beqrl", XLOCB(19,BOT,CBEQ,16,1), XLBOCBBB_MASK, POWER, { CR } },
1557{ "bsolr", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
1558{ "bsolr-", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
1559{ "bsolr+", XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
1560{ "bsor", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, POWER, { CR } },
1561{ "bsolrl", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
1562{ "bsolrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
1563{ "bsolrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
1564{ "bsorl", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, POWER, { CR } },
1565{ "bunlr", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
1566{ "bunlr-", XLOCB(19,BOT,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
1567{ "bunlr+", XLOCB(19,BOTP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
1568{ "bunlrl", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
1569{ "bunlrl-", XLOCB(19,BOT,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
1570{ "bunlrl+", XLOCB(19,BOTP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
1571{ "bgelr", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1572{ "bgelr-", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1573{ "bgelr+", XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1574{ "bger", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, POWER, { CR } },
1575{ "bgelrl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1576{ "bgelrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1577{ "bgelrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1578{ "bgerl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, POWER, { CR } },
1579{ "bnllr", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1580{ "bnllr-", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1581{ "bnllr+", XLOCB(19,BOFP,CBLT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1582{ "bnlr", XLOCB(19,BOF,CBLT,16,0), XLBOCBBB_MASK, POWER, { CR } },
1583{ "bnllrl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1584{ "bnllrl-", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1585{ "bnllrl+", XLOCB(19,BOFP,CBLT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1586{ "bnlrl", XLOCB(19,BOF,CBLT,16,1), XLBOCBBB_MASK, POWER, { CR } },
1587{ "blelr", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1588{ "blelr-", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1589{ "blelr+", XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1590{ "bler", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, POWER, { CR } },
1591{ "blelrl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1592{ "blelrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1593{ "blelrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1594{ "blerl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, POWER, { CR } },
1595{ "bnglr", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1596{ "bnglr-", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1597{ "bnglr+", XLOCB(19,BOFP,CBGT,16,0), XLBOCBBB_MASK, PPC, { CR } },
1598{ "bngr", XLOCB(19,BOF,CBGT,16,0), XLBOCBBB_MASK, POWER, { CR } },
1599{ "bnglrl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1600{ "bnglrl-", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1601{ "bnglrl+", XLOCB(19,BOFP,CBGT,16,1), XLBOCBBB_MASK, PPC, { CR } },
1602{ "bngrl", XLOCB(19,BOF,CBGT,16,1), XLBOCBBB_MASK, POWER, { CR } },
1603{ "bnelr", XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
1604{ "bnelr-", XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
1605{ "bnelr+", XLOCB(19,BOFP,CBEQ,16,0), XLBOCBBB_MASK, PPC, { CR } },
1606{ "bner", XLOCB(19,BOF,CBEQ,16,0), XLBOCBBB_MASK, POWER, { CR } },
1607{ "bnelrl", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
1608{ "bnelrl-", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
1609{ "bnelrl+", XLOCB(19,BOFP,CBEQ,16,1), XLBOCBBB_MASK, PPC, { CR } },
1610{ "bnerl", XLOCB(19,BOF,CBEQ,16,1), XLBOCBBB_MASK, POWER, { CR } },
1611{ "bnslr", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
1612{ "bnslr-", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
1613{ "bnslr+", XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
1614{ "bnsr", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, POWER, { CR } },
1615{ "bnslrl", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
1616{ "bnslrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
1617{ "bnslrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
1618{ "bnsrl", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, POWER, { CR } },
1619{ "bnulr", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
1620{ "bnulr-", XLOCB(19,BOF,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
1621{ "bnulr+", XLOCB(19,BOFP,CBSO,16,0), XLBOCBBB_MASK, PPC, { CR } },
1622{ "bnulrl", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
1623{ "bnulrl-", XLOCB(19,BOF,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
1624{ "bnulrl+", XLOCB(19,BOFP,CBSO,16,1), XLBOCBBB_MASK, PPC, { CR } },
1625{ "btlr", XLO(19,BOT,16,0), XLBOBB_MASK, PPC, { BI } },
1626{ "btlr-", XLO(19,BOT,16,0), XLBOBB_MASK, PPC, { BI } },
1627{ "btlr+", XLO(19,BOTP,16,0), XLBOBB_MASK, PPC, { BI } },
1628{ "bbtr", XLO(19,BOT,16,0), XLBOBB_MASK, POWER, { BI } },
1629{ "btlrl", XLO(19,BOT,16,1), XLBOBB_MASK, PPC, { BI } },
1630{ "btlrl-", XLO(19,BOT,16,1), XLBOBB_MASK, PPC, { BI } },
1631{ "btlrl+", XLO(19,BOTP,16,1), XLBOBB_MASK, PPC, { BI } },
1632{ "bbtrl", XLO(19,BOT,16,1), XLBOBB_MASK, POWER, { BI } },
1633{ "bflr", XLO(19,BOF,16,0), XLBOBB_MASK, PPC, { BI } },
1634{ "bflr-", XLO(19,BOF,16,0), XLBOBB_MASK, PPC, { BI } },
1635{ "bflr+", XLO(19,BOFP,16,0), XLBOBB_MASK, PPC, { BI } },
1636{ "bbfr", XLO(19,BOF,16,0), XLBOBB_MASK, POWER, { BI } },
1637{ "bflrl", XLO(19,BOF,16,1), XLBOBB_MASK, PPC, { BI } },
1638{ "bflrl-", XLO(19,BOF,16,1), XLBOBB_MASK, PPC, { BI } },
1639{ "bflrl+", XLO(19,BOFP,16,1), XLBOBB_MASK, PPC, { BI } },
1640{ "bbfrl", XLO(19,BOF,16,1), XLBOBB_MASK, POWER, { BI } },
1641{ "bdnztlr", XLO(19,BODNZT,16,0), XLBOBB_MASK, PPC, { BI } },
1642{ "bdnztlr-",XLO(19,BODNZT,16,0), XLBOBB_MASK, PPC, { BI } },
1643{ "bdnztlr+",XLO(19,BODNZTP,16,0), XLBOBB_MASK, PPC, { BI } },
1644{ "bdnztlrl",XLO(19,BODNZT,16,1), XLBOBB_MASK, PPC, { BI } },
1645{ "bdnztlrl-",XLO(19,BODNZT,16,1), XLBOBB_MASK, PPC, { BI } },
1646{ "bdnztlrl+",XLO(19,BODNZTP,16,1), XLBOBB_MASK, PPC, { BI } },
1647{ "bdnzflr", XLO(19,BODNZF,16,0), XLBOBB_MASK, PPC, { BI } },
1648{ "bdnzflr-",XLO(19,BODNZF,16,0), XLBOBB_MASK, PPC, { BI } },
1649{ "bdnzflr+",XLO(19,BODNZFP,16,0), XLBOBB_MASK, PPC, { BI } },
1650{ "bdnzflrl",XLO(19,BODNZF,16,1), XLBOBB_MASK, PPC, { BI } },
1651{ "bdnzflrl-",XLO(19,BODNZF,16,1), XLBOBB_MASK, PPC, { BI } },
1652{ "bdnzflrl+",XLO(19,BODNZFP,16,1), XLBOBB_MASK, PPC, { BI } },
1653{ "bdztlr", XLO(19,BODZT,16,0), XLBOBB_MASK, PPC, { BI } },
1654{ "bdztlr-", XLO(19,BODZT,16,0), XLBOBB_MASK, PPC, { BI } },
1655{ "bdztlr+", XLO(19,BODZTP,16,0), XLBOBB_MASK, PPC, { BI } },
1656{ "bdztlrl", XLO(19,BODZT,16,1), XLBOBB_MASK, PPC, { BI } },
1657{ "bdztlrl-",XLO(19,BODZT,16,1), XLBOBB_MASK, PPC, { BI } },
1658{ "bdztlrl+",XLO(19,BODZTP,16,1), XLBOBB_MASK, PPC, { BI } },
1659{ "bdzflr", XLO(19,BODZF,16,0), XLBOBB_MASK, PPC, { BI } },
1660{ "bdzflr-", XLO(19,BODZF,16,0), XLBOBB_MASK, PPC, { BI } },
1661{ "bdzflr+", XLO(19,BODZFP,16,0), XLBOBB_MASK, PPC, { BI } },
1662{ "bdzflrl", XLO(19,BODZF,16,1), XLBOBB_MASK, PPC, { BI } },
1663{ "bdzflrl-",XLO(19,BODZF,16,1), XLBOBB_MASK, PPC, { BI } },
1664{ "bdzflrl+",XLO(19,BODZFP,16,1), XLBOBB_MASK, PPC, { BI } },
1665{ "bclr", XLLK(19,16,0), XLYBB_MASK, PPC, { BO, BI } },
1666{ "bclrl", XLLK(19,16,1), XLYBB_MASK, PPC, { BO, BI } },
1667{ "bclr+", XLYLK(19,16,1,0), XLYBB_MASK, PPC, { BOE, BI } },
1668{ "bclrl+", XLYLK(19,16,1,1), XLYBB_MASK, PPC, { BOE, BI } },
1669{ "bclr-", XLYLK(19,16,0,0), XLYBB_MASK, PPC, { BOE, BI } },
1670{ "bclrl-", XLYLK(19,16,0,1), XLYBB_MASK, PPC, { BOE, BI } },
1671{ "bcr", XLLK(19,16,0), XLBB_MASK, POWER, { BO, BI } },
1672{ "bcrl", XLLK(19,16,1), XLBB_MASK, POWER, { BO, BI } },
1673
1674{ "crnot", XL(19,33), XL_MASK, PPC, { BT, BA, BBA } },
1675{ "crnor", XL(19,33), XL_MASK, PPC|POWER, { BT, BA, BB } },
1676
1677{ "rfi", XL(19,50), 0xffffffff, PPC|POWER, { 0 } },
1678{ "rfci", XL(19,51), 0xffffffff, PPC, { 0 } },
1679
1680{ "rfsvc", XL(19,82), 0xffffffff, POWER, { 0 } },
1681
1682{ "crandc", XL(19,129), XL_MASK, PPC|POWER, { BT, BA, BB } },
1683
1684{ "isync", XL(19,150), 0xffffffff, PPC, { 0 } },
1685{ "ics", XL(19,150), 0xffffffff, POWER, { 0 } },
1686
1687{ "crclr", XL(19,193), XL_MASK, PPC, { BT, BAT, BBA } },
1688{ "crxor", XL(19,193), XL_MASK, PPC|POWER, { BT, BA, BB } },
1689
1690{ "crnand", XL(19,225), XL_MASK, PPC|POWER, { BT, BA, BB } },
1691
1692{ "crand", XL(19,257), XL_MASK, PPC|POWER, { BT, BA, BB } },
1693
1694{ "crset", XL(19,289), XL_MASK, PPC, { BT, BAT, BBA } },
1695{ "creqv", XL(19,289), XL_MASK, PPC|POWER, { BT, BA, BB } },
1696
1697{ "crorc", XL(19,417), XL_MASK, PPC|POWER, { BT, BA, BB } },
1698
1699{ "crmove", XL(19,449), XL_MASK, PPC, { BT, BA, BBA } },
1700{ "cror", XL(19,449), XL_MASK, PPC|POWER, { BT, BA, BB } },
1701
1702{ "bctr", XLO(19,BOU,528,0), XLBOBIBB_MASK, PPC|POWER, { 0 } },
1703{ "bctrl", XLO(19,BOU,528,1), XLBOBIBB_MASK, PPC|POWER, { 0 } },
1704{ "bltctr", XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1705{ "bltctr-", XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1706{ "bltctr+", XLOCB(19,BOTP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1707{ "bltctrl", XLOCB(19,BOT,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1708{ "bltctrl-",XLOCB(19,BOT,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1709{ "bltctrl+",XLOCB(19,BOTP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1710{ "bgtctr", XLOCB(19,BOT,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1711{ "bgtctr-", XLOCB(19,BOT,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1712{ "bgtctr+", XLOCB(19,BOTP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1713{ "bgtctrl", XLOCB(19,BOT,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1714{ "bgtctrl-",XLOCB(19,BOT,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1715{ "bgtctrl+",XLOCB(19,BOTP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1716{ "beqctr", XLOCB(19,BOT,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
1717{ "beqctr-", XLOCB(19,BOT,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
1718{ "beqctr+", XLOCB(19,BOTP,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
1719{ "beqctrl", XLOCB(19,BOT,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
1720{ "beqctrl-",XLOCB(19,BOT,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
1721{ "beqctrl+",XLOCB(19,BOTP,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
1722{ "bsoctr", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
1723{ "bsoctr-", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
1724{ "bsoctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
1725{ "bsoctrl", XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
1726{ "bsoctrl-",XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
1727{ "bsoctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
1728{ "bunctr", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
1729{ "bunctr-", XLOCB(19,BOT,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
1730{ "bunctr+", XLOCB(19,BOTP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
1731{ "bunctrl", XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
1732{ "bunctrl-",XLOCB(19,BOT,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
1733{ "bunctrl+",XLOCB(19,BOTP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
1734{ "bgectr", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1735{ "bgectr-", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1736{ "bgectr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1737{ "bgectrl", XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1738{ "bgectrl-",XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1739{ "bgectrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1740{ "bnlctr", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1741{ "bnlctr-", XLOCB(19,BOF,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1742{ "bnlctr+", XLOCB(19,BOFP,CBLT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1743{ "bnlctrl", XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1744{ "bnlctrl-",XLOCB(19,BOF,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1745{ "bnlctrl+",XLOCB(19,BOFP,CBLT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1746{ "blectr", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1747{ "blectr-", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1748{ "blectr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1749{ "blectrl", XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1750{ "blectrl-",XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1751{ "blectrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1752{ "bngctr", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1753{ "bngctr-", XLOCB(19,BOF,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1754{ "bngctr+", XLOCB(19,BOFP,CBGT,528,0), XLBOCBBB_MASK, PPC, { CR } },
1755{ "bngctrl", XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1756{ "bngctrl-",XLOCB(19,BOF,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1757{ "bngctrl+",XLOCB(19,BOFP,CBGT,528,1), XLBOCBBB_MASK, PPC, { CR } },
1758{ "bnectr", XLOCB(19,BOF,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
1759{ "bnectr-", XLOCB(19,BOF,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
1760{ "bnectr+", XLOCB(19,BOFP,CBEQ,528,0), XLBOCBBB_MASK, PPC, { CR } },
1761{ "bnectrl", XLOCB(19,BOF,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
1762{ "bnectrl-",XLOCB(19,BOF,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
1763{ "bnectrl+",XLOCB(19,BOFP,CBEQ,528,1), XLBOCBBB_MASK, PPC, { CR } },
1764{ "bnsctr", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
1765{ "bnsctr-", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
1766{ "bnsctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
1767{ "bnsctrl", XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
1768{ "bnsctrl-",XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
1769{ "bnsctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
1770{ "bnuctr", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
1771{ "bnuctr-", XLOCB(19,BOF,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
1772{ "bnuctr+", XLOCB(19,BOFP,CBSO,528,0), XLBOCBBB_MASK, PPC, { CR } },
1773{ "bnuctrl", XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
1774{ "bnuctrl-",XLOCB(19,BOF,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
1775{ "bnuctrl+",XLOCB(19,BOFP,CBSO,528,1), XLBOCBBB_MASK, PPC, { CR } },
1776{ "btctr", XLO(19,BOT,528,0), XLBOBB_MASK, PPC, { BI } },
1777{ "btctr-", XLO(19,BOT,528,0), XLBOBB_MASK, PPC, { BI } },
1778{ "btctr+", XLO(19,BOTP,528,0), XLBOBB_MASK, PPC, { BI } },
1779{ "btctrl", XLO(19,BOT,528,1), XLBOBB_MASK, PPC, { BI } },
1780{ "btctrl-", XLO(19,BOT,528,1), XLBOBB_MASK, PPC, { BI } },
1781{ "btctrl+", XLO(19,BOTP,528,1), XLBOBB_MASK, PPC, { BI } },
1782{ "bfctr", XLO(19,BOF,528,0), XLBOBB_MASK, PPC, { BI } },
1783{ "bfctr-", XLO(19,BOF,528,0), XLBOBB_MASK, PPC, { BI } },
1784{ "bfctr+", XLO(19,BOFP,528,0), XLBOBB_MASK, PPC, { BI } },
1785{ "bfctrl", XLO(19,BOF,528,1), XLBOBB_MASK, PPC, { BI } },
1786{ "bfctrl-", XLO(19,BOF,528,1), XLBOBB_MASK, PPC, { BI } },
1787{ "bfctrl+", XLO(19,BOFP,528,1), XLBOBB_MASK, PPC, { BI } },
1788{ "bcctr", XLLK(19,528,0), XLYBB_MASK, PPC, { BO, BI } },
1789{ "bcctr-", XLYLK(19,528,0,0), XLYBB_MASK, PPC, { BOE, BI } },
1790{ "bcctr+", XLYLK(19,528,1,0), XLYBB_MASK, PPC, { BOE, BI } },
1791{ "bcctrl", XLLK(19,528,1), XLYBB_MASK, PPC, { BO, BI } },
1792{ "bcctrl-", XLYLK(19,528,0,1), XLYBB_MASK, PPC, { BOE, BI } },
1793{ "bcctrl+", XLYLK(19,528,1,1), XLYBB_MASK, PPC, { BOE, BI } },
1794{ "bcc", XLLK(19,528,0), XLBB_MASK, POWER, { BO, BI } },
1795{ "bccl", XLLK(19,528,1), XLBB_MASK, POWER, { BO, BI } },
1796
1797{ "rlwimi", M(20,0), M_MASK, PPC, { RA,RS,SH,MBE,ME } },
1798{ "rlimi", M(20,0), M_MASK, POWER, { RA,RS,SH,MBE,ME } },
1799
1800{ "rlwimi.", M(20,1), M_MASK, PPC, { RA,RS,SH,MBE,ME } },
1801{ "rlimi.", M(20,1), M_MASK, POWER, { RA,RS,SH,MBE,ME } },
1802
1803{ "rotlwi", MME(21,31,0), MMBME_MASK, PPC, { RA, RS, SH } },
1804{ "clrlwi", MME(21,31,0), MSHME_MASK, PPC, { RA, RS, MB } },
1805{ "rlwinm", M(21,0), M_MASK, PPC, { RA,RS,SH,MBE,ME } },
1806{ "rlinm", M(21,0), M_MASK, POWER, { RA,RS,SH,MBE,ME } },
1807{ "rotlwi.", MME(21,31,1), MMBME_MASK, PPC, { RA,RS,SH } },
1808{ "clrlwi.", MME(21,31,1), MSHME_MASK, PPC, { RA, RS, MB } },
1809{ "rlwinm.", M(21,1), M_MASK, PPC, { RA,RS,SH,MBE,ME } },
1810{ "rlinm.", M(21,1), M_MASK, POWER, { RA,RS,SH,MBE,ME } },
1811
1812{ "rlmi", M(22,0), M_MASK, POWER|M601, { RA,RS,RB,MBE,ME } },
1813{ "rlmi.", M(22,1), M_MASK, POWER|M601, { RA,RS,RB,MBE,ME } },
1814
1815{ "rotlw", MME(23,31,0), MMBME_MASK, PPC, { RA, RS, RB } },
1816{ "rlwnm", M(23,0), M_MASK, PPC, { RA,RS,RB,MBE,ME } },
1817{ "rlnm", M(23,0), M_MASK, POWER, { RA,RS,RB,MBE,ME } },
1818{ "rotlw.", MME(23,31,1), MMBME_MASK, PPC, { RA, RS, RB } },
1819{ "rlwnm.", M(23,1), M_MASK, PPC, { RA,RS,RB,MBE,ME } },
1820{ "rlnm.", M(23,1), M_MASK, POWER, { RA,RS,RB,MBE,ME } },
1821
1822{ "nop", OP(24), 0xffffffff, PPC, { 0 } },
1823{ "ori", OP(24), OP_MASK, PPC, { RA, RS, UI } },
1824{ "oril", OP(24), OP_MASK, POWER, { RA, RS, UI } },
1825
1826{ "oris", OP(25), OP_MASK, PPC, { RA, RS, UI } },
1827{ "oriu", OP(25), OP_MASK, POWER, { RA, RS, UI } },
1828
1829{ "xori", OP(26), OP_MASK, PPC, { RA, RS, UI } },
1830{ "xoril", OP(26), OP_MASK, POWER, { RA, RS, UI } },
1831
1832{ "xoris", OP(27), OP_MASK, PPC, { RA, RS, UI } },
1833{ "xoriu", OP(27), OP_MASK, POWER, { RA, RS, UI } },
1834
1835{ "andi.", OP(28), OP_MASK, PPC, { RA, RS, UI } },
1836{ "andil.", OP(28), OP_MASK, POWER, { RA, RS, UI } },
1837
1838{ "andis.", OP(29), OP_MASK, PPC, { RA, RS, UI } },
1839{ "andiu.", OP(29), OP_MASK, POWER, { RA, RS, UI } },
1840
1841{ "rotldi", MD(30,0,0), MDMB_MASK, PPC|B64, { RA, RS, SH6 } },
1842{ "clrldi", MD(30,0,0), MDSH_MASK, PPC|B64, { RA, RS, MB6 } },
1843{ "rldicl", MD(30,0,0), MD_MASK, PPC|B64, { RA, RS, SH6, MB6 } },
1844{ "rotldi.", MD(30,0,1), MDMB_MASK, PPC|B64, { RA, RS, SH6 } },
1845{ "clrldi.", MD(30,0,1), MDSH_MASK, PPC|B64, { RA, RS, MB6 } },
1846{ "rldicl.", MD(30,0,1), MD_MASK, PPC|B64, { RA, RS, SH6, MB6 } },
1847
1848{ "rldicr", MD(30,1,0), MD_MASK, PPC|B64, { RA, RS, SH6, ME6 } },
1849{ "rldicr.", MD(30,1,1), MD_MASK, PPC|B64, { RA, RS, SH6, ME6 } },
1850
1851{ "rldic", MD(30,2,0), MD_MASK, PPC|B64, { RA, RS, SH6, MB6 } },
1852{ "rldic.", MD(30,2,1), MD_MASK, PPC|B64, { RA, RS, SH6, MB6 } },
1853
1854{ "rldimi", MD(30,3,0), MD_MASK, PPC|B64, { RA, RS, SH6, MB6 } },
1855{ "rldimi.", MD(30,3,1), MD_MASK, PPC|B64, { RA, RS, SH6, MB6 } },
1856
1857{ "rotld", MDS(30,8,0), MDSMB_MASK, PPC|B64, { RA, RS, RB } },
1858{ "rldcl", MDS(30,8,0), MDS_MASK, PPC|B64, { RA, RS, RB, MB6 } },
1859{ "rotld.", MDS(30,8,1), MDSMB_MASK, PPC|B64, { RA, RS, RB } },
1860{ "rldcl.", MDS(30,8,1), MDS_MASK, PPC|B64, { RA, RS, RB, MB6 } },
1861
1862{ "rldcr", MDS(30,9,0), MDS_MASK, PPC|B64, { RA, RS, RB, ME6 } },
1863{ "rldcr.", MDS(30,9,1), MDS_MASK, PPC|B64, { RA, RS, RB, ME6 } },
1864
1865{ "cmpw", XCMPL(31,0,0), XCMPL_MASK, PPC, { OBF, RA, RB } },
1866{ "cmpd", XCMPL(31,0,1), XCMPL_MASK, PPC|B64, { OBF, RA, RB } },
1867{ "cmp", X(31,0), XCMP_MASK, PPC, { BF, L, RA, RB } },
1868{ "cmp", X(31,0), XCMPL_MASK, POWER, { BF, RA, RB } },
1869
1870{ "twlgt", XTO(31,4,TOLGT), XTO_MASK, PPC, { RA, RB } },
1871{ "tlgt", XTO(31,4,TOLGT), XTO_MASK, POWER, { RA, RB } },
1872{ "twllt", XTO(31,4,TOLLT), XTO_MASK, PPC, { RA, RB } },
1873{ "tllt", XTO(31,4,TOLLT), XTO_MASK, POWER, { RA, RB } },
1874{ "tweq", XTO(31,4,TOEQ), XTO_MASK, PPC, { RA, RB } },
1875{ "teq", XTO(31,4,TOEQ), XTO_MASK, POWER, { RA, RB } },
1876{ "twlge", XTO(31,4,TOLGE), XTO_MASK, PPC, { RA, RB } },
1877{ "tlge", XTO(31,4,TOLGE), XTO_MASK, POWER, { RA, RB } },
1878{ "twlnl", XTO(31,4,TOLNL), XTO_MASK, PPC, { RA, RB } },
1879{ "tlnl", XTO(31,4,TOLNL), XTO_MASK, POWER, { RA, RB } },
1880{ "twlle", XTO(31,4,TOLLE), XTO_MASK, PPC, { RA, RB } },
1881{ "tlle", XTO(31,4,TOLLE), XTO_MASK, POWER, { RA, RB } },
1882{ "twlng", XTO(31,4,TOLNG), XTO_MASK, PPC, { RA, RB } },
1883{ "tlng", XTO(31,4,TOLNG), XTO_MASK, POWER, { RA, RB } },
1884{ "twgt", XTO(31,4,TOGT), XTO_MASK, PPC, { RA, RB } },
1885{ "tgt", XTO(31,4,TOGT), XTO_MASK, POWER, { RA, RB } },
1886{ "twge", XTO(31,4,TOGE), XTO_MASK, PPC, { RA, RB } },
1887{ "tge", XTO(31,4,TOGE), XTO_MASK, POWER, { RA, RB } },
1888{ "twnl", XTO(31,4,TONL), XTO_MASK, PPC, { RA, RB } },
1889{ "tnl", XTO(31,4,TONL), XTO_MASK, POWER, { RA, RB } },
1890{ "twlt", XTO(31,4,TOLT), XTO_MASK, PPC, { RA, RB } },
1891{ "tlt", XTO(31,4,TOLT), XTO_MASK, POWER, { RA, RB } },
1892{ "twle", XTO(31,4,TOLE), XTO_MASK, PPC, { RA, RB } },
1893{ "tle", XTO(31,4,TOLE), XTO_MASK, POWER, { RA, RB } },
1894{ "twng", XTO(31,4,TONG), XTO_MASK, PPC, { RA, RB } },
1895{ "tng", XTO(31,4,TONG), XTO_MASK, POWER, { RA, RB } },
1896{ "twne", XTO(31,4,TONE), XTO_MASK, PPC, { RA, RB } },
1897{ "tne", XTO(31,4,TONE), XTO_MASK, POWER, { RA, RB } },
1898{ "trap", XTO(31,4,TOU), 0xffffffff, PPC, { 0 } },
1899{ "tw", X(31,4), X_MASK, PPC, { TO, RA, RB } },
1900{ "t", X(31,4), X_MASK, POWER, { TO, RA, RB } },
1901
1902{ "subfc", XO(31,8,0,0), XO_MASK, PPC, { RT, RA, RB } },
1903{ "sf", XO(31,8,0,0), XO_MASK, POWER, { RT, RA, RB } },
1904{ "subc", XO(31,8,0,0), XO_MASK, PPC, { RT, RB, RA } },
1905{ "subfc.", XO(31,8,0,1), XO_MASK, PPC, { RT, RA, RB } },
1906{ "sf.", XO(31,8,0,1), XO_MASK, POWER, { RT, RA, RB } },
1907{ "subc.", XO(31,8,0,1), XO_MASK, PPC, { RT, RB, RA } },
1908{ "subfco", XO(31,8,1,0), XO_MASK, PPC, { RT, RA, RB } },
1909{ "sfo", XO(31,8,1,0), XO_MASK, POWER, { RT, RA, RB } },
1910{ "subco", XO(31,8,1,0), XO_MASK, PPC, { RT, RB, RA } },
1911{ "subfco.", XO(31,8,1,1), XO_MASK, PPC, { RT, RA, RB } },
1912{ "sfo.", XO(31,8,1,1), XO_MASK, POWER, { RT, RA, RB } },
1913{ "subco.", XO(31,8,1,1), XO_MASK, PPC, { RT, RB, RA } },
1914
1915{ "mulhdu", XO(31,9,0,0), XO_MASK, PPC|B64, { RT, RA, RB } },
1916{ "mulhdu.", XO(31,9,0,1), XO_MASK, PPC|B64, { RT, RA, RB } },
1917
1918{ "addc", XO(31,10,0,0), XO_MASK, PPC, { RT, RA, RB } },
1919{ "a", XO(31,10,0,0), XO_MASK, POWER, { RT, RA, RB } },
1920{ "addc.", XO(31,10,0,1), XO_MASK, PPC, { RT, RA, RB } },
1921{ "a.", XO(31,10,0,1), XO_MASK, POWER, { RT, RA, RB } },
1922{ "addco", XO(31,10,1,0), XO_MASK, PPC, { RT, RA, RB } },
1923{ "ao", XO(31,10,1,0), XO_MASK, POWER, { RT, RA, RB } },
1924{ "addco.", XO(31,10,1,1), XO_MASK, PPC, { RT, RA, RB } },
1925{ "ao.", XO(31,10,1,1), XO_MASK, POWER, { RT, RA, RB } },
1926
1927{ "mulhwu", XO(31,11,0,0), XO_MASK, PPC, { RT, RA, RB } },
1928{ "mulhwu.", XO(31,11,0,1), XO_MASK, PPC, { RT, RA, RB } },
1929
1930{ "mfcr", X(31,19), XRARB_MASK, POWER|PPC, { RT } },
1931
1932{ "lwarx", X(31,20), X_MASK, PPC, { RT, RA, RB } },
1933
1934{ "ldx", X(31,21), X_MASK, PPC|B64, { RT, RA, RB } },
1935
1936{ "lwzx", X(31,23), X_MASK, PPC, { RT, RA, RB } },
1937{ "lx", X(31,23), X_MASK, POWER, { RT, RA, RB } },
1938
1939{ "slw", XRC(31,24,0), X_MASK, PPC, { RA, RS, RB } },
1940{ "sl", XRC(31,24,0), X_MASK, POWER, { RA, RS, RB } },
1941{ "slw.", XRC(31,24,1), X_MASK, PPC, { RA, RS, RB } },
1942{ "sl.", XRC(31,24,1), X_MASK, POWER, { RA, RS, RB } },
1943
1944{ "cntlzw", XRC(31,26,0), XRB_MASK, PPC, { RA, RS } },
1945{ "cntlz", XRC(31,26,0), XRB_MASK, POWER, { RA, RS } },
1946{ "cntlzw.", XRC(31,26,1), XRB_MASK, PPC, { RA, RS } },
1947{ "cntlz.", XRC(31,26,1), XRB_MASK, POWER, { RA, RS } },
1948
1949{ "sld", XRC(31,27,0), X_MASK, PPC|B64, { RA, RS, RB } },
1950{ "sld.", XRC(31,27,1), X_MASK, PPC|B64, { RA, RS, RB } },
1951
1952{ "and", XRC(31,28,0), X_MASK, PPC|POWER, { RA, RS, RB } },
1953{ "and.", XRC(31,28,1), X_MASK, PPC|POWER, { RA, RS, RB } },
1954
1955{ "maskg", XRC(31,29,0), X_MASK, POWER|M601, { RA, RS, RB } },
1956{ "maskg.", XRC(31,29,1), X_MASK, POWER|M601, { RA, RS, RB } },
1957
1958{ "cmplw", XCMPL(31,32,0), XCMPL_MASK, PPC, { OBF, RA, RB } },
1959{ "cmpld", XCMPL(31,32,1), XCMPL_MASK, PPC|B64, { OBF, RA, RB } },
1960{ "cmpl", X(31,32), XCMP_MASK, PPC, { BF, L, RA, RB } },
1961{ "cmpl", X(31,32), XCMPL_MASK, POWER, { BF, RA, RB } },
1962
1963{ "subf", XO(31,40,0,0), XO_MASK, PPC, { RT, RA, RB } },
1964{ "sub", XO(31,40,0,0), XO_MASK, PPC, { RT, RB, RA } },
1965{ "subf.", XO(31,40,0,1), XO_MASK, PPC, { RT, RA, RB } },
1966{ "sub.", XO(31,40,0,1), XO_MASK, PPC, { RT, RB, RA } },
1967{ "subfo", XO(31,40,1,0), XO_MASK, PPC, { RT, RA, RB } },
1968{ "subo", XO(31,40,1,0), XO_MASK, PPC, { RT, RB, RA } },
1969{ "subfo.", XO(31,40,1,1), XO_MASK, PPC, { RT, RA, RB } },
1970{ "subo.", XO(31,40,1,1), XO_MASK, PPC, { RT, RB, RA } },
1971
1972{ "ldux", X(31,53), X_MASK, PPC|B64, { RT, RAL, RB } },
1973
1974{ "dcbst", X(31,54), XRT_MASK, PPC, { RA, RB } },
1975
1976{ "lwzux", X(31,55), X_MASK, PPC, { RT, RAL, RB } },
1977{ "lux", X(31,55), X_MASK, POWER, { RT, RA, RB } },
1978
1979{ "cntlzd", XRC(31,58,0), XRB_MASK, PPC|B64, { RA, RS } },
1980{ "cntlzd.", XRC(31,58,1), XRB_MASK, PPC|B64, { RA, RS } },
1981
1982{ "andc", XRC(31,60,0), X_MASK, PPC|POWER, { RA, RS, RB } },
1983{ "andc.", XRC(31,60,1), X_MASK, PPC|POWER, { RA, RS, RB } },
1984
1985{ "tdlgt", XTO(31,68,TOLGT), XTO_MASK, PPC|B64, { RA, RB } },
1986{ "tdllt", XTO(31,68,TOLLT), XTO_MASK, PPC|B64, { RA, RB } },
1987{ "tdeq", XTO(31,68,TOEQ), XTO_MASK, PPC|B64, { RA, RB } },
1988{ "tdlge", XTO(31,68,TOLGE), XTO_MASK, PPC|B64, { RA, RB } },
1989{ "tdlnl", XTO(31,68,TOLNL), XTO_MASK, PPC|B64, { RA, RB } },
1990{ "tdlle", XTO(31,68,TOLLE), XTO_MASK, PPC|B64, { RA, RB } },
1991{ "tdlng", XTO(31,68,TOLNG), XTO_MASK, PPC|B64, { RA, RB } },
1992{ "tdgt", XTO(31,68,TOGT), XTO_MASK, PPC|B64, { RA, RB } },
1993{ "tdge", XTO(31,68,TOGE), XTO_MASK, PPC|B64, { RA, RB } },
1994{ "tdnl", XTO(31,68,TONL), XTO_MASK, PPC|B64, { RA, RB } },
1995{ "tdlt", XTO(31,68,TOLT), XTO_MASK, PPC|B64, { RA, RB } },
1996{ "tdle", XTO(31,68,TOLE), XTO_MASK, PPC|B64, { RA, RB } },
1997{ "tdng", XTO(31,68,TONG), XTO_MASK, PPC|B64, { RA, RB } },
1998{ "tdne", XTO(31,68,TONE), XTO_MASK, PPC|B64, { RA, RB } },
1999{ "td", X(31,68), X_MASK, PPC|B64, { TO, RA, RB } },
2000
2001{ "mulhd", XO(31,73,0,0), XO_MASK, PPC|B64, { RT, RA, RB } },
2002{ "mulhd.", XO(31,73,0,1), XO_MASK, PPC|B64, { RT, RA, RB } },
2003
2004{ "mulhw", XO(31,75,0,0), XO_MASK, PPC, { RT, RA, RB } },
2005{ "mulhw.", XO(31,75,0,1), XO_MASK, PPC, { RT, RA, RB } },
2006
2007{ "mfmsr", X(31,83), XRARB_MASK, PPC|POWER, { RT } },
2008
2009{ "ldarx", X(31,84), X_MASK, PPC|B64, { RT, RA, RB } },
2010
2011{ "dcbf", X(31,86), XRT_MASK, PPC, { RA, RB } },
2012
2013{ "lbzx", X(31,87), X_MASK, PPC|POWER, { RT, RA, RB } },
2014
2015{ "neg", XO(31,104,0,0), XORB_MASK, PPC|POWER, { RT, RA } },
2016{ "neg.", XO(31,104,0,1), XORB_MASK, PPC|POWER, { RT, RA } },
2017{ "nego", XO(31,104,1,0), XORB_MASK, PPC|POWER, { RT, RA } },
2018{ "nego.", XO(31,104,1,1), XORB_MASK, PPC|POWER, { RT, RA } },
2019
2020{ "mul", XO(31,107,0,0), XO_MASK, POWER|M601, { RT, RA, RB } },
2021{ "mul.", XO(31,107,0,1), XO_MASK, POWER|M601, { RT, RA, RB } },
2022{ "mulo", XO(31,107,1,0), XO_MASK, POWER|M601, { RT, RA, RB } },
2023{ "mulo.", XO(31,107,1,1), XO_MASK, POWER|M601, { RT, RA, RB } },
2024
2025{ "clf", X(31,118), XRB_MASK, POWER, { RT, RA } },
2026
2027{ "lbzux", X(31,119), X_MASK, PPC|POWER, { RT, RAL, RB } },
2028
2029{ "not", XRC(31,124,0), X_MASK, PPC|POWER, { RA, RS, RBS } },
2030{ "nor", XRC(31,124,0), X_MASK, PPC|POWER, { RA, RS, RB } },
2031{ "not.", XRC(31,124,1), X_MASK, PPC|POWER, { RA, RS, RBS } },
2032{ "nor.", XRC(31,124,1), X_MASK, PPC|POWER, { RA, RS, RB } },
2033
2034{ "subfe", XO(31,136,0,0), XO_MASK, PPC, { RT, RA, RB } },
2035{ "sfe", XO(31,136,0,0), XO_MASK, POWER, { RT, RA, RB } },
2036{ "subfe.", XO(31,136,0,1), XO_MASK, PPC, { RT, RA, RB } },
2037{ "sfe.", XO(31,136,0,1), XO_MASK, POWER, { RT, RA, RB } },
2038{ "subfeo", XO(31,136,1,0), XO_MASK, PPC, { RT, RA, RB } },
2039{ "sfeo", XO(31,136,1,0), XO_MASK, POWER, { RT, RA, RB } },
2040{ "subfeo.", XO(31,136,1,1), XO_MASK, PPC, { RT, RA, RB } },
2041{ "sfeo.", XO(31,136,1,1), XO_MASK, POWER, { RT, RA, RB } },
2042
2043{ "adde", XO(31,138,0,0), XO_MASK, PPC, { RT, RA, RB } },
2044{ "ae", XO(31,138,0,0), XO_MASK, POWER, { RT, RA, RB } },
2045{ "adde.", XO(31,138,0,1), XO_MASK, PPC, { RT, RA, RB } },
2046{ "ae.", XO(31,138,0,1), XO_MASK, POWER, { RT, RA, RB } },
2047{ "addeo", XO(31,138,1,0), XO_MASK, PPC, { RT, RA, RB } },
2048{ "aeo", XO(31,138,1,0), XO_MASK, POWER, { RT, RA, RB } },
2049{ "addeo.", XO(31,138,1,1), XO_MASK, PPC, { RT, RA, RB } },
2050{ "aeo.", XO(31,138,1,1), XO_MASK, POWER, { RT, RA, RB } },
2051
2052{ "mtcr", XFXM(31,144,0xff), XFXFXM_MASK|FXM_MASK, PPC|POWER, { RS }},
2053{ "mtcrf", X(31,144), XFXFXM_MASK, PPC|POWER, { FXM, RS } },
2054
2055{ "mtmsr", X(31,146), XRARB_MASK, PPC|POWER, { RS } },
2056
2057{ "stdx", X(31,149), X_MASK, PPC|B64, { RS, RA, RB } },
2058
2059{ "stwcx.", XRC(31,150,1), X_MASK, PPC, { RS, RA, RB } },
2060
2061{ "stwx", X(31,151), X_MASK, PPC, { RS, RA, RB } },
2062{ "stx", X(31,151), X_MASK, POWER, { RS, RA, RB } },
2063
2064{ "slq", XRC(31,152,0), X_MASK, POWER|M601, { RA, RS, RB } },
2065{ "slq.", XRC(31,152,1), X_MASK, POWER|M601, { RA, RS, RB } },
2066
2067{ "sle", XRC(31,153,0), X_MASK, POWER|M601, { RA, RS, RB } },
2068{ "sle.", XRC(31,153,1), X_MASK, POWER|M601, { RA, RS, RB } },
2069
2070{ "stdux", X(31,181), X_MASK, PPC|B64, { RS, RAS, RB } },
2071
2072{ "stwux", X(31,183), X_MASK, PPC, { RS, RAS, RB } },
2073{ "stux", X(31,183), X_MASK, POWER, { RS, RA, RB } },
2074
2075{ "sliq", XRC(31,184,0), X_MASK, POWER|M601, { RA, RS, SH } },
2076{ "sliq.", XRC(31,184,1), X_MASK, POWER|M601, { RA, RS, SH } },
2077
2078{ "subfze", XO(31,200,0,0), XORB_MASK, PPC, { RT, RA } },
2079{ "sfze", XO(31,200,0,0), XORB_MASK, POWER, { RT, RA } },
2080{ "subfze.", XO(31,200,0,1), XORB_MASK, PPC, { RT, RA } },
2081{ "sfze.", XO(31,200,0,1), XORB_MASK, POWER, { RT, RA } },
2082{ "subfzeo", XO(31,200,1,0), XORB_MASK, PPC, { RT, RA } },
2083{ "sfzeo", XO(31,200,1,0), XORB_MASK, POWER, { RT, RA } },
2084{ "subfzeo.",XO(31,200,1,1), XORB_MASK, PPC, { RT, RA } },
2085{ "sfzeo.", XO(31,200,1,1), XORB_MASK, POWER, { RT, RA } },
2086
2087{ "addze", XO(31,202,0,0), XORB_MASK, PPC, { RT, RA } },
2088{ "aze", XO(31,202,0,0), XORB_MASK, POWER, { RT, RA } },
2089{ "addze.", XO(31,202,0,1), XORB_MASK, PPC, { RT, RA } },
2090{ "aze.", XO(31,202,0,1), XORB_MASK, POWER, { RT, RA } },
2091{ "addzeo", XO(31,202,1,0), XORB_MASK, PPC, { RT, RA } },
2092{ "azeo", XO(31,202,1,0), XORB_MASK, POWER, { RT, RA } },
2093{ "addzeo.", XO(31,202,1,1), XORB_MASK, PPC, { RT, RA } },
2094{ "azeo.", XO(31,202,1,1), XORB_MASK, POWER, { RT, RA } },
2095
2096{ "mtsr", X(31,210), XRB_MASK|(1<<20), PPC|POWER|B32, { SR, RS } },
2097
2098{ "stdcx.", XRC(31,214,1), X_MASK, PPC|B64, { RS, RA, RB } },
2099
2100{ "stbx", X(31,215), X_MASK, PPC|POWER, { RS, RA, RB } },
2101
2102{ "sllq", XRC(31,216,0), X_MASK, POWER|M601, { RA, RS, RB } },
2103{ "sllq.", XRC(31,216,1), X_MASK, POWER|M601, { RA, RS, RB } },
2104
2105{ "sleq", XRC(31,217,0), X_MASK, POWER|M601, { RA, RS, RB } },
2106{ "sleq.", XRC(31,217,1), X_MASK, POWER|M601, { RA, RS, RB } },
2107
2108{ "subfme", XO(31,232,0,0), XORB_MASK, PPC, { RT, RA } },
2109{ "sfme", XO(31,232,0,0), XORB_MASK, POWER, { RT, RA } },
2110{ "subfme.", XO(31,232,0,1), XORB_MASK, PPC, { RT, RA } },
2111{ "sfme.", XO(31,232,0,1), XORB_MASK, POWER, { RT, RA } },
2112{ "subfmeo", XO(31,232,1,0), XORB_MASK, PPC, { RT, RA } },
2113{ "sfmeo", XO(31,232,1,0), XORB_MASK, POWER, { RT, RA } },
2114{ "subfmeo.",XO(31,232,1,1), XORB_MASK, PPC, { RT, RA } },
2115{ "sfmeo.", XO(31,232,1,1), XORB_MASK, POWER, { RT, RA } },
2116
2117{ "mulld", XO(31,233,0,0), XO_MASK, PPC|B64, { RT, RA, RB } },
2118{ "mulld.", XO(31,233,0,1), XO_MASK, PPC|B64, { RT, RA, RB } },
2119{ "mulldo", XO(31,233,1,0), XO_MASK, PPC|B64, { RT, RA, RB } },
2120{ "mulldo.", XO(31,233,1,1), XO_MASK, PPC|B64, { RT, RA, RB } },
2121
2122{ "addme", XO(31,234,0,0), XORB_MASK, PPC, { RT, RA } },
2123{ "ame", XO(31,234,0,0), XORB_MASK, POWER, { RT, RA } },
2124{ "addme.", XO(31,234,0,1), XORB_MASK, PPC, { RT, RA } },
2125{ "ame.", XO(31,234,0,1), XORB_MASK, POWER, { RT, RA } },
2126{ "addmeo", XO(31,234,1,0), XORB_MASK, PPC, { RT, RA } },
2127{ "ameo", XO(31,234,1,0), XORB_MASK, POWER, { RT, RA } },
2128{ "addmeo.", XO(31,234,1,1), XORB_MASK, PPC, { RT, RA } },
2129{ "ameo.", XO(31,234,1,1), XORB_MASK, POWER, { RT, RA } },
2130
2131{ "mullw", XO(31,235,0,0), XO_MASK, PPC, { RT, RA, RB } },
2132{ "muls", XO(31,235,0,0), XO_MASK, POWER, { RT, RA, RB } },
2133{ "mullw.", XO(31,235,0,1), XO_MASK, PPC, { RT, RA, RB } },
2134{ "muls.", XO(31,235,0,1), XO_MASK, POWER, { RT, RA, RB } },
2135{ "mullwo", XO(31,235,1,0), XO_MASK, PPC, { RT, RA, RB } },
2136{ "mulso", XO(31,235,1,0), XO_MASK, POWER, { RT, RA, RB } },
2137{ "mullwo.", XO(31,235,1,1), XO_MASK, PPC, { RT, RA, RB } },
2138{ "mulso.", XO(31,235,1,1), XO_MASK, POWER, { RT, RA, RB } },
2139
2140{ "mtsrin", X(31,242), XRA_MASK, PPC|B32, { RS, RB } },
2141{ "mtsri", X(31,242), XRA_MASK, POWER|B32, { RS, RB } },
2142
2143{ "dcbtst", X(31,246), XRT_MASK, PPC, { RA, RB } },
2144
2145{ "stbux", X(31,247), X_MASK, PPC|POWER, { RS, RAS, RB } },
2146
2147{ "slliq", XRC(31,248,0), X_MASK, POWER|M601, { RA, RS, SH } },
2148{ "slliq.", XRC(31,248,1), X_MASK, POWER|M601, { RA, RS, SH } },
2149
2150{ "doz", XO(31,264,0,0), XO_MASK, POWER|M601, { RT, RA, RB } },
2151{ "doz.", XO(31,264,0,1), XO_MASK, POWER|M601, { RT, RA, RB } },
2152{ "dozo", XO(31,264,1,0), XO_MASK, POWER|M601, { RT, RA, RB } },
2153{ "dozo.", XO(31,264,1,1), XO_MASK, POWER|M601, { RT, RA, RB } },
2154
2155{ "add", XO(31,266,0,0), XO_MASK, PPC, { RT, RA, RB } },
2156{ "cax", XO(31,266,0,0), XO_MASK, POWER, { RT, RA, RB } },
2157{ "add.", XO(31,266,0,1), XO_MASK, PPC, { RT, RA, RB } },
2158{ "cax.", XO(31,266,0,1), XO_MASK, POWER, { RT, RA, RB } },
2159{ "addo", XO(31,266,1,0), XO_MASK, PPC, { RT, RA, RB } },
2160{ "caxo", XO(31,266,1,0), XO_MASK, POWER, { RT, RA, RB } },
2161{ "addo.", XO(31,266,1,1), XO_MASK, PPC, { RT, RA, RB } },
2162{ "caxo.", XO(31,266,1,1), XO_MASK, POWER, { RT, RA, RB } },
2163
2164{ "lscbx", XRC(31,277,0), X_MASK, POWER|M601, { RT, RA, RB } },
2165{ "lscbx.", XRC(31,277,1), X_MASK, POWER|M601, { RT, RA, RB } },
2166
2167{ "dcbt", X(31,278), XRT_MASK, PPC, { RA, RB } },
2168
2169{ "lhzx", X(31,279), X_MASK, PPC|POWER, { RT, RA, RB } },
2170
2171{ "icbt", X(31,262), XRT_MASK, PPC, { RA, RB } },
2172
2173{ "eqv", XRC(31,284,0), X_MASK, PPC|POWER, { RA, RS, RB } },
2174{ "eqv.", XRC(31,284,1), X_MASK, PPC|POWER, { RA, RS, RB } },
2175
2176{ "tlbie", X(31,306), XRTRA_MASK, PPC, { RB } },
2177{ "tlbi", X(31,306), XRTRA_MASK, POWER, { RB } },
2178
2179{ "eciwx", X(31,310), X_MASK, PPC, { RT, RA, RB } },
2180
2181{ "lhzux", X(31,311), X_MASK, PPC|POWER, { RT, RAL, RB } },
2182
2183{ "xor", XRC(31,316,0), X_MASK, PPC|POWER, { RA, RS, RB } },
2184{ "xor.", XRC(31,316,1), X_MASK, PPC|POWER, { RA, RS, RB } },
2185
2186{ "mfdcr", X(31,323), X_MASK, PPC, { RT, SPR } },
2187
2188{ "div", XO(31,331,0,0), XO_MASK, POWER|M601, { RT, RA, RB } },
2189{ "div.", XO(31,331,0,1), XO_MASK, POWER|M601, { RT, RA, RB } },
2190{ "divo", XO(31,331,1,0), XO_MASK, POWER|M601, { RT, RA, RB } },
2191{ "divo.", XO(31,331,1,1), XO_MASK, POWER|M601, { RT, RA, RB } },
2192
2193{ "mfmq", XSPR(31,339,0), XSPR_MASK, POWER|M601, { RT } },
2194{ "mfxer", XSPR(31,339,1), XSPR_MASK, PPC|POWER, { RT } },
2195{ "mfrtcu", XSPR(31,339,4), XSPR_MASK, PPC|POWER, { RT } },
2196{ "mfrtcl", XSPR(31,339,5), XSPR_MASK, PPC|POWER, { RT } },
2197{ "mfdec", XSPR(31,339,6), XSPR_MASK, POWER|M601, { RT } },
2198{ "mflr", XSPR(31,339,8), XSPR_MASK, PPC|POWER, { RT } },
2199{ "mfctr", XSPR(31,339,9), XSPR_MASK, PPC|POWER, { RT } },
2200{ "mftid", XSPR(31,339,17), XSPR_MASK, POWER, { RT } },
2201{ "mfdsisr", XSPR(31,339,18), XSPR_MASK, PPC|POWER, { RT } },
2202{ "mfdar", XSPR(31,339,19), XSPR_MASK, PPC|POWER, { RT } },
2203{ "mfdec", XSPR(31,339,22), XSPR_MASK, PPC, { RT } },
2204{ "mfsdr0", XSPR(31,339,24), XSPR_MASK, POWER, { RT } },
2205{ "mfsdr1", XSPR(31,339,25), XSPR_MASK, PPC|POWER, { RT } },
2206{ "mfsrr0", XSPR(31,339,26), XSPR_MASK, PPC|POWER, { RT } },
2207{ "mfsrr1", XSPR(31,339,27), XSPR_MASK, PPC|POWER, { RT } },
2208{ "mfsprg", XSPR(31,339,272), XSPRG_MASK, PPC, { RT, SPRG } },
2209{ "mfasr", XSPR(31,339,280), XSPR_MASK, PPC|B64, { RT } },
2210{ "mfear", XSPR(31,339,282), XSPR_MASK, PPC, { RT } },
2211{ "mfpvr", XSPR(31,339,287), XSPR_MASK, PPC, { RT } },
2212{ "mfibatu", XSPR(31,339,528), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
2213{ "mfibatl", XSPR(31,339,529), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
2214{ "mfdbatu", XSPR(31,339,536), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
2215{ "mfdbatl", XSPR(31,339,537), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
2216{ "mfspr", X(31,339), X_MASK, PPC|POWER, { RT, SPR } },
2217
2218{ "lwax", X(31,341), X_MASK, PPC|B64, { RT, RA, RB } },
2219
2220{ "lhax", X(31,343), X_MASK, PPC|POWER, { RT, RA, RB } },
2221
2222{ "dccci", X(31,454), XRT_MASK, PPC, { RA, RB } },
2223
2224{ "abs", XO(31,360,0,0), XORB_MASK, POWER|M601, { RT, RA } },
2225{ "abs.", XO(31,360,0,1), XORB_MASK, POWER|M601, { RT, RA } },
2226{ "abso", XO(31,360,1,0), XORB_MASK, POWER|M601, { RT, RA } },
2227{ "abso.", XO(31,360,1,1), XORB_MASK, POWER|M601, { RT, RA } },
2228
2229{ "divs", XO(31,363,0,0), XO_MASK, POWER|M601, { RT, RA, RB } },
2230{ "divs.", XO(31,363,0,1), XO_MASK, POWER|M601, { RT, RA, RB } },
2231{ "divso", XO(31,363,1,0), XO_MASK, POWER|M601, { RT, RA, RB } },
2232{ "divso.", XO(31,363,1,1), XO_MASK, POWER|M601, { RT, RA, RB } },
2233
2234{ "tlbia", X(31,370), 0xffffffff, PPC, { 0 } },
2235
2236{ "mftbu", XSPR(31,371,269), XSPR_MASK, PPC, { RT } },
2237{ "mftb", X(31,371), X_MASK, PPC, { RT, TBR } },
2238
2239{ "lwaux", X(31,373), X_MASK, PPC|B64, { RT, RAL, RB } },
2240
2241{ "lhaux", X(31,375), X_MASK, PPC|POWER, { RT, RAL, RB } },
2242
2243{ "sthx", X(31,407), X_MASK, PPC|POWER, { RS, RA, RB } },
2244
2245{ "lfqx", X(31,791), X_MASK, POWER2, { FRT, RA, RB } },
2246
2247{ "lfqux", X(31,823), X_MASK, POWER2, { FRT, RA, RB } },
2248
2249{ "stfqx", X(31,919), X_MASK, POWER2, { FRS, RA, RB } },
2250
2251{ "stfqux", X(31,951), X_MASK, POWER2, { FRS, RA, RB } },
2252
2253{ "orc", XRC(31,412,0), X_MASK, PPC|POWER, { RA, RS, RB } },
2254{ "orc.", XRC(31,412,1), X_MASK, PPC|POWER, { RA, RS, RB } },
2255
2256{ "sradi", XS(31,413,0), XS_MASK, PPC|B64, { RA, RS, SH6 } },
2257{ "sradi.", XS(31,413,1), XS_MASK, PPC|B64, { RA, RS, SH6 } },
2258
2259{ "slbie", X(31,434), XRTRA_MASK, PPC|B64, { RB } },
2260
2261{ "ecowx", X(31,438), X_MASK, PPC, { RT, RA, RB } },
2262
2263{ "sthux", X(31,439), X_MASK, PPC|POWER, { RS, RAS, RB } },
2264
2265{ "mr", XRC(31,444,0), X_MASK, PPC|POWER, { RA, RS, RBS } },
2266{ "or", XRC(31,444,0), X_MASK, PPC|POWER, { RA, RS, RB } },
2267{ "mr.", XRC(31,444,1), X_MASK, PPC|POWER, { RA, RS, RBS } },
2268{ "or.", XRC(31,444,1), X_MASK, PPC|POWER, { RA, RS, RB } },
2269
2270{ "mtdcr", X(31,451), X_MASK, PPC, { SPR, RS } },
2271
2272{ "divdu", XO(31,457,0,0), XO_MASK, PPC|B64, { RT, RA, RB } },
2273{ "divdu.", XO(31,457,0,1), XO_MASK, PPC|B64, { RT, RA, RB } },
2274{ "divduo", XO(31,457,1,0), XO_MASK, PPC|B64, { RT, RA, RB } },
2275{ "divduo.", XO(31,457,1,1), XO_MASK, PPC|B64, { RT, RA, RB } },
2276
2277{ "divwu", XO(31,459,0,0), XO_MASK, PPC, { RT, RA, RB } },
2278{ "divwu.", XO(31,459,0,1), XO_MASK, PPC, { RT, RA, RB } },
2279{ "divwuo", XO(31,459,1,0), XO_MASK, PPC, { RT, RA, RB } },
2280{ "divwuo.", XO(31,459,1,1), XO_MASK, PPC, { RT, RA, RB } },
2281
2282{ "mtmq", XSPR(31,467,0), XSPR_MASK, POWER|M601, { RS } },
2283{ "mtxer", XSPR(31,467,1), XSPR_MASK, PPC|POWER, { RS } },
2284{ "mtlr", XSPR(31,467,8), XSPR_MASK, PPC|POWER, { RS } },
2285{ "mtctr", XSPR(31,467,9), XSPR_MASK, PPC|POWER, { RS } },
2286{ "mttid", XSPR(31,467,17), XSPR_MASK, POWER, { RS } },
2287{ "mtdsisr", XSPR(31,467,18), XSPR_MASK, PPC|POWER, { RS } },
2288{ "mtdar", XSPR(31,467,19), XSPR_MASK, PPC|POWER, { RS } },
2289{ "mtrtcu", XSPR(31,467,20), XSPR_MASK, PPC|POWER, { RS } },
2290{ "mtrtcl", XSPR(31,467,21), XSPR_MASK, PPC|POWER, { RS } },
2291{ "mtdec", XSPR(31,467,22), XSPR_MASK, PPC|POWER, { RS } },
2292{ "mtsdr0", XSPR(31,467,24), XSPR_MASK, POWER, { RS } },
2293{ "mtsdr1", XSPR(31,467,25), XSPR_MASK, PPC|POWER, { RS } },
2294{ "mtsrr0", XSPR(31,467,26), XSPR_MASK, PPC|POWER, { RS } },
2295{ "mtsrr1", XSPR(31,467,27), XSPR_MASK, PPC|POWER, { RS } },
2296{ "mtsprg", XSPR(31,467,272), XSPRG_MASK, PPC, { SPRG, RS } },
2297{ "mtasr", XSPR(31,467,280), XSPR_MASK, PPC|B64, { RS } },
2298{ "mtear", XSPR(31,467,282), XSPR_MASK, PPC, { RS } },
2299{ "mttbl", XSPR(31,467,284), XSPR_MASK, PPC, { RS } },
2300{ "mttbu", XSPR(31,467,285), XSPR_MASK, PPC, { RS } },
2301{ "mtibatu", XSPR(31,467,528), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
2302{ "mtibatl", XSPR(31,467,529), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
2303{ "mtdbatu", XSPR(31,467,536), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
2304{ "mtdbatl", XSPR(31,467,537), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
2305{ "mtspr", X(31,467), X_MASK, PPC|POWER, { SPR, RS } },
2306
2307{ "dcbi", X(31,470), XRT_MASK, PPC, { RA, RB } },
2308
2309{ "nand", XRC(31,476,0), X_MASK, PPC|POWER, { RA, RS, RB } },
2310{ "nand.", XRC(31,476,1), X_MASK, PPC|POWER, { RA, RS, RB } },
2311
2312{ "nabs", XO(31,488,0,0), XORB_MASK, POWER|M601, { RT, RA } },
2313{ "nabs.", XO(31,488,0,1), XORB_MASK, POWER|M601, { RT, RA } },
2314{ "nabso", XO(31,488,1,0), XORB_MASK, POWER|M601, { RT, RA } },
2315{ "nabso.", XO(31,488,1,1), XORB_MASK, POWER|M601, { RT, RA } },
2316
2317{ "divd", XO(31,489,0,0), XO_MASK, PPC|B64, { RT, RA, RB } },
2318{ "divd.", XO(31,489,0,1), XO_MASK, PPC|B64, { RT, RA, RB } },
2319{ "divdo", XO(31,489,1,0), XO_MASK, PPC|B64, { RT, RA, RB } },
2320{ "divdo.", XO(31,489,1,1), XO_MASK, PPC|B64, { RT, RA, RB } },
2321
2322{ "divw", XO(31,491,0,0), XO_MASK, PPC, { RT, RA, RB } },
2323{ "divw.", XO(31,491,0,1), XO_MASK, PPC, { RT, RA, RB } },
2324{ "divwo", XO(31,491,1,0), XO_MASK, PPC, { RT, RA, RB } },
2325{ "divwo.", XO(31,491,1,1), XO_MASK, PPC, { RT, RA, RB } },
2326
2327{ "slbia", X(31,498), 0xffffffff, PPC|B64, { 0 } },
2328
2329{ "cli", X(31,502), XRB_MASK, POWER, { RT, RA } },
2330
2331{ "mcrxr", X(31,512), XRARB_MASK|(3<<21), PPC|POWER, { BF } },
2332
2333{ "clcs", X(31,531), XRB_MASK, POWER|M601, { RT, RA } },
2334
2335{ "lswx", X(31,533), X_MASK, PPC, { RT, RA, RB } },
2336{ "lsx", X(31,533), X_MASK, POWER, { RT, RA, RB } },
2337
2338{ "lwbrx", X(31,534), X_MASK, PPC, { RT, RA, RB } },
2339{ "lbrx", X(31,534), X_MASK, POWER, { RT, RA, RB } },
2340
2341{ "lfsx", X(31,535), X_MASK, PPC|POWER, { FRT, RA, RB } },
2342
2343{ "srw", XRC(31,536,0), X_MASK, PPC, { RA, RS, RB } },
2344{ "sr", XRC(31,536,0), X_MASK, POWER, { RA, RS, RB } },
2345{ "srw.", XRC(31,536,1), X_MASK, PPC, { RA, RS, RB } },
2346{ "sr.", XRC(31,536,1), X_MASK, POWER, { RA, RS, RB } },
2347
2348{ "rrib", XRC(31,537,0), X_MASK, POWER|M601, { RA, RS, RB } },
2349{ "rrib.", XRC(31,537,1), X_MASK, POWER|M601, { RA, RS, RB } },
2350
2351{ "srd", XRC(31,539,0), X_MASK, PPC|B64, { RA, RS, RB } },
2352{ "srd.", XRC(31,539,1), X_MASK, PPC|B64, { RA, RS, RB } },
2353
2354{ "maskir", XRC(31,541,0), X_MASK, POWER|M601, { RA, RS, RB } },
2355{ "maskir.", XRC(31,541,1), X_MASK, POWER|M601, { RA, RS, RB } },
2356
2357{ "tlbsync", X(31,566), 0xffffffff, PPC, { 0 } },
2358
2359{ "lfsux", X(31,567), X_MASK, PPC|POWER, { FRT, RAS, RB } },
2360
2361{ "mfsr", X(31,595), XRB_MASK|(1<<20), PPC|POWER|B32, { RT, SR } },
2362
2363{ "lswi", X(31,597), X_MASK, PPC, { RT, RA, NB } },
2364{ "lsi", X(31,597), X_MASK, POWER, { RT, RA, NB } },
2365
2366{ "sync", X(31,598), 0xffffffff, PPC, { 0 } },
2367{ "dcs", X(31,598), 0xffffffff, POWER, { 0 } },
2368
2369{ "lfdx", X(31,599), X_MASK, PPC|POWER, { FRT, RA, RB } },
2370
2371{ "mfsri", X(31,627), X_MASK, POWER, { RT, RA, RB } },
2372
2373{ "dclst", X(31,630), XRB_MASK, POWER, { RS, RA } },
2374
2375{ "lfdux", X(31,631), X_MASK, PPC|POWER, { FRT, RAS, RB } },
2376
2377{ "mfsrin", X(31,659), XRA_MASK, PPC|B32, { RT, RB } },
2378
2379{ "stswx", X(31,661), X_MASK, PPC, { RS, RA, RB } },
2380{ "stsx", X(31,661), X_MASK, POWER, { RS, RA, RB } },
2381
2382{ "stwbrx", X(31,662), X_MASK, PPC, { RS, RA, RB } },
2383{ "stbrx", X(31,662), X_MASK, POWER, { RS, RA, RB } },
2384
2385{ "stfsx", X(31,663), X_MASK, PPC|POWER, { FRS, RA, RB } },
2386
2387{ "srq", XRC(31,664,0), X_MASK, POWER|M601, { RA, RS, RB } },
2388{ "srq.", XRC(31,664,1), X_MASK, POWER|M601, { RA, RS, RB } },
2389
2390{ "sre", XRC(31,665,0), X_MASK, POWER|M601, { RA, RS, RB } },
2391{ "sre.", XRC(31,665,1), X_MASK, POWER|M601, { RA, RS, RB } },
2392
2393{ "stfsux", X(31,695), X_MASK, PPC|POWER, { FRS, RAS, RB } },
2394
2395{ "sriq", XRC(31,696,0), X_MASK, POWER|M601, { RA, RS, SH } },
2396{ "sriq.", XRC(31,696,1), X_MASK, POWER|M601, { RA, RS, SH } },
2397
2398{ "stswi", X(31,725), X_MASK, PPC, { RS, RA, NB } },
2399{ "stsi", X(31,725), X_MASK, POWER, { RS, RA, NB } },
2400
2401{ "stfdx", X(31,727), X_MASK, PPC|POWER, { FRS, RA, RB } },
2402
2403{ "srlq", XRC(31,728,0), X_MASK, POWER|M601, { RA, RS, RB } },
2404{ "srlq.", XRC(31,728,1), X_MASK, POWER|M601, { RA, RS, RB } },
2405
2406{ "sreq", XRC(31,729,0), X_MASK, POWER|M601, { RA, RS, RB } },
2407{ "sreq.", XRC(31,729,1), X_MASK, POWER|M601, { RA, RS, RB } },
2408
2409{ "stfdux", X(31,759), X_MASK, PPC|POWER, { FRS, RAS, RB } },
2410
2411{ "srliq", XRC(31,760,0), X_MASK, POWER|M601, { RA, RS, SH } },
2412{ "srliq.", XRC(31,760,1), X_MASK, POWER|M601, { RA, RS, SH } },
2413
2414{ "lhbrx", X(31,790), X_MASK, PPC|POWER, { RT, RA, RB } },
2415
2416{ "sraw", XRC(31,792,0), X_MASK, PPC, { RA, RS, RB } },
2417{ "sra", XRC(31,792,0), X_MASK, POWER, { RA, RS, RB } },
2418{ "sraw.", XRC(31,792,1), X_MASK, PPC, { RA, RS, RB } },
2419{ "sra.", XRC(31,792,1), X_MASK, POWER, { RA, RS, RB } },
2420
2421{ "srad", XRC(31,794,0), X_MASK, PPC|B64, { RA, RS, RB } },
2422{ "srad.", XRC(31,794,1), X_MASK, PPC|B64, { RA, RS, RB } },
2423
2424{ "rac", X(31,818), X_MASK, POWER, { RT, RA, RB } },
2425
2426{ "srawi", XRC(31,824,0), X_MASK, PPC, { RA, RS, SH } },
2427{ "srai", XRC(31,824,0), X_MASK, POWER, { RA, RS, SH } },
2428{ "srawi.", XRC(31,824,1), X_MASK, PPC, { RA, RS, SH } },
2429{ "srai.", XRC(31,824,1), X_MASK, POWER, { RA, RS, SH } },
2430
2431{ "eieio", X(31,854), 0xffffffff, PPC, { 0 } },
2432
2433{ "sthbrx", X(31,918), X_MASK, PPC|POWER, { RS, RA, RB } },
2434
2435{ "sraq", XRC(31,920,0), X_MASK, POWER|M601, { RA, RS, RB } },
2436{ "sraq.", XRC(31,920,1), X_MASK, POWER|M601, { RA, RS, RB } },
2437
2438{ "srea", XRC(31,921,0), X_MASK, POWER|M601, { RA, RS, RB } },
2439{ "srea.", XRC(31,921,1), X_MASK, POWER|M601, { RA, RS, RB } },
2440
2441{ "extsh", XRC(31,922,0), XRB_MASK, PPC, { RA, RS } },
2442{ "exts", XRC(31,922,0), XRB_MASK, POWER, { RA, RS } },
2443{ "extsh.", XRC(31,922,1), XRB_MASK, PPC, { RA, RS } },
2444{ "exts.", XRC(31,922,1), XRB_MASK, POWER, { RA, RS } },
2445
2446{ "sraiq", XRC(31,952,0), X_MASK, POWER|M601, { RA, RS, SH } },
2447{ "sraiq.", XRC(31,952,1), X_MASK, POWER|M601, { RA, RS, SH } },
2448
2449{ "extsb", XRC(31,954,0), XRB_MASK, PPC, { RA, RS} },
2450{ "extsb.", XRC(31,954,1), XRB_MASK, PPC, { RA, RS} },
2451
2452{ "iccci", X(31,966), XRT_MASK, PPC, { RA, RB } },
2453
2454{ "icbi", X(31,982), XRT_MASK, PPC, { RA, RB } },
2455
2456{ "stfiwx", X(31,983), X_MASK, PPC, { FRS, RA, RB } },
2457
2458{ "extsw", XRC(31,986,0), XRB_MASK, PPC, { RA, RS } },
2459{ "extsw.", XRC(31,986,1), XRB_MASK, PPC, { RA, RS } },
2460
2461{ "dcbz", X(31,1014), XRT_MASK, PPC, { RA, RB } },
2462{ "dclz", X(31,1014), XRT_MASK, PPC, { RA, RB } },
2463
2464{ "lwz", OP(32), OP_MASK, PPC, { RT, D, RA } },
2465{ "l", OP(32), OP_MASK, POWER, { RT, D, RA } },
2466
2467{ "lwzu", OP(33), OP_MASK, PPC, { RT, D, RAL } },
2468{ "lu", OP(33), OP_MASK, POWER, { RT, D, RA } },
2469
2470{ "lbz", OP(34), OP_MASK, PPC|POWER, { RT, D, RA } },
2471
2472{ "lbzu", OP(35), OP_MASK, PPC|POWER, { RT, D, RAL } },
2473
2474{ "stw", OP(36), OP_MASK, PPC, { RS, D, RA } },
2475{ "st", OP(36), OP_MASK, POWER, { RS, D, RA } },
2476
2477{ "stwu", OP(37), OP_MASK, PPC, { RS, D, RAS } },
2478{ "stu", OP(37), OP_MASK, POWER, { RS, D, RA } },
2479
2480{ "stb", OP(38), OP_MASK, PPC|POWER, { RS, D, RA } },
2481
2482{ "stbu", OP(39), OP_MASK, PPC|POWER, { RS, D, RAS } },
2483
2484{ "lhz", OP(40), OP_MASK, PPC|POWER, { RT, D, RA } },
2485
2486{ "lhzu", OP(41), OP_MASK, PPC|POWER, { RT, D, RAL } },
2487
2488{ "lha", OP(42), OP_MASK, PPC|POWER, { RT, D, RA } },
2489
2490{ "lhau", OP(43), OP_MASK, PPC|POWER, { RT, D, RAL } },
2491
2492{ "sth", OP(44), OP_MASK, PPC|POWER, { RS, D, RA } },
2493
2494{ "sthu", OP(45), OP_MASK, PPC|POWER, { RS, D, RAS } },
2495
2496{ "lmw", OP(46), OP_MASK, PPC, { RT, D, RAM } },
2497{ "lm", OP(46), OP_MASK, POWER, { RT, D, RA } },
2498
2499{ "stmw", OP(47), OP_MASK, PPC, { RS, D, RA } },
2500{ "stm", OP(47), OP_MASK, POWER, { RS, D, RA } },
2501
2502{ "lfs", OP(48), OP_MASK, PPC|POWER, { FRT, D, RA } },
2503
2504{ "lfsu", OP(49), OP_MASK, PPC|POWER, { FRT, D, RAS } },
2505
2506{ "lfd", OP(50), OP_MASK, PPC|POWER, { FRT, D, RA } },
2507
2508{ "lfdu", OP(51), OP_MASK, PPC|POWER, { FRT, D, RAS } },
2509
2510{ "stfs", OP(52), OP_MASK, PPC|POWER, { FRS, D, RA } },
2511
2512{ "stfsu", OP(53), OP_MASK, PPC|POWER, { FRS, D, RAS } },
2513
2514{ "stfd", OP(54), OP_MASK, PPC|POWER, { FRS, D, RA } },
2515
2516{ "stfdu", OP(55), OP_MASK, PPC|POWER, { FRS, D, RAS } },
2517
2518{ "lfq", OP(56), OP_MASK, POWER2, { FRT, D, RA } },
2519
2520{ "lfqu", OP(57), OP_MASK, POWER2, { FRT, D, RA } },
2521
2522{ "ld", DSO(58,0), DS_MASK, PPC|B64, { RT, DS, RA } },
2523
2524{ "ldu", DSO(58,1), DS_MASK, PPC|B64, { RT, DS, RAL } },
2525
2526{ "lwa", DSO(58,2), DS_MASK, PPC|B64, { RT, DS, RA } },
2527
2528{ "fdivs", A(59,18,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
2529{ "fdivs.", A(59,18,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
2530
2531{ "fsubs", A(59,20,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
2532{ "fsubs.", A(59,20,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
2533
2534{ "fadds", A(59,21,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
2535{ "fadds.", A(59,21,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
2536
2537{ "fsqrts", A(59,22,0), AFRAFRC_MASK, PPC, { FRT, FRB } },
2538{ "fsqrts.", A(59,22,1), AFRAFRC_MASK, PPC, { FRT, FRB } },
2539
2540{ "fres", A(59,24,0), AFRAFRC_MASK, PPC, { FRT, FRB } },
2541{ "fres.", A(59,24,1), AFRAFRC_MASK, PPC, { FRT, FRB } },
2542
2543{ "fmuls", A(59,25,0), AFRB_MASK, PPC, { FRT, FRA, FRC } },
2544{ "fmuls.", A(59,25,1), AFRB_MASK, PPC, { FRT, FRA, FRC } },
2545
2546{ "fmsubs", A(59,28,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2547{ "fmsubs.", A(59,28,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2548
2549{ "fmadds", A(59,29,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2550{ "fmadds.", A(59,29,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2551
2552{ "fnmsubs", A(59,30,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2553{ "fnmsubs.",A(59,30,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2554
2555{ "fnmadds", A(59,31,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2556{ "fnmadds.",A(59,31,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2557
2558{ "stfq", OP(60), OP_MASK, POWER2, { FRS, D, RA } },
2559
2560{ "stfqu", OP(61), OP_MASK, POWER2, { FRS, D, RA } },
2561
2562{ "std", DSO(62,0), DS_MASK, PPC|B64, { RS, DS, RA } },
2563
2564{ "stdu", DSO(62,1), DS_MASK, PPC|B64, { RS, DS, RAS } },
2565
2566{ "fcmpu", X(63,0), X_MASK|(3<<21), PPC|POWER, { BF, FRA, FRB } },
2567
2568{ "frsp", XRC(63,12,0), XRA_MASK, PPC|POWER, { FRT, FRB } },
2569{ "frsp.", XRC(63,12,1), XRA_MASK, PPC|POWER, { FRT, FRB } },
2570
2571{ "fctiw", XRC(63,14,0), XRA_MASK, PPC, { FRT, FRB } },
2572{ "fcir", XRC(63,14,0), XRA_MASK, POWER2, { FRT, FRB } },
2573{ "fctiw.", XRC(63,14,1), XRA_MASK, PPC, { FRT, FRB } },
2574{ "fcir.", XRC(63,14,1), XRA_MASK, POWER2, { FRT, FRB } },
2575
2576{ "fctiwz", XRC(63,15,0), XRA_MASK, PPC, { FRT, FRB } },
2577{ "fcirz", XRC(63,15,0), XRA_MASK, POWER2, { FRT, FRB } },
2578{ "fctiwz.", XRC(63,15,1), XRA_MASK, PPC, { FRT, FRB } },
2579{ "fcirz.", XRC(63,15,1), XRA_MASK, POWER2, { FRT, FRB } },
2580
2581{ "fdiv", A(63,18,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
2582{ "fd", A(63,18,0), AFRC_MASK, POWER, { FRT, FRA, FRB } },
2583{ "fdiv.", A(63,18,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
2584{ "fd.", A(63,18,1), AFRC_MASK, POWER, { FRT, FRA, FRB } },
2585
2586{ "fsub", A(63,20,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
2587{ "fs", A(63,20,0), AFRC_MASK, POWER, { FRT, FRA, FRB } },
2588{ "fsub.", A(63,20,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
2589{ "fs.", A(63,20,1), AFRC_MASK, POWER, { FRT, FRA, FRB } },
2590
2591{ "fadd", A(63,21,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
2592{ "fa", A(63,21,0), AFRC_MASK, POWER, { FRT, FRA, FRB } },
2593{ "fadd.", A(63,21,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
2594{ "fa.", A(63,21,1), AFRC_MASK, POWER, { FRT, FRA, FRB } },
2595
2596{ "fsqrt", A(63,22,0), AFRAFRC_MASK, PPC|POWER2, { FRT, FRB } },
2597{ "fsqrt.", A(63,22,1), AFRAFRC_MASK, PPC|POWER2, { FRT, FRB } },
2598
2599{ "fsel", A(63,23,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2600{ "fsel.", A(63,23,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2601
2602{ "fmul", A(63,25,0), AFRB_MASK, PPC, { FRT, FRA, FRC } },
2603{ "fm", A(63,25,0), AFRB_MASK, POWER, { FRT, FRA, FRC } },
2604{ "fmul.", A(63,25,1), AFRB_MASK, PPC, { FRT, FRA, FRC } },
2605{ "fm.", A(63,25,1), AFRB_MASK, POWER, { FRT, FRA, FRC } },
2606
2607{ "frsqrte", A(63,26,0), AFRAFRC_MASK, PPC, { FRT, FRB } },
2608{ "frsqrte.",A(63,26,1), AFRAFRC_MASK, PPC, { FRT, FRB } },
2609
2610{ "fmsub", A(63,28,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2611{ "fms", A(63,28,0), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
2612{ "fmsub.", A(63,28,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2613{ "fms.", A(63,28,1), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
2614
2615{ "fmadd", A(63,29,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2616{ "fma", A(63,29,0), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
2617{ "fmadd.", A(63,29,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2618{ "fma.", A(63,29,1), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
2619
2620{ "fnmsub", A(63,30,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2621{ "fnms", A(63,30,0), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
2622{ "fnmsub.", A(63,30,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2623{ "fnms.", A(63,30,1), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
2624
2625{ "fnmadd", A(63,31,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2626{ "fnma", A(63,31,0), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
2627{ "fnmadd.", A(63,31,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
2628{ "fnma.", A(63,31,1), A_MASK, POWER, { FRT,FRA,FRC,FRB } },
2629
2630{ "fcmpo", X(63,30), X_MASK|(3<<21), PPC|POWER, { BF, FRA, FRB } },
2631
2632{ "mtfsb1", XRC(63,38,0), XRARB_MASK, PPC|POWER, { BT } },
2633{ "mtfsb1.", XRC(63,38,1), XRARB_MASK, PPC|POWER, { BT } },
2634
2635{ "fneg", XRC(63,40,0), XRA_MASK, PPC|POWER, { FRT, FRB } },
2636{ "fneg.", XRC(63,40,1), XRA_MASK, PPC|POWER, { FRT, FRB } },
2637
2638{ "mcrfs", X(63,64), XRB_MASK|(3<<21)|(3<<16), PPC|POWER, { BF, BFA } },
2639
2640{ "mtfsb0", XRC(63,70,0), XRARB_MASK, PPC|POWER, { BT } },
2641{ "mtfsb0.", XRC(63,70,1), XRARB_MASK, PPC|POWER, { BT } },
2642
2643{ "fmr", XRC(63,72,0), XRA_MASK, PPC|POWER, { FRT, FRB } },
2644{ "fmr.", XRC(63,72,1), XRA_MASK, PPC|POWER, { FRT, FRB } },
2645
2646{ "mtfsfi", XRC(63,134,0), XRA_MASK|(3<<21)|(1<<11), PPC|POWER, { BF, U } },
2647{ "mtfsfi.", XRC(63,134,1), XRA_MASK|(3<<21)|(1<<11), PPC|POWER, { BF, U } },
2648
2649{ "fnabs", XRC(63,136,0), XRA_MASK, PPC|POWER, { FRT, FRB } },
2650{ "fnabs.", XRC(63,136,1), XRA_MASK, PPC|POWER, { FRT, FRB } },
2651
2652{ "fabs", XRC(63,264,0), XRA_MASK, PPC|POWER, { FRT, FRB } },
2653{ "fabs.", XRC(63,264,1), XRA_MASK, PPC|POWER, { FRT, FRB } },
2654
2655{ "mffs", XRC(63,583,0), XRARB_MASK, PPC|POWER, { FRT } },
2656{ "mffs.", XRC(63,583,1), XRARB_MASK, PPC|POWER, { FRT } },
2657
2658{ "mtfsf", XFL(63,711,0), XFL_MASK, PPC|POWER, { FLM, FRB } },
2659{ "mtfsf.", XFL(63,711,1), XFL_MASK, PPC|POWER, { FLM, FRB } },
2660
2661{ "fctid", XRC(63,814,0), XRA_MASK, PPC|B64, { FRT, FRB } },
2662{ "fctid.", XRC(63,814,1), XRA_MASK, PPC|B64, { FRT, FRB } },
2663
2664{ "fctidz", XRC(63,815,0), XRA_MASK, PPC|B64, { FRT, FRB } },
2665{ "fctidz.", XRC(63,815,1), XRA_MASK, PPC|B64, { FRT, FRB } },
2666
2667{ "fcfid", XRC(63,846,0), XRA_MASK, PPC|B64, { FRT, FRB } },
2668{ "fcfid.", XRC(63,846,1), XRA_MASK, PPC|B64, { FRT, FRB } },
2669
2670};
2671
2672const int powerpc_num_opcodes =
2673 sizeof (powerpc_opcodes) / sizeof (powerpc_opcodes[0]);
2674
2675/* The macro table. This is only used by the assembler. */
2676
2677const struct powerpc_macro powerpc_macros[] = {
2678{ "extldi", 4, PPC|B64, "rldicr %0,%1,%3,(%2)-1" },
2679{ "extldi.", 4, PPC|B64, "rldicr. %0,%1,%3,(%2)-1" },
2680{ "extrdi", 4, PPC|B64, "rldicl %0,%1,(%2)+(%3),64-(%2)" },
2681{ "extrdi.", 4, PPC|B64, "rldicl. %0,%1,(%2)+(%3),64-(%2)" },
2682{ "insrdi", 4, PPC|B64, "rldimi %0,%1,64-((%2)+(%3)),%3" },
2683{ "insrdi.", 4, PPC|B64, "rldimi. %0,%1,64-((%2)+(%3)),%3" },
2684{ "rotrdi", 3, PPC|B64, "rldicl %0,%1,64-(%2),0" },
2685{ "rotrdi.", 3, PPC|B64, "rldicl. %0,%1,64-(%2),0" },
2686{ "sldi", 3, PPC|B64, "rldicr %0,%1,%2,63-(%2)" },
2687{ "sldi.", 3, PPC|B64, "rldicr. %0,%1,%2,63-(%2)" },
2688{ "srdi", 3, PPC|B64, "rldicl %0,%1,64-(%2),%2" },
2689{ "srdi.", 3, PPC|B64, "rldicl. %0,%1,64-(%2),%2" },
2690{ "clrrdi", 3, PPC|B64, "rldicr %0,%1,0,63-(%2)" },
2691{ "clrrdi.", 3, PPC|B64, "rldicr. %0,%1,0,63-(%2)" },
2692{ "clrlsldi",4, PPC|B64, "rldic %0,%1,%3,(%2)-(%3)" },
2693{ "clrlsldi.",4, PPC|B64, "rldic. %0,%1,%3,(%2)-(%3)" },
2694
2695{ "extlwi", 4, PPC, "rlwinm %0,%1,%3,0,(%2)-1" },
2696{ "extlwi.", 4, PPC, "rlwinm. %0,%1,%3,0,(%2)-1" },
2697{ "extrwi", 4, PPC, "rlwinm %0,%1,(%2)+(%3),32-(%2),31" },
2698{ "extrwi.", 4, PPC, "rlwinm. %0,%1,(%2)+(%3),32-(%2),31" },
2699{ "inslwi", 4, PPC, "rlwimi %0,%1,32-(%3),%3,(%2)+(%3)-1" },
2700{ "inslwi.", 4, PPC, "rlwimi. %0,%1,32-(%3),%3,(%2)+(%3)-1" },
2701{ "insrwi", 4, PPC, "rlwimi %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1" },
2702{ "insrwi.", 4, PPC, "rlwimi. %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1"},
2703{ "rotrwi", 3, PPC, "rlwinm %0,%1,32-(%2),0,31" },
2704{ "rotrwi.", 3, PPC, "rlwinm. %0,%1,32-(%2),0,31" },
2705{ "slwi", 3, PPC, "rlwinm %0,%1,%2,0,31-(%2)" },
2706{ "sli", 3, POWER, "rlinm %0,%1,%2,0,31-(%2)" },
2707{ "slwi.", 3, PPC, "rlwinm. %0,%1,%2,0,31-(%2)" },
2708{ "sli.", 3, POWER, "rlinm. %0,%1,%2,0,31-(%2)" },
2709{ "srwi", 3, PPC, "rlwinm %0,%1,32-(%2),%2,31" },
2710{ "sri", 3, POWER, "rlinm %0,%1,32-(%2),%2,31" },
2711{ "srwi.", 3, PPC, "rlwinm. %0,%1,32-(%2),%2,31" },
2712{ "sri.", 3, POWER, "rlinm. %0,%1,32-(%2),%2,31" },
2713{ "clrrwi", 3, PPC, "rlwinm %0,%1,0,0,31-(%2)" },
2714{ "clrrwi.", 3, PPC, "rlwinm. %0,%1,0,0,31-(%2)" },
2715{ "clrlslwi",4, PPC, "rlwinm %0,%1,%3,(%2)-(%3),31-(%3)" },
2716{ "clrlslwi.",4, PPC, "rlwinm. %0,%1,%3,(%2)-(%3),31-(%3)" },
2717
2718};
2719
2720const int powerpc_num_macros =
2721 sizeof (powerpc_macros) / sizeof (powerpc_macros[0]);
diff --git a/arch/ppc/xmon/ppc.h b/arch/ppc/xmon/ppc.h
new file mode 100644
index 000000000000..2345ecba1fe9
--- /dev/null
+++ b/arch/ppc/xmon/ppc.h
@@ -0,0 +1,240 @@
1/* ppc.h -- Header file for PowerPC opcode table
2 Copyright 1994 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Cygnus Support
4
5This file is part of GDB, GAS, and the GNU binutils.
6
7GDB, GAS, and the GNU binutils are free software; you can redistribute
8them and/or modify them under the terms of the GNU General Public
9License as published by the Free Software Foundation; either version
101, or (at your option) any later version.
11
12GDB, GAS, and the GNU binutils are distributed in the hope that they
13will be useful, but WITHOUT ANY WARRANTY; without even the implied
14warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15the GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this file; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21#ifndef PPC_H
22#define PPC_H
23
24/* The opcode table is an array of struct powerpc_opcode. */
25
26struct powerpc_opcode
27{
28 /* The opcode name. */
29 const char *name;
30
31 /* The opcode itself. Those bits which will be filled in with
32 operands are zeroes. */
33 unsigned long opcode;
34
35 /* The opcode mask. This is used by the disassembler. This is a
36 mask containing ones indicating those bits which must match the
37 opcode field, and zeroes indicating those bits which need not
38 match (and are presumably filled in by operands). */
39 unsigned long mask;
40
41 /* One bit flags for the opcode. These are used to indicate which
42 specific processors support the instructions. The defined values
43 are listed below. */
44 unsigned long flags;
45
46 /* An array of operand codes. Each code is an index into the
47 operand table. They appear in the order which the operands must
48 appear in assembly code, and are terminated by a zero. */
49 unsigned char operands[8];
50};
51
52/* The table itself is sorted by major opcode number, and is otherwise
53 in the order in which the disassembler should consider
54 instructions. */
55extern const struct powerpc_opcode powerpc_opcodes[];
56extern const int powerpc_num_opcodes;
57
58/* Values defined for the flags field of a struct powerpc_opcode. */
59
60/* Opcode is defined for the PowerPC architecture. */
61#define PPC_OPCODE_PPC (01)
62
63/* Opcode is defined for the POWER (RS/6000) architecture. */
64#define PPC_OPCODE_POWER (02)
65
66/* Opcode is defined for the POWER2 (Rios 2) architecture. */
67#define PPC_OPCODE_POWER2 (04)
68
69/* Opcode is only defined on 32 bit architectures. */
70#define PPC_OPCODE_32 (010)
71
72/* Opcode is only defined on 64 bit architectures. */
73#define PPC_OPCODE_64 (020)
74
75/* Opcode is supported by the Motorola PowerPC 601 processor. The 601
76 is assumed to support all PowerPC (PPC_OPCODE_PPC) instructions,
77 but it also supports many additional POWER instructions. */
78#define PPC_OPCODE_601 (040)
79
80/* A macro to extract the major opcode from an instruction. */
81#define PPC_OP(i) (((i) >> 26) & 0x3f)
82
83/* The operands table is an array of struct powerpc_operand. */
84
85struct powerpc_operand
86{
87 /* The number of bits in the operand. */
88 int bits;
89
90 /* How far the operand is left shifted in the instruction. */
91 int shift;
92
93 /* Insertion function. This is used by the assembler. To insert an
94 operand value into an instruction, check this field.
95
96 If it is NULL, execute
97 i |= (op & ((1 << o->bits) - 1)) << o->shift;
98 (i is the instruction which we are filling in, o is a pointer to
99 this structure, and op is the opcode value; this assumes twos
100 complement arithmetic).
101
102 If this field is not NULL, then simply call it with the
103 instruction and the operand value. It will return the new value
104 of the instruction. If the ERRMSG argument is not NULL, then if
105 the operand value is illegal, *ERRMSG will be set to a warning
106 string (the operand will be inserted in any case). If the
107 operand value is legal, *ERRMSG will be unchanged (most operands
108 can accept any value). */
109 unsigned long (*insert) PARAMS ((unsigned long instruction, long op,
110 const char **errmsg));
111
112 /* Extraction function. This is used by the disassembler. To
113 extract this operand type from an instruction, check this field.
114
115 If it is NULL, compute
116 op = ((i) >> o->shift) & ((1 << o->bits) - 1);
117 if ((o->flags & PPC_OPERAND_SIGNED) != 0
118 && (op & (1 << (o->bits - 1))) != 0)
119 op -= 1 << o->bits;
120 (i is the instruction, o is a pointer to this structure, and op
121 is the result; this assumes twos complement arithmetic).
122
123 If this field is not NULL, then simply call it with the
124 instruction value. It will return the value of the operand. If
125 the INVALID argument is not NULL, *INVALID will be set to
126 non-zero if this operand type can not actually be extracted from
127 this operand (i.e., the instruction does not match). If the
128 operand is valid, *INVALID will not be changed. */
129 long (*extract) PARAMS ((unsigned long instruction, int *invalid));
130
131 /* One bit syntax flags. */
132 unsigned long flags;
133};
134
135/* Elements in the table are retrieved by indexing with values from
136 the operands field of the powerpc_opcodes table. */
137
138extern const struct powerpc_operand powerpc_operands[];
139
140/* Values defined for the flags field of a struct powerpc_operand. */
141
142/* This operand takes signed values. */
143#define PPC_OPERAND_SIGNED (01)
144
145/* This operand takes signed values, but also accepts a full positive
146 range of values when running in 32 bit mode. That is, if bits is
147 16, it takes any value from -0x8000 to 0xffff. In 64 bit mode,
148 this flag is ignored. */
149#define PPC_OPERAND_SIGNOPT (02)
150
151/* This operand does not actually exist in the assembler input. This
152 is used to support extended mnemonics such as mr, for which two
153 operands fields are identical. The assembler should call the
154 insert function with any op value. The disassembler should call
155 the extract function, ignore the return value, and check the value
156 placed in the valid argument. */
157#define PPC_OPERAND_FAKE (04)
158
159/* The next operand should be wrapped in parentheses rather than
160 separated from this one by a comma. This is used for the load and
161 store instructions which want their operands to look like
162 reg,displacement(reg)
163 */
164#define PPC_OPERAND_PARENS (010)
165
166/* This operand may use the symbolic names for the CR fields, which
167 are
168 lt 0 gt 1 eq 2 so 3 un 3
169 cr0 0 cr1 1 cr2 2 cr3 3
170 cr4 4 cr5 5 cr6 6 cr7 7
171 These may be combined arithmetically, as in cr2*4+gt. These are
172 only supported on the PowerPC, not the POWER. */
173#define PPC_OPERAND_CR (020)
174
175/* This operand names a register. The disassembler uses this to print
176 register names with a leading 'r'. */
177#define PPC_OPERAND_GPR (040)
178
179/* This operand names a floating point register. The disassembler
180 prints these with a leading 'f'. */
181#define PPC_OPERAND_FPR (0100)
182
183/* This operand is a relative branch displacement. The disassembler
184 prints these symbolically if possible. */
185#define PPC_OPERAND_RELATIVE (0200)
186
187/* This operand is an absolute branch address. The disassembler
188 prints these symbolically if possible. */
189#define PPC_OPERAND_ABSOLUTE (0400)
190
191/* This operand is optional, and is zero if omitted. This is used for
192 the optional BF and L fields in the comparison instructions. The
193 assembler must count the number of operands remaining on the line,
194 and the number of operands remaining for the opcode, and decide
195 whether this operand is present or not. The disassembler should
196 print this operand out only if it is not zero. */
197#define PPC_OPERAND_OPTIONAL (01000)
198
199/* This flag is only used with PPC_OPERAND_OPTIONAL. If this operand
200 is omitted, then for the next operand use this operand value plus
201 1, ignoring the next operand field for the opcode. This wretched
202 hack is needed because the Power rotate instructions can take
203 either 4 or 5 operands. The disassembler should print this operand
204 out regardless of the PPC_OPERAND_OPTIONAL field. */
205#define PPC_OPERAND_NEXT (02000)
206
207/* This operand should be regarded as a negative number for the
208 purposes of overflow checking (i.e., the normal most negative
209 number is disallowed and one more than the normal most positive
210 number is allowed). This flag will only be set for a signed
211 operand. */
212#define PPC_OPERAND_NEGATIVE (04000)
213
214/* The POWER and PowerPC assemblers use a few macros. We keep them
215 with the operands table for simplicity. The macro table is an
216 array of struct powerpc_macro. */
217
218struct powerpc_macro
219{
220 /* The macro name. */
221 const char *name;
222
223 /* The number of operands the macro takes. */
224 unsigned int operands;
225
226 /* One bit flags for the opcode. These are used to indicate which
227 specific processors support the instructions. The values are the
228 same as those for the struct powerpc_opcode flags field. */
229 unsigned long flags;
230
231 /* A format string to turn the macro into a normal instruction.
232 Each %N in the string is replaced with operand number N (zero
233 based). */
234 const char *format;
235};
236
237extern const struct powerpc_macro powerpc_macros[];
238extern const int powerpc_num_macros;
239
240#endif /* PPC_H */
diff --git a/arch/ppc/xmon/privinst.h b/arch/ppc/xmon/privinst.h
new file mode 100644
index 000000000000..93978c027ca0
--- /dev/null
+++ b/arch/ppc/xmon/privinst.h
@@ -0,0 +1,91 @@
1/*
2 * Copyright (C) 1996 Paul Mackerras.
3 */
4#include <linux/config.h>
5
6#define GETREG(reg) \
7 static inline int get_ ## reg (void) \
8 { int ret; asm volatile ("mf" #reg " %0" : "=r" (ret) :); return ret; }
9
10#define SETREG(reg) \
11 static inline void set_ ## reg (int val) \
12 { asm volatile ("mt" #reg " %0" : : "r" (val)); }
13
14GETREG(msr)
15SETREG(msr)
16GETREG(cr)
17
18#define GSETSPR(n, name) \
19 static inline int get_ ## name (void) \
20 { int ret; asm volatile ("mfspr %0," #n : "=r" (ret) : ); return ret; } \
21 static inline void set_ ## name (int val) \
22 { asm volatile ("mtspr " #n ",%0" : : "r" (val)); }
23
24GSETSPR(0, mq)
25GSETSPR(1, xer)
26GSETSPR(4, rtcu)
27GSETSPR(5, rtcl)
28GSETSPR(8, lr)
29GSETSPR(9, ctr)
30GSETSPR(18, dsisr)
31GSETSPR(19, dar)
32GSETSPR(22, dec)
33GSETSPR(25, sdr1)
34GSETSPR(26, srr0)
35GSETSPR(27, srr1)
36GSETSPR(272, sprg0)
37GSETSPR(273, sprg1)
38GSETSPR(274, sprg2)
39GSETSPR(275, sprg3)
40GSETSPR(282, ear)
41GSETSPR(287, pvr)
42#ifndef CONFIG_8xx
43GSETSPR(528, bat0u)
44GSETSPR(529, bat0l)
45GSETSPR(530, bat1u)
46GSETSPR(531, bat1l)
47GSETSPR(532, bat2u)
48GSETSPR(533, bat2l)
49GSETSPR(534, bat3u)
50GSETSPR(535, bat3l)
51GSETSPR(1008, hid0)
52GSETSPR(1009, hid1)
53GSETSPR(1010, iabr)
54GSETSPR(1013, dabr)
55GSETSPR(1023, pir)
56#else
57GSETSPR(144, cmpa)
58GSETSPR(145, cmpb)
59GSETSPR(146, cmpc)
60GSETSPR(147, cmpd)
61GSETSPR(158, ictrl)
62#endif
63
64static inline int get_sr(int n)
65{
66 int ret;
67
68 asm (" mfsrin %0,%1" : "=r" (ret) : "r" (n << 28));
69 return ret;
70}
71
72static inline void set_sr(int n, int val)
73{
74 asm ("mtsrin %0,%1" : : "r" (val), "r" (n << 28));
75}
76
77static inline void store_inst(void *p)
78{
79 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
80}
81
82static inline void cflush(void *p)
83{
84 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
85}
86
87static inline void cinval(void *p)
88{
89 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
90}
91
diff --git a/arch/ppc/xmon/setjmp.c b/arch/ppc/xmon/setjmp.c
new file mode 100644
index 000000000000..28352bac2ae6
--- /dev/null
+++ b/arch/ppc/xmon/setjmp.c
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 1996 Paul Mackerras.
3 *
4 * NB this file must be compiled with -O2.
5 */
6
7int
8xmon_setjmp(long *buf)
9{
10 asm ("mflr 0; stw 0,0(%0);"
11 "stw 1,4(%0); stw 2,8(%0);"
12 "mfcr 0; stw 0,12(%0);"
13 "stmw 13,16(%0)"
14 : : "r" (buf));
15 /* XXX should save fp regs as well */
16 return 0;
17}
18
19void
20xmon_longjmp(long *buf, int val)
21{
22 if (val == 0)
23 val = 1;
24 asm ("lmw 13,16(%0);"
25 "lwz 0,12(%0); mtcrf 0x38,0;"
26 "lwz 0,0(%0); lwz 1,4(%0); lwz 2,8(%0);"
27 "mtlr 0; mr 3,%1"
28 : : "r" (buf), "r" (val));
29}
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
new file mode 100644
index 000000000000..507d4eeffe07
--- /dev/null
+++ b/arch/ppc/xmon/start.c
@@ -0,0 +1,646 @@
1/*
2 * Copyright (C) 1996 Paul Mackerras.
3 */
4#include <linux/config.h>
5#include <linux/string.h>
6#include <asm/machdep.h>
7#include <asm/io.h>
8#include <asm/page.h>
9#include <linux/adb.h>
10#include <linux/pmu.h>
11#include <linux/cuda.h>
12#include <linux/kernel.h>
13#include <linux/errno.h>
14#include <linux/sysrq.h>
15#include <linux/bitops.h>
16#include <asm/xmon.h>
17#include <asm/prom.h>
18#include <asm/bootx.h>
19#include <asm/machdep.h>
20#include <asm/errno.h>
21#include <asm/pmac_feature.h>
22#include <asm/processor.h>
23#include <asm/delay.h>
24#include <asm/btext.h>
25
26static volatile unsigned char *sccc, *sccd;
27unsigned int TXRDY, RXRDY, DLAB;
28static int xmon_expect(const char *str, unsigned int timeout);
29
30static int use_serial;
31static int use_screen;
32static int via_modem;
33static int xmon_use_sccb;
34static struct device_node *channel_node;
35
36#define TB_SPEED 25000000
37
38static inline unsigned int readtb(void)
39{
40 unsigned int ret;
41
42 asm volatile("mftb %0" : "=r" (ret) :);
43 return ret;
44}
45
46void buf_access(void)
47{
48 if (DLAB)
49 sccd[3] &= ~DLAB; /* reset DLAB */
50}
51
52extern int adb_init(void);
53
54#ifdef CONFIG_PPC_CHRP
55/*
56 * This looks in the "ranges" property for the primary PCI host bridge
57 * to find the physical address of the start of PCI/ISA I/O space.
58 * It is basically a cut-down version of pci_process_bridge_OF_ranges.
59 */
60static unsigned long chrp_find_phys_io_base(void)
61{
62 struct device_node *node;
63 unsigned int *ranges;
64 unsigned long base = CHRP_ISA_IO_BASE;
65 int rlen = 0;
66 int np;
67
68 node = find_devices("isa");
69 if (node != NULL) {
70 node = node->parent;
71 if (node == NULL || node->type == NULL
72 || strcmp(node->type, "pci") != 0)
73 node = NULL;
74 }
75 if (node == NULL)
76 node = find_devices("pci");
77 if (node == NULL)
78 return base;
79
80 ranges = (unsigned int *) get_property(node, "ranges", &rlen);
81 np = prom_n_addr_cells(node) + 5;
82 while ((rlen -= np * sizeof(unsigned int)) >= 0) {
83 if ((ranges[0] >> 24) == 1 && ranges[2] == 0) {
84 /* I/O space starting at 0, grab the phys base */
85 base = ranges[np - 3];
86 break;
87 }
88 ranges += np;
89 }
90 return base;
91}
92#endif /* CONFIG_PPC_CHRP */
93
94#ifdef CONFIG_MAGIC_SYSRQ
95static void sysrq_handle_xmon(int key, struct pt_regs *regs,
96 struct tty_struct *tty)
97{
98 xmon(regs);
99}
100
101static struct sysrq_key_op sysrq_xmon_op =
102{
103 .handler = sysrq_handle_xmon,
104 .help_msg = "Xmon",
105 .action_msg = "Entering xmon",
106};
107#endif
108
109void
110xmon_map_scc(void)
111{
112#ifdef CONFIG_PPC_MULTIPLATFORM
113 volatile unsigned char *base;
114
115 if (_machine == _MACH_Pmac) {
116 struct device_node *np;
117 unsigned long addr;
118#ifdef CONFIG_BOOTX_TEXT
119 if (!use_screen && !use_serial
120 && !machine_is_compatible("iMac")) {
121 /* see if there is a keyboard in the device tree
122 with a parent of type "adb" */
123 for (np = find_devices("keyboard"); np; np = np->next)
124 if (np->parent && np->parent->type
125 && strcmp(np->parent->type, "adb") == 0)
126 break;
127
128 /* needs to be hacked if xmon_printk is to be used
129 from within find_via_pmu() */
130#ifdef CONFIG_ADB_PMU
131 if (np != NULL && boot_text_mapped && find_via_pmu())
132 use_screen = 1;
133#endif
134#ifdef CONFIG_ADB_CUDA
135 if (np != NULL && boot_text_mapped && find_via_cuda())
136 use_screen = 1;
137#endif
138 }
139 if (!use_screen && (np = find_devices("escc")) != NULL) {
140 /*
141 * look for the device node for the serial port
142 * we're using and see if it says it has a modem
143 */
144 char *name = xmon_use_sccb? "ch-b": "ch-a";
145 char *slots;
146 int l;
147
148 np = np->child;
149 while (np != NULL && strcmp(np->name, name) != 0)
150 np = np->sibling;
151 if (np != NULL) {
152 /* XXX should parse this properly */
153 channel_node = np;
154 slots = get_property(np, "slot-names", &l);
155 if (slots != NULL && l >= 10
156 && strcmp(slots+4, "Modem") == 0)
157 via_modem = 1;
158 }
159 }
160 btext_drawstring("xmon uses ");
161 if (use_screen)
162 btext_drawstring("screen and keyboard\n");
163 else {
164 if (via_modem)
165 btext_drawstring("modem on ");
166 btext_drawstring(xmon_use_sccb? "printer": "modem");
167 btext_drawstring(" port\n");
168 }
169
170#endif /* CONFIG_BOOTX_TEXT */
171
172#ifdef CHRP_ESCC
173 addr = 0xc1013020;
174#else
175 addr = 0xf3013020;
176#endif
177 TXRDY = 4;
178 RXRDY = 1;
179
180 np = find_devices("mac-io");
181 if (np && np->n_addrs)
182 addr = np->addrs[0].address + 0x13020;
183 base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
184 sccc = base + (addr & ~PAGE_MASK);
185 sccd = sccc + 0x10;
186
187 } else {
188 base = (volatile unsigned char *) isa_io_base;
189 if (_machine == _MACH_chrp)
190 base = (volatile unsigned char *)
191 ioremap(chrp_find_phys_io_base(), 0x1000);
192
193 sccc = base + 0x3fd;
194 sccd = base + 0x3f8;
195 if (xmon_use_sccb) {
196 sccc -= 0x100;
197 sccd -= 0x100;
198 }
199 TXRDY = 0x20;
200 RXRDY = 1;
201 DLAB = 0x80;
202 }
203#elif defined(CONFIG_GEMINI)
204 /* should already be mapped by the kernel boot */
205 sccc = (volatile unsigned char *) 0xffeffb0d;
206 sccd = (volatile unsigned char *) 0xffeffb08;
207 TXRDY = 0x20;
208 RXRDY = 1;
209 DLAB = 0x80;
210#elif defined(CONFIG_405GP)
211 sccc = (volatile unsigned char *)0xef600305;
212 sccd = (volatile unsigned char *)0xef600300;
213 TXRDY = 0x20;
214 RXRDY = 1;
215 DLAB = 0x80;
216#endif /* platform */
217
218 register_sysrq_key('x', &sysrq_xmon_op);
219}
220
221static int scc_initialized = 0;
222
223void xmon_init_scc(void);
224extern void cuda_poll(void);
225
226static inline void do_poll_adb(void)
227{
228#ifdef CONFIG_ADB_PMU
229 if (sys_ctrler == SYS_CTRLER_PMU)
230 pmu_poll_adb();
231#endif /* CONFIG_ADB_PMU */
232#ifdef CONFIG_ADB_CUDA
233 if (sys_ctrler == SYS_CTRLER_CUDA)
234 cuda_poll();
235#endif /* CONFIG_ADB_CUDA */
236}
237
238int
239xmon_write(void *handle, void *ptr, int nb)
240{
241 char *p = ptr;
242 int i, c, ct;
243
244#ifdef CONFIG_SMP
245 static unsigned long xmon_write_lock;
246 int lock_wait = 1000000;
247 int locked;
248
249 while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0)
250 if (--lock_wait == 0)
251 break;
252#endif
253
254#ifdef CONFIG_BOOTX_TEXT
255 if (use_screen) {
256 /* write it on the screen */
257 for (i = 0; i < nb; ++i)
258 btext_drawchar(*p++);
259 goto out;
260 }
261#endif
262 if (!scc_initialized)
263 xmon_init_scc();
264 ct = 0;
265 for (i = 0; i < nb; ++i) {
266 while ((*sccc & TXRDY) == 0)
267 do_poll_adb();
268 c = p[i];
269 if (c == '\n' && !ct) {
270 c = '\r';
271 ct = 1;
272 --i;
273 } else {
274 ct = 0;
275 }
276 buf_access();
277 *sccd = c;
278 eieio();
279 }
280
281 out:
282#ifdef CONFIG_SMP
283 if (!locked)
284 clear_bit(0, &xmon_write_lock);
285#endif
286 return nb;
287}
288
289int xmon_wants_key;
290int xmon_adb_keycode;
291
292#ifdef CONFIG_BOOTX_TEXT
293static int xmon_adb_shiftstate;
294
295static unsigned char xmon_keytab[128] =
296 "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */
297 "yt123465=97-80]o" /* 0x10 - 0x1f */
298 "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */
299 "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
300 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
301 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
302
303static unsigned char xmon_shift_keytab[128] =
304 "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */
305 "YT!@#$^%+(&_*)}O" /* 0x10 - 0x1f */
306 "U{IP\rLJ\"K:|<?NM>" /* 0x20 - 0x2f */
307 "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
308 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
309 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
310
311static int
312xmon_get_adb_key(void)
313{
314 int k, t, on;
315
316 xmon_wants_key = 1;
317 for (;;) {
318 xmon_adb_keycode = -1;
319 t = 0;
320 on = 0;
321 do {
322 if (--t < 0) {
323 on = 1 - on;
324 btext_drawchar(on? 0xdb: 0x20);
325 btext_drawchar('\b');
326 t = 200000;
327 }
328 do_poll_adb();
329 } while (xmon_adb_keycode == -1);
330 k = xmon_adb_keycode;
331 if (on)
332 btext_drawstring(" \b");
333
334 /* test for shift keys */
335 if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
336 xmon_adb_shiftstate = (k & 0x80) == 0;
337 continue;
338 }
339 if (k >= 0x80)
340 continue; /* ignore up transitions */
341 k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
342 if (k != 0)
343 break;
344 }
345 xmon_wants_key = 0;
346 return k;
347}
348#endif /* CONFIG_BOOTX_TEXT */
349
350int
351xmon_read(void *handle, void *ptr, int nb)
352{
353 char *p = ptr;
354 int i;
355
356#ifdef CONFIG_BOOTX_TEXT
357 if (use_screen) {
358 for (i = 0; i < nb; ++i)
359 *p++ = xmon_get_adb_key();
360 return i;
361 }
362#endif
363 if (!scc_initialized)
364 xmon_init_scc();
365 for (i = 0; i < nb; ++i) {
366 while ((*sccc & RXRDY) == 0)
367 do_poll_adb();
368 buf_access();
369 *p++ = *sccd;
370 }
371 return i;
372}
373
374int
375xmon_read_poll(void)
376{
377 if ((*sccc & RXRDY) == 0) {
378 do_poll_adb();
379 return -1;
380 }
381 buf_access();
382 return *sccd;
383}
384
385static unsigned char scc_inittab[] = {
386 13, 0, /* set baud rate divisor */
387 12, 1,
388 14, 1, /* baud rate gen enable, src=rtxc */
389 11, 0x50, /* clocks = br gen */
390 5, 0xea, /* tx 8 bits, assert DTR & RTS */
391 4, 0x46, /* x16 clock, 1 stop */
392 3, 0xc1, /* rx enable, 8 bits */
393};
394
395void
396xmon_init_scc(void)
397{
398 if ( _machine == _MACH_chrp )
399 {
400 sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */
401 sccd[0] = 12; eieio(); /* DLL = 9600 baud */
402 sccd[1] = 0; eieio();
403 sccd[2] = 0; eieio(); /* FCR = 0 */
404 sccd[3] = 3; eieio(); /* LCR = 8N1 */
405 sccd[1] = 0; eieio(); /* IER = 0 */
406 }
407 else if ( _machine == _MACH_Pmac )
408 {
409 int i, x;
410
411 if (channel_node != 0)
412 pmac_call_feature(
413 PMAC_FTR_SCC_ENABLE,
414 channel_node,
415 PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
416 printk(KERN_INFO "Serial port locked ON by debugger !\n");
417 if (via_modem && channel_node != 0) {
418 unsigned int t0;
419
420 pmac_call_feature(
421 PMAC_FTR_MODEM_ENABLE,
422 channel_node, 0, 1);
423 printk(KERN_INFO "Modem powered up by debugger !\n");
424 t0 = readtb();
425 while (readtb() - t0 < 3*TB_SPEED)
426 eieio();
427 }
428 /* use the B channel if requested */
429 if (xmon_use_sccb) {
430 sccc = (volatile unsigned char *)
431 ((unsigned long)sccc & ~0x20);
432 sccd = sccc + 0x10;
433 }
434 for (i = 20000; i != 0; --i) {
435 x = *sccc; eieio();
436 }
437 *sccc = 9; eieio(); /* reset A or B side */
438 *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio();
439 for (i = 0; i < sizeof(scc_inittab); ++i) {
440 *sccc = scc_inittab[i];
441 eieio();
442 }
443 }
444 scc_initialized = 1;
445 if (via_modem) {
446 for (;;) {
447 xmon_write(NULL, "ATE1V1\r", 7);
448 if (xmon_expect("OK", 5)) {
449 xmon_write(NULL, "ATA\r", 4);
450 if (xmon_expect("CONNECT", 40))
451 break;
452 }
453 xmon_write(NULL, "+++", 3);
454 xmon_expect("OK", 3);
455 }
456 }
457}
458
459#if 0
460extern int (*prom_entry)(void *);
461
462int
463xmon_exit(void)
464{
465 struct prom_args {
466 char *service;
467 } args;
468
469 for (;;) {
470 args.service = "exit";
471 (*prom_entry)(&args);
472 }
473}
474#endif
475
476void *xmon_stdin;
477void *xmon_stdout;
478void *xmon_stderr;
479
480void
481xmon_init(void)
482{
483}
484
485int
486xmon_putc(int c, void *f)
487{
488 char ch = c;
489
490 if (c == '\n')
491 xmon_putc('\r', f);
492 return xmon_write(f, &ch, 1) == 1? c: -1;
493}
494
495int
496xmon_putchar(int c)
497{
498 return xmon_putc(c, xmon_stdout);
499}
500
501int
502xmon_fputs(char *str, void *f)
503{
504 int n = strlen(str);
505
506 return xmon_write(f, str, n) == n? 0: -1;
507}
508
509int
510xmon_readchar(void)
511{
512 char ch;
513
514 for (;;) {
515 switch (xmon_read(xmon_stdin, &ch, 1)) {
516 case 1:
517 return ch;
518 case -1:
519 xmon_printf("read(stdin) returned -1\r\n", 0, 0);
520 return -1;
521 }
522 }
523}
524
525static char line[256];
526static char *lineptr;
527static int lineleft;
528
529int xmon_expect(const char *str, unsigned int timeout)
530{
531 int c;
532 unsigned int t0;
533
534 timeout *= TB_SPEED;
535 t0 = readtb();
536 do {
537 lineptr = line;
538 for (;;) {
539 c = xmon_read_poll();
540 if (c == -1) {
541 if (readtb() - t0 > timeout)
542 return 0;
543 continue;
544 }
545 if (c == '\n')
546 break;
547 if (c != '\r' && lineptr < &line[sizeof(line) - 1])
548 *lineptr++ = c;
549 }
550 *lineptr = 0;
551 } while (strstr(line, str) == NULL);
552 return 1;
553}
554
555int
556xmon_getchar(void)
557{
558 int c;
559
560 if (lineleft == 0) {
561 lineptr = line;
562 for (;;) {
563 c = xmon_readchar();
564 if (c == -1 || c == 4)
565 break;
566 if (c == '\r' || c == '\n') {
567 *lineptr++ = '\n';
568 xmon_putchar('\n');
569 break;
570 }
571 switch (c) {
572 case 0177:
573 case '\b':
574 if (lineptr > line) {
575 xmon_putchar('\b');
576 xmon_putchar(' ');
577 xmon_putchar('\b');
578 --lineptr;
579 }
580 break;
581 case 'U' & 0x1F:
582 while (lineptr > line) {
583 xmon_putchar('\b');
584 xmon_putchar(' ');
585 xmon_putchar('\b');
586 --lineptr;
587 }
588 break;
589 default:
590 if (lineptr >= &line[sizeof(line) - 1])
591 xmon_putchar('\a');
592 else {
593 xmon_putchar(c);
594 *lineptr++ = c;
595 }
596 }
597 }
598 lineleft = lineptr - line;
599 lineptr = line;
600 }
601 if (lineleft == 0)
602 return -1;
603 --lineleft;
604 return *lineptr++;
605}
606
607char *
608xmon_fgets(char *str, int nb, void *f)
609{
610 char *p;
611 int c;
612
613 for (p = str; p < str + nb - 1; ) {
614 c = xmon_getchar();
615 if (c == -1) {
616 if (p == str)
617 return NULL;
618 break;
619 }
620 *p++ = c;
621 if (c == '\n')
622 break;
623 }
624 *p = 0;
625 return str;
626}
627
628void
629xmon_enter(void)
630{
631#ifdef CONFIG_ADB_PMU
632 if (_machine == _MACH_Pmac) {
633 pmu_suspend();
634 }
635#endif
636}
637
638void
639xmon_leave(void)
640{
641#ifdef CONFIG_ADB_PMU
642 if (_machine == _MACH_Pmac) {
643 pmu_resume();
644 }
645#endif
646}
diff --git a/arch/ppc/xmon/start_8xx.c b/arch/ppc/xmon/start_8xx.c
new file mode 100644
index 000000000000..a48bd594cf61
--- /dev/null
+++ b/arch/ppc/xmon/start_8xx.c
@@ -0,0 +1,287 @@
1/*
2 * Copyright (C) 1996 Paul Mackerras.
3 * Copyright (C) 2000 Dan Malek.
4 * Quick hack of Paul's code to make XMON work on 8xx processors. Lots
5 * of assumptions, like the SMC1 is used, it has been initialized by the
6 * loader at some point, and we can just stuff and suck bytes.
7 * We rely upon the 8xx uart driver to support us, as the interface
8 * changes between boot up and operational phases of the kernel.
9 */
10#include <linux/string.h>
11#include <asm/machdep.h>
12#include <asm/io.h>
13#include <asm/page.h>
14#include <linux/kernel.h>
15#include <asm/8xx_immap.h>
16#include <asm/mpc8xx.h>
17#include <asm/commproc.h>
18
19extern void xmon_printf(const char *fmt, ...);
20extern int xmon_8xx_write(char *str, int nb);
21extern int xmon_8xx_read_poll(void);
22extern int xmon_8xx_read_char(void);
23void prom_drawhex(uint);
24void prom_drawstring(const char *str);
25
26static int use_screen = 1; /* default */
27
28#define TB_SPEED 25000000
29
30static inline unsigned int readtb(void)
31{
32 unsigned int ret;
33
34 asm volatile("mftb %0" : "=r" (ret) :);
35 return ret;
36}
37
38void buf_access(void)
39{
40}
41
42void
43xmon_map_scc(void)
44{
45
46 cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
47 use_screen = 0;
48
49 prom_drawstring("xmon uses serial port\n");
50}
51
52static int scc_initialized = 0;
53
54void xmon_init_scc(void);
55
56int
57xmon_write(void *handle, void *ptr, int nb)
58{
59 char *p = ptr;
60 int i, c, ct;
61
62 if (!scc_initialized)
63 xmon_init_scc();
64
65 return(xmon_8xx_write(ptr, nb));
66}
67
68int xmon_wants_key;
69
70int
71xmon_read(void *handle, void *ptr, int nb)
72{
73 char *p = ptr;
74 int i;
75
76 if (!scc_initialized)
77 xmon_init_scc();
78
79 for (i = 0; i < nb; ++i) {
80 *p++ = xmon_8xx_read_char();
81 }
82 return i;
83}
84
85int
86xmon_read_poll(void)
87{
88 return(xmon_8xx_read_poll());
89}
90
91void
92xmon_init_scc()
93{
94 scc_initialized = 1;
95}
96
97#if 0
98extern int (*prom_entry)(void *);
99
100int
101xmon_exit(void)
102{
103 struct prom_args {
104 char *service;
105 } args;
106
107 for (;;) {
108 args.service = "exit";
109 (*prom_entry)(&args);
110 }
111}
112#endif
113
114void *xmon_stdin;
115void *xmon_stdout;
116void *xmon_stderr;
117
118void
119xmon_init(void)
120{
121}
122
123int
124xmon_putc(int c, void *f)
125{
126 char ch = c;
127
128 if (c == '\n')
129 xmon_putc('\r', f);
130 return xmon_write(f, &ch, 1) == 1? c: -1;
131}
132
133int
134xmon_putchar(int c)
135{
136 return xmon_putc(c, xmon_stdout);
137}
138
139int
140xmon_fputs(char *str, void *f)
141{
142 int n = strlen(str);
143
144 return xmon_write(f, str, n) == n? 0: -1;
145}
146
147int
148xmon_readchar(void)
149{
150 char ch;
151
152 for (;;) {
153 switch (xmon_read(xmon_stdin, &ch, 1)) {
154 case 1:
155 return ch;
156 case -1:
157 xmon_printf("read(stdin) returned -1\r\n", 0, 0);
158 return -1;
159 }
160 }
161}
162
163static char line[256];
164static char *lineptr;
165static int lineleft;
166
167#if 0
168int xmon_expect(const char *str, unsigned int timeout)
169{
170 int c;
171 unsigned int t0;
172
173 timeout *= TB_SPEED;
174 t0 = readtb();
175 do {
176 lineptr = line;
177 for (;;) {
178 c = xmon_read_poll();
179 if (c == -1) {
180 if (readtb() - t0 > timeout)
181 return 0;
182 continue;
183 }
184 if (c == '\n')
185 break;
186 if (c != '\r' && lineptr < &line[sizeof(line) - 1])
187 *lineptr++ = c;
188 }
189 *lineptr = 0;
190 } while (strstr(line, str) == NULL);
191 return 1;
192}
193#endif
194
195int
196xmon_getchar(void)
197{
198 int c;
199
200 if (lineleft == 0) {
201 lineptr = line;
202 for (;;) {
203 c = xmon_readchar();
204 if (c == -1 || c == 4)
205 break;
206 if (c == '\r' || c == '\n') {
207 *lineptr++ = '\n';
208 xmon_putchar('\n');
209 break;
210 }
211 switch (c) {
212 case 0177:
213 case '\b':
214 if (lineptr > line) {
215 xmon_putchar('\b');
216 xmon_putchar(' ');
217 xmon_putchar('\b');
218 --lineptr;
219 }
220 break;
221 case 'U' & 0x1F:
222 while (lineptr > line) {
223 xmon_putchar('\b');
224 xmon_putchar(' ');
225 xmon_putchar('\b');
226 --lineptr;
227 }
228 break;
229 default:
230 if (lineptr >= &line[sizeof(line) - 1])
231 xmon_putchar('\a');
232 else {
233 xmon_putchar(c);
234 *lineptr++ = c;
235 }
236 }
237 }
238 lineleft = lineptr - line;
239 lineptr = line;
240 }
241 if (lineleft == 0)
242 return -1;
243 --lineleft;
244 return *lineptr++;
245}
246
247char *
248xmon_fgets(char *str, int nb, void *f)
249{
250 char *p;
251 int c;
252
253 for (p = str; p < str + nb - 1; ) {
254 c = xmon_getchar();
255 if (c == -1) {
256 if (p == str)
257 return 0;
258 break;
259 }
260 *p++ = c;
261 if (c == '\n')
262 break;
263 }
264 *p = 0;
265 return str;
266}
267
268void
269prom_drawhex(uint val)
270{
271 unsigned char buf[10];
272
273 int i;
274 for (i = 7; i >= 0; i--)
275 {
276 buf[i] = "0123456789abcdef"[val & 0x0f];
277 val >>= 4;
278 }
279 buf[8] = '\0';
280 xmon_fputs(buf, xmon_stdout);
281}
282
283void
284prom_drawstring(const char *str)
285{
286 xmon_fputs(str, xmon_stdout);
287}
diff --git a/arch/ppc/xmon/subr_prf.c b/arch/ppc/xmon/subr_prf.c
new file mode 100644
index 000000000000..126624f3f2ed
--- /dev/null
+++ b/arch/ppc/xmon/subr_prf.c
@@ -0,0 +1,55 @@
1/*
2 * Written by Cort Dougan to replace the version originally used
3 * by Paul Mackerras, which came from NetBSD and thus had copyright
4 * conflicts with Linux.
5 *
6 * This file makes liberal use of the standard linux utility
7 * routines to reduce the size of the binary. We assume we can
8 * trust some parts of Linux inside the debugger.
9 * -- Cort (cort@cs.nmt.edu)
10 *
11 * Copyright (C) 1999 Cort Dougan.
12 */
13
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <stdarg.h>
17#include "nonstdio.h"
18
19extern int xmon_write(void *, void *, int);
20
21void
22xmon_vfprintf(void *f, const char *fmt, va_list ap)
23{
24 static char xmon_buf[2048];
25 int n;
26
27 n = vsprintf(xmon_buf, fmt, ap);
28 xmon_write(f, xmon_buf, n);
29}
30
31void
32xmon_printf(const char *fmt, ...)
33{
34 va_list ap;
35
36 va_start(ap, fmt);
37 xmon_vfprintf(stdout, fmt, ap);
38 va_end(ap);
39}
40
41void
42xmon_fprintf(void *f, const char *fmt, ...)
43{
44 va_list ap;
45
46 va_start(ap, fmt);
47 xmon_vfprintf(f, fmt, ap);
48 va_end(ap);
49}
50
51void
52xmon_puts(char *s)
53{
54 xmon_write(stdout, s, strlen(s));
55}
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
new file mode 100644
index 000000000000..8565f49b8b0b
--- /dev/null
+++ b/arch/ppc/xmon/xmon.c
@@ -0,0 +1,2008 @@
1/*
2 * Routines providing a simple monitor for use on the PowerMac.
3 *
4 * Copyright (C) 1996 Paul Mackerras.
5 */
6#include <linux/config.h>
7#include <linux/errno.h>
8#include <linux/sched.h>
9#include <linux/smp.h>
10#include <linux/interrupt.h>
11#include <linux/bitops.h>
12#include <asm/ptrace.h>
13#include <asm/string.h>
14#include <asm/prom.h>
15#include <asm/bootx.h>
16#include <asm/machdep.h>
17#include <asm/xmon.h>
18#ifdef CONFIG_PMAC_BACKLIGHT
19#include <asm/backlight.h>
20#endif
21#include "nonstdio.h"
22#include "privinst.h"
23
24#define scanhex xmon_scanhex
25#define skipbl xmon_skipbl
26
27#ifdef CONFIG_SMP
28static unsigned long cpus_in_xmon = 0;
29static unsigned long got_xmon = 0;
30static volatile int take_xmon = -1;
31#endif /* CONFIG_SMP */
32
33static unsigned adrs;
34static int size = 1;
35static unsigned ndump = 64;
36static unsigned nidump = 16;
37static unsigned ncsum = 4096;
38static int termch;
39
40static u_int bus_error_jmp[100];
41#define setjmp xmon_setjmp
42#define longjmp xmon_longjmp
43
44/* Breakpoint stuff */
45struct bpt {
46 unsigned address;
47 unsigned instr;
48 unsigned count;
49 unsigned char enabled;
50};
51
52#define NBPTS 16
53static struct bpt bpts[NBPTS];
54static struct bpt dabr;
55static struct bpt iabr;
56static unsigned bpinstr = 0x7fe00008; /* trap */
57
58/* Prototypes */
59extern void (*debugger_fault_handler)(struct pt_regs *);
60static int cmds(struct pt_regs *);
61static int mread(unsigned, void *, int);
62static int mwrite(unsigned, void *, int);
63static void handle_fault(struct pt_regs *);
64static void byterev(unsigned char *, int);
65static void memex(void);
66static int bsesc(void);
67static void dump(void);
68static void prdump(unsigned, int);
69#ifdef __MWERKS__
70static void prndump(unsigned, int);
71static int nvreadb(unsigned);
72#endif
73static int ppc_inst_dump(unsigned, int);
74void print_address(unsigned);
75static int getsp(void);
76static void dump_hash_table(void);
77static void backtrace(struct pt_regs *);
78static void excprint(struct pt_regs *);
79static void prregs(struct pt_regs *);
80static void memops(int);
81static void memlocate(void);
82static void memzcan(void);
83static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
84int skipbl(void);
85int scanhex(unsigned *valp);
86static void scannl(void);
87static int hexdigit(int);
88void getstring(char *, int);
89static void flush_input(void);
90static int inchar(void);
91static void take_input(char *);
92/* static void openforth(void); */
93static unsigned read_spr(int);
94static void write_spr(int, unsigned);
95static void super_regs(void);
96static void print_sysmap(void);
97static void sysmap_lookup(void);
98static void remove_bpts(void);
99static void insert_bpts(void);
100static struct bpt *at_breakpoint(unsigned pc);
101static void bpt_cmds(void);
102static void cacheflush(void);
103#ifdef CONFIG_SMP
104static void cpu_cmd(void);
105#endif /* CONFIG_SMP */
106static int pretty_print_addr(unsigned long addr);
107static void csum(void);
108#ifdef CONFIG_BOOTX_TEXT
109static void vidcmds(void);
110#endif
111static void bootcmds(void);
112static void proccall(void);
113static void printtime(void);
114
115extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned);
116extern void printf(const char *fmt, ...);
117extern int putchar(int ch);
118extern int setjmp(u_int *);
119extern void longjmp(u_int *, int);
120
121extern void xmon_enter(void);
122extern void xmon_leave(void);
123extern char* xmon_find_symbol(unsigned long addr, unsigned long* saddr);
124extern unsigned long xmon_symbol_to_addr(char* symbol);
125
126static unsigned start_tb[NR_CPUS][2];
127static unsigned stop_tb[NR_CPUS][2];
128
129#define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
130
131#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
132 || ('a' <= (c) && (c) <= 'f') \
133 || ('A' <= (c) && (c) <= 'F'))
134#define isalnum(c) (('0' <= (c) && (c) <= '9') \
135 || ('a' <= (c) && (c) <= 'z') \
136 || ('A' <= (c) && (c) <= 'Z'))
137#define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
138
139static char *help_string = "\
140Commands:\n\
141 d dump bytes\n\
142 di dump instructions\n\
143 df dump float values\n\
144 dd dump double values\n\
145 e print exception information\n\
146 h dump hash table\n\
147 m examine/change memory\n\
148 mm move a block of memory\n\
149 ms set a block of memory\n\
150 md compare two blocks of memory\n\
151 M print System.map\n\
152 r print registers\n\
153 S print special registers\n\
154 t print backtrace\n\
155 la lookup address in system.map\n\
156 ls lookup symbol in system.map\n\
157 x exit monitor\n\
158";
159
160static int xmon_trace[NR_CPUS];
161#define SSTEP 1 /* stepping because of 's' command */
162#define BRSTEP 2 /* stepping over breakpoint */
163
164static struct pt_regs *xmon_regs[NR_CPUS];
165
166extern inline void sync(void)
167{
168 asm volatile("sync; isync");
169}
170
171extern inline void __delay(unsigned int loops)
172{
173 if (loops != 0)
174 __asm__ __volatile__("mtctr %0; 1: bdnz 1b" : :
175 "r" (loops) : "ctr");
176}
177
178static void get_tb(unsigned *p)
179{
180 unsigned hi, lo, hiagain;
181
182 if ((get_pvr() >> 16) == 1)
183 return;
184
185 do {
186 asm volatile("mftbu %0; mftb %1; mftbu %2"
187 : "=r" (hi), "=r" (lo), "=r" (hiagain));
188 } while (hi != hiagain);
189 p[0] = hi;
190 p[1] = lo;
191}
192
193void
194xmon(struct pt_regs *excp)
195{
196 struct pt_regs regs;
197 int msr, cmd;
198
199 get_tb(stop_tb[smp_processor_id()]);
200 if (excp == NULL) {
201 asm volatile ("stw 0,0(%0)\n\
202 lwz 0,0(1)\n\
203 stw 0,4(%0)\n\
204 stmw 2,8(%0)" : : "b" (&regs));
205 regs.nip = regs.link = ((unsigned long *)regs.gpr[1])[1];
206 regs.msr = get_msr();
207 regs.ctr = get_ctr();
208 regs.xer = get_xer();
209 regs.ccr = get_cr();
210 regs.trap = 0;
211 excp = &regs;
212 }
213
214 msr = get_msr();
215 set_msr(msr & ~0x8000); /* disable interrupts */
216 xmon_regs[smp_processor_id()] = excp;
217 xmon_enter();
218 excprint(excp);
219#ifdef CONFIG_SMP
220 if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon))
221 for (;;)
222 ;
223 while (test_and_set_bit(0, &got_xmon)) {
224 if (take_xmon == smp_processor_id()) {
225 take_xmon = -1;
226 break;
227 }
228 }
229 /*
230 * XXX: breakpoints are removed while any cpu is in xmon
231 */
232#endif /* CONFIG_SMP */
233 remove_bpts();
234#ifdef CONFIG_PMAC_BACKLIGHT
235 if( setjmp(bus_error_jmp) == 0 ) {
236 debugger_fault_handler = handle_fault;
237 sync();
238 set_backlight_enable(1);
239 set_backlight_level(BACKLIGHT_MAX);
240 sync();
241 }
242 debugger_fault_handler = NULL;
243#endif /* CONFIG_PMAC_BACKLIGHT */
244 cmd = cmds(excp);
245 if (cmd == 's') {
246 xmon_trace[smp_processor_id()] = SSTEP;
247 excp->msr |= 0x400;
248 } else if (at_breakpoint(excp->nip)) {
249 xmon_trace[smp_processor_id()] = BRSTEP;
250 excp->msr |= 0x400;
251 } else {
252 xmon_trace[smp_processor_id()] = 0;
253 insert_bpts();
254 }
255 xmon_leave();
256 xmon_regs[smp_processor_id()] = NULL;
257#ifdef CONFIG_SMP
258 clear_bit(0, &got_xmon);
259 clear_bit(smp_processor_id(), &cpus_in_xmon);
260#endif /* CONFIG_SMP */
261 set_msr(msr); /* restore interrupt enable */
262 get_tb(start_tb[smp_processor_id()]);
263}
264
265irqreturn_t
266xmon_irq(int irq, void *d, struct pt_regs *regs)
267{
268 unsigned long flags;
269 local_irq_save(flags);
270 printf("Keyboard interrupt\n");
271 xmon(regs);
272 local_irq_restore(flags);
273 return IRQ_HANDLED;
274}
275
276int
277xmon_bpt(struct pt_regs *regs)
278{
279 struct bpt *bp;
280
281 bp = at_breakpoint(regs->nip);
282 if (!bp)
283 return 0;
284 if (bp->count) {
285 --bp->count;
286 remove_bpts();
287 excprint(regs);
288 xmon_trace[smp_processor_id()] = BRSTEP;
289 regs->msr |= 0x400;
290 } else {
291 xmon(regs);
292 }
293 return 1;
294}
295
296int
297xmon_sstep(struct pt_regs *regs)
298{
299 if (!xmon_trace[smp_processor_id()])
300 return 0;
301 if (xmon_trace[smp_processor_id()] == BRSTEP) {
302 xmon_trace[smp_processor_id()] = 0;
303 insert_bpts();
304 } else {
305 xmon(regs);
306 }
307 return 1;
308}
309
310int
311xmon_dabr_match(struct pt_regs *regs)
312{
313 if (dabr.enabled && dabr.count) {
314 --dabr.count;
315 remove_bpts();
316 excprint(regs);
317 xmon_trace[smp_processor_id()] = BRSTEP;
318 regs->msr |= 0x400;
319 } else {
320 dabr.instr = regs->nip;
321 xmon(regs);
322 }
323 return 1;
324}
325
326int
327xmon_iabr_match(struct pt_regs *regs)
328{
329 if (iabr.enabled && iabr.count) {
330 --iabr.count;
331 remove_bpts();
332 excprint(regs);
333 xmon_trace[smp_processor_id()] = BRSTEP;
334 regs->msr |= 0x400;
335 } else {
336 xmon(regs);
337 }
338 return 1;
339}
340
341static struct bpt *
342at_breakpoint(unsigned pc)
343{
344 int i;
345 struct bpt *bp;
346
347 if (dabr.enabled && pc == dabr.instr)
348 return &dabr;
349 if (iabr.enabled && pc == iabr.address)
350 return &iabr;
351 bp = bpts;
352 for (i = 0; i < NBPTS; ++i, ++bp)
353 if (bp->enabled && pc == bp->address)
354 return bp;
355 return NULL;
356}
357
358static void
359insert_bpts(void)
360{
361 int i;
362 struct bpt *bp;
363
364 bp = bpts;
365 for (i = 0; i < NBPTS; ++i, ++bp) {
366 if (!bp->enabled)
367 continue;
368 if (mread(bp->address, &bp->instr, 4) != 4
369 || mwrite(bp->address, &bpinstr, 4) != 4) {
370 printf("Couldn't insert breakpoint at %x, disabling\n",
371 bp->address);
372 bp->enabled = 0;
373 }
374 store_inst((void *) bp->address);
375 }
376#if !defined(CONFIG_8xx)
377 if (dabr.enabled)
378 set_dabr(dabr.address);
379 if (iabr.enabled)
380 set_iabr(iabr.address);
381#endif
382}
383
384static void
385remove_bpts(void)
386{
387 int i;
388 struct bpt *bp;
389 unsigned instr;
390
391#if !defined(CONFIG_8xx)
392 set_dabr(0);
393 set_iabr(0);
394#endif
395 bp = bpts;
396 for (i = 0; i < NBPTS; ++i, ++bp) {
397 if (!bp->enabled)
398 continue;
399 if (mread(bp->address, &instr, 4) == 4
400 && instr == bpinstr
401 && mwrite(bp->address, &bp->instr, 4) != 4)
402 printf("Couldn't remove breakpoint at %x\n",
403 bp->address);
404 store_inst((void *) bp->address);
405 }
406}
407
408static char *last_cmd;
409
410/* Command interpreting routine */
411static int
412cmds(struct pt_regs *excp)
413{
414 int cmd;
415
416 last_cmd = NULL;
417 for(;;) {
418#ifdef CONFIG_SMP
419 printf("%d:", smp_processor_id());
420#endif /* CONFIG_SMP */
421 printf("mon> ");
422 fflush(stdout);
423 flush_input();
424 termch = 0;
425 cmd = skipbl();
426 if( cmd == '\n' ) {
427 if (last_cmd == NULL)
428 continue;
429 take_input(last_cmd);
430 last_cmd = NULL;
431 cmd = inchar();
432 }
433 switch (cmd) {
434 case 'm':
435 cmd = inchar();
436 switch (cmd) {
437 case 'm':
438 case 's':
439 case 'd':
440 memops(cmd);
441 break;
442 case 'l':
443 memlocate();
444 break;
445 case 'z':
446 memzcan();
447 break;
448 default:
449 termch = cmd;
450 memex();
451 }
452 break;
453 case 'd':
454 dump();
455 break;
456 case 'l':
457 sysmap_lookup();
458 break;
459 case 'r':
460 if (excp != NULL)
461 prregs(excp); /* print regs */
462 break;
463 case 'e':
464 if (excp == NULL)
465 printf("No exception information\n");
466 else
467 excprint(excp);
468 break;
469 case 'M':
470 print_sysmap();
471 break;
472 case 'S':
473 super_regs();
474 break;
475 case 't':
476 backtrace(excp);
477 break;
478 case 'f':
479 cacheflush();
480 break;
481 case 'h':
482 dump_hash_table();
483 break;
484 case 's':
485 case 'x':
486 case EOF:
487 return cmd;
488 case '?':
489 printf(help_string);
490 break;
491 default:
492 printf("Unrecognized command: ");
493 if( ' ' < cmd && cmd <= '~' )
494 putchar(cmd);
495 else
496 printf("\\x%x", cmd);
497 printf(" (type ? for help)\n");
498 break;
499 case 'b':
500 bpt_cmds();
501 break;
502 case 'C':
503 csum();
504 break;
505#ifdef CONFIG_SMP
506 case 'c':
507 cpu_cmd();
508 break;
509#endif /* CONFIG_SMP */
510#ifdef CONFIG_BOOTX_TEXT
511 case 'v':
512 vidcmds();
513 break;
514#endif
515 case 'z':
516 bootcmds();
517 break;
518 case 'p':
519 proccall();
520 break;
521 case 'T':
522 printtime();
523 break;
524 }
525 }
526}
527
528extern unsigned tb_to_us;
529
530#define mulhwu(x,y) \
531({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
532
533static void printtime(void)
534{
535 unsigned int delta;
536
537 delta = stop_tb[smp_processor_id()][1]
538 - start_tb[smp_processor_id()][1];
539 delta = mulhwu(tb_to_us, delta);
540 printf("%u.%06u seconds\n", delta / 1000000, delta % 1000000);
541}
542
543static void bootcmds(void)
544{
545 int cmd;
546
547 cmd = inchar();
548 if (cmd == 'r')
549 ppc_md.restart(NULL);
550 else if (cmd == 'h')
551 ppc_md.halt();
552 else if (cmd == 'p')
553 ppc_md.power_off();
554}
555
556#ifdef CONFIG_SMP
557static void cpu_cmd(void)
558{
559 unsigned cpu;
560 int timeout;
561 int cmd;
562
563 cmd = inchar();
564 if (cmd == 'i') {
565 /* interrupt other cpu(s) */
566 cpu = MSG_ALL_BUT_SELF;
567 if (scanhex(&cpu))
568 smp_send_xmon_break(cpu);
569 return;
570 }
571 termch = cmd;
572 if (!scanhex(&cpu)) {
573 /* print cpus waiting or in xmon */
574 printf("cpus stopped:");
575 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
576 if (test_bit(cpu, &cpus_in_xmon)) {
577 printf(" %d", cpu);
578 if (cpu == smp_processor_id())
579 printf("*", cpu);
580 }
581 }
582 printf("\n");
583 return;
584 }
585 /* try to switch to cpu specified */
586 take_xmon = cpu;
587 timeout = 10000000;
588 while (take_xmon >= 0) {
589 if (--timeout == 0) {
590 /* yes there's a race here */
591 take_xmon = -1;
592 printf("cpu %u didn't take control\n", cpu);
593 return;
594 }
595 }
596 /* now have to wait to be given control back */
597 while (test_and_set_bit(0, &got_xmon)) {
598 if (take_xmon == smp_processor_id()) {
599 take_xmon = -1;
600 break;
601 }
602 }
603}
604#endif /* CONFIG_SMP */
605
606#ifdef CONFIG_BOOTX_TEXT
607extern boot_infos_t disp_bi;
608
609static void vidcmds(void)
610{
611 int c = inchar();
612 unsigned int val, w;
613 extern int boot_text_mapped;
614
615 if (!boot_text_mapped)
616 return;
617 if (c != '\n' && scanhex(&val)) {
618 switch (c) {
619 case 'd':
620 w = disp_bi.dispDeviceRowBytes
621 / (disp_bi.dispDeviceDepth >> 3);
622 disp_bi.dispDeviceDepth = val;
623 disp_bi.dispDeviceRowBytes = w * (val >> 3);
624 return;
625 case 'p':
626 disp_bi.dispDeviceRowBytes = val;
627 return;
628 case 'w':
629 disp_bi.dispDeviceRect[2] = val;
630 return;
631 case 'h':
632 disp_bi.dispDeviceRect[3] = val;
633 return;
634 }
635 }
636 printf("W = %d (0x%x) H = %d (0x%x) D = %d (0x%x) P = %d (0x%x)\n",
637 disp_bi.dispDeviceRect[2], disp_bi.dispDeviceRect[2],
638 disp_bi.dispDeviceRect[3], disp_bi.dispDeviceRect[3],
639 disp_bi.dispDeviceDepth, disp_bi.dispDeviceDepth,
640 disp_bi.dispDeviceRowBytes, disp_bi.dispDeviceRowBytes);
641}
642#endif /* CONFIG_BOOTX_TEXT */
643
644static unsigned short fcstab[256] = {
645 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
646 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
647 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
648 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
649 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
650 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
651 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
652 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
653 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
654 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
655 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
656 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
657 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
658 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
659 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
660 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
661 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
662 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
663 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
664 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
665 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
666 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
667 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
668 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
669 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
670 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
671 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
672 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
673 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
674 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
675 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
676 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
677};
678
679#define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
680
681static void
682csum(void)
683{
684 unsigned int i;
685 unsigned short fcs;
686 unsigned char v;
687
688 if (!scanhex(&adrs))
689 return;
690 if (!scanhex(&ncsum))
691 return;
692 fcs = 0xffff;
693 for (i = 0; i < ncsum; ++i) {
694 if (mread(adrs+i, &v, 1) == 0) {
695 printf("csum stopped at %x\n", adrs+i);
696 break;
697 }
698 fcs = FCS(fcs, v);
699 }
700 printf("%x\n", fcs);
701}
702
703static void
704bpt_cmds(void)
705{
706 int cmd;
707 unsigned a;
708 int mode, i;
709 struct bpt *bp;
710
711 cmd = inchar();
712 switch (cmd) {
713#if !defined(CONFIG_8xx)
714 case 'd':
715 mode = 7;
716 cmd = inchar();
717 if (cmd == 'r')
718 mode = 5;
719 else if (cmd == 'w')
720 mode = 6;
721 else
722 termch = cmd;
723 cmd = inchar();
724 if (cmd == 'p')
725 mode &= ~4;
726 else
727 termch = cmd;
728 dabr.address = 0;
729 dabr.count = 0;
730 dabr.enabled = scanhex(&dabr.address);
731 scanhex(&dabr.count);
732 if (dabr.enabled)
733 dabr.address = (dabr.address & ~7) | mode;
734 break;
735 case 'i':
736 cmd = inchar();
737 if (cmd == 'p')
738 mode = 2;
739 else
740 mode = 3;
741 iabr.address = 0;
742 iabr.count = 0;
743 iabr.enabled = scanhex(&iabr.address);
744 if (iabr.enabled)
745 iabr.address |= mode;
746 scanhex(&iabr.count);
747 break;
748#endif
749 case 'c':
750 if (!scanhex(&a)) {
751 /* clear all breakpoints */
752 for (i = 0; i < NBPTS; ++i)
753 bpts[i].enabled = 0;
754 iabr.enabled = 0;
755 dabr.enabled = 0;
756 printf("All breakpoints cleared\n");
757 } else {
758 bp = at_breakpoint(a);
759 if (bp == 0) {
760 printf("No breakpoint at %x\n", a);
761 } else {
762 bp->enabled = 0;
763 }
764 }
765 break;
766 default:
767 termch = cmd;
768 if (!scanhex(&a)) {
769 /* print all breakpoints */
770 printf("type address count\n");
771 if (dabr.enabled) {
772 printf("data %.8x %8x [", dabr.address & ~7,
773 dabr.count);
774 if (dabr.address & 1)
775 printf("r");
776 if (dabr.address & 2)
777 printf("w");
778 if (!(dabr.address & 4))
779 printf("p");
780 printf("]\n");
781 }
782 if (iabr.enabled)
783 printf("inst %.8x %8x\n", iabr.address & ~3,
784 iabr.count);
785 for (bp = bpts; bp < &bpts[NBPTS]; ++bp)
786 if (bp->enabled)
787 printf("trap %.8x %8x\n", bp->address,
788 bp->count);
789 break;
790 }
791 bp = at_breakpoint(a);
792 if (bp == 0) {
793 for (bp = bpts; bp < &bpts[NBPTS]; ++bp)
794 if (!bp->enabled)
795 break;
796 if (bp >= &bpts[NBPTS]) {
797 printf("Sorry, no free breakpoints\n");
798 break;
799 }
800 }
801 bp->enabled = 1;
802 bp->address = a;
803 bp->count = 0;
804 scanhex(&bp->count);
805 break;
806 }
807}
808
809static void
810backtrace(struct pt_regs *excp)
811{
812 unsigned sp;
813 unsigned stack[2];
814 struct pt_regs regs;
815 extern char ret_from_except, ret_from_except_full, ret_from_syscall;
816
817 printf("backtrace:\n");
818
819 if (excp != NULL)
820 sp = excp->gpr[1];
821 else
822 sp = getsp();
823 scanhex(&sp);
824 scannl();
825 for (; sp != 0; sp = stack[0]) {
826 if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
827 break;
828 pretty_print_addr(stack[1]);
829 printf(" ");
830 if (stack[1] == (unsigned) &ret_from_except
831 || stack[1] == (unsigned) &ret_from_except_full
832 || stack[1] == (unsigned) &ret_from_syscall) {
833 if (mread(sp+16, &regs, sizeof(regs)) != sizeof(regs))
834 break;
835 printf("\nexception:%x [%x] %x ", regs.trap, sp+16,
836 regs.nip);
837 sp = regs.gpr[1];
838 if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
839 break;
840 }
841 printf("\n");
842 }
843}
844
845int
846getsp(void)
847{
848 int x;
849
850 asm("mr %0,1" : "=r" (x) :);
851 return x;
852}
853
854void
855excprint(struct pt_regs *fp)
856{
857 int trap;
858
859#ifdef CONFIG_SMP
860 printf("cpu %d: ", smp_processor_id());
861#endif /* CONFIG_SMP */
862 printf("vector: %x at pc = ", fp->trap);
863 pretty_print_addr(fp->nip);
864 printf(", lr = ");
865 pretty_print_addr(fp->link);
866 printf("\nmsr = %x, sp = %x [%x]\n", fp->msr, fp->gpr[1], fp);
867 trap = TRAP(fp);
868 if (trap == 0x300 || trap == 0x600)
869 printf("dar = %x, dsisr = %x\n", fp->dar, fp->dsisr);
870 if (current)
871 printf("current = %x, pid = %d, comm = %s\n",
872 current, current->pid, current->comm);
873}
874
875void
876prregs(struct pt_regs *fp)
877{
878 int n;
879 unsigned base;
880
881 if (scanhex(&base))
882 fp = (struct pt_regs *) base;
883 for (n = 0; n < 32; ++n) {
884 printf("R%.2d = %.8x%s", n, fp->gpr[n],
885 (n & 3) == 3? "\n": " ");
886 if (n == 12 && !FULL_REGS(fp)) {
887 printf("\n");
888 break;
889 }
890 }
891 printf("pc = %.8x msr = %.8x lr = %.8x cr = %.8x\n",
892 fp->nip, fp->msr, fp->link, fp->ccr);
893 printf("ctr = %.8x xer = %.8x trap = %4x\n",
894 fp->ctr, fp->xer, fp->trap);
895}
896
897void
898cacheflush(void)
899{
900 int cmd;
901 unsigned nflush;
902
903 cmd = inchar();
904 if (cmd != 'i')
905 termch = cmd;
906 scanhex(&adrs);
907 if (termch != '\n')
908 termch = 0;
909 nflush = 1;
910 scanhex(&nflush);
911 nflush = (nflush + 31) / 32;
912 if (cmd != 'i') {
913 for (; nflush > 0; --nflush, adrs += 0x20)
914 cflush((void *) adrs);
915 } else {
916 for (; nflush > 0; --nflush, adrs += 0x20)
917 cinval((void *) adrs);
918 }
919}
920
921unsigned int
922read_spr(int n)
923{
924 unsigned int instrs[2];
925 int (*code)(void);
926
927 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
928 instrs[1] = 0x4e800020;
929 store_inst(instrs);
930 store_inst(instrs+1);
931 code = (int (*)(void)) instrs;
932 return code();
933}
934
935void
936write_spr(int n, unsigned int val)
937{
938 unsigned int instrs[2];
939 int (*code)(unsigned int);
940
941 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
942 instrs[1] = 0x4e800020;
943 store_inst(instrs);
944 store_inst(instrs+1);
945 code = (int (*)(unsigned int)) instrs;
946 code(val);
947}
948
949static unsigned int regno;
950extern char exc_prolog;
951extern char dec_exc;
952
953void
954print_sysmap(void)
955{
956 extern char *sysmap;
957 if ( sysmap ) {
958 printf("System.map: \n");
959 if( setjmp(bus_error_jmp) == 0 ) {
960 debugger_fault_handler = handle_fault;
961 sync();
962 xmon_puts(sysmap);
963 sync();
964 }
965 debugger_fault_handler = NULL;
966 }
967 else
968 printf("No System.map\n");
969}
970
971void
972super_regs(void)
973{
974 int i, cmd;
975 unsigned val;
976
977 cmd = skipbl();
978 if (cmd == '\n') {
979 printf("msr = %x, pvr = %x\n", get_msr(), get_pvr());
980 printf("sprg0-3 = %x %x %x %x\n", get_sprg0(), get_sprg1(),
981 get_sprg2(), get_sprg3());
982 printf("srr0 = %x, srr1 = %x\n", get_srr0(), get_srr1());
983#ifdef CONFIG_PPC_STD_MMU
984 printf("sr0-15 =");
985 for (i = 0; i < 16; ++i)
986 printf(" %x", get_sr(i));
987 printf("\n");
988#endif
989 asm("mr %0,1" : "=r" (i) :);
990 printf("sp = %x ", i);
991 asm("mr %0,2" : "=r" (i) :);
992 printf("toc = %x\n", i);
993 return;
994 }
995
996 scanhex(&regno);
997 switch (cmd) {
998 case 'w':
999 val = read_spr(regno);
1000 scanhex(&val);
1001 write_spr(regno, val);
1002 /* fall through */
1003 case 'r':
1004 printf("spr %x = %x\n", regno, read_spr(regno));
1005 break;
1006 case 's':
1007 val = get_sr(regno);
1008 scanhex(&val);
1009 set_sr(regno, val);
1010 break;
1011 case 'm':
1012 val = get_msr();
1013 scanhex(&val);
1014 set_msr(val);
1015 break;
1016 }
1017 scannl();
1018}
1019
1020#ifndef CONFIG_PPC_STD_MMU
1021static void
1022dump_hash_table(void)
1023{
1024 printf("This CPU doesn't have a hash table.\n");
1025}
1026#else
1027
1028#ifndef CONFIG_PPC64BRIDGE
1029static void
1030dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
1031{
1032 extern void *Hash;
1033 extern unsigned long Hash_size;
1034 unsigned *htab = Hash;
1035 unsigned hsize = Hash_size;
1036 unsigned v, hmask, va, last_va = 0;
1037 int found, last_found, i;
1038 unsigned *hg, w1, last_w2 = 0, last_va0 = 0;
1039
1040 last_found = 0;
1041 hmask = hsize / 64 - 1;
1042 va = start;
1043 start = (start >> 12) & 0xffff;
1044 end = (end >> 12) & 0xffff;
1045 for (v = start; v < end; ++v) {
1046 found = 0;
1047 hg = htab + (((v ^ seg) & hmask) * 16);
1048 w1 = 0x80000000 | (seg << 7) | (v >> 10);
1049 for (i = 0; i < 8; ++i, hg += 2) {
1050 if (*hg == w1) {
1051 found = 1;
1052 break;
1053 }
1054 }
1055 if (!found) {
1056 w1 ^= 0x40;
1057 hg = htab + ((~(v ^ seg) & hmask) * 16);
1058 for (i = 0; i < 8; ++i, hg += 2) {
1059 if (*hg == w1) {
1060 found = 1;
1061 break;
1062 }
1063 }
1064 }
1065 if (!(last_found && found && (hg[1] & ~0x180) == last_w2 + 4096)) {
1066 if (last_found) {
1067 if (last_va != last_va0)
1068 printf(" ... %x", last_va);
1069 printf("\n");
1070 }
1071 if (found) {
1072 printf("%x to %x", va, hg[1]);
1073 last_va0 = va;
1074 }
1075 last_found = found;
1076 }
1077 if (found) {
1078 last_w2 = hg[1] & ~0x180;
1079 last_va = va;
1080 }
1081 va += 4096;
1082 }
1083 if (last_found)
1084 printf(" ... %x\n", last_va);
1085}
1086
1087#else /* CONFIG_PPC64BRIDGE */
1088static void
1089dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
1090{
1091 extern void *Hash;
1092 extern unsigned long Hash_size;
1093 unsigned *htab = Hash;
1094 unsigned hsize = Hash_size;
1095 unsigned v, hmask, va, last_va;
1096 int found, last_found, i;
1097 unsigned *hg, w1, last_w2, last_va0;
1098
1099 last_found = 0;
1100 hmask = hsize / 128 - 1;
1101 va = start;
1102 start = (start >> 12) & 0xffff;
1103 end = (end >> 12) & 0xffff;
1104 for (v = start; v < end; ++v) {
1105 found = 0;
1106 hg = htab + (((v ^ seg) & hmask) * 32);
1107 w1 = 1 | (seg << 12) | ((v & 0xf800) >> 4);
1108 for (i = 0; i < 8; ++i, hg += 4) {
1109 if (hg[1] == w1) {
1110 found = 1;
1111 break;
1112 }
1113 }
1114 if (!found) {
1115 w1 ^= 2;
1116 hg = htab + ((~(v ^ seg) & hmask) * 32);
1117 for (i = 0; i < 8; ++i, hg += 4) {
1118 if (hg[1] == w1) {
1119 found = 1;
1120 break;
1121 }
1122 }
1123 }
1124 if (!(last_found && found && (hg[3] & ~0x180) == last_w2 + 4096)) {
1125 if (last_found) {
1126 if (last_va != last_va0)
1127 printf(" ... %x", last_va);
1128 printf("\n");
1129 }
1130 if (found) {
1131 printf("%x to %x", va, hg[3]);
1132 last_va0 = va;
1133 }
1134 last_found = found;
1135 }
1136 if (found) {
1137 last_w2 = hg[3] & ~0x180;
1138 last_va = va;
1139 }
1140 va += 4096;
1141 }
1142 if (last_found)
1143 printf(" ... %x\n", last_va);
1144}
1145#endif /* CONFIG_PPC64BRIDGE */
1146
1147static unsigned hash_ctx;
1148static unsigned hash_start;
1149static unsigned hash_end;
1150
1151static void
1152dump_hash_table(void)
1153{
1154 int seg;
1155 unsigned seg_start, seg_end;
1156
1157 hash_ctx = 0;
1158 hash_start = 0;
1159 hash_end = 0xfffff000;
1160 scanhex(&hash_ctx);
1161 scanhex(&hash_start);
1162 scanhex(&hash_end);
1163 printf("Mappings for context %x\n", hash_ctx);
1164 seg_start = hash_start;
1165 for (seg = hash_start >> 28; seg <= hash_end >> 28; ++seg) {
1166 seg_end = (seg << 28) | 0x0ffff000;
1167 if (seg_end > hash_end)
1168 seg_end = hash_end;
1169 dump_hash_table_seg((hash_ctx << 4) + (seg * 0x111),
1170 seg_start, seg_end);
1171 seg_start = seg_end + 0x1000;
1172 }
1173}
1174#endif /* CONFIG_PPC_STD_MMU */
1175
1176/*
1177 * Stuff for reading and writing memory safely
1178 */
1179
1180int
1181mread(unsigned adrs, void *buf, int size)
1182{
1183 volatile int n;
1184 char *p, *q;
1185
1186 n = 0;
1187 if( setjmp(bus_error_jmp) == 0 ){
1188 debugger_fault_handler = handle_fault;
1189 sync();
1190 p = (char *) adrs;
1191 q = (char *) buf;
1192 switch (size) {
1193 case 2: *(short *)q = *(short *)p; break;
1194 case 4: *(int *)q = *(int *)p; break;
1195 default:
1196 for( ; n < size; ++n ) {
1197 *q++ = *p++;
1198 sync();
1199 }
1200 }
1201 sync();
1202 /* wait a little while to see if we get a machine check */
1203 __delay(200);
1204 n = size;
1205 }
1206 debugger_fault_handler = NULL;
1207 return n;
1208}
1209
1210int
1211mwrite(unsigned adrs, void *buf, int size)
1212{
1213 volatile int n;
1214 char *p, *q;
1215
1216 n = 0;
1217 if( setjmp(bus_error_jmp) == 0 ){
1218 debugger_fault_handler = handle_fault;
1219 sync();
1220 p = (char *) adrs;
1221 q = (char *) buf;
1222 switch (size) {
1223 case 2: *(short *)p = *(short *)q; break;
1224 case 4: *(int *)p = *(int *)q; break;
1225 default:
1226 for( ; n < size; ++n ) {
1227 *p++ = *q++;
1228 sync();
1229 }
1230 }
1231 sync();
1232 n = size;
1233 } else {
1234 printf("*** Error writing address %x\n", adrs + n);
1235 }
1236 debugger_fault_handler = NULL;
1237 return n;
1238}
1239
1240static int fault_type;
1241static int fault_except;
1242static char *fault_chars[] = { "--", "**", "##" };
1243
1244static void
1245handle_fault(struct pt_regs *regs)
1246{
1247 fault_except = TRAP(regs);
1248 fault_type = TRAP(regs) == 0x200? 0: TRAP(regs) == 0x300? 1: 2;
1249 longjmp(bus_error_jmp, 1);
1250}
1251
1252#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1253
1254void
1255byterev(unsigned char *val, int size)
1256{
1257 int t;
1258
1259 switch (size) {
1260 case 2:
1261 SWAP(val[0], val[1], t);
1262 break;
1263 case 4:
1264 SWAP(val[0], val[3], t);
1265 SWAP(val[1], val[2], t);
1266 break;
1267 }
1268}
1269
1270static int brev;
1271static int mnoread;
1272
1273void
1274memex(void)
1275{
1276 int cmd, inc, i, nslash;
1277 unsigned n;
1278 unsigned char val[4];
1279
1280 last_cmd = "m\n";
1281 scanhex(&adrs);
1282 while ((cmd = skipbl()) != '\n') {
1283 switch( cmd ){
1284 case 'b': size = 1; break;
1285 case 'w': size = 2; break;
1286 case 'l': size = 4; break;
1287 case 'r': brev = !brev; break;
1288 case 'n': mnoread = 1; break;
1289 case '.': mnoread = 0; break;
1290 }
1291 }
1292 if( size <= 0 )
1293 size = 1;
1294 else if( size > 4 )
1295 size = 4;
1296 for(;;){
1297 if (!mnoread)
1298 n = mread(adrs, val, size);
1299 printf("%.8x%c", adrs, brev? 'r': ' ');
1300 if (!mnoread) {
1301 if (brev)
1302 byterev(val, size);
1303 putchar(' ');
1304 for (i = 0; i < n; ++i)
1305 printf("%.2x", val[i]);
1306 for (; i < size; ++i)
1307 printf("%s", fault_chars[fault_type]);
1308 }
1309 putchar(' ');
1310 inc = size;
1311 nslash = 0;
1312 for(;;){
1313 if( scanhex(&n) ){
1314 for (i = 0; i < size; ++i)
1315 val[i] = n >> (i * 8);
1316 if (!brev)
1317 byterev(val, size);
1318 mwrite(adrs, val, size);
1319 inc = size;
1320 }
1321 cmd = skipbl();
1322 if (cmd == '\n')
1323 break;
1324 inc = 0;
1325 switch (cmd) {
1326 case '\'':
1327 for(;;){
1328 n = inchar();
1329 if( n == '\\' )
1330 n = bsesc();
1331 else if( n == '\'' )
1332 break;
1333 for (i = 0; i < size; ++i)
1334 val[i] = n >> (i * 8);
1335 if (!brev)
1336 byterev(val, size);
1337 mwrite(adrs, val, size);
1338 adrs += size;
1339 }
1340 adrs -= size;
1341 inc = size;
1342 break;
1343 case ',':
1344 adrs += size;
1345 break;
1346 case '.':
1347 mnoread = 0;
1348 break;
1349 case ';':
1350 break;
1351 case 'x':
1352 case EOF:
1353 scannl();
1354 return;
1355 case 'b':
1356 case 'v':
1357 size = 1;
1358 break;
1359 case 'w':
1360 size = 2;
1361 break;
1362 case 'l':
1363 size = 4;
1364 break;
1365 case '^':
1366 adrs -= size;
1367 break;
1368 break;
1369 case '/':
1370 if (nslash > 0)
1371 adrs -= 1 << nslash;
1372 else
1373 nslash = 0;
1374 nslash += 4;
1375 adrs += 1 << nslash;
1376 break;
1377 case '\\':
1378 if (nslash < 0)
1379 adrs += 1 << -nslash;
1380 else
1381 nslash = 0;
1382 nslash -= 4;
1383 adrs -= 1 << -nslash;
1384 break;
1385 case 'm':
1386 scanhex(&adrs);
1387 break;
1388 case 'n':
1389 mnoread = 1;
1390 break;
1391 case 'r':
1392 brev = !brev;
1393 break;
1394 case '<':
1395 n = size;
1396 scanhex(&n);
1397 adrs -= n;
1398 break;
1399 case '>':
1400 n = size;
1401 scanhex(&n);
1402 adrs += n;
1403 break;
1404 }
1405 }
1406 adrs += inc;
1407 }
1408}
1409
1410int
1411bsesc(void)
1412{
1413 int c;
1414
1415 c = inchar();
1416 switch( c ){
1417 case 'n': c = '\n'; break;
1418 case 'r': c = '\r'; break;
1419 case 'b': c = '\b'; break;
1420 case 't': c = '\t'; break;
1421 }
1422 return c;
1423}
1424
1425void
1426dump(void)
1427{
1428 int c;
1429
1430 c = inchar();
1431 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1432 termch = c;
1433 scanhex(&adrs);
1434 if( termch != '\n')
1435 termch = 0;
1436 if( c == 'i' ){
1437 scanhex(&nidump);
1438 if( nidump == 0 )
1439 nidump = 16;
1440 adrs += ppc_inst_dump(adrs, nidump);
1441 last_cmd = "di\n";
1442 } else {
1443 scanhex(&ndump);
1444 if( ndump == 0 )
1445 ndump = 64;
1446 prdump(adrs, ndump);
1447 adrs += ndump;
1448 last_cmd = "d\n";
1449 }
1450}
1451
1452void
1453prdump(unsigned adrs, int ndump)
1454{
1455 register int n, m, c, r, nr;
1456 unsigned char temp[16];
1457
1458 for( n = ndump; n > 0; ){
1459 printf("%.8x", adrs);
1460 putchar(' ');
1461 r = n < 16? n: 16;
1462 nr = mread(adrs, temp, r);
1463 adrs += nr;
1464 for( m = 0; m < r; ++m ){
1465 putchar((m & 3) == 0 && m > 0? '.': ' ');
1466 if( m < nr )
1467 printf("%.2x", temp[m]);
1468 else
1469 printf("%s", fault_chars[fault_type]);
1470 }
1471 for(; m < 16; ++m )
1472 printf(" ");
1473 printf(" |");
1474 for( m = 0; m < r; ++m ){
1475 if( m < nr ){
1476 c = temp[m];
1477 putchar(' ' <= c && c <= '~'? c: '.');
1478 } else
1479 putchar(' ');
1480 }
1481 n -= r;
1482 for(; m < 16; ++m )
1483 putchar(' ');
1484 printf("|\n");
1485 if( nr < r )
1486 break;
1487 }
1488}
1489
1490int
1491ppc_inst_dump(unsigned adr, int count)
1492{
1493 int nr, dotted;
1494 unsigned first_adr;
1495 unsigned long inst, last_inst = 0;
1496 unsigned char val[4];
1497
1498 dotted = 0;
1499 for (first_adr = adr; count > 0; --count, adr += 4){
1500 nr = mread(adr, val, 4);
1501 if( nr == 0 ){
1502 const char *x = fault_chars[fault_type];
1503 printf("%.8x %s%s%s%s\n", adr, x, x, x, x);
1504 break;
1505 }
1506 inst = GETWORD(val);
1507 if (adr > first_adr && inst == last_inst) {
1508 if (!dotted) {
1509 printf(" ...\n");
1510 dotted = 1;
1511 }
1512 continue;
1513 }
1514 dotted = 0;
1515 last_inst = inst;
1516 printf("%.8x ", adr);
1517 printf("%.8x\t", inst);
1518 print_insn_big_powerpc(stdout, inst, adr); /* always returns 4 */
1519 printf("\n");
1520 }
1521 return adr - first_adr;
1522}
1523
1524void
1525print_address(unsigned addr)
1526{
1527 printf("0x%x", addr);
1528}
1529
1530/*
1531 * Memory operations - move, set, print differences
1532 */
1533static unsigned mdest; /* destination address */
1534static unsigned msrc; /* source address */
1535static unsigned mval; /* byte value to set memory to */
1536static unsigned mcount; /* # bytes to affect */
1537static unsigned mdiffs; /* max # differences to print */
1538
1539void
1540memops(int cmd)
1541{
1542 scanhex(&mdest);
1543 if( termch != '\n' )
1544 termch = 0;
1545 scanhex(cmd == 's'? &mval: &msrc);
1546 if( termch != '\n' )
1547 termch = 0;
1548 scanhex(&mcount);
1549 switch( cmd ){
1550 case 'm':
1551 memmove((void *)mdest, (void *)msrc, mcount);
1552 break;
1553 case 's':
1554 memset((void *)mdest, mval, mcount);
1555 break;
1556 case 'd':
1557 if( termch != '\n' )
1558 termch = 0;
1559 scanhex(&mdiffs);
1560 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
1561 break;
1562 }
1563}
1564
1565void
1566memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
1567{
1568 unsigned n, prt;
1569
1570 prt = 0;
1571 for( n = nb; n > 0; --n )
1572 if( *p1++ != *p2++ )
1573 if( ++prt <= maxpr )
1574 printf("%.8x %.2x # %.8x %.2x\n", (unsigned)p1 - 1,
1575 p1[-1], (unsigned)p2 - 1, p2[-1]);
1576 if( prt > maxpr )
1577 printf("Total of %d differences\n", prt);
1578}
1579
1580static unsigned mend;
1581static unsigned mask;
1582
1583void
1584memlocate(void)
1585{
1586 unsigned a, n;
1587 unsigned char val[4];
1588
1589 last_cmd = "ml";
1590 scanhex(&mdest);
1591 if (termch != '\n') {
1592 termch = 0;
1593 scanhex(&mend);
1594 if (termch != '\n') {
1595 termch = 0;
1596 scanhex(&mval);
1597 mask = ~0;
1598 if (termch != '\n') termch = 0;
1599 scanhex(&mask);
1600 }
1601 }
1602 n = 0;
1603 for (a = mdest; a < mend; a += 4) {
1604 if (mread(a, val, 4) == 4
1605 && ((GETWORD(val) ^ mval) & mask) == 0) {
1606 printf("%.8x: %.8x\n", a, GETWORD(val));
1607 if (++n >= 10)
1608 break;
1609 }
1610 }
1611}
1612
1613static unsigned mskip = 0x1000;
1614static unsigned mlim = 0xffffffff;
1615
1616void
1617memzcan(void)
1618{
1619 unsigned char v;
1620 unsigned a;
1621 int ok, ook;
1622
1623 scanhex(&mdest);
1624 if (termch != '\n') termch = 0;
1625 scanhex(&mskip);
1626 if (termch != '\n') termch = 0;
1627 scanhex(&mlim);
1628 ook = 0;
1629 for (a = mdest; a < mlim; a += mskip) {
1630 ok = mread(a, &v, 1);
1631 if (ok && !ook) {
1632 printf("%.8x .. ", a);
1633 fflush(stdout);
1634 } else if (!ok && ook)
1635 printf("%.8x\n", a - mskip);
1636 ook = ok;
1637 if (a + mskip < a)
1638 break;
1639 }
1640 if (ook)
1641 printf("%.8x\n", a - mskip);
1642}
1643
1644void proccall(void)
1645{
1646 unsigned int args[8];
1647 unsigned int ret;
1648 int i;
1649 typedef unsigned int (*callfunc_t)(unsigned int, unsigned int,
1650 unsigned int, unsigned int, unsigned int,
1651 unsigned int, unsigned int, unsigned int);
1652 callfunc_t func;
1653
1654 scanhex(&adrs);
1655 if (termch != '\n')
1656 termch = 0;
1657 for (i = 0; i < 8; ++i)
1658 args[i] = 0;
1659 for (i = 0; i < 8; ++i) {
1660 if (!scanhex(&args[i]) || termch == '\n')
1661 break;
1662 termch = 0;
1663 }
1664 func = (callfunc_t) adrs;
1665 ret = 0;
1666 if (setjmp(bus_error_jmp) == 0) {
1667 debugger_fault_handler = handle_fault;
1668 sync();
1669 ret = func(args[0], args[1], args[2], args[3],
1670 args[4], args[5], args[6], args[7]);
1671 sync();
1672 printf("return value is %x\n", ret);
1673 } else {
1674 printf("*** %x exception occurred\n", fault_except);
1675 }
1676 debugger_fault_handler = NULL;
1677}
1678
1679/* Input scanning routines */
1680int
1681skipbl(void)
1682{
1683 int c;
1684
1685 if( termch != 0 ){
1686 c = termch;
1687 termch = 0;
1688 } else
1689 c = inchar();
1690 while( c == ' ' || c == '\t' )
1691 c = inchar();
1692 return c;
1693}
1694
1695#define N_PTREGS 44
1696static char *regnames[N_PTREGS] = {
1697 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1698 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1699 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1700 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
1701 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "mq",
1702 "trap", "dar", "dsisr", "res"
1703};
1704
1705int
1706scanhex(unsigned *vp)
1707{
1708 int c, d;
1709 unsigned v;
1710
1711 c = skipbl();
1712 if (c == '%') {
1713 /* parse register name */
1714 char regname[8];
1715 int i;
1716
1717 for (i = 0; i < sizeof(regname) - 1; ++i) {
1718 c = inchar();
1719 if (!isalnum(c)) {
1720 termch = c;
1721 break;
1722 }
1723 regname[i] = c;
1724 }
1725 regname[i] = 0;
1726 for (i = 0; i < N_PTREGS; ++i) {
1727 if (strcmp(regnames[i], regname) == 0) {
1728 unsigned *rp = (unsigned *)
1729 xmon_regs[smp_processor_id()];
1730 if (rp == NULL) {
1731 printf("regs not available\n");
1732 return 0;
1733 }
1734 *vp = rp[i];
1735 return 1;
1736 }
1737 }
1738 printf("invalid register name '%%%s'\n", regname);
1739 return 0;
1740 } else if (c == '$') {
1741 static char symname[64];
1742 int i;
1743 for (i=0; i<63; i++) {
1744 c = inchar();
1745 if (isspace(c)) {
1746 termch = c;
1747 break;
1748 }
1749 symname[i] = c;
1750 }
1751 symname[i++] = 0;
1752 *vp = xmon_symbol_to_addr(symname);
1753 if (!(*vp)) {
1754 printf("unknown symbol\n");
1755 return 0;
1756 }
1757 return 1;
1758 }
1759
1760 d = hexdigit(c);
1761 if( d == EOF ){
1762 termch = c;
1763 return 0;
1764 }
1765 v = 0;
1766 do {
1767 v = (v << 4) + d;
1768 c = inchar();
1769 d = hexdigit(c);
1770 } while( d != EOF );
1771 termch = c;
1772 *vp = v;
1773 return 1;
1774}
1775
1776void
1777scannl(void)
1778{
1779 int c;
1780
1781 c = termch;
1782 termch = 0;
1783 while( c != '\n' )
1784 c = inchar();
1785}
1786
1787int hexdigit(int c)
1788{
1789 if( '0' <= c && c <= '9' )
1790 return c - '0';
1791 if( 'A' <= c && c <= 'F' )
1792 return c - ('A' - 10);
1793 if( 'a' <= c && c <= 'f' )
1794 return c - ('a' - 10);
1795 return EOF;
1796}
1797
1798void
1799getstring(char *s, int size)
1800{
1801 int c;
1802
1803 c = skipbl();
1804 do {
1805 if( size > 1 ){
1806 *s++ = c;
1807 --size;
1808 }
1809 c = inchar();
1810 } while( c != ' ' && c != '\t' && c != '\n' );
1811 termch = c;
1812 *s = 0;
1813}
1814
1815static char line[256];
1816static char *lineptr;
1817
1818void
1819flush_input(void)
1820{
1821 lineptr = NULL;
1822}
1823
1824int
1825inchar(void)
1826{
1827 if (lineptr == NULL || *lineptr == 0) {
1828 if (fgets(line, sizeof(line), stdin) == NULL) {
1829 lineptr = NULL;
1830 return EOF;
1831 }
1832 lineptr = line;
1833 }
1834 return *lineptr++;
1835}
1836
1837void
1838take_input(char *str)
1839{
1840 lineptr = str;
1841}
1842
1843void
1844sysmap_lookup(void)
1845{
1846 int type = inchar();
1847 unsigned addr;
1848 static char tmp[64];
1849 char* cur;
1850
1851 extern char *sysmap;
1852 extern unsigned long sysmap_size;
1853 if ( !sysmap || !sysmap_size )
1854 return;
1855
1856 switch(type) {
1857 case 'a':
1858 if (scanhex(&addr)) {
1859 pretty_print_addr(addr);
1860 printf("\n");
1861 }
1862 termch = 0;
1863 break;
1864 case 's':
1865 getstring(tmp, 64);
1866 if( setjmp(bus_error_jmp) == 0 ) {
1867 debugger_fault_handler = handle_fault;
1868 sync();
1869 cur = sysmap;
1870 do {
1871 cur = strstr(cur, tmp);
1872 if (cur) {
1873 static char res[64];
1874 char *p, *d;
1875 p = cur;
1876 while(p > sysmap && *p != 10)
1877 p--;
1878 if (*p == 10) p++;
1879 d = res;
1880 while(*p && p < (sysmap + sysmap_size) && *p != 10)
1881 *(d++) = *(p++);
1882 *(d++) = 0;
1883 printf("%s\n", res);
1884 cur++;
1885 }
1886 } while (cur);
1887 sync();
1888 }
1889 debugger_fault_handler = NULL;
1890 termch = 0;
1891 break;
1892 }
1893}
1894
1895static int
1896pretty_print_addr(unsigned long addr)
1897{
1898 char *sym;
1899 unsigned long saddr;
1900
1901 printf("%08x", addr);
1902 sym = xmon_find_symbol(addr, &saddr);
1903 if (sym)
1904 printf(" (%s+0x%x)", sym, addr-saddr);
1905 return (sym != 0);
1906}
1907
1908char*
1909xmon_find_symbol(unsigned long addr, unsigned long* saddr)
1910{
1911 static char rbuffer[64];
1912 char *p, *ep, *limit;
1913 unsigned long prev, next;
1914 char* psym;
1915
1916 extern char *sysmap;
1917 extern unsigned long sysmap_size;
1918 if ( !sysmap || !sysmap_size )
1919 return NULL;
1920
1921 prev = 0;
1922 psym = NULL;
1923 p = sysmap;
1924 limit = p + sysmap_size;
1925 if( setjmp(bus_error_jmp) == 0 ) {
1926 debugger_fault_handler = handle_fault;
1927 sync();
1928 do {
1929 next = simple_strtoul(p, &p, 16);
1930 if (next > addr && prev <= addr) {
1931 if (!psym)
1932 goto bail;
1933 ep = rbuffer;
1934 p = psym;
1935 while(*p && p < limit && *p == 32)
1936 p++;
1937 while(*p && p < limit && *p != 10 && (ep - rbuffer) < 63)
1938 *(ep++) = *(p++);
1939 *(ep++) = 0;
1940 if (saddr)
1941 *saddr = prev;
1942 debugger_fault_handler = NULL;
1943 return rbuffer;
1944 }
1945 prev = next;
1946 psym = p;
1947 while(*p && p < limit && *p != 10)
1948 p++;
1949 if (*p) p++;
1950 } while(*p && p < limit && next);
1951bail:
1952 sync();
1953 }
1954 debugger_fault_handler = NULL;
1955 return NULL;
1956}
1957
1958unsigned long
1959xmon_symbol_to_addr(char* symbol)
1960{
1961 char *p, *cur;
1962 char *match = NULL;
1963 int goodness = 0;
1964 int result = 0;
1965
1966 extern char *sysmap;
1967 extern unsigned long sysmap_size;
1968 if ( !sysmap || !sysmap_size )
1969 return 0;
1970
1971 if( setjmp(bus_error_jmp) == 0 ) {
1972 debugger_fault_handler = handle_fault;
1973 sync();
1974 cur = sysmap;
1975 while(cur) {
1976 cur = strstr(cur, symbol);
1977 if (cur) {
1978 int gd = 1;
1979
1980 /* best match if equal, better match if
1981 * begins with
1982 */
1983 if (cur == sysmap || *(cur-1) == ' ') {
1984 gd++;
1985 if (cur[strlen(symbol)] == 10)
1986 gd++;
1987 }
1988 if (gd > goodness) {
1989 match = cur;
1990 goodness = gd;
1991 if (gd == 3)
1992 break;
1993 }
1994 cur++;
1995 }
1996 }
1997 if (goodness) {
1998 p = match;
1999 while(p > sysmap && *p != 10)
2000 p--;
2001 if (*p == 10) p++;
2002 result = simple_strtoul(p, &p, 16);
2003 }
2004 sync();
2005 }
2006 debugger_fault_handler = NULL;
2007 return result;
2008}