mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-08 01:08:03 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
14
arch/powerpc/xmon/Makefile
Normal file
14
arch/powerpc/xmon/Makefile
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Makefile for xmon
|
||||
|
||||
subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
|
||||
|
||||
GCOV_PROFILE := n
|
||||
|
||||
ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
|
||||
|
||||
obj-y += xmon.o nonstdio.o
|
||||
|
||||
ifdef CONFIG_XMON_DISASSEMBLY
|
||||
obj-y += ppc-dis.o ppc-opc.o
|
||||
obj-$(CONFIG_SPU_BASE) += spu-dis.o spu-opc.o
|
||||
endif
|
141
arch/powerpc/xmon/ansidecl.h
Normal file
141
arch/powerpc/xmon/ansidecl.h
Normal file
|
@ -0,0 +1,141 @@
|
|||
/* ANSI and traditional C compatibility macros
|
||||
Copyright 1991, 1992 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* ANSI and traditional C compatibility macros
|
||||
|
||||
ANSI C is assumed if __STDC__ is #defined.
|
||||
|
||||
Macro ANSI C definition Traditional C definition
|
||||
----- ---- - ---------- ----------- - ----------
|
||||
PTR `void *' `char *'
|
||||
LONG_DOUBLE `long double' `double'
|
||||
VOLATILE `volatile' `'
|
||||
SIGNED `signed' `'
|
||||
PTRCONST `void *const' `char *'
|
||||
ANSI_PROTOTYPES 1 not defined
|
||||
|
||||
CONST is also defined, but is obsolete. Just use const.
|
||||
|
||||
DEFUN (name, arglist, args)
|
||||
|
||||
Defines function NAME.
|
||||
|
||||
ARGLIST lists the arguments, separated by commas and enclosed in
|
||||
parentheses. ARGLIST becomes the argument list in traditional C.
|
||||
|
||||
ARGS list the arguments with their types. It becomes a prototype in
|
||||
ANSI C, and the type declarations in traditional C. Arguments should
|
||||
be separated with `AND'. For functions with a variable number of
|
||||
arguments, the last thing listed should be `DOTS'.
|
||||
|
||||
DEFUN_VOID (name)
|
||||
|
||||
Defines a function NAME, which takes no arguments.
|
||||
|
||||
obsolete -- EXFUN (name, (prototype)) -- obsolete.
|
||||
|
||||
Replaced by PARAMS. Do not use; will disappear someday soon.
|
||||
Was used in external function declarations.
|
||||
In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in
|
||||
parentheses). In traditional C it is `NAME()'.
|
||||
For a function that takes no arguments, PROTOTYPE should be `(void)'.
|
||||
|
||||
PARAMS ((args))
|
||||
|
||||
We could use the EXFUN macro to handle prototype declarations, but
|
||||
the name is misleading and the result is ugly. So we just define a
|
||||
simple macro to handle the parameter lists, as in:
|
||||
|
||||
static int foo PARAMS ((int, char));
|
||||
|
||||
This produces: `static int foo();' or `static int foo (int, char);'
|
||||
|
||||
EXFUN would have done it like this:
|
||||
|
||||
static int EXFUN (foo, (int, char));
|
||||
|
||||
but the function is not external...and it's hard to visually parse
|
||||
the function name out of the mess. EXFUN should be considered
|
||||
obsolete; new code should be written to use PARAMS.
|
||||
|
||||
For example:
|
||||
extern int printf PARAMS ((CONST char *format DOTS));
|
||||
int DEFUN(fprintf, (stream, format),
|
||||
FILE *stream AND CONST char *format DOTS) { ... }
|
||||
void DEFUN_VOID(abort) { ... }
|
||||
*/
|
||||
|
||||
#ifndef _ANSIDECL_H
|
||||
|
||||
#define _ANSIDECL_H 1
|
||||
|
||||
|
||||
/* Every source file includes this file,
|
||||
so they will all get the switch for lint. */
|
||||
/* LINTLIBRARY */
|
||||
|
||||
|
||||
#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32)
|
||||
/* All known AIX compilers implement these things (but don't always
|
||||
define __STDC__). The RISC/OS MIPS compiler defines these things
|
||||
in SVR4 mode, but does not define __STDC__. */
|
||||
|
||||
#define PTR void *
|
||||
#define PTRCONST void *CONST
|
||||
#define LONG_DOUBLE long double
|
||||
|
||||
#define AND ,
|
||||
#define NOARGS void
|
||||
#define CONST const
|
||||
#define VOLATILE volatile
|
||||
#define SIGNED signed
|
||||
#define DOTS , ...
|
||||
|
||||
#define EXFUN(name, proto) name proto
|
||||
#define DEFUN(name, arglist, args) name(args)
|
||||
#define DEFUN_VOID(name) name(void)
|
||||
|
||||
#define PROTO(type, name, arglist) type name arglist
|
||||
#define PARAMS(paramlist) paramlist
|
||||
#define ANSI_PROTOTYPES 1
|
||||
|
||||
#else /* Not ANSI C. */
|
||||
|
||||
#define PTR char *
|
||||
#define PTRCONST PTR
|
||||
#define LONG_DOUBLE double
|
||||
|
||||
#define AND ;
|
||||
#define NOARGS
|
||||
#define CONST
|
||||
#ifndef const /* some systems define it in header files for non-ansi mode */
|
||||
#define const
|
||||
#endif
|
||||
#define VOLATILE
|
||||
#define SIGNED
|
||||
#define DOTS
|
||||
|
||||
#define EXFUN(name, proto) name()
|
||||
#define DEFUN(name, arglist, args) name arglist args;
|
||||
#define DEFUN_VOID(name) name()
|
||||
#define PROTO(type, name, arglist) type name ()
|
||||
#define PARAMS(paramlist) ()
|
||||
|
||||
#endif /* ANSI C. */
|
||||
|
||||
#endif /* ansidecl.h */
|
31
arch/powerpc/xmon/dis-asm.h
Normal file
31
arch/powerpc/xmon/dis-asm.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef _POWERPC_XMON_DIS_ASM_H
|
||||
#define _POWERPC_XMON_DIS_ASM_H
|
||||
/*
|
||||
* Copyright (C) 2006 Michael Ellerman, IBM Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
extern void print_address (unsigned long memaddr);
|
||||
|
||||
#ifdef CONFIG_XMON_DISASSEMBLY
|
||||
extern int print_insn_powerpc(unsigned long insn, unsigned long memaddr);
|
||||
extern int print_insn_spu(unsigned long insn, unsigned long memaddr);
|
||||
#else
|
||||
static inline int print_insn_powerpc(unsigned long insn, unsigned long memaddr)
|
||||
{
|
||||
printf("%.8x", insn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int print_insn_spu(unsigned long insn, unsigned long memaddr)
|
||||
{
|
||||
printf("%.8x", insn);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _POWERPC_XMON_DIS_ASM_H */
|
132
arch/powerpc/xmon/nonstdio.c
Normal file
132
arch/powerpc/xmon/nonstdio.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright (C) 1996-2005 Paul Mackerras.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
#include <linux/string.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/time.h>
|
||||
#include "nonstdio.h"
|
||||
|
||||
|
||||
static int xmon_write(const void *ptr, int nb)
|
||||
{
|
||||
return udbg_write(ptr, nb);
|
||||
}
|
||||
|
||||
static int xmon_readchar(void)
|
||||
{
|
||||
if (udbg_getc)
|
||||
return udbg_getc();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int xmon_putchar(int c)
|
||||
{
|
||||
char ch = c;
|
||||
|
||||
if (c == '\n')
|
||||
xmon_putchar('\r');
|
||||
return xmon_write(&ch, 1) == 1? c: -1;
|
||||
}
|
||||
|
||||
static char line[256];
|
||||
static char *lineptr;
|
||||
static int lineleft;
|
||||
|
||||
static int xmon_getchar(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
if (lineleft == 0) {
|
||||
lineptr = line;
|
||||
for (;;) {
|
||||
c = xmon_readchar();
|
||||
if (c == -1 || c == 4)
|
||||
break;
|
||||
if (c == '\r' || c == '\n') {
|
||||
*lineptr++ = '\n';
|
||||
xmon_putchar('\n');
|
||||
break;
|
||||
}
|
||||
switch (c) {
|
||||
case 0177:
|
||||
case '\b':
|
||||
if (lineptr > line) {
|
||||
xmon_putchar('\b');
|
||||
xmon_putchar(' ');
|
||||
xmon_putchar('\b');
|
||||
--lineptr;
|
||||
}
|
||||
break;
|
||||
case 'U' & 0x1F:
|
||||
while (lineptr > line) {
|
||||
xmon_putchar('\b');
|
||||
xmon_putchar(' ');
|
||||
xmon_putchar('\b');
|
||||
--lineptr;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (lineptr >= &line[sizeof(line) - 1])
|
||||
xmon_putchar('\a');
|
||||
else {
|
||||
xmon_putchar(c);
|
||||
*lineptr++ = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
lineleft = lineptr - line;
|
||||
lineptr = line;
|
||||
}
|
||||
if (lineleft == 0)
|
||||
return -1;
|
||||
--lineleft;
|
||||
return *lineptr++;
|
||||
}
|
||||
|
||||
char *xmon_gets(char *str, int nb)
|
||||
{
|
||||
char *p;
|
||||
int c;
|
||||
|
||||
for (p = str; p < str + nb - 1; ) {
|
||||
c = xmon_getchar();
|
||||
if (c == -1) {
|
||||
if (p == str)
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
*p++ = c;
|
||||
if (c == '\n')
|
||||
break;
|
||||
}
|
||||
*p = 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
void xmon_printf(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
static char xmon_outbuf[1024];
|
||||
int rc, n;
|
||||
|
||||
va_start(args, format);
|
||||
n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args);
|
||||
va_end(args);
|
||||
|
||||
rc = xmon_write(xmon_outbuf, n);
|
||||
|
||||
if (n && rc == 0) {
|
||||
/* No udbg hooks, fallback to printk() - dangerous */
|
||||
printk("%s", xmon_outbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void xmon_puts(const char *str)
|
||||
{
|
||||
xmon_write(str, strlen(str));
|
||||
}
|
9
arch/powerpc/xmon/nonstdio.h
Normal file
9
arch/powerpc/xmon/nonstdio.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#define EOF (-1)
|
||||
|
||||
#define printf xmon_printf
|
||||
#define putchar xmon_putchar
|
||||
|
||||
extern int xmon_putchar(int c);
|
||||
extern void xmon_puts(const char *);
|
||||
extern char *xmon_gets(char *, int);
|
||||
extern void xmon_printf(const char *, ...);
|
195
arch/powerpc/xmon/ppc-dis.c
Normal file
195
arch/powerpc/xmon/ppc-dis.c
Normal file
|
@ -0,0 +1,195 @@
|
|||
/* ppc-dis.c -- Disassemble PowerPC instructions
|
||||
Copyright 1994, 1995, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Cygnus Support
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
||||
them and/or modify them under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either version
|
||||
2, or (at your option) any later version.
|
||||
|
||||
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
||||
will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this file; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include <asm/cputable.h>
|
||||
#include "nonstdio.h"
|
||||
#include "ansidecl.h"
|
||||
#include "ppc.h"
|
||||
#include "dis-asm.h"
|
||||
|
||||
/* Print a PowerPC or POWER instruction. */
|
||||
|
||||
int
|
||||
print_insn_powerpc (unsigned long insn, unsigned long memaddr)
|
||||
{
|
||||
const struct powerpc_opcode *opcode;
|
||||
const struct powerpc_opcode *opcode_end;
|
||||
unsigned long op;
|
||||
int dialect;
|
||||
|
||||
dialect = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_COMMON
|
||||
| PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_ALTIVEC;
|
||||
|
||||
if (cpu_has_feature(CPU_FTRS_POWER5))
|
||||
dialect |= PPC_OPCODE_POWER5;
|
||||
|
||||
if (cpu_has_feature(CPU_FTRS_CELL))
|
||||
dialect |= PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC;
|
||||
|
||||
if (cpu_has_feature(CPU_FTRS_POWER6))
|
||||
dialect |= PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC;
|
||||
|
||||
/* Get the major opcode of the instruction. */
|
||||
op = PPC_OP (insn);
|
||||
|
||||
/* Find the first match in the opcode table. We could speed this up
|
||||
a bit by doing a binary search on the major opcode. */
|
||||
opcode_end = powerpc_opcodes + powerpc_num_opcodes;
|
||||
again:
|
||||
for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++)
|
||||
{
|
||||
unsigned long table_op;
|
||||
const unsigned char *opindex;
|
||||
const struct powerpc_operand *operand;
|
||||
int invalid;
|
||||
int need_comma;
|
||||
int need_paren;
|
||||
|
||||
table_op = PPC_OP (opcode->opcode);
|
||||
if (op < table_op)
|
||||
break;
|
||||
if (op > table_op)
|
||||
continue;
|
||||
|
||||
if ((insn & opcode->mask) != opcode->opcode
|
||||
|| (opcode->flags & dialect) == 0)
|
||||
continue;
|
||||
|
||||
/* Make two passes over the operands. First see if any of them
|
||||
have extraction functions, and, if they do, make sure the
|
||||
instruction is valid. */
|
||||
invalid = 0;
|
||||
for (opindex = opcode->operands; *opindex != 0; opindex++)
|
||||
{
|
||||
operand = powerpc_operands + *opindex;
|
||||
if (operand->extract)
|
||||
(*operand->extract) (insn, dialect, &invalid);
|
||||
}
|
||||
if (invalid)
|
||||
continue;
|
||||
|
||||
/* The instruction is valid. */
|
||||
printf("%s", opcode->name);
|
||||
if (opcode->operands[0] != 0)
|
||||
printf("\t");
|
||||
|
||||
/* Now extract and print the operands. */
|
||||
need_comma = 0;
|
||||
need_paren = 0;
|
||||
for (opindex = opcode->operands; *opindex != 0; opindex++)
|
||||
{
|
||||
long value;
|
||||
|
||||
operand = powerpc_operands + *opindex;
|
||||
|
||||
/* Operands that are marked FAKE are simply ignored. We
|
||||
already made sure that the extract function considered
|
||||
the instruction to be valid. */
|
||||
if ((operand->flags & PPC_OPERAND_FAKE) != 0)
|
||||
continue;
|
||||
|
||||
/* Extract the value from the instruction. */
|
||||
if (operand->extract)
|
||||
value = (*operand->extract) (insn, dialect, &invalid);
|
||||
else
|
||||
{
|
||||
value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
|
||||
if ((operand->flags & PPC_OPERAND_SIGNED) != 0
|
||||
&& (value & (1 << (operand->bits - 1))) != 0)
|
||||
value -= 1 << operand->bits;
|
||||
}
|
||||
|
||||
/* If the operand is optional, and the value is zero, don't
|
||||
print anything. */
|
||||
if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
|
||||
&& (operand->flags & PPC_OPERAND_NEXT) == 0
|
||||
&& value == 0)
|
||||
continue;
|
||||
|
||||
if (need_comma)
|
||||
{
|
||||
printf(",");
|
||||
need_comma = 0;
|
||||
}
|
||||
|
||||
/* Print the operand as directed by the flags. */
|
||||
if ((operand->flags & PPC_OPERAND_GPR) != 0
|
||||
|| ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
|
||||
printf("r%ld", value);
|
||||
else if ((operand->flags & PPC_OPERAND_FPR) != 0)
|
||||
printf("f%ld", value);
|
||||
else if ((operand->flags & PPC_OPERAND_VR) != 0)
|
||||
printf("v%ld", value);
|
||||
else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
|
||||
print_address (memaddr + value);
|
||||
else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
|
||||
print_address (value & 0xffffffff);
|
||||
else if ((operand->flags & PPC_OPERAND_CR) == 0
|
||||
|| (dialect & PPC_OPCODE_PPC) == 0)
|
||||
printf("%ld", value);
|
||||
else
|
||||
{
|
||||
if (operand->bits == 3)
|
||||
printf("cr%ld", value);
|
||||
else
|
||||
{
|
||||
static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
|
||||
int cr;
|
||||
int cc;
|
||||
|
||||
cr = value >> 2;
|
||||
if (cr != 0)
|
||||
printf("4*cr%d+", cr);
|
||||
cc = value & 3;
|
||||
printf("%s", cbnames[cc]);
|
||||
}
|
||||
}
|
||||
|
||||
if (need_paren)
|
||||
{
|
||||
printf(")");
|
||||
need_paren = 0;
|
||||
}
|
||||
|
||||
if ((operand->flags & PPC_OPERAND_PARENS) == 0)
|
||||
need_comma = 1;
|
||||
else
|
||||
{
|
||||
printf("(");
|
||||
need_paren = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* We have found and printed an instruction; return. */
|
||||
return 4;
|
||||
}
|
||||
|
||||
if ((dialect & PPC_OPCODE_ANY) != 0)
|
||||
{
|
||||
dialect = ~PPC_OPCODE_ANY;
|
||||
goto again;
|
||||
}
|
||||
|
||||
/* We could not find a match. */
|
||||
printf(".long 0x%lx", insn);
|
||||
|
||||
return 4;
|
||||
}
|
4993
arch/powerpc/xmon/ppc-opc.c
Normal file
4993
arch/powerpc/xmon/ppc-opc.c
Normal file
File diff suppressed because it is too large
Load diff
322
arch/powerpc/xmon/ppc.h
Normal file
322
arch/powerpc/xmon/ppc.h
Normal file
|
@ -0,0 +1,322 @@
|
|||
/* ppc.h -- Header file for PowerPC opcode table
|
||||
Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Cygnus Support
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
||||
them and/or modify them under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either version
|
||||
1, or (at your option) any later version.
|
||||
|
||||
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
||||
will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this file; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef PPC_H
|
||||
#define PPC_H
|
||||
|
||||
/* The opcode table is an array of struct powerpc_opcode. */
|
||||
|
||||
struct powerpc_opcode
|
||||
{
|
||||
/* The opcode name. */
|
||||
const char *name;
|
||||
|
||||
/* The opcode itself. Those bits which will be filled in with
|
||||
operands are zeroes. */
|
||||
unsigned long opcode;
|
||||
|
||||
/* The opcode mask. This is used by the disassembler. This is a
|
||||
mask containing ones indicating those bits which must match the
|
||||
opcode field, and zeroes indicating those bits which need not
|
||||
match (and are presumably filled in by operands). */
|
||||
unsigned long mask;
|
||||
|
||||
/* One bit flags for the opcode. These are used to indicate which
|
||||
specific processors support the instructions. The defined values
|
||||
are listed below. */
|
||||
unsigned long flags;
|
||||
|
||||
/* An array of operand codes. Each code is an index into the
|
||||
operand table. They appear in the order which the operands must
|
||||
appear in assembly code, and are terminated by a zero. */
|
||||
unsigned char operands[8];
|
||||
};
|
||||
|
||||
/* The table itself is sorted by major opcode number, and is otherwise
|
||||
in the order in which the disassembler should consider
|
||||
instructions. */
|
||||
extern const struct powerpc_opcode powerpc_opcodes[];
|
||||
extern const int powerpc_num_opcodes;
|
||||
|
||||
/* Values defined for the flags field of a struct powerpc_opcode. */
|
||||
|
||||
/* Opcode is defined for the PowerPC architecture. */
|
||||
#define PPC_OPCODE_PPC 1
|
||||
|
||||
/* Opcode is defined for the POWER (RS/6000) architecture. */
|
||||
#define PPC_OPCODE_POWER 2
|
||||
|
||||
/* Opcode is defined for the POWER2 (Rios 2) architecture. */
|
||||
#define PPC_OPCODE_POWER2 4
|
||||
|
||||
/* Opcode is only defined on 32 bit architectures. */
|
||||
#define PPC_OPCODE_32 8
|
||||
|
||||
/* Opcode is only defined on 64 bit architectures. */
|
||||
#define PPC_OPCODE_64 0x10
|
||||
|
||||
/* Opcode is supported by the Motorola PowerPC 601 processor. The 601
|
||||
is assumed to support all PowerPC (PPC_OPCODE_PPC) instructions,
|
||||
but it also supports many additional POWER instructions. */
|
||||
#define PPC_OPCODE_601 0x20
|
||||
|
||||
/* Opcode is supported in both the Power and PowerPC architectures
|
||||
(ie, compiler's -mcpu=common or assembler's -mcom). */
|
||||
#define PPC_OPCODE_COMMON 0x40
|
||||
|
||||
/* Opcode is supported for any Power or PowerPC platform (this is
|
||||
for the assembler's -many option, and it eliminates duplicates). */
|
||||
#define PPC_OPCODE_ANY 0x80
|
||||
|
||||
/* Opcode is supported as part of the 64-bit bridge. */
|
||||
#define PPC_OPCODE_64_BRIDGE 0x100
|
||||
|
||||
/* Opcode is supported by Altivec Vector Unit */
|
||||
#define PPC_OPCODE_ALTIVEC 0x200
|
||||
|
||||
/* Opcode is supported by PowerPC 403 processor. */
|
||||
#define PPC_OPCODE_403 0x400
|
||||
|
||||
/* Opcode is supported by PowerPC BookE processor. */
|
||||
#define PPC_OPCODE_BOOKE 0x800
|
||||
|
||||
/* Opcode is only supported by 64-bit PowerPC BookE processor. */
|
||||
#define PPC_OPCODE_BOOKE64 0x1000
|
||||
|
||||
/* Opcode is supported by PowerPC 440 processor. */
|
||||
#define PPC_OPCODE_440 0x2000
|
||||
|
||||
/* Opcode is only supported by Power4 architecture. */
|
||||
#define PPC_OPCODE_POWER4 0x4000
|
||||
|
||||
/* Opcode isn't supported by Power4 architecture. */
|
||||
#define PPC_OPCODE_NOPOWER4 0x8000
|
||||
|
||||
/* Opcode is only supported by POWERPC Classic architecture. */
|
||||
#define PPC_OPCODE_CLASSIC 0x10000
|
||||
|
||||
/* Opcode is only supported by e500x2 Core. */
|
||||
#define PPC_OPCODE_SPE 0x20000
|
||||
|
||||
/* Opcode is supported by e500x2 Integer select APU. */
|
||||
#define PPC_OPCODE_ISEL 0x40000
|
||||
|
||||
/* Opcode is an e500 SPE floating point instruction. */
|
||||
#define PPC_OPCODE_EFS 0x80000
|
||||
|
||||
/* Opcode is supported by branch locking APU. */
|
||||
#define PPC_OPCODE_BRLOCK 0x100000
|
||||
|
||||
/* Opcode is supported by performance monitor APU. */
|
||||
#define PPC_OPCODE_PMR 0x200000
|
||||
|
||||
/* Opcode is supported by cache locking APU. */
|
||||
#define PPC_OPCODE_CACHELCK 0x400000
|
||||
|
||||
/* Opcode is supported by machine check APU. */
|
||||
#define PPC_OPCODE_RFMCI 0x800000
|
||||
|
||||
/* Opcode is only supported by Power5 architecture. */
|
||||
#define PPC_OPCODE_POWER5 0x1000000
|
||||
|
||||
/* Opcode is supported by PowerPC e300 family. */
|
||||
#define PPC_OPCODE_E300 0x2000000
|
||||
|
||||
/* Opcode is only supported by Power6 architecture. */
|
||||
#define PPC_OPCODE_POWER6 0x4000000
|
||||
|
||||
/* Opcode is only supported by PowerPC Cell family. */
|
||||
#define PPC_OPCODE_CELL 0x8000000
|
||||
|
||||
/* A macro to extract the major opcode from an instruction. */
|
||||
#define PPC_OP(i) (((i) >> 26) & 0x3f)
|
||||
|
||||
/* The operands table is an array of struct powerpc_operand. */
|
||||
|
||||
struct powerpc_operand
|
||||
{
|
||||
/* The number of bits in the operand. */
|
||||
int bits;
|
||||
|
||||
/* How far the operand is left shifted in the instruction. */
|
||||
int shift;
|
||||
|
||||
/* Insertion function. This is used by the assembler. To insert an
|
||||
operand value into an instruction, check this field.
|
||||
|
||||
If it is NULL, execute
|
||||
i |= (op & ((1 << o->bits) - 1)) << o->shift;
|
||||
(i is the instruction which we are filling in, o is a pointer to
|
||||
this structure, and op is the opcode value; this assumes twos
|
||||
complement arithmetic).
|
||||
|
||||
If this field is not NULL, then simply call it with the
|
||||
instruction and the operand value. It will return the new value
|
||||
of the instruction. If the ERRMSG argument is not NULL, then if
|
||||
the operand value is illegal, *ERRMSG will be set to a warning
|
||||
string (the operand will be inserted in any case). If the
|
||||
operand value is legal, *ERRMSG will be unchanged (most operands
|
||||
can accept any value). */
|
||||
unsigned long (*insert)
|
||||
(unsigned long instruction, long op, int dialect, const char **errmsg);
|
||||
|
||||
/* Extraction function. This is used by the disassembler. To
|
||||
extract this operand type from an instruction, check this field.
|
||||
|
||||
If it is NULL, compute
|
||||
op = ((i) >> o->shift) & ((1 << o->bits) - 1);
|
||||
if ((o->flags & PPC_OPERAND_SIGNED) != 0
|
||||
&& (op & (1 << (o->bits - 1))) != 0)
|
||||
op -= 1 << o->bits;
|
||||
(i is the instruction, o is a pointer to this structure, and op
|
||||
is the result; this assumes twos complement arithmetic).
|
||||
|
||||
If this field is not NULL, then simply call it with the
|
||||
instruction value. It will return the value of the operand. If
|
||||
the INVALID argument is not NULL, *INVALID will be set to
|
||||
non-zero if this operand type can not actually be extracted from
|
||||
this operand (i.e., the instruction does not match). If the
|
||||
operand is valid, *INVALID will not be changed. */
|
||||
long (*extract) (unsigned long instruction, int dialect, int *invalid);
|
||||
|
||||
/* One bit syntax flags. */
|
||||
unsigned long flags;
|
||||
};
|
||||
|
||||
/* Elements in the table are retrieved by indexing with values from
|
||||
the operands field of the powerpc_opcodes table. */
|
||||
|
||||
extern const struct powerpc_operand powerpc_operands[];
|
||||
|
||||
/* Values defined for the flags field of a struct powerpc_operand. */
|
||||
|
||||
/* This operand takes signed values. */
|
||||
#define PPC_OPERAND_SIGNED (01)
|
||||
|
||||
/* This operand takes signed values, but also accepts a full positive
|
||||
range of values when running in 32 bit mode. That is, if bits is
|
||||
16, it takes any value from -0x8000 to 0xffff. In 64 bit mode,
|
||||
this flag is ignored. */
|
||||
#define PPC_OPERAND_SIGNOPT (02)
|
||||
|
||||
/* This operand does not actually exist in the assembler input. This
|
||||
is used to support extended mnemonics such as mr, for which two
|
||||
operands fields are identical. The assembler should call the
|
||||
insert function with any op value. The disassembler should call
|
||||
the extract function, ignore the return value, and check the value
|
||||
placed in the valid argument. */
|
||||
#define PPC_OPERAND_FAKE (04)
|
||||
|
||||
/* The next operand should be wrapped in parentheses rather than
|
||||
separated from this one by a comma. This is used for the load and
|
||||
store instructions which want their operands to look like
|
||||
reg,displacement(reg)
|
||||
*/
|
||||
#define PPC_OPERAND_PARENS (010)
|
||||
|
||||
/* This operand may use the symbolic names for the CR fields, which
|
||||
are
|
||||
lt 0 gt 1 eq 2 so 3 un 3
|
||||
cr0 0 cr1 1 cr2 2 cr3 3
|
||||
cr4 4 cr5 5 cr6 6 cr7 7
|
||||
These may be combined arithmetically, as in cr2*4+gt. These are
|
||||
only supported on the PowerPC, not the POWER. */
|
||||
#define PPC_OPERAND_CR (020)
|
||||
|
||||
/* This operand names a register. The disassembler uses this to print
|
||||
register names with a leading 'r'. */
|
||||
#define PPC_OPERAND_GPR (040)
|
||||
|
||||
/* Like PPC_OPERAND_GPR, but don't print a leading 'r' for r0. */
|
||||
#define PPC_OPERAND_GPR_0 (0100)
|
||||
|
||||
/* This operand names a floating point register. The disassembler
|
||||
prints these with a leading 'f'. */
|
||||
#define PPC_OPERAND_FPR (0200)
|
||||
|
||||
/* This operand is a relative branch displacement. The disassembler
|
||||
prints these symbolically if possible. */
|
||||
#define PPC_OPERAND_RELATIVE (0400)
|
||||
|
||||
/* This operand is an absolute branch address. The disassembler
|
||||
prints these symbolically if possible. */
|
||||
#define PPC_OPERAND_ABSOLUTE (01000)
|
||||
|
||||
/* This operand is optional, and is zero if omitted. This is used for
|
||||
example, in the optional BF field in the comparison instructions. The
|
||||
assembler must count the number of operands remaining on the line,
|
||||
and the number of operands remaining for the opcode, and decide
|
||||
whether this operand is present or not. The disassembler should
|
||||
print this operand out only if it is not zero. */
|
||||
#define PPC_OPERAND_OPTIONAL (02000)
|
||||
|
||||
/* This flag is only used with PPC_OPERAND_OPTIONAL. If this operand
|
||||
is omitted, then for the next operand use this operand value plus
|
||||
1, ignoring the next operand field for the opcode. This wretched
|
||||
hack is needed because the Power rotate instructions can take
|
||||
either 4 or 5 operands. The disassembler should print this operand
|
||||
out regardless of the PPC_OPERAND_OPTIONAL field. */
|
||||
#define PPC_OPERAND_NEXT (04000)
|
||||
|
||||
/* This operand should be regarded as a negative number for the
|
||||
purposes of overflow checking (i.e., the normal most negative
|
||||
number is disallowed and one more than the normal most positive
|
||||
number is allowed). This flag will only be set for a signed
|
||||
operand. */
|
||||
#define PPC_OPERAND_NEGATIVE (010000)
|
||||
|
||||
/* This operand names a vector unit register. The disassembler
|
||||
prints these with a leading 'v'. */
|
||||
#define PPC_OPERAND_VR (020000)
|
||||
|
||||
/* This operand is for the DS field in a DS form instruction. */
|
||||
#define PPC_OPERAND_DS (040000)
|
||||
|
||||
/* This operand is for the DQ field in a DQ form instruction. */
|
||||
#define PPC_OPERAND_DQ (0100000)
|
||||
|
||||
/* The POWER and PowerPC assemblers use a few macros. We keep them
|
||||
with the operands table for simplicity. The macro table is an
|
||||
array of struct powerpc_macro. */
|
||||
|
||||
struct powerpc_macro
|
||||
{
|
||||
/* The macro name. */
|
||||
const char *name;
|
||||
|
||||
/* The number of operands the macro takes. */
|
||||
unsigned int operands;
|
||||
|
||||
/* One bit flags for the opcode. These are used to indicate which
|
||||
specific processors support the instructions. The values are the
|
||||
same as those for the struct powerpc_opcode flags field. */
|
||||
unsigned long flags;
|
||||
|
||||
/* A format string to turn the macro into a normal instruction.
|
||||
Each %N in the string is replaced with operand number N (zero
|
||||
based). */
|
||||
const char *format;
|
||||
};
|
||||
|
||||
extern const struct powerpc_macro powerpc_macros[];
|
||||
extern const int powerpc_num_macros;
|
||||
|
||||
#endif /* PPC_H */
|
248
arch/powerpc/xmon/spu-dis.c
Normal file
248
arch/powerpc/xmon/spu-dis.c
Normal file
|
@ -0,0 +1,248 @@
|
|||
/* Disassemble SPU instructions
|
||||
|
||||
Copyright 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include <linux/string.h>
|
||||
#include "nonstdio.h"
|
||||
#include "ansidecl.h"
|
||||
#include "spu.h"
|
||||
#include "dis-asm.h"
|
||||
|
||||
/* This file provides a disassembler function which uses
|
||||
the disassembler interface defined in dis-asm.h. */
|
||||
|
||||
extern const struct spu_opcode spu_opcodes[];
|
||||
extern const int spu_num_opcodes;
|
||||
|
||||
#define SPU_DISASM_TBL_SIZE (1 << 11)
|
||||
static const struct spu_opcode *spu_disassemble_table[SPU_DISASM_TBL_SIZE];
|
||||
|
||||
static void
|
||||
init_spu_disassemble (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* If two instructions have the same opcode then we prefer the first
|
||||
* one. In most cases it is just an alternate mnemonic. */
|
||||
for (i = 0; i < spu_num_opcodes; i++)
|
||||
{
|
||||
int o = spu_opcodes[i].opcode;
|
||||
if (o >= SPU_DISASM_TBL_SIZE)
|
||||
continue; /* abort (); */
|
||||
if (spu_disassemble_table[o] == 0)
|
||||
spu_disassemble_table[o] = &spu_opcodes[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine the instruction from the 10 least significant bits. */
|
||||
static const struct spu_opcode *
|
||||
get_index_for_opcode (unsigned int insn)
|
||||
{
|
||||
const struct spu_opcode *index;
|
||||
unsigned int opcode = insn >> (32-11);
|
||||
|
||||
/* Init the table. This assumes that element 0/opcode 0 (currently
|
||||
* NOP) is always used */
|
||||
if (spu_disassemble_table[0] == 0)
|
||||
init_spu_disassemble ();
|
||||
|
||||
if ((index = spu_disassemble_table[opcode & 0x780]) != 0
|
||||
&& index->insn_type == RRR)
|
||||
return index;
|
||||
|
||||
if ((index = spu_disassemble_table[opcode & 0x7f0]) != 0
|
||||
&& (index->insn_type == RI18 || index->insn_type == LBT))
|
||||
return index;
|
||||
|
||||
if ((index = spu_disassemble_table[opcode & 0x7f8]) != 0
|
||||
&& index->insn_type == RI10)
|
||||
return index;
|
||||
|
||||
if ((index = spu_disassemble_table[opcode & 0x7fc]) != 0
|
||||
&& (index->insn_type == RI16))
|
||||
return index;
|
||||
|
||||
if ((index = spu_disassemble_table[opcode & 0x7fe]) != 0
|
||||
&& (index->insn_type == RI8))
|
||||
return index;
|
||||
|
||||
if ((index = spu_disassemble_table[opcode & 0x7ff]) != 0)
|
||||
return index;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Print a Spu instruction. */
|
||||
|
||||
int
|
||||
print_insn_spu (unsigned long insn, unsigned long memaddr)
|
||||
{
|
||||
int value;
|
||||
int hex_value;
|
||||
const struct spu_opcode *index;
|
||||
enum spu_insns tag;
|
||||
|
||||
index = get_index_for_opcode (insn);
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
printf(".long 0x%x", insn);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
int paren = 0;
|
||||
tag = (enum spu_insns)(index - spu_opcodes);
|
||||
printf("%s", index->mnemonic);
|
||||
if (tag == M_BI || tag == M_BISL || tag == M_IRET || tag == M_BISLED
|
||||
|| tag == M_BIHNZ || tag == M_BIHZ || tag == M_BINZ || tag == M_BIZ
|
||||
|| tag == M_SYNC || tag == M_HBR)
|
||||
{
|
||||
int fb = (insn >> (32-18)) & 0x7f;
|
||||
if (fb & 0x40)
|
||||
printf(tag == M_SYNC ? "c" : "p");
|
||||
if (fb & 0x20)
|
||||
printf("d");
|
||||
if (fb & 0x10)
|
||||
printf("e");
|
||||
}
|
||||
if (index->arg[0] != 0)
|
||||
printf("\t");
|
||||
hex_value = 0;
|
||||
for (i = 1; i <= index->arg[0]; i++)
|
||||
{
|
||||
int arg = index->arg[i];
|
||||
if (arg != A_P && !paren && i > 1)
|
||||
printf(",");
|
||||
|
||||
switch (arg)
|
||||
{
|
||||
case A_T:
|
||||
printf("$%d",
|
||||
DECODE_INSN_RT (insn));
|
||||
break;
|
||||
case A_A:
|
||||
printf("$%d",
|
||||
DECODE_INSN_RA (insn));
|
||||
break;
|
||||
case A_B:
|
||||
printf("$%d",
|
||||
DECODE_INSN_RB (insn));
|
||||
break;
|
||||
case A_C:
|
||||
printf("$%d",
|
||||
DECODE_INSN_RC (insn));
|
||||
break;
|
||||
case A_S:
|
||||
printf("$sp%d",
|
||||
DECODE_INSN_RA (insn));
|
||||
break;
|
||||
case A_H:
|
||||
printf("$ch%d",
|
||||
DECODE_INSN_RA (insn));
|
||||
break;
|
||||
case A_P:
|
||||
paren++;
|
||||
printf("(");
|
||||
break;
|
||||
case A_U7A:
|
||||
printf("%d",
|
||||
173 - DECODE_INSN_U8 (insn));
|
||||
break;
|
||||
case A_U7B:
|
||||
printf("%d",
|
||||
155 - DECODE_INSN_U8 (insn));
|
||||
break;
|
||||
case A_S3:
|
||||
case A_S6:
|
||||
case A_S7:
|
||||
case A_S7N:
|
||||
case A_U3:
|
||||
case A_U5:
|
||||
case A_U6:
|
||||
case A_U7:
|
||||
hex_value = DECODE_INSN_I7 (insn);
|
||||
printf("%d", hex_value);
|
||||
break;
|
||||
case A_S11:
|
||||
print_address(memaddr + DECODE_INSN_I9a (insn) * 4);
|
||||
break;
|
||||
case A_S11I:
|
||||
print_address(memaddr + DECODE_INSN_I9b (insn) * 4);
|
||||
break;
|
||||
case A_S10:
|
||||
case A_S10B:
|
||||
hex_value = DECODE_INSN_I10 (insn);
|
||||
printf("%d", hex_value);
|
||||
break;
|
||||
case A_S14:
|
||||
hex_value = DECODE_INSN_I10 (insn) * 16;
|
||||
printf("%d", hex_value);
|
||||
break;
|
||||
case A_S16:
|
||||
hex_value = DECODE_INSN_I16 (insn);
|
||||
printf("%d", hex_value);
|
||||
break;
|
||||
case A_X16:
|
||||
hex_value = DECODE_INSN_U16 (insn);
|
||||
printf("%u", hex_value);
|
||||
break;
|
||||
case A_R18:
|
||||
value = DECODE_INSN_I16 (insn) * 4;
|
||||
if (value == 0)
|
||||
printf("%d", value);
|
||||
else
|
||||
{
|
||||
hex_value = memaddr + value;
|
||||
print_address(hex_value & 0x3ffff);
|
||||
}
|
||||
break;
|
||||
case A_S18:
|
||||
value = DECODE_INSN_U16 (insn) * 4;
|
||||
if (value == 0)
|
||||
printf("%d", value);
|
||||
else
|
||||
print_address(value);
|
||||
break;
|
||||
case A_U18:
|
||||
value = DECODE_INSN_U18 (insn);
|
||||
if (value == 0 || 1)
|
||||
{
|
||||
hex_value = value;
|
||||
printf("%u", value);
|
||||
}
|
||||
else
|
||||
print_address(value);
|
||||
break;
|
||||
case A_U14:
|
||||
hex_value = DECODE_INSN_U14 (insn);
|
||||
printf("%u", hex_value);
|
||||
break;
|
||||
}
|
||||
if (arg != A_P && paren)
|
||||
{
|
||||
printf(")");
|
||||
paren--;
|
||||
}
|
||||
}
|
||||
if (hex_value > 16)
|
||||
printf("\t# %x", hex_value);
|
||||
}
|
||||
return 4;
|
||||
}
|
410
arch/powerpc/xmon/spu-insns.h
Normal file
410
arch/powerpc/xmon/spu-insns.h
Normal file
|
@ -0,0 +1,410 @@
|
|||
/* SPU ELF support for BFD.
|
||||
|
||||
Copyright 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* SPU Opcode Table
|
||||
|
||||
-=-=-= FORMAT =-=-=-
|
||||
|
||||
+----+-------+-------+-------+-------+ +------------+-------+-------+-------+
|
||||
RRR | op | RC | RB | RA | RT | RI7 | op | I7 | RA | RT |
|
||||
+----+-------+-------+-------+-------+ +------------+-------+-------+-------+
|
||||
0 3 1 1 2 3 0 1 1 2 3
|
||||
0 7 4 1 0 7 4 1
|
||||
|
||||
+-----------+--------+-------+-------+ +---------+----------+-------+-------+
|
||||
RI8 | op | I8 | RA | RT | RI10 | op | I10 | RA | RT |
|
||||
+-----------+--------+-------+-------+ +---------+----------+-------+-------+
|
||||
0 9 1 2 3 0 7 1 2 3
|
||||
7 4 1 7 4 1
|
||||
|
||||
+----------+-----------------+-------+ +--------+-------------------+-------+
|
||||
RI16 | op | I16 | RT | RI18 | op | I18 | RT |
|
||||
+----------+-----------------+-------+ +--------+-------------------+-------+
|
||||
0 8 2 3 0 6 2 3
|
||||
4 1 4 1
|
||||
|
||||
+------------+-------+-------+-------+ +-------+--+-----------------+-------+
|
||||
RR | op | RB | RA | RT | LBT | op |RO| I16 | RO |
|
||||
+------------+-------+-------+-------+ +-------+--+-----------------+-------+
|
||||
0 1 1 2 3 0 6 8 2 3
|
||||
0 7 4 1 4 1
|
||||
|
||||
+------------+----+--+-------+-------+
|
||||
LBTI | op | // |RO| RA | RO |
|
||||
+------------+----+--+-------+-------+
|
||||
0 1 1 1 2 3
|
||||
0 5 7 4 1
|
||||
|
||||
-=-=-= OPCODE =-=-=-
|
||||
|
||||
OPCODE field specifies the most significant 11bit of the instruction. Some formats don't have 11bits for opcode field, and in this
|
||||
case, bit field other than op are defined as 0s. For example, opcode of fma instruction which is RRR format is defined as 0x700,
|
||||
since 0x700 -> 11'b11100000000, this means opcode is 4'b1110, and other 7bits are defined as 7'b0000000.
|
||||
|
||||
-=-=-= ASM_FORMAT =-=-=-
|
||||
|
||||
RRR category RI7 category
|
||||
ASM_RRR mnemonic RC, RA, RB, RT ASM_RI4 mnemonic RT, RA, I4
|
||||
ASM_RI7 mnemonic RT, RA, I7
|
||||
|
||||
RI8 category RI10 category
|
||||
ASM_RUI8 mnemonic RT, RA, UI8 ASM_AI10 mnemonic RA, I10
|
||||
ASM_RI10 mnemonic RT, RA, R10
|
||||
ASM_RI10IDX mnemonic RT, I10(RA)
|
||||
|
||||
RI16 category RI18 category
|
||||
ASM_I16W mnemonic I16W ASM_RI18 mnemonic RT, I18
|
||||
ASM_RI16 mnemonic RT, I16
|
||||
ASM_RI16W mnemonic RT, I16W
|
||||
|
||||
RR category LBT category
|
||||
ASM_MFSPR mnemonic RT, SA ASM_LBT mnemonic brinst, brtarg
|
||||
ASM_MTSPR mnemonic SA, RT
|
||||
ASM_NOOP mnemonic LBTI category
|
||||
ASM_RA mnemonic RA ASM_LBTI mnemonic brinst, RA
|
||||
ASM_RAB mnemonic RA, RB
|
||||
ASM_RDCH mnemonic RT, CA
|
||||
ASM_RR mnemonic RT, RA, RB
|
||||
ASM_RT mnemonic RT
|
||||
ASM_RTA mnemonic RT, RA
|
||||
ASM_WRCH mnemonic CA, RT
|
||||
|
||||
Note that RRR instructions have the names for RC and RT reversed from
|
||||
what's in the ISA, in order to put RT in the same position it appears
|
||||
for other formats.
|
||||
|
||||
-=-=-= DEPENDENCY =-=-=-
|
||||
|
||||
DEPENDENCY filed consists of 5 digits. This represents which register is used as source and which register is used as target.
|
||||
The first(most significant) digit is always 0. Then it is followd by RC, RB, RA and RT digits.
|
||||
If the digit is 0, this means the corresponding register is not used in the instruction.
|
||||
If the digit is 1, this means the corresponding register is used as a source in the instruction.
|
||||
If the digit is 2, this means the corresponding register is used as a target in the instruction.
|
||||
If the digit is 3, this means the corresponding register is used as both source and target in the instruction.
|
||||
For example, fms instruction has 00113 as the DEPENDENCY field. This means RC is not used in this operation, RB and RA are
|
||||
used as sources and RT is the target.
|
||||
|
||||
-=-=-= PIPE =-=-=-
|
||||
|
||||
This field shows which execution pipe is used for the instruction
|
||||
|
||||
pipe0 execution pipelines:
|
||||
FP6 SP floating pipeline
|
||||
FP7 integer operations executed in SP floating pipeline
|
||||
FPD DP floating pipeline
|
||||
FX2 FXU pipeline
|
||||
FX3 Rotate/Shift pipeline
|
||||
FXB Byte pipeline
|
||||
NOP No pipeline
|
||||
|
||||
pipe1 execution pipelines:
|
||||
BR Branch pipeline
|
||||
LNOP No pipeline
|
||||
LS Load/Store pipeline
|
||||
SHUF Shuffle pipeline
|
||||
SPR SPR/CH pipeline
|
||||
|
||||
*/
|
||||
|
||||
#define _A0() {0}
|
||||
#define _A1(a) {1,a}
|
||||
#define _A2(a,b) {2,a,b}
|
||||
#define _A3(a,b,c) {3,a,b,c}
|
||||
#define _A4(a,b,c,d) {4,a,b,c,d}
|
||||
|
||||
/* TAG FORMAT OPCODE MNEMONIC ASM_FORMAT DEPENDENCY PIPE COMMENT */
|
||||
/* 0[RC][RB][RA][RT] */
|
||||
/* 1:src, 2:target */
|
||||
|
||||
APUOP(M_BR, RI16, 0x190, "br", _A1(A_R18), 00000, BR) /* BRel IP<-IP+I16 */
|
||||
APUOP(M_BRSL, RI16, 0x198, "brsl", _A2(A_T,A_R18), 00002, BR) /* BRelSetLink RT,IP<-IP,IP+I16 */
|
||||
APUOP(M_BRA, RI16, 0x180, "bra", _A1(A_S18), 00000, BR) /* BRAbs IP<-I16 */
|
||||
APUOP(M_BRASL, RI16, 0x188, "brasl", _A2(A_T,A_S18), 00002, BR) /* BRAbsSetLink RT,IP<-IP,I16 */
|
||||
APUOP(M_FSMBI, RI16, 0x194, "fsmbi", _A2(A_T,A_X16), 00002, SHUF) /* FormSelMask%I RT<-fsm(I16) */
|
||||
APUOP(M_LQA, RI16, 0x184, "lqa", _A2(A_T,A_S18), 00002, LS) /* LoadQAbs RT<-M[I16] */
|
||||
APUOP(M_LQR, RI16, 0x19C, "lqr", _A2(A_T,A_R18), 00002, LS) /* LoadQRel RT<-M[IP+I16] */
|
||||
APUOP(M_STOP, RR, 0x000, "stop", _A0(), 00000, BR) /* STOP stop */
|
||||
APUOP(M_STOP2, RR, 0x000, "stop", _A1(A_U14), 00000, BR) /* STOP stop */
|
||||
APUOP(M_STOPD, RR, 0x140, "stopd", _A3(A_T,A_A,A_B), 00111, BR) /* STOPD stop (with register dependencies) */
|
||||
APUOP(M_LNOP, RR, 0x001, "lnop", _A0(), 00000, LNOP) /* LNOP no_operation */
|
||||
APUOP(M_SYNC, RR, 0x002, "sync", _A0(), 00000, BR) /* SYNC flush_pipe */
|
||||
APUOP(M_DSYNC, RR, 0x003, "dsync", _A0(), 00000, BR) /* DSYNC flush_store_queue */
|
||||
APUOP(M_MFSPR, RR, 0x00c, "mfspr", _A2(A_T,A_S), 00002, SPR) /* MFSPR RT<-SA */
|
||||
APUOP(M_RDCH, RR, 0x00d, "rdch", _A2(A_T,A_H), 00002, SPR) /* ReaDCHannel RT<-CA:data */
|
||||
APUOP(M_RCHCNT, RR, 0x00f, "rchcnt", _A2(A_T,A_H), 00002, SPR) /* ReaDCHanCouNT RT<-CA:count */
|
||||
APUOP(M_HBRA, LBT, 0x080, "hbra", _A2(A_S11,A_S18), 00000, LS) /* HBRA BTB[B9]<-M[I16] */
|
||||
APUOP(M_HBRR, LBT, 0x090, "hbrr", _A2(A_S11,A_R18), 00000, LS) /* HBRR BTB[B9]<-M[IP+I16] */
|
||||
APUOP(M_BRZ, RI16, 0x100, "brz", _A2(A_T,A_R18), 00001, BR) /* BRZ IP<-IP+I16_if(RT) */
|
||||
APUOP(M_BRNZ, RI16, 0x108, "brnz", _A2(A_T,A_R18), 00001, BR) /* BRNZ IP<-IP+I16_if(RT) */
|
||||
APUOP(M_BRHZ, RI16, 0x110, "brhz", _A2(A_T,A_R18), 00001, BR) /* BRHZ IP<-IP+I16_if(RT) */
|
||||
APUOP(M_BRHNZ, RI16, 0x118, "brhnz", _A2(A_T,A_R18), 00001, BR) /* BRHNZ IP<-IP+I16_if(RT) */
|
||||
APUOP(M_STQA, RI16, 0x104, "stqa", _A2(A_T,A_S18), 00001, LS) /* SToreQAbs M[I16]<-RT */
|
||||
APUOP(M_STQR, RI16, 0x11C, "stqr", _A2(A_T,A_R18), 00001, LS) /* SToreQRel M[IP+I16]<-RT */
|
||||
APUOP(M_MTSPR, RR, 0x10c, "mtspr", _A2(A_S,A_T), 00001, SPR) /* MTSPR SA<-RT */
|
||||
APUOP(M_WRCH, RR, 0x10d, "wrch", _A2(A_H,A_T), 00001, SPR) /* ChanWRite CA<-RT */
|
||||
APUOP(M_LQD, RI10, 0x1a0, "lqd", _A4(A_T,A_S14,A_P,A_A), 00012, LS) /* LoadQDisp RT<-M[Ra+I10] */
|
||||
APUOP(M_BI, RR, 0x1a8, "bi", _A1(A_A), 00010, BR) /* BI IP<-RA */
|
||||
APUOP(M_BISL, RR, 0x1a9, "bisl", _A2(A_T,A_A), 00012, BR) /* BISL RT,IP<-IP,RA */
|
||||
APUOP(M_IRET, RR, 0x1aa, "iret", _A1(A_A), 00010, BR) /* IRET IP<-SRR0 */
|
||||
APUOP(M_IRET2, RR, 0x1aa, "iret", _A0(), 00010, BR) /* IRET IP<-SRR0 */
|
||||
APUOP(M_BISLED, RR, 0x1ab, "bisled", _A2(A_T,A_A), 00012, BR) /* BISLED RT,IP<-IP,RA_if(ext) */
|
||||
APUOP(M_HBR, LBTI, 0x1ac, "hbr", _A2(A_S11I,A_A), 00010, LS) /* HBR BTB[B9]<-M[Ra] */
|
||||
APUOP(M_FREST, RR, 0x1b8, "frest", _A2(A_T,A_A), 00012, SHUF) /* FREST RT<-recip(RA) */
|
||||
APUOP(M_FRSQEST, RR, 0x1b9, "frsqest", _A2(A_T,A_A), 00012, SHUF) /* FRSQEST RT<-rsqrt(RA) */
|
||||
APUOP(M_FSM, RR, 0x1b4, "fsm", _A2(A_T,A_A), 00012, SHUF) /* FormSelMask% RT<-expand(Ra) */
|
||||
APUOP(M_FSMH, RR, 0x1b5, "fsmh", _A2(A_T,A_A), 00012, SHUF) /* FormSelMask% RT<-expand(Ra) */
|
||||
APUOP(M_FSMB, RR, 0x1b6, "fsmb", _A2(A_T,A_A), 00012, SHUF) /* FormSelMask% RT<-expand(Ra) */
|
||||
APUOP(M_GB, RR, 0x1b0, "gb", _A2(A_T,A_A), 00012, SHUF) /* GatherBits% RT<-gather(RA) */
|
||||
APUOP(M_GBH, RR, 0x1b1, "gbh", _A2(A_T,A_A), 00012, SHUF) /* GatherBits% RT<-gather(RA) */
|
||||
APUOP(M_GBB, RR, 0x1b2, "gbb", _A2(A_T,A_A), 00012, SHUF) /* GatherBits% RT<-gather(RA) */
|
||||
APUOP(M_CBD, RI7, 0x1f4, "cbd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */
|
||||
APUOP(M_CHD, RI7, 0x1f5, "chd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */
|
||||
APUOP(M_CWD, RI7, 0x1f6, "cwd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */
|
||||
APUOP(M_CDD, RI7, 0x1f7, "cdd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */
|
||||
APUOP(M_ROTQBII, RI7, 0x1f8, "rotqbii", _A3(A_T,A_A,A_U3), 00012, SHUF) /* ROTQBII RT<-RA<<<I7 */
|
||||
APUOP(M_ROTQBYI, RI7, 0x1fc, "rotqbyi", _A3(A_T,A_A,A_S7N), 00012, SHUF) /* ROTQBYI RT<-RA<<<(I7*8) */
|
||||
APUOP(M_ROTQMBII, RI7, 0x1f9, "rotqmbii", _A3(A_T,A_A,A_S3), 00012, SHUF) /* ROTQMBII RT<-RA<<I7 */
|
||||
APUOP(M_ROTQMBYI, RI7, 0x1fd, "rotqmbyi", _A3(A_T,A_A,A_S6), 00012, SHUF) /* ROTQMBYI RT<-RA<<I7 */
|
||||
APUOP(M_SHLQBII, RI7, 0x1fb, "shlqbii", _A3(A_T,A_A,A_U3), 00012, SHUF) /* SHLQBII RT<-RA<<I7 */
|
||||
APUOP(M_SHLQBYI, RI7, 0x1ff, "shlqbyi", _A3(A_T,A_A,A_U5), 00012, SHUF) /* SHLQBYI RT<-RA<<I7 */
|
||||
APUOP(M_STQD, RI10, 0x120, "stqd", _A4(A_T,A_S14,A_P,A_A), 00011, LS) /* SToreQDisp M[Ra+I10]<-RT */
|
||||
APUOP(M_BIHNZ, RR, 0x12b, "bihnz", _A2(A_T,A_A), 00011, BR) /* BIHNZ IP<-RA_if(RT) */
|
||||
APUOP(M_BIHZ, RR, 0x12a, "bihz", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
|
||||
APUOP(M_BINZ, RR, 0x129, "binz", _A2(A_T,A_A), 00011, BR) /* BINZ IP<-RA_if(RT) */
|
||||
APUOP(M_BIZ, RR, 0x128, "biz", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
|
||||
APUOP(M_CBX, RR, 0x1d4, "cbx", _A3(A_T,A_A,A_B), 00112, SHUF) /* genCtl%%insX RT<-sta(Ra+Rb,siz) */
|
||||
APUOP(M_CHX, RR, 0x1d5, "chx", _A3(A_T,A_A,A_B), 00112, SHUF) /* genCtl%%insX RT<-sta(Ra+Rb,siz) */
|
||||
APUOP(M_CWX, RR, 0x1d6, "cwx", _A3(A_T,A_A,A_B), 00112, SHUF) /* genCtl%%insX RT<-sta(Ra+Rb,siz) */
|
||||
APUOP(M_CDX, RR, 0x1d7, "cdx", _A3(A_T,A_A,A_B), 00112, SHUF) /* genCtl%%insX RT<-sta(Ra+Rb,siz) */
|
||||
APUOP(M_LQX, RR, 0x1c4, "lqx", _A3(A_T,A_A,A_B), 00112, LS) /* LoadQindeX RT<-M[Ra+Rb] */
|
||||
APUOP(M_ROTQBI, RR, 0x1d8, "rotqbi", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQBI RT<-RA<<<Rb */
|
||||
APUOP(M_ROTQMBI, RR, 0x1d9, "rotqmbi", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQMBI RT<-RA<<Rb */
|
||||
APUOP(M_SHLQBI, RR, 0x1db, "shlqbi", _A3(A_T,A_A,A_B), 00112, SHUF) /* SHLQBI RT<-RA<<Rb */
|
||||
APUOP(M_ROTQBY, RR, 0x1dc, "rotqby", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQBY RT<-RA<<<(Rb*8) */
|
||||
APUOP(M_ROTQMBY, RR, 0x1dd, "rotqmby", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQMBY RT<-RA<<Rb */
|
||||
APUOP(M_SHLQBY, RR, 0x1df, "shlqby", _A3(A_T,A_A,A_B), 00112, SHUF) /* SHLQBY RT<-RA<<Rb */
|
||||
APUOP(M_ROTQBYBI, RR, 0x1cc, "rotqbybi", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQBYBI RT<-RA<<Rb */
|
||||
APUOP(M_ROTQMBYBI, RR, 0x1cd, "rotqmbybi", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQMBYBI RT<-RA<<Rb */
|
||||
APUOP(M_SHLQBYBI, RR, 0x1cf, "shlqbybi", _A3(A_T,A_A,A_B), 00112, SHUF) /* SHLQBYBI RT<-RA<<Rb */
|
||||
APUOP(M_STQX, RR, 0x144, "stqx", _A3(A_T,A_A,A_B), 00111, LS) /* SToreQindeX M[Ra+Rb]<-RT */
|
||||
APUOP(M_SHUFB, RRR, 0x580, "shufb", _A4(A_C,A_A,A_B,A_T), 02111, SHUF) /* SHUFfleBytes RC<-f(RA,RB,RT) */
|
||||
APUOP(M_IL, RI16, 0x204, "il", _A2(A_T,A_S16), 00002, FX2) /* ImmLoad RT<-sxt(I16) */
|
||||
APUOP(M_ILH, RI16, 0x20c, "ilh", _A2(A_T,A_X16), 00002, FX2) /* ImmLoadH RT<-I16 */
|
||||
APUOP(M_ILHU, RI16, 0x208, "ilhu", _A2(A_T,A_X16), 00002, FX2) /* ImmLoadHUpper RT<-I16<<16 */
|
||||
APUOP(M_ILA, RI18, 0x210, "ila", _A2(A_T,A_U18), 00002, FX2) /* ImmLoadAddr RT<-zxt(I18) */
|
||||
APUOP(M_NOP, RR, 0x201, "nop", _A1(A_T), 00000, NOP) /* XNOP no_operation */
|
||||
APUOP(M_NOP2, RR, 0x201, "nop", _A0(), 00000, NOP) /* XNOP no_operation */
|
||||
APUOP(M_IOHL, RI16, 0x304, "iohl", _A2(A_T,A_X16), 00003, FX2) /* AddImmeXt RT<-RT+sxt(I16) */
|
||||
APUOP(M_ANDBI, RI10, 0x0b0, "andbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* AND%I RT<-RA&I10 */
|
||||
APUOP(M_ANDHI, RI10, 0x0a8, "andhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* AND%I RT<-RA&I10 */
|
||||
APUOP(M_ANDI, RI10, 0x0a0, "andi", _A3(A_T,A_A,A_S10), 00012, FX2) /* AND%I RT<-RA&I10 */
|
||||
APUOP(M_ORBI, RI10, 0x030, "orbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* OR%I RT<-RA|I10 */
|
||||
APUOP(M_ORHI, RI10, 0x028, "orhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* OR%I RT<-RA|I10 */
|
||||
APUOP(M_ORI, RI10, 0x020, "ori", _A3(A_T,A_A,A_S10), 00012, FX2) /* OR%I RT<-RA|I10 */
|
||||
APUOP(M_ORX, RR, 0x1f0, "orx", _A2(A_T,A_A), 00012, BR) /* ORX RT<-RA.w0|RA.w1|RA.w2|RA.w3 */
|
||||
APUOP(M_XORBI, RI10, 0x230, "xorbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* XOR%I RT<-RA^I10 */
|
||||
APUOP(M_XORHI, RI10, 0x228, "xorhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* XOR%I RT<-RA^I10 */
|
||||
APUOP(M_XORI, RI10, 0x220, "xori", _A3(A_T,A_A,A_S10), 00012, FX2) /* XOR%I RT<-RA^I10 */
|
||||
APUOP(M_AHI, RI10, 0x0e8, "ahi", _A3(A_T,A_A,A_S10), 00012, FX2) /* Add%Immed RT<-RA+I10 */
|
||||
APUOP(M_AI, RI10, 0x0e0, "ai", _A3(A_T,A_A,A_S10), 00012, FX2) /* Add%Immed RT<-RA+I10 */
|
||||
APUOP(M_SFHI, RI10, 0x068, "sfhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* SubFrom%Imm RT<-I10-RA */
|
||||
APUOP(M_SFI, RI10, 0x060, "sfi", _A3(A_T,A_A,A_S10), 00012, FX2) /* SubFrom%Imm RT<-I10-RA */
|
||||
APUOP(M_CGTBI, RI10, 0x270, "cgtbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* CGT%I RT<-(RA>I10) */
|
||||
APUOP(M_CGTHI, RI10, 0x268, "cgthi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CGT%I RT<-(RA>I10) */
|
||||
APUOP(M_CGTI, RI10, 0x260, "cgti", _A3(A_T,A_A,A_S10), 00012, FX2) /* CGT%I RT<-(RA>I10) */
|
||||
APUOP(M_CLGTBI, RI10, 0x2f0, "clgtbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* CLGT%I RT<-(RA>I10) */
|
||||
APUOP(M_CLGTHI, RI10, 0x2e8, "clgthi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CLGT%I RT<-(RA>I10) */
|
||||
APUOP(M_CLGTI, RI10, 0x2e0, "clgti", _A3(A_T,A_A,A_S10), 00012, FX2) /* CLGT%I RT<-(RA>I10) */
|
||||
APUOP(M_CEQBI, RI10, 0x3f0, "ceqbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* CEQ%I RT<-(RA=I10) */
|
||||
APUOP(M_CEQHI, RI10, 0x3e8, "ceqhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CEQ%I RT<-(RA=I10) */
|
||||
APUOP(M_CEQI, RI10, 0x3e0, "ceqi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CEQ%I RT<-(RA=I10) */
|
||||
APUOP(M_HGTI, RI10, 0x278, "hgti", _A3(A_T,A_A,A_S10), 00010, FX2) /* HaltGTI halt_if(RA>I10) */
|
||||
APUOP(M_HGTI2, RI10, 0x278, "hgti", _A2(A_A,A_S10), 00010, FX2) /* HaltGTI halt_if(RA>I10) */
|
||||
APUOP(M_HLGTI, RI10, 0x2f8, "hlgti", _A3(A_T,A_A,A_S10), 00010, FX2) /* HaltLGTI halt_if(RA>I10) */
|
||||
APUOP(M_HLGTI2, RI10, 0x2f8, "hlgti", _A2(A_A,A_S10), 00010, FX2) /* HaltLGTI halt_if(RA>I10) */
|
||||
APUOP(M_HEQI, RI10, 0x3f8, "heqi", _A3(A_T,A_A,A_S10), 00010, FX2) /* HaltEQImm halt_if(RA=I10) */
|
||||
APUOP(M_HEQI2, RI10, 0x3f8, "heqi", _A2(A_A,A_S10), 00010, FX2) /* HaltEQImm halt_if(RA=I10) */
|
||||
APUOP(M_MPYI, RI10, 0x3a0, "mpyi", _A3(A_T,A_A,A_S10), 00012, FP7) /* MPYI RT<-RA*I10 */
|
||||
APUOP(M_MPYUI, RI10, 0x3a8, "mpyui", _A3(A_T,A_A,A_S10), 00012, FP7) /* MPYUI RT<-RA*I10 */
|
||||
APUOP(M_CFLTS, RI8, 0x3b0, "cflts", _A3(A_T,A_A,A_U7A), 00012, FP7) /* CFLTS RT<-int(RA,I8) */
|
||||
APUOP(M_CFLTU, RI8, 0x3b2, "cfltu", _A3(A_T,A_A,A_U7A), 00012, FP7) /* CFLTU RT<-int(RA,I8) */
|
||||
APUOP(M_CSFLT, RI8, 0x3b4, "csflt", _A3(A_T,A_A,A_U7B), 00012, FP7) /* CSFLT RT<-flt(RA,I8) */
|
||||
APUOP(M_CUFLT, RI8, 0x3b6, "cuflt", _A3(A_T,A_A,A_U7B), 00012, FP7) /* CUFLT RT<-flt(RA,I8) */
|
||||
APUOP(M_FESD, RR, 0x3b8, "fesd", _A2(A_T,A_A), 00012, FPD) /* FESD RT<-double(RA) */
|
||||
APUOP(M_FRDS, RR, 0x3b9, "frds", _A2(A_T,A_A), 00012, FPD) /* FRDS RT<-single(RA) */
|
||||
APUOP(M_FSCRRD, RR, 0x398, "fscrrd", _A1(A_T), 00002, FPD) /* FSCRRD RT<-FP_status */
|
||||
APUOP(M_FSCRWR, RR, 0x3ba, "fscrwr", _A2(A_T,A_A), 00010, FP7) /* FSCRWR FP_status<-RA */
|
||||
APUOP(M_FSCRWR2, RR, 0x3ba, "fscrwr", _A1(A_A), 00010, FP7) /* FSCRWR FP_status<-RA */
|
||||
APUOP(M_CLZ, RR, 0x2a5, "clz", _A2(A_T,A_A), 00012, FX2) /* CLZ RT<-clz(RA) */
|
||||
APUOP(M_CNTB, RR, 0x2b4, "cntb", _A2(A_T,A_A), 00012, FXB) /* CNT RT<-pop(RA) */
|
||||
APUOP(M_XSBH, RR, 0x2b6, "xsbh", _A2(A_T,A_A), 00012, FX2) /* eXtSignBtoH RT<-sign_ext(RA) */
|
||||
APUOP(M_XSHW, RR, 0x2ae, "xshw", _A2(A_T,A_A), 00012, FX2) /* eXtSignHtoW RT<-sign_ext(RA) */
|
||||
APUOP(M_XSWD, RR, 0x2a6, "xswd", _A2(A_T,A_A), 00012, FX2) /* eXtSignWtoD RT<-sign_ext(RA) */
|
||||
APUOP(M_ROTI, RI7, 0x078, "roti", _A3(A_T,A_A,A_S7N), 00012, FX3) /* ROT%I RT<-RA<<<I7 */
|
||||
APUOP(M_ROTMI, RI7, 0x079, "rotmi", _A3(A_T,A_A,A_S7), 00012, FX3) /* ROT%MI RT<-RA<<I7 */
|
||||
APUOP(M_ROTMAI, RI7, 0x07a, "rotmai", _A3(A_T,A_A,A_S7), 00012, FX3) /* ROTMA%I RT<-RA<<I7 */
|
||||
APUOP(M_SHLI, RI7, 0x07b, "shli", _A3(A_T,A_A,A_U6), 00012, FX3) /* SHL%I RT<-RA<<I7 */
|
||||
APUOP(M_ROTHI, RI7, 0x07c, "rothi", _A3(A_T,A_A,A_S7N), 00012, FX3) /* ROT%I RT<-RA<<<I7 */
|
||||
APUOP(M_ROTHMI, RI7, 0x07d, "rothmi", _A3(A_T,A_A,A_S6), 00012, FX3) /* ROT%MI RT<-RA<<I7 */
|
||||
APUOP(M_ROTMAHI, RI7, 0x07e, "rotmahi", _A3(A_T,A_A,A_S6), 00012, FX3) /* ROTMA%I RT<-RA<<I7 */
|
||||
APUOP(M_SHLHI, RI7, 0x07f, "shlhi", _A3(A_T,A_A,A_U5), 00012, FX3) /* SHL%I RT<-RA<<I7 */
|
||||
APUOP(M_A, RR, 0x0c0, "a", _A3(A_T,A_A,A_B), 00112, FX2) /* Add% RT<-RA+RB */
|
||||
APUOP(M_AH, RR, 0x0c8, "ah", _A3(A_T,A_A,A_B), 00112, FX2) /* Add% RT<-RA+RB */
|
||||
APUOP(M_SF, RR, 0x040, "sf", _A3(A_T,A_A,A_B), 00112, FX2) /* SubFrom% RT<-RB-RA */
|
||||
APUOP(M_SFH, RR, 0x048, "sfh", _A3(A_T,A_A,A_B), 00112, FX2) /* SubFrom% RT<-RB-RA */
|
||||
APUOP(M_CGT, RR, 0x240, "cgt", _A3(A_T,A_A,A_B), 00112, FX2) /* CGT% RT<-(RA>RB) */
|
||||
APUOP(M_CGTB, RR, 0x250, "cgtb", _A3(A_T,A_A,A_B), 00112, FX2) /* CGT% RT<-(RA>RB) */
|
||||
APUOP(M_CGTH, RR, 0x248, "cgth", _A3(A_T,A_A,A_B), 00112, FX2) /* CGT% RT<-(RA>RB) */
|
||||
APUOP(M_CLGT, RR, 0x2c0, "clgt", _A3(A_T,A_A,A_B), 00112, FX2) /* CLGT% RT<-(RA>RB) */
|
||||
APUOP(M_CLGTB, RR, 0x2d0, "clgtb", _A3(A_T,A_A,A_B), 00112, FX2) /* CLGT% RT<-(RA>RB) */
|
||||
APUOP(M_CLGTH, RR, 0x2c8, "clgth", _A3(A_T,A_A,A_B), 00112, FX2) /* CLGT% RT<-(RA>RB) */
|
||||
APUOP(M_CEQ, RR, 0x3c0, "ceq", _A3(A_T,A_A,A_B), 00112, FX2) /* CEQ% RT<-(RA=RB) */
|
||||
APUOP(M_CEQB, RR, 0x3d0, "ceqb", _A3(A_T,A_A,A_B), 00112, FX2) /* CEQ% RT<-(RA=RB) */
|
||||
APUOP(M_CEQH, RR, 0x3c8, "ceqh", _A3(A_T,A_A,A_B), 00112, FX2) /* CEQ% RT<-(RA=RB) */
|
||||
APUOP(M_HGT, RR, 0x258, "hgt", _A3(A_T,A_A,A_B), 00110, FX2) /* HaltGT halt_if(RA>RB) */
|
||||
APUOP(M_HGT2, RR, 0x258, "hgt", _A2(A_A,A_B), 00110, FX2) /* HaltGT halt_if(RA>RB) */
|
||||
APUOP(M_HLGT, RR, 0x2d8, "hlgt", _A3(A_T,A_A,A_B), 00110, FX2) /* HaltLGT halt_if(RA>RB) */
|
||||
APUOP(M_HLGT2, RR, 0x2d8, "hlgt", _A2(A_A,A_B), 00110, FX2) /* HaltLGT halt_if(RA>RB) */
|
||||
APUOP(M_HEQ, RR, 0x3d8, "heq", _A3(A_T,A_A,A_B), 00110, FX2) /* HaltEQ halt_if(RA=RB) */
|
||||
APUOP(M_HEQ2, RR, 0x3d8, "heq", _A2(A_A,A_B), 00110, FX2) /* HaltEQ halt_if(RA=RB) */
|
||||
APUOP(M_FCEQ, RR, 0x3c2, "fceq", _A3(A_T,A_A,A_B), 00112, FX2) /* FCEQ RT<-(RA=RB) */
|
||||
APUOP(M_FCMEQ, RR, 0x3ca, "fcmeq", _A3(A_T,A_A,A_B), 00112, FX2) /* FCMEQ RT<-(|RA|=|RB|) */
|
||||
APUOP(M_FCGT, RR, 0x2c2, "fcgt", _A3(A_T,A_A,A_B), 00112, FX2) /* FCGT RT<-(RA<RB) */
|
||||
APUOP(M_FCMGT, RR, 0x2ca, "fcmgt", _A3(A_T,A_A,A_B), 00112, FX2) /* FCMGT RT<-(|RA|<|RB|) */
|
||||
APUOP(M_AND, RR, 0x0c1, "and", _A3(A_T,A_A,A_B), 00112, FX2) /* AND RT<-RA&RB */
|
||||
APUOP(M_NAND, RR, 0x0c9, "nand", _A3(A_T,A_A,A_B), 00112, FX2) /* NAND RT<-!(RA&RB) */
|
||||
APUOP(M_OR, RR, 0x041, "or", _A3(A_T,A_A,A_B), 00112, FX2) /* OR RT<-RA|RB */
|
||||
APUOP(M_NOR, RR, 0x049, "nor", _A3(A_T,A_A,A_B), 00112, FX2) /* NOR RT<-!(RA&RB) */
|
||||
APUOP(M_XOR, RR, 0x241, "xor", _A3(A_T,A_A,A_B), 00112, FX2) /* XOR RT<-RA^RB */
|
||||
APUOP(M_EQV, RR, 0x249, "eqv", _A3(A_T,A_A,A_B), 00112, FX2) /* EQuiValent RT<-!(RA^RB) */
|
||||
APUOP(M_ANDC, RR, 0x2c1, "andc", _A3(A_T,A_A,A_B), 00112, FX2) /* ANDComplement RT<-RA&!RB */
|
||||
APUOP(M_ORC, RR, 0x2c9, "orc", _A3(A_T,A_A,A_B), 00112, FX2) /* ORComplement RT<-RA|!RB */
|
||||
APUOP(M_ABSDB, RR, 0x053, "absdb", _A3(A_T,A_A,A_B), 00112, FXB) /* ABSoluteDiff RT<-|RA-RB| */
|
||||
APUOP(M_AVGB, RR, 0x0d3, "avgb", _A3(A_T,A_A,A_B), 00112, FXB) /* AVG% RT<-(RA+RB+1)/2 */
|
||||
APUOP(M_SUMB, RR, 0x253, "sumb", _A3(A_T,A_A,A_B), 00112, FXB) /* SUM% RT<-f(RA,RB) */
|
||||
APUOP(M_DFA, RR, 0x2cc, "dfa", _A3(A_T,A_A,A_B), 00112, FPD) /* DFAdd RT<-RA+RB */
|
||||
APUOP(M_DFM, RR, 0x2ce, "dfm", _A3(A_T,A_A,A_B), 00112, FPD) /* DFMul RT<-RA*RB */
|
||||
APUOP(M_DFS, RR, 0x2cd, "dfs", _A3(A_T,A_A,A_B), 00112, FPD) /* DFSub RT<-RA-RB */
|
||||
APUOP(M_FA, RR, 0x2c4, "fa", _A3(A_T,A_A,A_B), 00112, FP6) /* FAdd RT<-RA+RB */
|
||||
APUOP(M_FM, RR, 0x2c6, "fm", _A3(A_T,A_A,A_B), 00112, FP6) /* FMul RT<-RA*RB */
|
||||
APUOP(M_FS, RR, 0x2c5, "fs", _A3(A_T,A_A,A_B), 00112, FP6) /* FSub RT<-RA-RB */
|
||||
APUOP(M_MPY, RR, 0x3c4, "mpy", _A3(A_T,A_A,A_B), 00112, FP7) /* MPY RT<-RA*RB */
|
||||
APUOP(M_MPYH, RR, 0x3c5, "mpyh", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYH RT<-(RAh*RB)<<16 */
|
||||
APUOP(M_MPYHH, RR, 0x3c6, "mpyhh", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYHH RT<-RAh*RBh */
|
||||
APUOP(M_MPYHHU, RR, 0x3ce, "mpyhhu", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYHHU RT<-RAh*RBh */
|
||||
APUOP(M_MPYS, RR, 0x3c7, "mpys", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYS RT<-(RA*RB)>>16 */
|
||||
APUOP(M_MPYU, RR, 0x3cc, "mpyu", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYU RT<-RA*RB */
|
||||
APUOP(M_FI, RR, 0x3d4, "fi", _A3(A_T,A_A,A_B), 00112, FP7) /* FInterpolate RT<-f(RA,RB) */
|
||||
APUOP(M_ROT, RR, 0x058, "rot", _A3(A_T,A_A,A_B), 00112, FX3) /* ROT% RT<-RA<<<RB */
|
||||
APUOP(M_ROTM, RR, 0x059, "rotm", _A3(A_T,A_A,A_B), 00112, FX3) /* ROT%M RT<-RA<<Rb */
|
||||
APUOP(M_ROTMA, RR, 0x05a, "rotma", _A3(A_T,A_A,A_B), 00112, FX3) /* ROTMA% RT<-RA<<Rb */
|
||||
APUOP(M_SHL, RR, 0x05b, "shl", _A3(A_T,A_A,A_B), 00112, FX3) /* SHL% RT<-RA<<Rb */
|
||||
APUOP(M_ROTH, RR, 0x05c, "roth", _A3(A_T,A_A,A_B), 00112, FX3) /* ROT% RT<-RA<<<RB */
|
||||
APUOP(M_ROTHM, RR, 0x05d, "rothm", _A3(A_T,A_A,A_B), 00112, FX3) /* ROT%M RT<-RA<<Rb */
|
||||
APUOP(M_ROTMAH, RR, 0x05e, "rotmah", _A3(A_T,A_A,A_B), 00112, FX3) /* ROTMA% RT<-RA<<Rb */
|
||||
APUOP(M_SHLH, RR, 0x05f, "shlh", _A3(A_T,A_A,A_B), 00112, FX3) /* SHL% RT<-RA<<Rb */
|
||||
APUOP(M_MPYHHA, RR, 0x346, "mpyhha", _A3(A_T,A_A,A_B), 00113, FP7) /* MPYHHA RT<-RAh*RBh+RT */
|
||||
APUOP(M_MPYHHAU, RR, 0x34e, "mpyhhau", _A3(A_T,A_A,A_B), 00113, FP7) /* MPYHHAU RT<-RAh*RBh+RT */
|
||||
APUOP(M_DFMA, RR, 0x35c, "dfma", _A3(A_T,A_A,A_B), 00113, FPD) /* DFMAdd RT<-RT+RA*RB */
|
||||
APUOP(M_DFMS, RR, 0x35d, "dfms", _A3(A_T,A_A,A_B), 00113, FPD) /* DFMSub RT<-RA*RB-RT */
|
||||
APUOP(M_DFNMS, RR, 0x35e, "dfnms", _A3(A_T,A_A,A_B), 00113, FPD) /* DFNMSub RT<-RT-RA*RB */
|
||||
APUOP(M_DFNMA, RR, 0x35f, "dfnma", _A3(A_T,A_A,A_B), 00113, FPD) /* DFNMAdd RT<-(-RT)-RA*RB */
|
||||
APUOP(M_FMA, RRR, 0x700, "fma", _A4(A_C,A_A,A_B,A_T), 02111, FP6) /* FMAdd RC<-RT+RA*RB */
|
||||
APUOP(M_FMS, RRR, 0x780, "fms", _A4(A_C,A_A,A_B,A_T), 02111, FP6) /* FMSub RC<-RA*RB-RT */
|
||||
APUOP(M_FNMS, RRR, 0x680, "fnms", _A4(A_C,A_A,A_B,A_T), 02111, FP6) /* FNMSub RC<-RT-RA*RB */
|
||||
APUOP(M_MPYA, RRR, 0x600, "mpya", _A4(A_C,A_A,A_B,A_T), 02111, FP7) /* MPYA RC<-RA*RB+RT */
|
||||
APUOP(M_SELB, RRR, 0x400, "selb", _A4(A_C,A_A,A_B,A_T), 02111, FX2) /* SELectBits RC<-RA&RT|RB&!RT */
|
||||
/* for system function call, this uses op-code of mtspr */
|
||||
APUOP(M_SYSCALL, RI7, 0x10c, "syscall", _A3(A_T,A_A,A_S7N), 00002, SPR) /* System Call */
|
||||
/*
|
||||
pseudo instruction:
|
||||
system call
|
||||
value of I9 operation
|
||||
0 halt
|
||||
1 rt[0] = open(MEM[ra[0]], ra[1])
|
||||
2 rt[0] = close(ra[0])
|
||||
3 rt[0] = read(ra[0], MEM[ra[1]], ra[2])
|
||||
4 rt[0] = write(ra[0], MEM[ra[1]], ra[2])
|
||||
5 printf(MEM[ra[0]], ra[1], ra[2], ra[3])
|
||||
42 rt[0] = clock()
|
||||
52 rt[0] = lseek(ra0, ra1, ra2)
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/* new multiprecision add/sub */
|
||||
APUOP(M_ADDX, RR, 0x340, "addx", _A3(A_T,A_A,A_B), 00113, FX2) /* Add_eXtended RT<-RA+RB+RT */
|
||||
APUOP(M_CG, RR, 0x0c2, "cg", _A3(A_T,A_A,A_B), 00112, FX2) /* CarryGenerate RT<-cout(RA+RB) */
|
||||
APUOP(M_CGX, RR, 0x342, "cgx", _A3(A_T,A_A,A_B), 00113, FX2) /* CarryGen_eXtd RT<-cout(RA+RB+RT) */
|
||||
APUOP(M_SFX, RR, 0x341, "sfx", _A3(A_T,A_A,A_B), 00113, FX2) /* Add_eXtended RT<-RA+RB+RT */
|
||||
APUOP(M_BG, RR, 0x042, "bg", _A3(A_T,A_A,A_B), 00112, FX2) /* CarryGenerate RT<-cout(RA+RB) */
|
||||
APUOP(M_BGX, RR, 0x343, "bgx", _A3(A_T,A_A,A_B), 00113, FX2) /* CarryGen_eXtd RT<-cout(RA+RB+RT) */
|
||||
|
||||
/*
|
||||
|
||||
The following ops are a subset of above except with feature bits set.
|
||||
Feature bits are bits 11-17 of the instruction:
|
||||
|
||||
11 - C & P feature bit
|
||||
12 - disable interrupts
|
||||
13 - enable interrupts
|
||||
|
||||
*/
|
||||
APUOPFB(M_BID, RR, 0x1a8, 0x20, "bid", _A1(A_A), 00010, BR) /* BI IP<-RA */
|
||||
APUOPFB(M_BIE, RR, 0x1a8, 0x10, "bie", _A1(A_A), 00010, BR) /* BI IP<-RA */
|
||||
APUOPFB(M_BISLD, RR, 0x1a9, 0x20, "bisld", _A2(A_T,A_A), 00012, BR) /* BISL RT,IP<-IP,RA */
|
||||
APUOPFB(M_BISLE, RR, 0x1a9, 0x10, "bisle", _A2(A_T,A_A), 00012, BR) /* BISL RT,IP<-IP,RA */
|
||||
APUOPFB(M_IRETD, RR, 0x1aa, 0x20, "iretd", _A1(A_A), 00010, BR) /* IRET IP<-SRR0 */
|
||||
APUOPFB(M_IRETD2, RR, 0x1aa, 0x20, "iretd", _A0(), 00010, BR) /* IRET IP<-SRR0 */
|
||||
APUOPFB(M_IRETE, RR, 0x1aa, 0x10, "irete", _A1(A_A), 00010, BR) /* IRET IP<-SRR0 */
|
||||
APUOPFB(M_IRETE2, RR, 0x1aa, 0x10, "irete", _A0(), 00010, BR) /* IRET IP<-SRR0 */
|
||||
APUOPFB(M_BISLEDD, RR, 0x1ab, 0x20, "bisledd", _A2(A_T,A_A), 00012, BR) /* BISLED RT,IP<-IP,RA_if(ext) */
|
||||
APUOPFB(M_BISLEDE, RR, 0x1ab, 0x10, "bislede", _A2(A_T,A_A), 00012, BR) /* BISLED RT,IP<-IP,RA_if(ext) */
|
||||
APUOPFB(M_BIHNZD, RR, 0x12b, 0x20, "bihnzd", _A2(A_T,A_A), 00011, BR) /* BIHNZ IP<-RA_if(RT) */
|
||||
APUOPFB(M_BIHNZE, RR, 0x12b, 0x10, "bihnze", _A2(A_T,A_A), 00011, BR) /* BIHNZ IP<-RA_if(RT) */
|
||||
APUOPFB(M_BIHZD, RR, 0x12a, 0x20, "bihzd", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
|
||||
APUOPFB(M_BIHZE, RR, 0x12a, 0x10, "bihze", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
|
||||
APUOPFB(M_BINZD, RR, 0x129, 0x20, "binzd", _A2(A_T,A_A), 00011, BR) /* BINZ IP<-RA_if(RT) */
|
||||
APUOPFB(M_BINZE, RR, 0x129, 0x10, "binze", _A2(A_T,A_A), 00011, BR) /* BINZ IP<-RA_if(RT) */
|
||||
APUOPFB(M_BIZD, RR, 0x128, 0x20, "bizd", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
|
||||
APUOPFB(M_BIZE, RR, 0x128, 0x10, "bize", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
|
||||
APUOPFB(M_SYNCC, RR, 0x002, 0x40, "syncc", _A0(), 00000, BR) /* SYNCC flush_pipe */
|
||||
APUOPFB(M_HBRP, LBTI, 0x1ac, 0x40, "hbrp", _A0(), 00010, LS) /* HBR BTB[B9]<-M[Ra] */
|
||||
|
||||
/* Synonyms required by the AS manual. */
|
||||
APUOP(M_LR, RI10, 0x020, "lr", _A2(A_T,A_A), 00012, FX2) /* OR%I RT<-RA|I10 */
|
||||
APUOP(M_BIHT, RR, 0x12b, "biht", _A2(A_T,A_A), 00011, BR) /* BIHNZ IP<-RA_if(RT) */
|
||||
APUOP(M_BIHF, RR, 0x12a, "bihf", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
|
||||
APUOP(M_BIT, RR, 0x129, "bit", _A2(A_T,A_A), 00011, BR) /* BINZ IP<-RA_if(RT) */
|
||||
APUOP(M_BIF, RR, 0x128, "bif", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
|
||||
APUOPFB(M_BIHTD, RR, 0x12b, 0x20, "bihtd", _A2(A_T,A_A), 00011, BR) /* BIHNF IP<-RA_if(RT) */
|
||||
APUOPFB(M_BIHTE, RR, 0x12b, 0x10, "bihte", _A2(A_T,A_A), 00011, BR) /* BIHNF IP<-RA_if(RT) */
|
||||
APUOPFB(M_BIHFD, RR, 0x12a, 0x20, "bihfd", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
|
||||
APUOPFB(M_BIHFE, RR, 0x12a, 0x10, "bihfe", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
|
||||
APUOPFB(M_BITD, RR, 0x129, 0x20, "bitd", _A2(A_T,A_A), 00011, BR) /* BINF IP<-RA_if(RT) */
|
||||
APUOPFB(M_BITE, RR, 0x129, 0x10, "bite", _A2(A_T,A_A), 00011, BR) /* BINF IP<-RA_if(RT) */
|
||||
APUOPFB(M_BIFD, RR, 0x128, 0x20, "bifd", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
|
||||
APUOPFB(M_BIFE, RR, 0x128, 0x10, "bife", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
|
||||
|
||||
#undef _A0
|
||||
#undef _A1
|
||||
#undef _A2
|
||||
#undef _A3
|
||||
#undef _A4
|
45
arch/powerpc/xmon/spu-opc.c
Normal file
45
arch/powerpc/xmon/spu-opc.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/* SPU opcode list
|
||||
|
||||
Copyright 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bug.h>
|
||||
#include "spu.h"
|
||||
|
||||
/* This file holds the Spu opcode table */
|
||||
|
||||
|
||||
/*
|
||||
Example contents of spu-insn.h
|
||||
id_tag mode mode type opcode mnemonic asmtype dependency FPU L/S? branch? instruction
|
||||
QUAD WORD (0,RC,RB,RA,RT) latency
|
||||
APUOP(M_LQD, 1, 0, RI9, 0x1f8, "lqd", ASM_RI9IDX, 00012, FXU, 1, 0) Load Quadword d-form
|
||||
*/
|
||||
|
||||
const struct spu_opcode spu_opcodes[] = {
|
||||
#define APUOP(TAG,MACFORMAT,OPCODE,MNEMONIC,ASMFORMAT,DEP,PIPE) \
|
||||
{ MACFORMAT, OPCODE, MNEMONIC, ASMFORMAT },
|
||||
#define APUOPFB(TAG,MACFORMAT,OPCODE,FB,MNEMONIC,ASMFORMAT,DEP,PIPE) \
|
||||
{ MACFORMAT, OPCODE, MNEMONIC, ASMFORMAT },
|
||||
#include "spu-insns.h"
|
||||
#undef APUOP
|
||||
#undef APUOPFB
|
||||
};
|
||||
|
||||
const int spu_num_opcodes = ARRAY_SIZE(spu_opcodes);
|
126
arch/powerpc/xmon/spu.h
Normal file
126
arch/powerpc/xmon/spu.h
Normal file
|
@ -0,0 +1,126 @@
|
|||
/* SPU ELF support for BFD.
|
||||
|
||||
Copyright 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
|
||||
/* These two enums are from rel_apu/common/spu_asm_format.h */
|
||||
/* definition of instruction format */
|
||||
typedef enum {
|
||||
RRR,
|
||||
RI18,
|
||||
RI16,
|
||||
RI10,
|
||||
RI8,
|
||||
RI7,
|
||||
RR,
|
||||
LBT,
|
||||
LBTI,
|
||||
IDATA,
|
||||
UNKNOWN_IFORMAT
|
||||
} spu_iformat;
|
||||
|
||||
/* These values describe assembly instruction arguments. They indicate
|
||||
* how to encode, range checking and which relocation to use. */
|
||||
typedef enum {
|
||||
A_T, /* register at pos 0 */
|
||||
A_A, /* register at pos 7 */
|
||||
A_B, /* register at pos 14 */
|
||||
A_C, /* register at pos 21 */
|
||||
A_S, /* special purpose register at pos 7 */
|
||||
A_H, /* channel register at pos 7 */
|
||||
A_P, /* parenthesis, this has to separate regs from immediates */
|
||||
A_S3,
|
||||
A_S6,
|
||||
A_S7N,
|
||||
A_S7,
|
||||
A_U7A,
|
||||
A_U7B,
|
||||
A_S10B,
|
||||
A_S10,
|
||||
A_S11,
|
||||
A_S11I,
|
||||
A_S14,
|
||||
A_S16,
|
||||
A_S18,
|
||||
A_R18,
|
||||
A_U3,
|
||||
A_U5,
|
||||
A_U6,
|
||||
A_U7,
|
||||
A_U14,
|
||||
A_X16,
|
||||
A_U18,
|
||||
A_MAX
|
||||
} spu_aformat;
|
||||
|
||||
enum spu_insns {
|
||||
#define APUOP(TAG,MACFORMAT,OPCODE,MNEMONIC,ASMFORMAT,DEP,PIPE) \
|
||||
TAG,
|
||||
#define APUOPFB(TAG,MACFORMAT,OPCODE,FB,MNEMONIC,ASMFORMAT,DEP,PIPE) \
|
||||
TAG,
|
||||
#include "spu-insns.h"
|
||||
#undef APUOP
|
||||
#undef APUOPFB
|
||||
M_SPU_MAX
|
||||
};
|
||||
|
||||
struct spu_opcode
|
||||
{
|
||||
spu_iformat insn_type;
|
||||
unsigned int opcode;
|
||||
char *mnemonic;
|
||||
int arg[5];
|
||||
};
|
||||
|
||||
#define SIGNED_EXTRACT(insn,size,pos) (((int)((insn) << (32-size-pos))) >> (32-size))
|
||||
#define UNSIGNED_EXTRACT(insn,size,pos) (((insn) >> pos) & ((1 << size)-1))
|
||||
|
||||
#define DECODE_INSN_RT(insn) (insn & 0x7f)
|
||||
#define DECODE_INSN_RA(insn) ((insn >> 7) & 0x7f)
|
||||
#define DECODE_INSN_RB(insn) ((insn >> 14) & 0x7f)
|
||||
#define DECODE_INSN_RC(insn) ((insn >> 21) & 0x7f)
|
||||
|
||||
#define DECODE_INSN_I10(insn) SIGNED_EXTRACT(insn,10,14)
|
||||
#define DECODE_INSN_U10(insn) UNSIGNED_EXTRACT(insn,10,14)
|
||||
|
||||
/* For branching, immediate loads, hbr and lqa/stqa. */
|
||||
#define DECODE_INSN_I16(insn) SIGNED_EXTRACT(insn,16,7)
|
||||
#define DECODE_INSN_U16(insn) UNSIGNED_EXTRACT(insn,16,7)
|
||||
|
||||
/* for stop */
|
||||
#define DECODE_INSN_U14(insn) UNSIGNED_EXTRACT(insn,14,0)
|
||||
|
||||
/* For ila */
|
||||
#define DECODE_INSN_I18(insn) SIGNED_EXTRACT(insn,18,7)
|
||||
#define DECODE_INSN_U18(insn) UNSIGNED_EXTRACT(insn,18,7)
|
||||
|
||||
/* For rotate and shift and generate control mask */
|
||||
#define DECODE_INSN_I7(insn) SIGNED_EXTRACT(insn,7,14)
|
||||
#define DECODE_INSN_U7(insn) UNSIGNED_EXTRACT(insn,7,14)
|
||||
|
||||
/* For float <-> int conversion */
|
||||
#define DECODE_INSN_I8(insn) SIGNED_EXTRACT(insn,8,14)
|
||||
#define DECODE_INSN_U8(insn) UNSIGNED_EXTRACT(insn,8,14)
|
||||
|
||||
/* For hbr */
|
||||
#define DECODE_INSN_I9a(insn) ((SIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0))
|
||||
#define DECODE_INSN_I9b(insn) ((SIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0))
|
||||
#define DECODE_INSN_U9a(insn) ((UNSIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0))
|
||||
#define DECODE_INSN_U9b(insn) ((UNSIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0))
|
||||
|
3246
arch/powerpc/xmon/xmon.c
Normal file
3246
arch/powerpc/xmon/xmon.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue