mirror of
https://github.com/radareorg/radare2.git
synced 2024-10-08 19:33:31 +00:00
Initial support for LANAI disassembler
This commit is contained in:
parent
073e08321a
commit
cdf63617d7
400
libr/asm/arch/include/opcode/lanai.h
Normal file
400
libr/asm/arch/include/opcode/lanai.h
Normal 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 */
|
7
libr/asm/arch/lanai/Makefile
Normal file
7
libr/asm/arch/lanai/Makefile
Normal 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
|
||||
|
505
libr/asm/arch/lanai/gnu/lanai-dis.c
Normal file
505
libr/asm/arch/lanai/gnu/lanai-dis.c
Normal 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;
|
||||
}
|
578
libr/asm/arch/lanai/gnu/lanai-opc.c
Normal file
578
libr/asm/arch/lanai/gnu/lanai-opc.c
Normal 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
105
libr/asm/p/asm_lanai_gnu.c
Normal 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
14
libr/asm/p/lanai_gnu.mk
Normal 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
|
@ -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
|
||||
|
@ -75,6 +75,7 @@ asm.ppc_cs
|
||||
asm.ppc_gnu
|
||||
asm.rar
|
||||
asm.riscv
|
||||
asm.lanai_gnu
|
||||
asm.sh
|
||||
asm.snes
|
||||
asm.sparc_cs
|
||||
|
Loading…
Reference in New Issue
Block a user