Initial support for LANAI disassembler

This commit is contained in:
pancake 2016-02-15 13:27:23 +01:00
parent 073e08321a
commit cdf63617d7
8 changed files with 1611 additions and 0 deletions

View File

@ -0,0 +1,400 @@
/*************************************************************************
* *
* Definitions for opcode table for the Lanai. *
* *
* Copyright (c) 1994, 1995 by Myricom, Inc. *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of version 2 of the GNU General Public License *
* as published by the Free Software Foundation. Myricom requests that *
* all modifications of this software be returned to Myricom, Inc. for *
* redistribution. The name of Myricom, Inc. may not be used to endorse *
* or promote products derived from this software without specific prior *
* written permission. *
* *
* Myricom, Inc. makes no representations about the suitability of this *
* software for any purpose. *
* *
* THIS FILE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND, WHETHER *
* EXPRESSED OR IMPLIED, INCLUDING THE WARRANTY OF MERCHANTABILITY OR *
* FITNESS FOR A PARTICULAR PURPOSE. MYRICOM, INC. SHALL HAVE NO *
* LIABILITY WITH RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE *
* SECRETS OR ANY PATENTS BY THIS FILE OR ANY PART THEREOF. *
* *
* In no event will Myricom, Inc. be liable for any lost revenue *
* or profits or other special, indirect and consequential damages, even *
* if Myricom has been advised of the possibility of such damages. *
* *
* Other copyrights might apply to parts of this software and are so *
* noted when applicable. *
* *
* Myricom, Inc. Email: info@myri.com *
* 325 N. Santa Anita Ave. World Wide Web: http://www.myri.com/ *
* Arcadia, CA 91024 *
*************************************************************************/
/* initial version released 5/95 */
/* This file is based upon sparc.h from the Gnu binutils-2.5.2
release, which had the following copyright notice: */
/* Definitions for opcode table for the sparc.
Copyright 1989, 1991, 1992 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler, GDB, the GNU debugger, and
the GNU Binutils.
GAS/GDB 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, or (at your option)
any later version.
GAS/GDB 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 GAS or GDB; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
USA. */
/* The Lanai opcode table (and other related data) is defined in
the opcodes library in lanai-opc.c. If you change anything here, make
sure you fix up that file, and vice versa. */
/* FIXME-someday: perhaps the ,a's and such should be embedded in the
instruction's name rather than the args. This would make gas faster, pinsn
slower, but would mess up some macros a bit. xoxorich. */
#define lanai_architecture bfd_lanai_architecture
#define architecture_pname bfd_lanai_architecture_pname
#define lanai_opcode bfd_lanai_opcode
#define lanai_opcodes bfd_lanai_opcodes
/*
* Structure of an opcode table entry.
* This enumerator must parallel the architecture_pname array
* in bfd/opc-lanai.c.
*/
enum lanai_architecture {
v0 = 0, v1
};
extern const char *architecture_pname[];
struct lanai_opcode {
const char *name;
unsigned long match; /* Bits that must be set. */
unsigned long lose; /* Bits that must be clear. */
const char *args;
unsigned int flags;
enum lanai_architecture architecture;
};
#define F_ALIAS 1 /* Alias for a "real" instruction */
#define F_JSR 2 /* Subroutine call */
#define F_RI 0x10
#define F_RR 0x20
#define F_RRR 0x40
#define F_RM 0x80
#define F_RRM 0x100
#define F_BR 0x200
#define F_SLS 0x400
#define F_SLI 0x800
#define F_SPLS 0x1000
#define F_PUNT 0x2000
#define F_SBR 0x4000
#define F_SCC 0x8000
#define F_BYTE 0x20000
#define F_HALF 0x10000
#define F_FULL 0x00000
#define F_DATA_SIZE(X) (4>>((X)&0x30000))
#define F_CONDITIONAL 0x40000
#define F_REL 0x80000
#define F_LEADZ 0x100000
#define F_POPC 0x200000
#define F_CONDBR (F_BR|F_CONDITIONAL) /* Conditional branch */
#define F_UNBR (F_BR) /* Unconditional branch */
#define F_RELCONDBR (F_REL|F_BR|F_CONDITIONAL) /* Conditional branch */
#define F_RELUNBR (F_REL|F_BR) /* Unconditional branch */
/* FIXME: Add F_ANACHRONISTIC flag for v9. */
/* FIXME: Add F_OBSOLETE flag for v9, for instructions that no longer exist? */
/*
All lanai opcodes are 32 bits.
The match component is a mask saying which bits must match a particular
opcode in order for an instruction to be an instance of that opcode.
The args component is a string containing one character for each operand of the
instruction.
Kinds of operands:
# Number used by optimizer. It is ignored.
1 Rs1 register.
2 Rs2 register.
3 Rs3 register.
d Rd register.
4 Op1 (for RRR)
5 Op2 (for RRR)
6 Op2 (for RRM)
J 0x????0000
j 0x0000????
L 0x????ffff
l 0xffff????
k -j
o 16 bit signed offset
s 6 bit signed shift constant
i 10 bit signed immediate.
I 5/16 split 21-bit unsigned immediate.
Y 5/16 split 21-bit unsigned immediate with 2 LSB's == 0.
B 2+23-bit absolute.
b 2+23-bit PC relative immediate.
P %pc or %r2 as Rd
p %pc or %r2 as Rs1
X Q %apc or %r29
X q %aps or %r28
X S %isr or %r31
X M %imr or %r30
! %r1
0 %r0
Literals:([])*+- ,
*/
/* whether to use certain insns */
#define L3_USE_SI
#define L3_USE_SPLS
#define L3_USE_SLS
#define L3_USE_SLI
#define L3_USE_SBR
/* encodings of various conditions */
#define L3_T 0
#define L3_F 1
#define L3_HI 2
#define L3_LS 3
#define L3_CC 4
#define L3_CS 5
#define L3_NE 6
#define L3_EQ 7
#define L3_VC 8
#define L3_VS 9
#define L3_PL 10
#define L3_MI 11
#define L3_GE 12
#define L3_LT 13
#define L3_GT 14
#define L3_LE 15
#define L3_UGE L3_CC
#define L3_ULT L3_CS
#define L3_UGT L3_GT
#define L3_ULE L3_LE
/* opcodes */
/* NOTE: The following masks specify all the bits that can be
determined solely by knowing which line in lanai-opc.c (in the opcodes
directory in the gnu binutils release) matched the line of assembly
code. The OPCODE_MASK specifies which bits of the instruction are constant
for all instructions in the family.
*/
#define L3_RI (0x00000000)
#define L3_RI_OPCODE_MASK (0x80000000)
#define L3_RI_MASK (0xf0030000)
#define L3_RR (0xc0000000)
#define L3_RR_OPCODE_MASK (0xf0000003)
#define L3_RR_MASK (0xf00207fb)
#define L3_LEADZ (0xc0000002)
#define L3_LEADZ_OPCODE_MASK L3_RR_OPCODE_MASK
#define L3_LEADZ_MASK (0xf00207fb)
#define L3_POPC (0xc0000003)
#define L3_POPC_OPCODE_MASK L3_RR_OPCODE_MASK
#define L3_POPC_MASK (0xf00207fb)
#define L3_RRR (0xd0000000)
#define L3_RRR_OPCODE_MASK (0xf0000000)
#define L3_RRR_MASK (0xf0000000)
#define L3_RM (0x80000000)
#define L3_RM_OPCODE_MASK (0xe0000000)
#define L3_RM_MASK (0xf0030000)
#define L3_RRM (0xa0000000)
#define L3_RRM_OPCODE_MASK (0xe0000000)
#define L3_RRM_MASK (0xe0030007)
#define L3_BR (0xe0000000)
#define L3_BR_OPCODE_MASK (0xf0000002)
#define L3_BR_MASK (0xfe000003)
#define L3_BRR (0xe1000002)
#define L3_BRR_OPCODE_MASK (0xf1000002)
#define L3_BRR_MASK (0xff000003)
#define L3_SCC (0xe0000002)
#define L3_SCC_OPCODE_MASK (0xf1000002)
#define L3_SCC_MASK (0xff000003)
#define L3_SLS (0xf0000000)
#define L3_SLS_OPCODE_MASK (0xf0020000)
#define L3_SLS_MASK (0xf0030000)
#define L3_SLI (0xf0020000)
#define L3_SLI_OPCODE_MASK (0xf0030000)
#define L3_SLI_MASK (0xf0030000)
#define L3_SPLS (0xf0030000)
#define L3_SPLS_OPCODE_MASK (0xf0038000)
#define L3_SPLS_MASK (0xf003fc00)
#ifdef BAD
/* BAD: needs fixing */
#define L3_SI (0xf0038000)
#define L3_SI_OPCODE_MASK ___bogus___
#define L3_SI_MASK (0xf003cf47)
#endif
#define L3_PUNT (0xf003ff47)
#define L3_PUNT_OPCODE_MASK (0xf003ff47)
#define L3_PUNT_MASK (0xf003ff47)
#define L3_SBR (0xf003c000)
#define L3_SBR_OPCODE_MASK (0xf003f806)
#define L3_SBR_MASK (0xfe03f807)
/* operations */
#define L3_ADD (0x00)
#define L3_ADDC (0x01)
#define L3_SUB (0x02)
#define L3_SUBB (0x03)
#define L3_AND (0x04)
#define L3_OR (0x05)
#define L3_XOR (0x06)
#define L3_SH (0x07)
#define L3_OP_MASK (0x07)
#define L3_FLAGS (0x08)
#define L3_ARITH (0x10)
/* Data sizes */
#define L3_HALFWORD 0
#define L3_BYTE 4 /* was 1 */
#define L3_FULLWORD 2
/* RRM modes for BYTE and HALFWORD load */
#define L3_SIGNED 0
#define L3_UNSIGNED 1 /* was 4 */
#define L3_SIGNED_HALFWORD ( L3_SIGNED | L3_HALFWORD )
#define L3_SIGNED_BYTE ( L3_SIGNED | L3_BYTE )
#define L3_SIGNED_FULLWORD ( L3_SIGNED | L3_FULLWORD )
#define L3_UNSIGNED_HALFWORD ( L3_UNSIGNED | L3_HALFWORD )
#define L3_UNSIGNED_BYTE ( L3_UNSIGNED | L3_BYTE )
#define L3_UNSIGNED_FULLWORD ( L3_UNSIGNED | L3_FULLWORD )
/* flags */
#define L3_RI_F (0x00020000)
#define L3_RI_H (0x00010000)
#define L3_RR_F (0x00020000)
#define L3_LEADZ_F L3_RR_F
#define L3_POPC_F L3_RR_F
#define L3_RRR_F (0x00020000)
#define L3_RRR_H (0x00010000)
#define L3_RM_P (0x00020000)
#define L3_RM_Q (0x00010000)
#define L3_RM_S (0x10000000)
#define L3_RRM_P (0x00020000)
#define L3_RRM_Q (0x00010000)
#define L3_RRM_S (0x10000000)
#define L3_RRM_Y (0x00000004)
#define L3_RRM_L (0x00000002)
#define L3_RRM_E (0x00000001)
#define L3_BR_R (0x00000002)
#define L3_SLS_S (0x00010000)
#define L3_SPLS_Y (0x00004000)
#define L3_SPLS_S (0x00002000)
#define L3_SPLS_E (0x00001000)
#define L3_SPLS_P (0x00000800)
#define L3_SPLS_Q (0x00000400)
#define L3_SI_F (0x00002000)
#define L3_SBR_H (0x00000004)
#define L3_SBR_R (0x00000002)
#define L3_SBR_N (0x00000001)
/* masks */
#define L3_CONST_MASK (0x0000ffff)
#define L3_BR_CONST_MASK (0x01fffffc)
#define L3_SPLS_CONST_MASK (0x000003ff)
/* field insertion */
#define L3_RD(x) (((x)&0x1f) << 23)
#define L3_RS1(x) (((x)&0x1f) << 18)
#define L3_RS2(x) (((x)&0x1f) << 11)
#define L3_RS3(x) (((x)&0x1f) << 3)
#define L3_RI_OP(x) (((x)&L3_OP_MASK) << 28)
#define L3_RR_OP(x) (((x)&L3_OP_MASK) << 8)
#define L3_RRR_OP1(x) (((x)&L3_OP_MASK) << 0)
#define L3_RRR_OP2(x) (((x)&L3_OP_MASK) << 8)
#define L3_RRM_OP(x) (((x)&L3_OP_MASK) << 8)
#define L3_RRM_MODE(x) (((x)&0x7) << 0)
#define L3_BR_COND(x) ((((x)&0xe) << 24) | ((x)&1) )
#define L3_SBR_COND(x) ((((x)&0xe) << 24) | ((x)&1) )
#define L3_SLS_HIBITS(x) (((x)&0x1f) << 18)
#define L3_SLS_CONST(x) ((((x)&0x1f) << 18) | ((x)&0xffff))
/* Delete this:
#define L3_SLI_HIBITS(x) (((x)&0x7) << 18)
*/
#define L3_SLI_CONST(x) ((((x)&0x1f) << 18) | ((x)&0xffff))
#define L3_SPLS_MODE(x) (((x)&0x5) << 12)
#define L3_SBR_OP(x) (((x)&0x7) << 8)
#define L3_OP1(x) (((x)&0x7) << 0)
#define L3_OP2(x) (((x)&0x7) << 8)
/* Sign-extend a value which is N bits long. */
#define SEX(value, bits) \
((((int)(value)) << ((8 * sizeof (int)) - bits) ) \
>> ((8 * sizeof (int)) - bits) )
/* Macros used to extract instruction fields. Not all fields have
macros defined here, only those which are actually used. */
#define X_RD(i) (((i) >> 23) & 0x1f)
#define X_RS1(i) (((i) >> 18) & 0x1f)
#define X_RS2(i) (((i) >> 11) & 0x1f)
#define X_RS3(i) (((i) >> 3) & 0x1f)
#define X_OP1(i) (((i) >> 0) & 0x07)
#define X_OP2(i) (((i) >> 8) & 0x07)
#define X_RI_OP(i) (((i) >> 28) & 0x07)
#define X_RR_OP(i) X_OP2(i)
#define X_RRM_OP(i) X_OP2(i)
#define X_RRR_OP1(i) X_OP1(i)
#define X_RRR_OP2(i) X_OP2(i)
#define X_C10(i) ((i) & 0x3ff)
#define X_C16(i) ((i) & 0xffff)
#define X_C21(i) (((i) & 0xffff) | (((i) & 0x7c0000)>>2))
#define X_C25(i) ((i) & 0x1fffffc)
extern struct lanai_opcode lanai_opcodes[];
extern const int bfd_lanai_num_opcodes;
#define NUMOPCODES bfd_lanai_num_opcodes
/* end of lanai.h */

View File

@ -0,0 +1,7 @@
all:
git clone https://github.com/myri/lanai-binutils.git
mkdir -p gnu
cp -f include/opcode/lanai.h ../include/opcode
cp -f opcodes/lanai-*.c gnu/
rm -rf lanai-binutils

View File

@ -0,0 +1,505 @@
/*************************************************************************
* *
* Print Lanai instructions. *
* *
* Copyright (c) 1994, 1995 by Myricom, Inc. *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of version 2 of the GNU General Public License *
* as published by the Free Software Foundation. Myricom requests that *
* all modifications of this software be returned to Myricom, Inc. for *
* redistribution. The name of Myricom, Inc. may not be used to endorse *
* or promote products derived from this software without specific prior *
* written permission. *
* *
* Myricom, Inc. makes no representations about the suitability of this *
* software for any purpose. *
* *
* THIS FILE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND, WHETHER *
* EXPRESSED OR IMPLIED, INCLUDING THE WARRANTY OF MERCHANTABILITY OR *
* FITNESS FOR A PARTICULAR PURPOSE. MYRICOM, INC. SHALL HAVE NO *
* LIABILITY WITH RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE *
* SECRETS OR ANY PATENTS BY THIS FILE OR ANY PART THEREOF. *
* *
* In no event will Myricom, Inc. be liable for any lost revenue *
* or profits or other special, indirect and consequential damages, even *
* if Myricom has been advised of the possibility of such damages. *
* *
* Other copyrights might apply to parts of this software and are so *
* noted when applicable. *
* *
* Myricom, Inc. Email: info@myri.com *
* 325 N. Santa Anita Ave. World Wide Web: http://www.myri.com/ *
* Arcadia, CA 91024 *
*************************************************************************/
/* initial version released 5/95 */
/* This file is based upon <> from the Gnu binutils-2.5.2
release, which had the following copyright notice: */
/* Print SPARC instructions.
Copyright 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "ansidecl.h"
#include "opcode/lanai.h"
#include "dis-asm.h"
static char *reg_names[] =
{ "r0", "r1", "pc", "ps", "sp", "fp", "r6", "r7",
"r8", "r9","r10","r11","r12","r13","r14","r15",
"r16","r17","r18","r19","r20","r21","r22","r23",
"r24","r25","r26","r27","r28","r29","r30","r31",
};
static char *op_names[] =
{ "add", "addc", "sub", "subb", "and", "or", "xor", "sh" };
/* Nonzero if INSN is the opcode for a delayed branch. */
static int is_delayed_branch (unsigned long insn);
static int
is_delayed_branch (insn)
unsigned long insn;
{
int i;
for (i = 0; i < NUMOPCODES; ++i)
{
CONST struct lanai_opcode *opcode = &lanai_opcodes[i];
if ((opcode->match & insn) == opcode->match
&& (opcode->lose & insn) == 0)
return (opcode->flags & F_BR);
}
return 0;
}
static int opcodes_sorted = 0;
/* extern void qsort (); */
static int compare_opcodes (char *a, char *b);
/* Print one instruction from MEMADDR on INFO->STREAM.
We suffix the instruction with a comment that gives the absolute
address involved, as well as its symbolic form, if the instruction
is preceded by a findable `sethi' and it either adds an immediate
displacement to that register, or it is an `add' or `or' instruction
on that register. */
int
print_insn_lanai (memaddr, info)
bfd_vma memaddr;
disassemble_info *info;
{
FILE *stream = info->stream;
bfd_byte buffer[4];
unsigned int insn;
register int i;
if (!opcodes_sorted)
{
qsort ((char *) lanai_opcodes, NUMOPCODES,
sizeof (lanai_opcodes[0]),
(int (*)(const void *,const void *))compare_opcodes);
opcodes_sorted = 1;
}
{
int status =
(*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
if (status != 0)
{
(*info->memory_error_func) (status, memaddr, info);
return -1;
}
}
insn = bfd_getb32 (buffer);
info->insn_info_valid = 1; /* We do return this info */
info->insn_type = dis_nonbranch; /* Assume non branch insn */
info->branch_delay_insns = 0; /* Assume no delay */
info->target = 0; /* Assume no target known */
for (i = 0; i < NUMOPCODES; ++i)
{
CONST struct lanai_opcode *opcode = &lanai_opcodes[i];
if ((opcode->match & insn) == opcode->match
&& (opcode->lose & insn) == 0)
{
/* Nonzero means that we have found an instruction which has
the effect of adding or or'ing the imm13 field to rs1. */
int imm_added_to_rs1 = 0;
/* Do we have an `add' or `or' immediate instruction where rs1 is
the same as rd? */
if (((!(opcode->match & 0x80000000) /* RI insn */
&& ( !(opcode->match & 0x70000000) /* RI add */
|| (opcode->match & 0x70000000) == 0x50000000 /* RI or */
))
|| ((opcode->match & 0xf0000000) == 0xc0000000 /* RR insn */
&& ( !(opcode->match & 0x00000700) /* RR add */
|| (opcode->match & 0x00000700) == 0x00000500 /* RR or */ )))
&& X_RS1(insn) == X_RD(insn))
{
imm_added_to_rs1 = 1;
}
#ifdef BAD
if (X_RS1 (insn) != X_RD (insn)
&& strchr (opcode->args, 'r') != 0)
/* Can't do simple format if source and dest are different. */
continue;
#endif
(*info->fprintf_func) (stream, opcode->name);
{
register CONST char *s;
unsigned int imm;
for (s = opcode->args; *s != '\0'; ++s)
{
(*info->fprintf_func) (stream, " ");
switch (*s)
{
/* By default, just print the character. */
default:
(*info->fprintf_func) (stream, "%c", *s);
break;
#define reg(n) (*info->fprintf_func) (stream, "%%%s", reg_names[n])
case '1':
reg (X_RS1 (insn));
break;
case '2':
reg (X_RS2 (insn));
break;
case '3':
reg (X_RS3 (insn));
break;
case 'd':
reg (X_RD (insn));
break;
#undef reg
case '4': /* Op1 (for RRR) */
(*info->fprintf_func) (stream, op_names[X_OP1(insn)]);
break;
case '5': /* Op2 (for RRR) */
(*info->fprintf_func) (stream, op_names[X_OP2(insn)]);
if(insn&L3_RRR_F)
(*info->fprintf_func) (stream, ".f");
break;
case '6': /* Op2 (for RRM) */
(*info->fprintf_func) (stream, op_names[X_OP2(insn)]);
break;
case 'J':
imm = X_C16(insn)<<16;
goto print_immediate;
case 'j':
imm = X_C16(insn);
goto print_immediate;
case 'L':
imm = (X_C16(insn)<<16)|0xffff;
goto print_immediate;
case 'l':
imm = X_C16(insn)|0xffff0000;
goto print_immediate;
case 'k':
/* This should never happen */
(*info->fprintf_func) (stream, "***ERROR***");
case 'o':
imm = SEX (X_C16(insn), 16);
if (X_RS1 (insn) == 0) goto print_address;
goto print_immediate;
case 's':
imm = SEX (X_C16(insn), 16);
goto print_immediate;
case 'i':
imm = SEX (X_C10(insn), 10);
if (X_RS1 (insn) == 0) goto print_address;
goto print_immediate;
case 'I':
imm = X_C21(insn);
goto print_address;
case 'Y':
imm = X_C21(insn);
goto print_address;
case 'B':
imm = X_C25(insn);
goto print_address;
case 'b':
imm = SEX (X_C25(insn), 25);
goto print_address;
print_immediate:
(*info->fprintf_func) (stream, "0x%x", imm);
break;
print_address:
info->target = imm;
(*info->print_address_func) (imm, info);
break;
/* Named registers */
case 'P':
(*info->fprintf_func) (stream, "%%pc");
break;
case 'p':
(*info->fprintf_func) (stream, "%%ps");
break;
case 'Q':
(*info->fprintf_func) (stream, "%%apc");
break;
case 'q':
(*info->fprintf_func) (stream, "%%aps");
break;
case 'S':
(*info->fprintf_func) (stream, "%%isr");
break;
case 'M':
(*info->fprintf_func) (stream, "%%imr");
break;
case '!':
(*info->fprintf_func) (stream, "%%r1");
break;
case '0':
(*info->fprintf_func) (stream, "%%r0");
break;
}
}
}
/* If we are adding or or'ing something to rs1, then
check to see whether the previous instruction was
a mov to the same register as in the or.
If so, attempt to print the result of the add or
or (in this context add and or do the same thing)
and its symbolic value. */
if (imm_added_to_rs1)
{
unsigned long prev_insn;
int errcode;
errcode =
(*info->read_memory_func)
(memaddr - 4, buffer, sizeof (buffer), info);
prev_insn = bfd_getb32 (buffer);
if (errcode == 0)
{
/* If it is a delayed branch, we need to look at the
instruction before the delayed branch. This handles
sequences such as
mov %hi(_foo), %r4
call _printf
or %r4, %lo(_foo), %r4
*/
if (is_delayed_branch (prev_insn))
{
errcode = (*info->read_memory_func)
(memaddr - 8, buffer, sizeof (buffer), info);
prev_insn = bfd_getb32 (buffer);
}
}
/* If there was a problem reading memory, then assume
the previous instruction was not sethi. */
if (errcode == 0)
{
/* Is it an "{and,or} %r0,0x????????,%rd" to the same reg */
if (((prev_insn & 0xf07c0000) == 0x00000000
|| (prev_insn & 0xf07c0000) == 0x50000000 )
&& X_RD (prev_insn) == X_RS1 (insn)
&& X_RD (prev_insn) )
{
(*info->fprintf_func) (stream, "\t! ");
info->target
= X_C16( insn) << (L3_RI_H& insn ? 16 : 0);
if((prev_insn & 0xf07c0000) == 0x50000000 ){
info->target
|= X_C16(prev_insn) << (L3_RI_H&prev_insn ? 16 : 0);
}else{
info->target
+= X_C16(prev_insn) << (L3_RI_H&prev_insn ? 16 : 0);
}
(*info->print_address_func) (info->target, info);
info->insn_type = dis_dref;
info->data_size = 4; /* FIXME!!! */
}
}
}
info->data_size = F_DATA_SIZE(opcode->flags);
if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
{
/* FIXME -- check is_annulled flag */
if (opcode->flags & F_UNBR)
info->insn_type = dis_branch;
else if (opcode->flags & F_CONDBR)
info->insn_type = dis_condbranch;
else if (opcode->flags & F_JSR)
info->insn_type = dis_jsr;
else if (opcode->flags & F_BR)
info->branch_delay_insns = 1;
}
return sizeof (buffer);
}
}
info->insn_type = dis_noninsn; /* Mark as non-valid instruction */
(*info->fprintf_func) (stream, "%#8x", insn);
return sizeof (buffer);
}
/* Compare opcodes A and B. */
static int
compare_opcodes (a, b)
char *a, *b;
{
struct lanai_opcode *op0 = (struct lanai_opcode *) a;
struct lanai_opcode *op1 = (struct lanai_opcode *) b;
unsigned long int match0 = op0->match, match1 = op1->match;
unsigned long int lose0 = op0->lose, lose1 = op1->lose;
register unsigned int i;
/* If a bit is set in both match and lose, there is something
wrong with the opcode table. */
if (match0 & lose0)
{
fprintf (stderr, "Internal error: bad lanai-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
op0->name, match0, lose0);
op0->lose &= ~op0->match;
lose0 = op0->lose;
}
if (match1 & lose1)
{
fprintf (stderr, "Internal error: bad lanai-opcode.h: \"%s\", %#.8lx, %#.8lx\n",
op1->name, match1, lose1);
op1->lose &= ~op1->match;
lose1 = op1->lose;
}
/* Because the bits that are variable in one opcode are constant in
another, it is important to order the opcodes in the right order. */
for (i = 0; i < 32; ++i)
{
unsigned long int x = 1 << i;
int x0 = (match0 & x) != 0;
int x1 = (match1 & x) != 0;
if (x0 != x1)
return x1 - x0;
}
for (i = 0; i < 32; ++i)
{
unsigned long int x = 1 << i;
int x0 = (lose0 & x) != 0;
int x1 = (lose1 & x) != 0;
if (x0 != x1)
return x1 - x0;
}
/* They are functionally equal. So as long as the opcode table is
valid, we can put whichever one first we want, on aesthetic grounds. */
/* Our first aesthetic ground is that aliases defer to real insns. */
{
int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
if (alias_diff != 0)
/* Put the one that isn't an alias first. */
return alias_diff;
}
/* Except for aliases, two "identical" instructions had
better have the same opcode. This is a sanity check on the table. */
i = strcmp (op0->name, op1->name);
if (i)
{
if (op0->flags & F_ALIAS) /* If they're both aliases, be arbitrary. */
{
return i;
}
else
{
fprintf (stderr,
"Internal error: bad lanai-opcode.h: \"%s\" == \"%s\"\n",
op0->name, op1->name);
}
}
/* Fewer arguments are preferred. */
{
int length_diff = strlen (op0->args) - strlen (op1->args);
if (length_diff != 0)
/* Put the one with fewer arguments first. */
return length_diff;
}
/* Put 1+i before i+1. */
{
char *p0 = (char *) strchr(op0->args, '+');
char *p1 = (char *) strchr(op1->args, '+');
if (p0 && p1)
{
/* There is a plus in both operands. Note that a plus
sign cannot be the first character in args,
so the following [-1]'s are valid. */
if (p0[-1] == 'i' && p1[1] == 'i')
/* op0 is i+1 and op1 is 1+i, so op1 goes first. */
return 1;
if (p0[1] == 'i' && p1[-1] == 'i')
/* op0 is 1+i and op1 is i+1, so op0 goes first. */
return -1;
}
}
/* They are, as far as we can tell, identical.
Since qsort may have rearranged the table partially, there is
no way to tell which one was first in the opcode table as
written, so just say there are equal. */
return 0;
}

View File

@ -0,0 +1,578 @@
/*************************************************************************
* *
* Table of opcodes for the Lanai. *
* *
* Copyright (c) 1994, 1995 by Myricom, Inc. *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of version 2 of the GNU General Public License *
* as published by the Free Software Foundation. Myricom requests that *
* all modifications of this software be returned to Myricom, Inc. for *
* redistribution. The name of Myricom, Inc. may not be used to endorse *
* or promote products derived from this software without specific prior *
* written permission. *
* *
* Myricom, Inc. makes no representations about the suitability of this *
* software for any purpose. *
* *
* THIS FILE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND, WHETHER *
* EXPRESSED OR IMPLIED, INCLUDING THE WARRANTY OF MERCHANTABILITY OR *
* FITNESS FOR A PARTICULAR PURPOSE. MYRICOM, INC. SHALL HAVE NO *
* LIABILITY WITH RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE *
* SECRETS OR ANY PATENTS BY THIS FILE OR ANY PART THEREOF. *
* *
* In no event will Myricom, Inc. be liable for any lost revenue *
* or profits or other special, indirect and consequential damages, even *
* if Myricom has been advised of the possibility of such damages. *
* *
* Other copyrights might apply to parts of this software and are so *
* noted when applicable. *
* *
* Myricom, Inc. Email: info@myri.com *
* 325 N. Santa Anita Ave. World Wide Web: http://www.myri.com/ *
* Arcadia, CA 91024 *
*************************************************************************/
/* initial version released 5/95 */
/* This file is based upon <> from the Gnu binutils-2.5.2
release, which had the following copyright notice: */
/* Table of opcodes for the sparc.
Copyright 1989, 1991, 1992 Free Software Foundation, Inc.
This file is part of the BFD library.
BFD 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, or (at your option) any later
version.
BFD 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 software; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
USA. */
/* FIXME-someday: perhaps the ,a's and such should be embedded in the
instruction's name rather than the args. This would make gas faster, pinsn
slower, but would mess up some macros a bit. xoxorich. */
/* v9 FIXME: Doesn't accept `iprefetch', `setX', `signx', `cleartop', `cas',
`casx', `clrx', `clruw' synthetic instructions for v9. */
#include <stdio.h>
#include "ansidecl.h"
#include "opcode/lanai.h"
const char *architecture_pname[] = {
"v0",
"v1",
NULL,
};
/* A pair is the set of all bits that must be high or low as determined
solely by the opcode. This macro takes a mask and the set of
all bits that must be high and generates the pair. I do this
so the macro definitions below are simpler. */
#define GENERIC_PAIR(mask,high) \
(high),((mask)&~(high))
/* Specifies the bits that must be set and the bits that must be cleared
for an RI instruction. */
#define RI_PAIR(op,f,h) GENERIC_PAIR(L3_RI_MASK, \
L3_RI | L3_RI_OP(op) | ((f)?L3_RI_F:0) | ((h)?L3_RI_H:0) )
#define RR_PAIR(f,op) GENERIC_PAIR(L3_RR_MASK, \
L3_RR | ((f)?L3_RR_F:0) | L3_RR_OP(op) \
| ((((op)&L3_OP_MASK)==L3_SH) ? ((op)&L3_ARITH?0xc0:0x80) : 0 ))
#define LEADZ_PAIR(f) GENERIC_PAIR(L3_LEADZ_MASK, \
L3_LEADZ | ((f)?L3_LEADZ_F:0))
#define POPC_PAIR(f) GENERIC_PAIR(L3_POPC_MASK, \
L3_POPC | ((f)?L3_POPC_F:0))
#define RRR_PAIR() GENERIC_PAIR(L3_RRR_MASK, \
L3_RRR )
#define RM_PAIR(s,p,q) GENERIC_PAIR(L3_RM_MASK, \
L3_RM | ((s)?L3_RM_S:0) | ((p)?L3_RM_P:0) | ((q)?L3_RM_Q:0) )
#define RRM_PAIR(s,p,q,mode) GENERIC_PAIR(L3_RRM_MASK, \
L3_RRM | ((s)?L3_RRM_S:0) | ((p)?L3_RRM_P:0) \
| ((q)?L3_RRM_Q:0) | L3_RRM_MODE(mode) )
#define BR_PAIR(cond,r) GENERIC_PAIR(L3_BR_MASK, \
L3_BR | L3_BR_COND(cond) | ((r)?L3_BR_R:0) )
#define SCC_PAIR(cond) GENERIC_PAIR (L3_SCC_MASK, L3_SCC | L3_BR_COND (cond))
#define SLS_PAIR(s) GENERIC_PAIR(L3_SLS_MASK, \
L3_SLS | ((s)?L3_SLS_S:0) )
#define SLI_PAIR() GENERIC_PAIR(L3_SLI_MASK, \
L3_SLI )
#define SPLS_PAIR(s,mode,p,q) GENERIC_PAIR(L3_SPLS_MASK, \
L3_SPLS | L3_SPLS_MODE(mode) | ((s)?L3_SPLS_S:0) \
| ((p)?L3_SPLS_P:0) | ((q)?L3_SPLS_Q:0) )
#define PUNT_PAIR() GENERIC_PAIR(L3_PUNT_MASK, \
L3_PUNT )
#define SBR_PAIR(cond,op,r) GENERIC_PAIR(L3_SBR_MASK, \
L3_SBR|L3_SBR_COND(cond)|L3_SBR_OP(op)|(r?L3_SBR_R:0))
#define PCREL_SBR_PAIR(cond) GENERIC_PAIR(L3_SBR_MASK|L3_RS1(0x1f)| \
L3_SBR_OP(7), \
L3_SBR|L3_SBR_COND(cond)|L3_SBR_OP(L3_ADD)|L3_RS1(2)|L3_SBR_R)
/* Specifies the bits that must be set and the bits that must be cleared
for an RI "mov" instruction. Note that Rs1 is 1 for AND type moves */
#define RI_MOV_PAIR(op,f,h) GENERIC_PAIR(L3_RI_MASK|L3_RS1(31), \
L3_RI|L3_RI_OP(op)|((f)?L3_RI_F:0)|((h)?L3_RI_H:0)|(((op)==L3_AND)?L3_RS1(1):0))
/* Similarly for RR "mov" insns */
#define RR_MOV_PAIR(f,op) GENERIC_PAIR(L3_RR_MASK|0x007c0000, \
L3_RR | ((f)?L3_RR_F:0) | L3_RR_OP(op) \
| (((op)&L3_ARITH)?1<<6:0) | ((op)==L3_SH?1<<7:0) )
/* The order of the opcodes in the table is significant:
* The assembler requires that all instances of the same mnemonic must
be consecutive. If they aren't, the assembler will bomb at runtime.
* The disassembler should not care about the order of the opcodes.
* instructions with constants must come at the end of the
list of instructions with the same mnemonic to avoid using
get_expression unless it is guaranteed to work because it
aborts if it fails.
*/
struct lanai_opcode lanai_opcodes[] = {
/* nop (at beginning so disassembler will use these if possible) */
{ "nop", 0x00000001,0xfffffffe ,"", F_RI, 0},
{ "nop(RI)", 0x00000000,0x8f820000 ,"", F_RI, 0},
{ "nop(RR)", 0xc0000000,0x3f820000 ,"", F_RR, 0},
{ "nop(RRR)", 0xd0000000,0x2f820000 ,"", F_RRR, 0},
{ "nop(BR)", 0xe2000000,0x1c000000 ,"", F_BR, 0},
{ "nop(SLI)", 0xf0020000,0x0f810000 ,"", F_SLI, 0},
{ "nop(SPLS)", 0xf0030000,0x0f808000 ,"", F_SPLS, 0},
{ "nop(SBR)", 0xf203c000,0x0c003800 ,"", F_SBR, 0},
/* mov (at beginning so disassembler will use these if possible) */
{ "mov", RR_MOV_PAIR(0,L3_ADD) ,"1,d", F_RR, 0},
{ "mov", BR_PAIR(L3_T,0) ,"B,P", F_ALIAS,0},
{ "mov", SLI_PAIR() ,"I,d", F_SLI, 0},
{ "mov", RI_MOV_PAIR(L3_ADD,0,0) ,"j,d", F_RI, 0},
{ "mov", RI_MOV_PAIR(L3_ADD,0,1) ,"J,d", F_RI, 0},
{ "mov", RI_MOV_PAIR(L3_AND,0,0) ,"l,d", F_RI, 0},
{ "mov", RI_MOV_PAIR(L3_AND,0,1) ,"L,d", F_RI, 0},
/*{ "mov", RI_MOV_PAIR(L3_SUB,0,0) ,"k,d", F_RI, 0}, */
/* These moves used only for disassembler */
{ "mov", RI_MOV_PAIR(L3_OR,0,0) ,"j,d", F_RI, 0},
{ "mov", RI_MOV_PAIR(L3_OR,0,1) ,"J,d", F_RI, 0},
{ "mov", RI_MOV_PAIR(L3_OR,0,0) ,"l,d", F_RI, 0},
{ "mov", RI_MOV_PAIR(L3_OR,0,1) ,"L,d", F_RI, 0},
/* add */
{ "add", RR_PAIR(0,L3_ADD) ,"1,2,d", F_RR,0},
{ "add", BR_PAIR(L3_T,1) ,"p,b,P", F_UNBR|F_ALIAS,0},
{ "add", RI_PAIR(L3_ADD,0,0) ,"1,j,d", F_RI,0},
{ "add", RI_PAIR(L3_ADD,0,1) ,"1,J,d", F_RI,0},
/*{ "add", RI_PAIR(L3_SUB,0,0) ,"18k,d", F_RI|F_ALIAS,0}, */
{ "add.f", RR_PAIR(1,L3_ADD) ,"1,2,d", F_RR,0},
{ "add.f", RI_PAIR(L3_ADD,1,0) ,"1,j,d", F_RI,0},
{ "add.f", RI_PAIR(L3_ADD,1,1) ,"1,J,d", F_RI,0},
/*{ "add.f", RI_PAIR(L3_SUB,1,1) ,"1,k,d", F_RI|F_ALIAS,0}, */
{ "addc", RR_PAIR(0,L3_ADDC) ,"1,2,d", F_RR,0},
{ "addc", RI_PAIR(L3_ADDC,0,0) ,"1,j,d", F_RI,0},
{ "addc", RI_PAIR(L3_ADDC,0,1) ,"1,J,d", F_RI,0},
/*{ "addc", RI_PAIR(L3_SUBB,0,0) ,"1,k,d", F_RI|F_ALIAS,0}, */
{ "addc.f", RR_PAIR(1,L3_ADDC) ,"1,2,d", F_RR,0},
{ "addc.f", RI_PAIR(L3_ADDC,1,0) ,"1,j,d", F_RI,0},
{ "addc.f", RI_PAIR(L3_ADDC,1,1) ,"1,J,d", F_RI,0},
/*{ "addc.f", RI_PAIR(L3_SUBB,0,1) ,"1,k,d", F_RI|F_ALIAS,0}, */
/* and */
{ "and", RR_PAIR(0,L3_AND) ,"1,2,d", F_RR,0},
{ "and", RI_PAIR(L3_AND,0,0) ,"1,l,d", F_RI,0},
{ "and", RI_PAIR(L3_AND,0,1) ,"1,L,d", F_RI,0},
{ "and.f", RR_PAIR(1,L3_AND) ,"1,2,d", F_RR,0},
{ "and.f", RI_PAIR(L3_AND,1,0) ,"1,l,d", F_RI,0},
{ "and.f", RI_PAIR(L3_AND,1,1) ,"1,L,d", F_RI,0},
/* b?? */
{ "bt", BR_PAIR(L3_T,0) ,"B", F_UNBR,0},
{ "bt", SBR_PAIR(L3_T,0,0) ,"1", F_UNBR,0},
{ "bt", SBR_PAIR(L3_T,0,0) ,"143", F_UNBR,0},
{ "bt.r", BR_PAIR(L3_T,1) ,"b", F_RELUNBR,0},
{ "bt.r", PCREL_SBR_PAIR(L3_T) ,"3", F_RELUNBR,0},
{ "bf", BR_PAIR(L3_F,0) ,"B", F_BR,0},
{ "bf", SBR_PAIR(L3_F,0,0) ,"1", F_BR,0},
{ "bf", SBR_PAIR(L3_F,0,0) ,"143", F_BR,0},
{ "bf.r", BR_PAIR(L3_F,1) ,"b", F_BR|F_REL,0},
{ "bf.r", PCREL_SBR_PAIR(L3_F) ,"3", F_BR|F_REL,0},
{ "bhi", BR_PAIR(L3_HI,0) ,"B", F_CONDBR,0},
{ "bhi", SBR_PAIR(L3_HI,0,0) ,"1", F_CONDBR,0},
{ "bhi", SBR_PAIR(L3_HI,0,0) ,"143", F_CONDBR,0},
{ "bhi.r", BR_PAIR(L3_HI,1) ,"b", F_RELCONDBR,0},
{ "bhi.r", PCREL_SBR_PAIR(L3_HI) ,"3", F_RELCONDBR,0},
{ "bugt", BR_PAIR(L3_HI,0) ,"B",F_ALIAS|F_CONDBR,0},
{ "bugt", SBR_PAIR(L3_HI,0,0) ,"1",F_ALIAS|F_CONDBR,0},
{ "bugt", SBR_PAIR(L3_HI,0,0) ,"143",F_ALIAS|F_CONDBR,0},
{ "bugt.r", BR_PAIR(L3_HI,1) ,"b",F_ALIAS|F_RELCONDBR,0},
{ "bugt.r", PCREL_SBR_PAIR(L3_HI) ,"3",F_ALIAS|F_RELCONDBR,0},
{ "bls", BR_PAIR(L3_LS,0) ,"B", F_CONDBR,0},
{ "bls", SBR_PAIR(L3_LS,0,0) ,"1", F_CONDBR,0},
{ "bls", SBR_PAIR(L3_LS,0,0) ,"143", F_CONDBR,0},
{ "bls.r", BR_PAIR(L3_LS,1) ,"b", F_RELCONDBR,0},
{ "bls.r", PCREL_SBR_PAIR(L3_LS) ,"3", F_RELCONDBR,0},
{ "bule", BR_PAIR(L3_LS,0) ,"B",F_ALIAS|F_CONDBR,0},
{ "bule", SBR_PAIR(L3_LS,0,0) ,"1",F_ALIAS|F_CONDBR,0},
{ "bule", SBR_PAIR(L3_LS,0,0) ,"143",F_ALIAS|F_CONDBR,0},
{ "bule.r", BR_PAIR(L3_LS,1) ,"b",F_ALIAS|F_RELCONDBR,0},
{ "bule.r", PCREL_SBR_PAIR(L3_LS) ,"3",F_ALIAS|F_RELCONDBR,0},
{ "bcc", BR_PAIR(L3_CC,0) ,"B", F_CONDBR,0},
{ "bcc", SBR_PAIR(L3_CC,0,0) ,"1", F_CONDBR,0},
{ "bcc", SBR_PAIR(L3_CC,0,0) ,"143", F_CONDBR,0},
{ "bcc.r", BR_PAIR(L3_CC,1) ,"b", F_RELCONDBR,0},
{ "bcc.r", PCREL_SBR_PAIR(L3_CC) ,"3", F_RELCONDBR,0},
{ "buge", BR_PAIR(L3_CS,0) ,"B",F_ALIAS|F_CONDBR,0},
{ "buge", SBR_PAIR(L3_CS,0,0) ,"1",F_ALIAS|F_CONDBR,0},
{ "buge", SBR_PAIR(L3_CS,0,0) ,"143",F_ALIAS|F_CONDBR,0},
{ "buge.r", BR_PAIR(L3_CS,1) ,"b",F_ALIAS|F_RELCONDBR,0},
{ "buge.r", PCREL_SBR_PAIR(L3_CS) ,"3",F_ALIAS|F_RELCONDBR,0},
{ "bcs", BR_PAIR(L3_CS,0) ,"B", F_CONDBR,0},
{ "bcs", SBR_PAIR(L3_CS,0,0) ,"1", F_CONDBR,0},
{ "bcs", SBR_PAIR(L3_CS,0,0) ,"143", F_CONDBR,0},
{ "bcs.r", BR_PAIR(L3_CS,1) ,"b", F_RELCONDBR,0},
{ "bcs.r", PCREL_SBR_PAIR(L3_CS) ,"3", F_RELCONDBR,0},
{ "bult", BR_PAIR(L3_CC,0) ,"B",F_ALIAS|F_CONDBR,0},
{ "bult", SBR_PAIR(L3_CC,0,0) ,"1",F_ALIAS|F_CONDBR,0},
{ "bult", SBR_PAIR(L3_CC,0,0) ,"143",F_ALIAS|F_CONDBR,0},
{ "bult.r", BR_PAIR(L3_CC,1) ,"b",F_ALIAS|F_RELCONDBR,0},
{ "bult.r", PCREL_SBR_PAIR(L3_CC) ,"3",F_ALIAS|F_RELCONDBR,0},
{ "bne", BR_PAIR(L3_NE,0) ,"B", F_CONDBR,0},
{ "bne", SBR_PAIR(L3_NE,0,0) ,"1", F_CONDBR,0},
{ "bne", SBR_PAIR(L3_NE,0,0) ,"143", F_CONDBR,0},
{ "bne.r", BR_PAIR(L3_NE,1) ,"b", F_RELCONDBR,0},
{ "bne.r", PCREL_SBR_PAIR(L3_NE) ,"3", F_RELCONDBR,0},
{ "beq", BR_PAIR(L3_EQ,0) ,"B", F_CONDBR,0},
{ "beq", SBR_PAIR(L3_EQ,0,0) ,"1", F_CONDBR,0},
{ "beq", SBR_PAIR(L3_EQ,0,0) ,"143", F_CONDBR,0},
{ "beq.r", BR_PAIR(L3_EQ,1) ,"b", F_RELCONDBR,0},
{ "beq.r", PCREL_SBR_PAIR(L3_EQ) ,"3", F_RELCONDBR,0},
{ "bvc", BR_PAIR(L3_VC,0) ,"B", F_CONDBR,0},
{ "bvc", SBR_PAIR(L3_VC,0,0) ,"1", F_CONDBR,0},
{ "bvc", SBR_PAIR(L3_VC,0,0) ,"143", F_CONDBR,0},
{ "bvc.r", BR_PAIR(L3_VC,1) ,"b", F_RELCONDBR,0},
{ "bvc.r", PCREL_SBR_PAIR(L3_VC) ,"3", F_RELCONDBR,0},
{ "bvs", BR_PAIR(L3_VS,0) ,"B", F_CONDBR,0},
{ "bvs", SBR_PAIR(L3_VS,0,0) ,"1", F_CONDBR,0},
{ "bvs", SBR_PAIR(L3_VS,0,0) ,"143", F_CONDBR,0},
{ "bvs.r", BR_PAIR(L3_VS,1) ,"b", F_RELCONDBR,0},
{ "bvs.r", PCREL_SBR_PAIR(L3_VS) ,"3", F_RELCONDBR,0},
{ "bpl", BR_PAIR(L3_PL,0) ,"B", F_CONDBR,0},
{ "bpl", SBR_PAIR(L3_PL,0,0) ,"1", F_CONDBR,0},
{ "bpl", SBR_PAIR(L3_PL,0,0) ,"143", F_CONDBR,0},
{ "bpl.r", BR_PAIR(L3_PL,1) ,"b", F_RELCONDBR,0},
{ "bpl.r", PCREL_SBR_PAIR(L3_PL) ,"3", F_RELCONDBR,0},
{ "bmi", BR_PAIR(L3_MI,0) ,"B", F_CONDBR,0},
{ "bmi", SBR_PAIR(L3_MI,0,0) ,"1", F_CONDBR,0},
{ "bmi", SBR_PAIR(L3_MI,0,0) ,"143", F_CONDBR,0},
{ "bmi.r", BR_PAIR(L3_MI,1) ,"b", F_RELCONDBR,0},
{ "bmi.r", PCREL_SBR_PAIR(L3_MI) ,"3", F_RELCONDBR,0},
{ "bge", BR_PAIR(L3_GE,0) ,"B", F_CONDBR,0},
{ "bge", SBR_PAIR(L3_GE,0,0) ,"1", F_CONDBR,0},
{ "bge", SBR_PAIR(L3_GE,0,0) ,"143", F_CONDBR,0},
{ "bge.r", BR_PAIR(L3_GE,1) ,"b", F_RELCONDBR,0},
{ "bge.r", PCREL_SBR_PAIR(L3_GE) ,"3", F_RELCONDBR,0},
{ "blt", BR_PAIR(L3_LT,0) ,"B", F_CONDBR,0},
{ "blt", SBR_PAIR(L3_LT,0,0) ,"1", F_CONDBR,0},
{ "blt", SBR_PAIR(L3_LT,0,0) ,"143", F_CONDBR,0},
{ "blt.r", BR_PAIR(L3_LT,1) ,"b", F_RELCONDBR,0},
{ "blt.r", PCREL_SBR_PAIR(L3_LT) ,"3", F_RELCONDBR,0},
{ "bgt", BR_PAIR(L3_GT,0) ,"B", F_CONDBR,0},
{ "bgt", SBR_PAIR(L3_GT,0,0) ,"1", F_CONDBR,0},
{ "bgt", SBR_PAIR(L3_GT,0,0) ,"143", F_CONDBR,0},
{ "bgt.r", BR_PAIR(L3_GT,1) ,"b", F_RELCONDBR,0},
{ "bgt.r", PCREL_SBR_PAIR(L3_GT) ,"3", F_RELCONDBR,0},
{ "ble", BR_PAIR(L3_LE,0) ,"B", F_CONDBR,0},
{ "ble", SBR_PAIR(L3_LE,0,0) ,"1", F_CONDBR,0},
{ "ble", SBR_PAIR(L3_LE,0,0) ,"143", F_CONDBR,0},
{ "ble.r", BR_PAIR(L3_LE,1) ,"b", F_RELCONDBR,0},
{ "ble.r", PCREL_SBR_PAIR(L3_LE) ,"3", F_RELCONDBR,0},
/* ld */
{ "ld", 0x80030004,0x7000fffb ,"[++1],d", F_RM,0},
{ "ld", 0x80010004,0x7002fffb ,"[1++],d", F_RM,0},
{ "ld", 0x8003fffc,0x70000003 ,"[--1],d", F_RM,0},
{ "ld", 0x8001fffc,0x70020003 ,"[1--],d", F_RM,0},
{ "ld", RRM_PAIR(0,1,0,L3_SIGNED_FULLWORD) ,"2[1],d", F_RRM,0},
{ "ld", RRM_PAIR(0,1,1,L3_SIGNED_FULLWORD) ,"2[*1],d", F_RRM,0},
{ "ld", RRM_PAIR(0,0,1,L3_SIGNED_FULLWORD) ,"2[1*],d", F_RRM,0},
{ "ld", RRM_PAIR(0,1,0,L3_SIGNED_FULLWORD) ,"[162],d", F_RRM,0},
{ "ld", RRM_PAIR(0,1,1,L3_SIGNED_FULLWORD) ,"[*162],d", F_RRM,0},
{ "ld", RRM_PAIR(0,0,1,L3_SIGNED_FULLWORD) ,"[1*62],d", F_RRM,0},
{ "ld", SLS_PAIR(0) ,"[Y],d", F_SLS,0},
{ "ld", 0x80020000,0x707d0000 ,"[o],d", F_RM,0},
/*{ "ld", RM_PAIR(0,1,0) ,"[o],d", F_RM,0},*/
{ "ld", RM_PAIR(0,1,0) ,"o[1],d", F_RM,0},
{ "ld", RM_PAIR(0,1,1) ,"o[*1],d", F_RM,0},
{ "ld", RM_PAIR(0,0,1) ,"o[1*],d", F_RM,0},
{ "uld", 0x80030004,0x7000fffb ,"[++1],d", F_ALIAS,0},
{ "uld", 0x80010004,0x7002fffb ,"[1++],d", F_ALIAS,0},
{ "uld", 0x8003fffc,0x70000003 ,"[--1],d", F_ALIAS,0},
{ "uld", 0x8001fffc,0x70020003 ,"[1--],d", F_ALIAS,0},
{ "uld", RRM_PAIR(0,1,0,L3_UNSIGNED_FULLWORD) ,"2[1],d", F_ALIAS,0},
{ "uld", RRM_PAIR(0,1,1,L3_UNSIGNED_FULLWORD) ,"2[*1],d", F_ALIAS,0},
{ "uld", RRM_PAIR(0,0,1,L3_UNSIGNED_FULLWORD) ,"2[1*],d", F_ALIAS,0},
{ "uld", RRM_PAIR(0,1,0,L3_UNSIGNED_FULLWORD) ,"[162],d", F_ALIAS,0},
{ "uld", RRM_PAIR(0,1,1,L3_UNSIGNED_FULLWORD) ,"[*162],d", F_ALIAS,0},
{ "uld", RRM_PAIR(0,0,1,L3_UNSIGNED_FULLWORD) ,"[1*62],d", F_ALIAS,0},
{ "uld", SLS_PAIR(0) ,"[Y],d", F_SLS|F_ALIAS,0},
/* Here, the second part of the RM_PAIR is wrong, but that's OK */
{ "uld", RM_PAIR(0,1,0) ,"[o],d", F_ALIAS,0},
{ "uld", RM_PAIR(0,1,0) ,"o[1],d", F_ALIAS,0},
{ "uld", RM_PAIR(0,1,1) ,"o[*1],d", F_ALIAS,0},
{ "uld", RM_PAIR(0,0,1) ,"o[1*],d", F_ALIAS,0},
{ "ld.h", 0xf0030c02,0x0000f3fd ,"[++1],d", F_HALF|F_SPLS,0},
{ "ld.h", 0xf0030402,0x0000fbfd ,"[1++],d", F_HALF|F_SPLS,0},
{ "ld.h", 0xf0030ffe,0x0000f001 ,"[--1],d", F_HALF|F_SPLS,0},
{ "ld.h", 0xf00307fe,0x0000f801 ,"[1--],d", F_HALF|F_SPLS,0},
{ "ld.h", RRM_PAIR(0,1,0,L3_SIGNED_HALFWORD) ,"2[1],d", F_HALF|F_RRM,0},
{ "ld.h", RRM_PAIR(0,1,1,L3_SIGNED_HALFWORD) ,"2[*1],d", F_HALF|F_RRM,0},
{ "ld.h", RRM_PAIR(0,0,1,L3_SIGNED_HALFWORD) ,"2[1*],d", F_HALF|F_RRM,0},
{ "ld.h", RRM_PAIR(0,1,0,L3_SIGNED_HALFWORD) ,"[162],d", F_HALF|F_RRM,0},
{ "ld.h", RRM_PAIR(0,1,1,L3_SIGNED_HALFWORD) ,"[*162],d", F_HALF|F_RRM,0},
{ "ld.h", RRM_PAIR(0,0,1,L3_SIGNED_HALFWORD) ,"[1*62],d", F_HALF|F_RRM,0},
{ "ld.h", 0xf0030800,0x007cf400 ,"[i],d", F_HALF|F_SPLS,0},
/*{ "ld.h", SPLS_PAIR(0,L3_SIGNED_HALFWORD,1,0) ,"[i],d", F_HALF|F_SPLS,0},*/
{ "ld.h", SPLS_PAIR(0,L3_SIGNED_HALFWORD,1,0) ,"i[1],d", F_HALF|F_SPLS,0},
{ "ld.h", SPLS_PAIR(0,L3_SIGNED_HALFWORD,1,1) ,"i[*1],d", F_HALF|F_SPLS,0},
{ "ld.h", SPLS_PAIR(0,L3_SIGNED_HALFWORD,0,1) ,"i[1*],d", F_HALF|F_SPLS,0},
{ "uld.h", 0xf0031c02,0x0000e3fd ,"[++1],d", F_HALF|F_SPLS,0},
{ "uld.h", 0xf0031402,0x0000ebfd ,"[1++],d", F_HALF|F_SPLS,0},
{ "uld.h", 0xf0031ffe,0x0000e001 ,"[--1],d", F_HALF|F_SPLS,0},
{ "uld.h", 0xf00317fe,0x0000e801 ,"[1--],d", F_HALF|F_SPLS,0},
{ "uld.h",RRM_PAIR(0,1,0,L3_UNSIGNED_HALFWORD),"2[1],d", F_HALF|F_RRM,0},
{ "uld.h",RRM_PAIR(0,1,1,L3_UNSIGNED_HALFWORD),"2[*1],d", F_HALF|F_RRM,0},
{ "uld.h",RRM_PAIR(0,0,1,L3_UNSIGNED_HALFWORD),"2[1*],d", F_HALF|F_RRM,0},
{ "uld.h",RRM_PAIR(0,1,0,L3_UNSIGNED_HALFWORD),"[162],d", F_HALF|F_RRM,0},
{ "uld.h",RRM_PAIR(0,1,1,L3_UNSIGNED_HALFWORD),"[*162],d", F_HALF|F_RRM,0},
{ "uld.h",RRM_PAIR(0,0,1,L3_UNSIGNED_HALFWORD),"[1*62],d", F_HALF|F_RRM,0},
{ "uld.h", 0xf0031800,0x007ce400 ,"[i],d", F_HALF|F_SPLS,0},
/*{ "uld.h",SPLS_PAIR(0,L3_UNSIGNED_HALFWORD,1,0),"[i],d", F_HALF|F_SPLS,0},*/
{ "uld.h",SPLS_PAIR(0,L3_UNSIGNED_HALFWORD,1,0),"i[1],d", F_HALF|F_SPLS,0},
{ "uld.h",SPLS_PAIR(0,L3_UNSIGNED_HALFWORD,1,1),"i[*1],d", F_HALF|F_SPLS,0},
{ "uld.h",SPLS_PAIR(0,L3_UNSIGNED_HALFWORD,0,1),"i[1*],d", F_HALF|F_SPLS,0},
{ "ld.b", 0xf0034c01,0x0000b3fe ,"[++1],d", F_BYTE|F_SPLS,0},
{ "ld.b", 0xf0034401,0x0000bbfe ,"[1++],d", F_BYTE|F_SPLS,0},
{ "ld.b", 0xf0034fff,0x0000b000 ,"[--1],d", F_BYTE|F_SPLS,0},
{ "ld.b", 0xf00347ff,0x0000b800 ,"[1--],d", F_BYTE|F_SPLS,0},
{ "ld.b", RRM_PAIR(0,1,0,L3_SIGNED_BYTE) ,"2[1],d", F_BYTE|F_RRM,0},
{ "ld.b", RRM_PAIR(0,1,1,L3_SIGNED_BYTE) ,"2[*1],d", F_BYTE|F_RRM,0},
{ "ld.b", RRM_PAIR(0,0,1,L3_SIGNED_BYTE) ,"2[1*],d", F_BYTE|F_RRM,0},
{ "ld.b", RRM_PAIR(0,1,0,L3_SIGNED_BYTE) ,"[162],d", F_BYTE|F_RRM,0},
{ "ld.b", RRM_PAIR(0,1,1,L3_SIGNED_BYTE) ,"[*162],d", F_BYTE|F_RRM,0},
{ "ld.b", RRM_PAIR(0,0,1,L3_SIGNED_BYTE) ,"[1*62],d", F_BYTE|F_RRM,0},
{ "ld.b", 0xf0034800,0x007cb400 ,"[i],d", F_BYTE|F_SPLS,0},
/*{ "ld.b", SPLS_PAIR(0,L3_SIGNED_BYTE,1,0) ,"[i],d", F_BYTE|F_SPLS,0},*/
{ "ld.b", SPLS_PAIR(0,L3_SIGNED_BYTE,1,0) ,"i[1],d", F_BYTE|F_SPLS,0},
{ "ld.b", SPLS_PAIR(0,L3_SIGNED_BYTE,1,1) ,"i[*1],d", F_BYTE|F_SPLS,0},
{ "ld.b", SPLS_PAIR(0,L3_SIGNED_BYTE,0,1) ,"i[1*],d", F_BYTE|F_SPLS,0},
{ "uld.b", 0xf0035c01,0x0000a3fe ,"[++1],d", F_BYTE|F_SPLS,0},
{ "uld.b", 0xf0035401,0x0000abfe ,"[1++],d", F_BYTE|F_SPLS,0},
{ "uld.b", 0xf0035fff,0x0000a000 ,"[--1],d", F_BYTE|F_SPLS,0},
{ "uld.b", 0xf00357ff,0x0000a800 ,"[1--],d", F_BYTE|F_SPLS,0},
{ "uld.b", RRM_PAIR(0,1,0,L3_UNSIGNED_BYTE) ,"2[1],d", F_BYTE|F_RRM,0},
{ "uld.b", RRM_PAIR(0,1,1,L3_UNSIGNED_BYTE) ,"2[*1],d", F_BYTE|F_RRM,0},
{ "uld.b", RRM_PAIR(0,0,1,L3_UNSIGNED_BYTE) ,"2[1*],d", F_BYTE|F_RRM,0},
{ "uld.b", RRM_PAIR(0,1,0,L3_UNSIGNED_BYTE) ,"[162],d", F_BYTE|F_RRM,0},
{ "uld.b", RRM_PAIR(0,1,1,L3_UNSIGNED_BYTE) ,"[*162],d", F_BYTE|F_RRM,0},
{ "uld.b", RRM_PAIR(0,0,1,L3_UNSIGNED_BYTE) ,"[1*62],d", F_BYTE|F_RRM,0},
{ "uld.b", 0xf0035800,0x007ca400 ,"[i],d", F_BYTE|F_SPLS,0},
/*{ "uld.b", SPLS_PAIR(0,L3_UNSIGNED_BYTE,1,0) ,"[i],d", F_BYTE|F_SPLS,0},*/
{ "uld.b", SPLS_PAIR(0,L3_UNSIGNED_BYTE,1,0) ,"i[1],d", F_BYTE|F_SPLS,0},
{ "uld.b", SPLS_PAIR(0,L3_UNSIGNED_BYTE,1,1) ,"i[*1],d", F_BYTE|F_SPLS,0},
{ "uld.b", SPLS_PAIR(0,L3_UNSIGNED_BYTE,0,1) ,"i[1*],d", F_BYTE|F_SPLS,0},
/* leadz */
{ "leadz", LEADZ_PAIR(0) ,"1,d", F_LEADZ,0},
{ "leadz.f", LEADZ_PAIR(1) ,"1,d", F_LEADZ,0},
/* or */
{ "or", RR_PAIR(0,L3_OR) ,"1,2,d", F_RR,0},
{ "or", RI_PAIR(L3_OR,0,0) ,"1,j,d", F_RI,0},
{ "or", RI_PAIR(L3_OR,0,1) ,"1,J,d", F_RI,0},
{ "or.f", RR_PAIR(1,L3_OR) ,"1,2,d", F_RR,0},
{ "or.f", RI_PAIR(L3_OR,1,0) ,"1,j,d", F_RI,0},
{ "or.f", RI_PAIR(L3_OR,1,1) ,"1,J,d", F_RI,0},
/* popc */
{ "popc", POPC_PAIR(0) ,"1,d", F_POPC,0},
{ "popc.f", POPC_PAIR(1) ,"1,d", F_POPC,0},
/* put */
{ "put", RRR_PAIR() ,"15(243),d",F_RRR, 0},
/* punt */
{ "punt", 0xf003ff47, 0x00000000 ,"", F_PUNT, 0},
/* sh */
{ "sh", RR_PAIR(0,L3_SH) ,"1,2,d", F_RR, 0},
{ "sh", RI_PAIR(L3_SH,0,0) ,"1,s,d", F_RI, 0},
{ "sh.f", RR_PAIR(1,L3_SH) ,"1,2,d", F_RR, 0},
{ "sh.f", RI_PAIR(L3_SH,1,0) ,"1,s,d", F_RI, 0},
{ "sha", RR_PAIR(0,L3_SH|L3_ARITH) ,"1,2,d", F_RR, 0},
{ "sha", RI_PAIR(L3_SH,0,1) ,"1,s,d", F_RI, 0},
{ "sha.f", RR_PAIR(1,L3_SH|L3_ARITH) ,"1,2,d", F_RR, 0},
{ "sha.f", RI_PAIR(L3_SH,1,1) ,"1,s,d", F_RI, 0},
/* st */
{ "st", 0x90030004,0x6000fffb ,"d,[++1]", F_RM,0},
{ "st", 0x90010004,0x6002fffb ,"d,[1++]", F_RM,0},
{ "st", 0x9003fffc,0x60000003 ,"d,[--1]", F_RM,0},
{ "st", 0x9001fffc,0x60020003 ,"d,[1--]", F_RM,0},
{ "st", RRM_PAIR(1,1,0,L3_SIGNED_FULLWORD) ,"d,2[1]", F_RRM,0},
{ "st", RRM_PAIR(1,1,1,L3_SIGNED_FULLWORD) ,"d,2[*1]", F_RRM,0},
{ "st", RRM_PAIR(1,0,1,L3_SIGNED_FULLWORD) ,"d,2[1*]", F_RRM,0},
{ "st", RRM_PAIR(1,1,0,L3_SIGNED_FULLWORD) ,"d,[162]", F_RRM,0},
{ "st", RRM_PAIR(1,1,1,L3_SIGNED_FULLWORD) ,"d,[*162]", F_RRM,0},
{ "st", RRM_PAIR(1,0,1,L3_SIGNED_FULLWORD) ,"d,[1*62]", F_RRM,0},
{ "st", SLS_PAIR(1) ,"d,[Y]", F_SLS,0},
{ "st", 0x90020000,0x607d0000 ,"d,[o]", F_RM,0},
/*{ "st", RM_PAIR(1,1,0) ,"d,[o]", F_RM,0},*/
{ "st", RM_PAIR(1,1,0) ,"d,o[1]", F_RM,0},
{ "st", RM_PAIR(1,1,1) ,"d,o[*1]", F_RM,0},
{ "st", RM_PAIR(1,0,1) ,"d,o[1*]", F_RM,0},
{ "st.h", 0xf0032c02,0x0000d3fd ,"d,[++1]", F_HALF|F_SPLS,0},
{ "st.h", 0xf0032402,0x0000dbfd ,"d,[1++]", F_HALF|F_SPLS,0},
{ "st.h", 0xf0032ffe,0x0000d001 ,"d,[--1]", F_HALF|F_SPLS,0},
{ "st.h", 0xf00327fe,0x0000d801 ,"d,[1--]", F_HALF|F_SPLS,0},
{ "st.h", RRM_PAIR(1,1,0,L3_SIGNED_HALFWORD) ,"d,2[1]", F_HALF|F_RRM,0},
{ "st.h", RRM_PAIR(1,1,1,L3_SIGNED_HALFWORD) ,"d,2[*1]", F_HALF|F_RRM,0},
{ "st.h", RRM_PAIR(1,0,1,L3_SIGNED_HALFWORD) ,"d,2[1*]", F_HALF|F_RRM,0},
{ "st.h", RRM_PAIR(1,1,0,L3_SIGNED_HALFWORD) ,"d,[162]", F_HALF|F_RRM,0},
{ "st.h", RRM_PAIR(1,1,1,L3_SIGNED_HALFWORD) ,"d,[*162]", F_HALF|F_RRM,0},
{ "st.h", RRM_PAIR(1,0,1,L3_SIGNED_HALFWORD) ,"d,[1*62]", F_HALF|F_RRM,0},
{ "st.h", 0xf0032800,0x007cd400 ,"d,[i]", F_HALF|F_SPLS,0},
/*{ "st.h", SPLS_PAIR(1,L3_SIGNED_HALFWORD,1,0) ,"d,[i]", F_HALF|F_SPLS,0},*/
{ "st.h", SPLS_PAIR(1,L3_SIGNED_HALFWORD,1,0) ,"d,i[1]", F_HALF|F_SPLS,0},
{ "st.h", SPLS_PAIR(1,L3_SIGNED_HALFWORD,1,1) ,"d,i[*1]", F_HALF|F_SPLS,0},
{ "st.h", SPLS_PAIR(1,L3_SIGNED_HALFWORD,0,1) ,"d,i[1*]", F_HALF|F_SPLS,0},
{ "st.b", 0xf0036c01,0x000093fe ,"d,[++1]", F_BYTE|F_SPLS,0},
{ "st.b", 0xf0036401,0x00009bfe ,"d,[1++]", F_BYTE|F_SPLS,0},
{ "st.b", 0xf0036fff,0x00009000 ,"d,[--1]", F_BYTE|F_SPLS,0},
{ "st.b", 0xf00367ff,0x00009800 ,"d,[1--]", F_BYTE|F_SPLS,0},
{ "st.b", RRM_PAIR(1,1,0,L3_SIGNED_BYTE) ,"d,2[1]", F_BYTE|F_RRM,0},
{ "st.b", RRM_PAIR(1,1,1,L3_SIGNED_BYTE) ,"d,2[*1]", F_BYTE|F_RRM,0},
{ "st.b", RRM_PAIR(1,0,1,L3_SIGNED_BYTE) ,"d,2[1*]", F_BYTE|F_RRM,0},
{ "st.b", RRM_PAIR(1,1,0,L3_SIGNED_BYTE) ,"d,[162]", F_BYTE|F_RRM,0},
{ "st.b", RRM_PAIR(1,1,1,L3_SIGNED_BYTE) ,"d,[*162]", F_BYTE|F_RRM,0},
{ "st.b", RRM_PAIR(1,0,1,L3_SIGNED_BYTE) ,"d,[1*62]", F_BYTE|F_RRM,0},
{ "st.b", 0xf0036800,0x007c9400 ,"d,[i]", F_BYTE|F_SPLS,0},
/*{ "st.b", SPLS_PAIR(1,L3_SIGNED_BYTE,1,0) ,"d,[i]", F_BYTE|F_SPLS,0},*/
{ "st.b", SPLS_PAIR(1,L3_SIGNED_BYTE,1,0) ,"d,i[1]", F_BYTE|F_SPLS,0},
{ "st.b", SPLS_PAIR(1,L3_SIGNED_BYTE,1,1) ,"d,i[*1]", F_BYTE|F_SPLS,0},
{ "st.b", SPLS_PAIR(1,L3_SIGNED_BYTE,0,1) ,"d,i[1*]", F_BYTE|F_SPLS,0},
/* sub */
{ "sub", RR_PAIR(0,L3_SUB) ,"1,2,d", F_RR,0},
{ "sub", RI_PAIR(L3_SUB,0,0) ,"1,j,d", F_RI,0},
{ "sub", RI_PAIR(L3_SUB,0,1) ,"1,J,d", F_RI,0},
/*{ "sub", RI_PAIR(L3_ADD,0,0) ,"1,k,d", F_ALIAS,0}, */
{ "sub.f", RR_PAIR(1,L3_SUB) ,"1,2,d", F_RR,0},
{ "sub.f", RI_PAIR(L3_SUB,1,0) ,"1,j,d", F_RI,0},
{ "sub.f", RI_PAIR(L3_SUB,1,1) ,"1,J,d", F_RI,0},
/*{ "sub.f", RI_PAIR(L3_ADD,1,0) ,"1,k,d", F_ALIAS,0}, */
{ "subb", RR_PAIR(0,L3_SUBB) ,"1,2,d", F_RR,0},
{ "subb", RI_PAIR(L3_SUBB,0,0) ,"1,j,d", F_RI,0},
{ "subb", RI_PAIR(L3_SUBB,0,1) ,"1,J,d", F_RI,0},
/*{ "subb", RI_PAIR(L3_ADDC,0,0) ,"1,k,d", F_ALIAS,0}, */
{ "subb.f", RR_PAIR(1,L3_SUBB) ,"1,2,d", F_RR,0},
{ "subb.f", RI_PAIR(L3_SUBB,1,0) ,"1,j,d", F_RI,0},
{ "subb.f", RI_PAIR(L3_SUBB,1,1) ,"1,J,d", F_RI,0},
/*{ "subb.f", RI_PAIR(L3_ADDC,1,0) ,"1,k,d", F_ALIAS,0}, */
/* sCC */
{ "shi", SCC_PAIR(L3_HI) ,"1", F_SCC|F_ALIAS,0},
{ "sugt", SCC_PAIR(L3_HI) ,"1", F_SCC,0},
{ "sls", SCC_PAIR(L3_LS) ,"1", F_SCC|F_ALIAS,0},
{ "sule", SCC_PAIR(L3_LS) ,"1", F_SCC,0},
{ "scc", SCC_PAIR(L3_CC) ,"1", F_SCC|F_ALIAS,0},
{ "suge", SCC_PAIR(L3_CS) ,"1", F_SCC,0},
{ "scs", SCC_PAIR(L3_CS) ,"1", F_SCC|F_ALIAS,0},
{ "sult", SCC_PAIR(L3_CC) ,"1", F_SCC,0},
{ "sne", SCC_PAIR(L3_NE) ,"1", F_SCC,0},
{ "seq", SCC_PAIR(L3_EQ) ,"1", F_SCC,0},
{ "svc", SCC_PAIR(L3_VC) ,"1", F_SCC,0},
{ "svs", SCC_PAIR(L3_VS) ,"1", F_SCC,0},
{ "spl", SCC_PAIR(L3_PL) ,"1", F_SCC,0},
{ "smi", SCC_PAIR(L3_MI) ,"1", F_SCC,0},
{ "sge", SCC_PAIR(L3_GE) ,"1", F_SCC,0},
{ "slt", SCC_PAIR(L3_LT) ,"1", F_SCC,0},
{ "sgt", SCC_PAIR(L3_GT) ,"1", F_SCC,0},
{ "sle", SCC_PAIR(L3_LE) ,"1", F_SCC,0},
/* xor */
{ "xor", RR_PAIR(0,L3_XOR) ,"1,2,d", F_RR,0},
{ "xor", RI_PAIR(L3_XOR,0,0) ,"1,j,d", F_RI,0},
{ "xor", RI_PAIR(L3_XOR,0,1) ,"1,J,d", F_RI,0},
{ "xor.f", RR_PAIR(1,L3_XOR) ,"1,2,d", F_RR,0},
{ "xor.f", RI_PAIR(L3_XOR,1,0) ,"1,j,d", F_RI,0},
{ "xor.f", RI_PAIR(L3_XOR,1,1) ,"1,J,d", F_RI,0},
};
const int bfd_lanai_num_opcodes = ((sizeof lanai_opcodes)/(sizeof lanai_opcodes[0]));

105
libr/asm/p/asm_lanai_gnu.c Normal file
View File

@ -0,0 +1,105 @@
/* radare - LGPL - Copyright 2016 - pancake */
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <r_types.h>
#include <r_lib.h>
#include <r_util.h>
#include <r_asm.h>
#include "dis-asm.h"
static unsigned long Offset = 0;
static char *buf_global = NULL;
static unsigned char bytes[4];
static int lanai_buffer_read_memory (bfd_vma memaddr, bfd_byte *myaddr, ut32 length, struct disassemble_info *info) {
memcpy (myaddr, bytes, length);
return 0;
}
static int symbol_at_address(bfd_vma addr, struct disassemble_info * info) {
return 0;
}
static void memory_error_func(int status, bfd_vma memaddr, struct disassemble_info *info) {
//--
}
static void print_address(bfd_vma address, struct disassemble_info *info) {
char tmp[32];
if (buf_global == NULL)
return;
sprintf(tmp, "0x%08"PFMT64x"", (ut64)address);
strcat(buf_global, tmp);
}
static int buf_fprintf(void *stream, const char *format, ...) {
int flen, glen;
va_list ap;
char *tmp;
if (buf_global == NULL)
return 0;
va_start (ap, format);
flen = strlen (format);
glen = strlen (buf_global);
tmp = malloc (flen + glen + 2);
memcpy (tmp, buf_global, glen);
memcpy (tmp+glen, format, flen);
tmp[flen+glen] = 0;
// XXX: overflow here?
vsprintf (buf_global, tmp, ap);
va_end (ap);
free (tmp);
return 0;
}
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
struct disassemble_info disasm_obj;
op->buf_asm[0]='\0';
if (len<4)
return -1;
buf_global = op->buf_asm;
Offset = a->pc;
memcpy (bytes, buf, 4); // TODO handle thumb
/* prepare disassembler */
memset (&disasm_obj, '\0', sizeof (struct disassemble_info));
disasm_obj.disassembler_options = (a->bits==64)? "64": "";
disasm_obj.buffer = bytes;
disasm_obj.read_memory_func = &lanai_buffer_read_memory;
disasm_obj.symbol_at_address_func = &symbol_at_address;
disasm_obj.memory_error_func = &memory_error_func;
disasm_obj.print_address_func = &print_address;
disasm_obj.endian = !a->big_endian;
disasm_obj.fprintf_func = &buf_fprintf;
disasm_obj.stream = stdout;
op->size = print_insn_lanai ((bfd_vma)Offset, &disasm_obj);
if (op->size == -1)
strncpy (op->buf_asm, " (data)", R_ASM_BUFSIZE);
return op->size;
}
RAsmPlugin r_asm_plugin_lanai_gnu = {
.name = "lanai", // .gnu",
.arch = "lanai",
.license = "GPL3",
.bits = 32,
.desc = "LANAI",
.disassemble = &disassemble,
0
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_lanai_gnu,
.version = R2_VERSION
};
#endif

14
libr/asm/p/lanai_gnu.mk Normal file
View File

@ -0,0 +1,14 @@
OBJ_LANAI=asm_lanai_gnu.o
OBJ_LANAI+=../arch/lanai/gnu/lanai-dis.o
OBJ_LANAI+=../arch/lanai/gnu/lanai-opc.o
STATIC_OBJ+=${OBJ_LANAI}
TARGET_LANAI=asm_lanai_gnu.${EXT_SO}
ifeq ($(WITHPIC),1)
ALL_TARGETS+=${TARGET_LANAI}
${TARGET_LANAI}: ${OBJ_LANAI}
${CC} $(call libname,asm_lanai) ${LDFLAGS} ${CFLAGS} \
-o asm_lanai_gnu.${EXT_SO} ${OBJ_LANAI}
endif

View File

@ -222,6 +222,7 @@ extern RAsmPlugin r_asm_plugin_mcs96;
extern RAsmPlugin r_asm_plugin_lm32;
extern RAsmPlugin r_asm_plugin_riscv;
extern RAsmPlugin r_asm_plugin_vax;
extern RAsmPlugin r_asm_plugin_lanai_gnu;
extern RAsmPlugin r_asm_plugin_xtensa;
extern RAsmPlugin r_asm_plugin_tricore;
#endif

View File

@ -75,6 +75,7 @@ asm.ppc_cs
asm.ppc_gnu
asm.rar
asm.riscv
asm.lanai_gnu
asm.sh
asm.snes
asm.sparc_cs