Remove NIOS-II architecture (#4457)
This commit is contained in:
parent
c2e0348437
commit
9526b6c0bc
8 changed files with 1 additions and 1541 deletions
|
|
@ -1,508 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2012, 2013 Free Software Foundation, Inc.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* Nios II opcode list for GAS, the GNU assembler.
|
||||
Copyright (C) 2012, 2013 Free Software Foundation, Inc.
|
||||
Contributed by Nigel Gray (ngray@altera.com).
|
||||
Contributed by Mentor Graphics, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler, and GDB, the GNU disassembler.
|
||||
|
||||
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 3, 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 COPYING3. If not, write to
|
||||
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef _NIOS2_H_
|
||||
#define _NIOS2_H_
|
||||
|
||||
#include <common_gnu/mybfd.h>
|
||||
|
||||
/****************************************************************************
|
||||
* This file contains structures, bit masks and shift counts used
|
||||
* by the GNU toolchain to define the Nios II instruction set and
|
||||
* access various opcode fields.
|
||||
****************************************************************************/
|
||||
|
||||
/* Identify different overflow situations for error messages. */
|
||||
enum overflow_type {
|
||||
call_target_overflow = 0,
|
||||
branch_target_overflow,
|
||||
address_offset_overflow,
|
||||
signed_immed16_overflow,
|
||||
unsigned_immed16_overflow,
|
||||
unsigned_immed5_overflow,
|
||||
custom_opcode_overflow,
|
||||
no_overflow
|
||||
};
|
||||
|
||||
/* This structure holds information for a particular instruction.
|
||||
|
||||
The args field is a string describing the operands. The following
|
||||
letters can appear in the args:
|
||||
c - a 5-bit control register index
|
||||
d - a 5-bit destination register index
|
||||
s - a 5-bit left source register index
|
||||
t - a 5-bit right source register index
|
||||
i - a 16-bit signed immediate
|
||||
u - a 16-bit unsigned immediate
|
||||
o - a 16-bit signed program counter relative offset
|
||||
j - a 5-bit unsigned immediate
|
||||
b - a 5-bit break instruction constant
|
||||
l - a 8-bit custom instruction constant
|
||||
m - a 26-bit unsigned immediate
|
||||
Literal ',', '(', and ')' characters may also appear in the args as
|
||||
delimiters.
|
||||
|
||||
The pinfo field is INSN_MACRO for a macro. Otherwise, it is a collection
|
||||
of bits describing the instruction, notably any relevant hazard
|
||||
information.
|
||||
|
||||
When assembling, the match field contains the opcode template, which
|
||||
is modified by the arguments to produce the actual opcode
|
||||
that is emitted. If pinfo is INSN_MACRO, then this is 0.
|
||||
|
||||
If pinfo is INSN_MACRO, the mask field stores the macro identifier.
|
||||
Otherwise this is a bit mask for the relevant portions of the opcode
|
||||
when disassembling. If the actual opcode anded with the match field
|
||||
equals the opcode field, then we have found the correct instruction. */
|
||||
|
||||
struct nios2_opcode {
|
||||
const char *name; /* The name of the instruction. */
|
||||
const char *args; /* A string describing the arguments for this
|
||||
instruction. */
|
||||
const char *args_test; /* Like args, but with an extra argument for
|
||||
the expected opcode. */
|
||||
unsigned long num_args; /* The number of arguments the instruction
|
||||
takes. */
|
||||
unsigned long match; /* The basic opcode for the instruction. */
|
||||
unsigned long mask; /* Mask for the opcode field of the
|
||||
instruction. */
|
||||
unsigned long pinfo; /* Is this a real instruction or instruction
|
||||
macro? */
|
||||
enum overflow_type overflow_msg; /* Used to generate informative
|
||||
message when fixup overflows. */
|
||||
};
|
||||
|
||||
/* This value is used in the nios2_opcode.pinfo field to indicate that the
|
||||
instruction is a macro or pseudo-op. This requires special treatment by
|
||||
the assembler, and is used by the disassembler to determine whether to
|
||||
check for a nop. */
|
||||
#define NIOS2_INSN_MACRO 0x80000000
|
||||
#define NIOS2_INSN_MACRO_MOV 0x80000001
|
||||
#define NIOS2_INSN_MACRO_MOVI 0x80000002
|
||||
#define NIOS2_INSN_MACRO_MOVIA 0x80000004
|
||||
|
||||
#define NIOS2_INSN_RELAXABLE 0x40000000
|
||||
#define NIOS2_INSN_UBRANCH 0x00000010
|
||||
#define NIOS2_INSN_CBRANCH 0x00000020
|
||||
#define NIOS2_INSN_CALL 0x00000040
|
||||
|
||||
#define NIOS2_INSN_ADDI 0x00000080
|
||||
#define NIOS2_INSN_ANDI 0x00000100
|
||||
#define NIOS2_INSN_ORI 0x00000200
|
||||
#define NIOS2_INSN_XORI 0x00000400
|
||||
|
||||
/* Associates a register name ($6) with a 5-bit index (eg 6). */
|
||||
struct nios2_reg {
|
||||
const char *name;
|
||||
const int index;
|
||||
};
|
||||
|
||||
/* These are bit masks and shift counts for accessing the various
|
||||
fields of a Nios II instruction. */
|
||||
|
||||
/* Macros for getting and setting an instruction field. */
|
||||
#define GET_INSN_FIELD(X, i) \
|
||||
(((i)&OP_MASK_##X) >> OP_SH_##X)
|
||||
#define SET_INSN_FIELD(X, i, j) \
|
||||
((i) = (((i) & ~OP_MASK_##X) | (((j) << OP_SH_##X) & OP_MASK_##X)))
|
||||
|
||||
/* Instruction field definitions. */
|
||||
#define IW_A_LSB 27
|
||||
#define IW_A_MSB 31
|
||||
#define IW_A_SZ 5
|
||||
#define IW_A_MASK 0x1f
|
||||
|
||||
#define IW_B_LSB 22
|
||||
#define IW_B_MSB 26
|
||||
#define IW_B_SZ 5
|
||||
#define IW_B_MASK 0x1f
|
||||
|
||||
#define IW_C_LSB 17
|
||||
#define IW_C_MSB 21
|
||||
#define IW_C_SZ 5
|
||||
#define IW_C_MASK 0x1f
|
||||
|
||||
#define IW_IMM16_LSB 6
|
||||
#define IW_IMM16_MSB 21
|
||||
#define IW_IMM16_SZ 16
|
||||
#define IW_IMM16_MASK 0xffff
|
||||
|
||||
#define IW_IMM26_LSB 6
|
||||
#define IW_IMM26_MSB 31
|
||||
#define IW_IMM26_SZ 26
|
||||
#define IW_IMM26_MASK 0x3ffffff
|
||||
|
||||
#define IW_OP_LSB 0
|
||||
#define IW_OP_MSB 5
|
||||
#define IW_OP_SZ 6
|
||||
#define IW_OP_MASK 0x3f
|
||||
|
||||
#define IW_OPX_LSB 11
|
||||
#define IW_OPX_MSB 16
|
||||
#define IW_OPX_SZ 6
|
||||
#define IW_OPX_MASK 0x3f
|
||||
|
||||
#define IW_SHIFT_IMM5_LSB 6
|
||||
#define IW_SHIFT_IMM5_MSB 10
|
||||
#define IW_SHIFT_IMM5_SZ 5
|
||||
#define IW_SHIFT_IMM5_MASK 0x1f
|
||||
|
||||
#define IW_CONTROL_REGNUM_LSB 6
|
||||
#define IW_CONTROL_REGNUM_MSB 9
|
||||
#define IW_CONTROL_REGNUM_SZ 4
|
||||
#define IW_CONTROL_REGNUM_MASK 0xf
|
||||
|
||||
/* Operator mask and shift. */
|
||||
#define OP_MASK_OP (IW_OP_MASK << IW_OP_LSB)
|
||||
#define OP_SH_OP IW_OP_LSB
|
||||
|
||||
/* Masks and shifts for I-type instructions. */
|
||||
#define OP_MASK_IOP (IW_OP_MASK << IW_OP_LSB)
|
||||
#define OP_SH_IOP IW_OP_LSB
|
||||
|
||||
#define OP_MASK_IMM16 (IW_IMM16_MASK << IW_IMM16_LSB)
|
||||
#define OP_SH_IMM16 IW_IMM16_LSB
|
||||
|
||||
#define OP_MASK_IRD (IW_B_MASK << IW_B_LSB)
|
||||
#define OP_SH_IRD IW_B_LSB /* The same as T for I-type. */
|
||||
|
||||
#define OP_MASK_IRT (IW_B_MASK << IW_B_LSB)
|
||||
#define OP_SH_IRT IW_B_LSB
|
||||
|
||||
#define OP_MASK_IRS (IW_A_MASK << IW_A_LSB)
|
||||
#define OP_SH_IRS IW_A_LSB
|
||||
|
||||
/* Masks and shifts for R-type instructions. */
|
||||
#define OP_MASK_ROP (IW_OP_MASK << IW_OP_LSB)
|
||||
#define OP_SH_ROP IW_OP_LSB
|
||||
|
||||
#define OP_MASK_ROPX (IW_OPX_MASK << IW_OPX_LSB)
|
||||
#define OP_SH_ROPX IW_OPX_LSB
|
||||
|
||||
#define OP_MASK_RRD (IW_C_MASK << IW_C_LSB)
|
||||
#define OP_SH_RRD IW_C_LSB
|
||||
|
||||
#define OP_MASK_RRT (IW_B_MASK << IW_B_LSB)
|
||||
#define OP_SH_RRT IW_B_LSB
|
||||
|
||||
#define OP_MASK_RRS (IW_A_MASK << IW_A_LSB)
|
||||
#define OP_SH_RRS IW_A_LSB
|
||||
|
||||
/* Masks and shifts for J-type instructions. */
|
||||
#define OP_MASK_JOP (IW_OP_MASK << IW_OP_LSB)
|
||||
#define OP_SH_JOP IW_OP_LSB
|
||||
|
||||
#define OP_MASK_IMM26 (IW_IMM26_MASK << IW_IMM26_LSB)
|
||||
#define OP_SH_IMM26 IW_IMM26_LSB
|
||||
|
||||
/* Masks and shifts for CTL instructions. */
|
||||
#define OP_MASK_RCTL 0x000007c0
|
||||
#define OP_SH_RCTL 6
|
||||
|
||||
/* Break instruction imm5 field. */
|
||||
#define OP_MASK_TRAP_IMM5 0x000007c0
|
||||
#define OP_SH_TRAP_IMM5 6
|
||||
|
||||
/* Instruction imm5 field. */
|
||||
#define OP_MASK_IMM5 (IW_SHIFT_IMM5_MASK << IW_SHIFT_IMM5_LSB)
|
||||
#define OP_SH_IMM5 IW_SHIFT_IMM5_LSB
|
||||
|
||||
/* Cache operation fields (type j,i(s)). */
|
||||
#define OP_MASK_CACHE_OPX (IW_B_MASK << IW_B_LSB)
|
||||
#define OP_SH_CACHE_OPX IW_B_LSB
|
||||
#define OP_MASK_CACHE_RRS (IW_A_MASK << IW_A_LSB)
|
||||
#define OP_SH_CACHE_RRS IW_A_LSB
|
||||
|
||||
/* Custom instruction masks. */
|
||||
#define OP_MASK_CUSTOM_A 0x00010000
|
||||
#define OP_SH_CUSTOM_A 16
|
||||
|
||||
#define OP_MASK_CUSTOM_B 0x00008000
|
||||
#define OP_SH_CUSTOM_B 15
|
||||
|
||||
#define OP_MASK_CUSTOM_C 0x00004000
|
||||
#define OP_SH_CUSTOM_C 14
|
||||
|
||||
#define OP_MASK_CUSTOM_N 0x00003fc0
|
||||
#define OP_SH_CUSTOM_N 6
|
||||
#define OP_MAX_CUSTOM_N 255
|
||||
|
||||
/* OP instruction values. */
|
||||
#define OP_ADDI 4
|
||||
#define OP_ANDHI 44
|
||||
#define OP_ANDI 12
|
||||
#define OP_BEQ 38
|
||||
#define OP_BGE 14
|
||||
#define OP_BGEU 46
|
||||
#define OP_BLT 22
|
||||
#define OP_BLTU 54
|
||||
#define OP_BNE 30
|
||||
#define OP_BR 6
|
||||
#define OP_CALL 0
|
||||
#define OP_CMPEQI 32
|
||||
#define OP_CMPGEI 8
|
||||
#define OP_CMPGEUI 40
|
||||
#define OP_CMPLTI 16
|
||||
#define OP_CMPLTUI 48
|
||||
#define OP_CMPNEI 24
|
||||
#define OP_CUSTOM 50
|
||||
#define OP_FLUSHD 59
|
||||
#define OP_FLUSHDA 27
|
||||
#define OP_INITD 51
|
||||
#define OP_INITDA 19
|
||||
#define OP_JMPI 1
|
||||
#define OP_LDB 7
|
||||
#define OP_LDBIO 39
|
||||
#define OP_LDBU 3
|
||||
#define OP_LDBUIO 35
|
||||
#define OP_LDH 15
|
||||
#define OP_LDHIO 47
|
||||
#define OP_LDHU 11
|
||||
#define OP_LDHUIO 43
|
||||
#define OP_LDL 31
|
||||
#define OP_LDW 23
|
||||
#define OP_LDWIO 55
|
||||
#define OP_MULI 36
|
||||
#define OP_OPX 58
|
||||
#define OP_ORHI 52
|
||||
#define OP_ORI 20
|
||||
#define OP_RDPRS 56
|
||||
#define OP_STB 5
|
||||
#define OP_STBIO 37
|
||||
#define OP_STC 29
|
||||
#define OP_STH 13
|
||||
#define OP_STHIO 45
|
||||
#define OP_STW 21
|
||||
#define OP_STWIO 53
|
||||
#define OP_XORHI 60
|
||||
#define OP_XORI 28
|
||||
|
||||
/* OPX instruction values. */
|
||||
#define OPX_ADD 49
|
||||
#define OPX_AND 14
|
||||
#define OPX_BREAK 52
|
||||
#define OPX_BRET 9
|
||||
#define OPX_CALLR 29
|
||||
#define OPX_CMPEQ 32
|
||||
#define OPX_CMPGE 8
|
||||
#define OPX_CMPGEU 40
|
||||
#define OPX_CMPLT 16
|
||||
#define OPX_CMPLTU 48
|
||||
#define OPX_CMPNE 24
|
||||
#define OPX_CRST 62
|
||||
#define OPX_DIV 37
|
||||
#define OPX_DIVU 36
|
||||
#define OPX_ERET 1
|
||||
#define OPX_FLUSHI 12
|
||||
#define OPX_FLUSHP 4
|
||||
#define OPX_HBREAK 53
|
||||
#define OPX_INITI 41
|
||||
#define OPX_INTR 61
|
||||
#define OPX_JMP 13
|
||||
#define OPX_MUL 39
|
||||
#define OPX_MULXSS 31
|
||||
#define OPX_MULXSU 23
|
||||
#define OPX_MULXUU 7
|
||||
#define OPX_NEXTPC 28
|
||||
#define OPX_NOR 6
|
||||
#define OPX_OR 22
|
||||
#define OPX_RDCTL 38
|
||||
#define OPX_RET 5
|
||||
#define OPX_ROL 3
|
||||
#define OPX_ROLI 2
|
||||
#define OPX_ROR 11
|
||||
#define OPX_SLL 19
|
||||
#define OPX_SLLI 18
|
||||
#define OPX_SRA 59
|
||||
#define OPX_SRAI 58
|
||||
#define OPX_SRL 27
|
||||
#define OPX_SRLI 26
|
||||
#define OPX_SUB 57
|
||||
#define OPX_SYNC 54
|
||||
#define OPX_TRAP 45
|
||||
#define OPX_WRCTL 46
|
||||
#define OPX_WRPRS 20
|
||||
#define OPX_XOR 30
|
||||
|
||||
/* The following macros define the opcode matches for each
|
||||
instruction code & OP_MASK_INST == OP_MATCH_INST. */
|
||||
|
||||
/* OP instruction matches. */
|
||||
#define OP_MATCH_ADDI OP_ADDI
|
||||
#define OP_MATCH_ANDHI OP_ANDHI
|
||||
#define OP_MATCH_ANDI OP_ANDI
|
||||
#define OP_MATCH_BEQ OP_BEQ
|
||||
#define OP_MATCH_BGE OP_BGE
|
||||
#define OP_MATCH_BGEU OP_BGEU
|
||||
#define OP_MATCH_BLT OP_BLT
|
||||
#define OP_MATCH_BLTU OP_BLTU
|
||||
#define OP_MATCH_BNE OP_BNE
|
||||
#define OP_MATCH_BR OP_BR
|
||||
#define OP_MATCH_FLUSHD OP_FLUSHD
|
||||
#define OP_MATCH_FLUSHDA OP_FLUSHDA
|
||||
#define OP_MATCH_INITD OP_INITD
|
||||
#define OP_MATCH_INITDA OP_INITDA
|
||||
#define OP_MATCH_CALL OP_CALL
|
||||
#define OP_MATCH_CMPEQI OP_CMPEQI
|
||||
#define OP_MATCH_CMPGEI OP_CMPGEI
|
||||
#define OP_MATCH_CMPGEUI OP_CMPGEUI
|
||||
#define OP_MATCH_CMPLTI OP_CMPLTI
|
||||
#define OP_MATCH_CMPLTUI OP_CMPLTUI
|
||||
#define OP_MATCH_CMPNEI OP_CMPNEI
|
||||
#define OP_MATCH_JMPI OP_JMPI
|
||||
#define OP_MATCH_LDB OP_LDB
|
||||
#define OP_MATCH_LDBIO OP_LDBIO
|
||||
#define OP_MATCH_LDBU OP_LDBU
|
||||
#define OP_MATCH_LDBUIO OP_LDBUIO
|
||||
#define OP_MATCH_LDH OP_LDH
|
||||
#define OP_MATCH_LDHIO OP_LDHIO
|
||||
#define OP_MATCH_LDHU OP_LDHU
|
||||
#define OP_MATCH_LDHUIO OP_LDHUIO
|
||||
#define OP_MATCH_LDL OP_LDL
|
||||
#define OP_MATCH_LDW OP_LDW
|
||||
#define OP_MATCH_LDWIO OP_LDWIO
|
||||
#define OP_MATCH_MULI OP_MULI
|
||||
#define OP_MATCH_OPX OP_OPX
|
||||
#define OP_MATCH_ORHI OP_ORHI
|
||||
#define OP_MATCH_ORI OP_ORI
|
||||
#define OP_MATCH_RDPRS OP_RDPRS
|
||||
#define OP_MATCH_STB OP_STB
|
||||
#define OP_MATCH_STBIO OP_STBIO
|
||||
#define OP_MATCH_STC OP_STC
|
||||
#define OP_MATCH_STH OP_STH
|
||||
#define OP_MATCH_STHIO OP_STHIO
|
||||
#define OP_MATCH_STW OP_STW
|
||||
#define OP_MATCH_STWIO OP_STWIO
|
||||
#define OP_MATCH_CUSTOM OP_CUSTOM
|
||||
#define OP_MATCH_XORHI OP_XORHI
|
||||
#define OP_MATCH_XORI OP_XORI
|
||||
#define OP_MATCH_OPX OP_OPX
|
||||
|
||||
/* OPX instruction values. */
|
||||
#define OPX_MATCH(code) ((code << IW_OPX_LSB) | OP_OPX)
|
||||
|
||||
#define OP_MATCH_ADD OPX_MATCH(OPX_ADD)
|
||||
#define OP_MATCH_AND OPX_MATCH(OPX_AND)
|
||||
#define OP_MATCH_BREAK ((0x1e << 17) | OPX_MATCH(OPX_BREAK))
|
||||
#define OP_MATCH_BRET (0xf0000000 | OPX_MATCH(OPX_BRET))
|
||||
#define OP_MATCH_CALLR ((0x1f << 17) | OPX_MATCH(OPX_CALLR))
|
||||
#define OP_MATCH_CMPEQ OPX_MATCH(OPX_CMPEQ)
|
||||
#define OP_MATCH_CMPGE OPX_MATCH(OPX_CMPGE)
|
||||
#define OP_MATCH_CMPGEU OPX_MATCH(OPX_CMPGEU)
|
||||
#define OP_MATCH_CMPLT OPX_MATCH(OPX_CMPLT)
|
||||
#define OP_MATCH_CMPLTU OPX_MATCH(OPX_CMPLTU)
|
||||
#define OP_MATCH_CMPNE OPX_MATCH(OPX_CMPNE)
|
||||
#define OP_MATCH_DIV OPX_MATCH(OPX_DIV)
|
||||
#define OP_MATCH_DIVU OPX_MATCH(OPX_DIVU)
|
||||
#define OP_MATCH_JMP OPX_MATCH(OPX_JMP)
|
||||
#define OP_MATCH_MUL OPX_MATCH(OPX_MUL)
|
||||
#define OP_MATCH_MULXSS OPX_MATCH(OPX_MULXSS)
|
||||
#define OP_MATCH_MULXSU OPX_MATCH(OPX_MULXSU)
|
||||
#define OP_MATCH_MULXUU OPX_MATCH(OPX_MULXUU)
|
||||
#define OP_MATCH_NEXTPC OPX_MATCH(OPX_NEXTPC)
|
||||
#define OP_MATCH_NOR OPX_MATCH(OPX_NOR)
|
||||
#define OP_MATCH_OR OPX_MATCH(OPX_OR)
|
||||
#define OP_MATCH_RDCTL OPX_MATCH(OPX_RDCTL)
|
||||
#define OP_MATCH_RET (0xf8000000 | OPX_MATCH(OPX_RET))
|
||||
#define OP_MATCH_ROL OPX_MATCH(OPX_ROL)
|
||||
#define OP_MATCH_ROLI OPX_MATCH(OPX_ROLI)
|
||||
#define OP_MATCH_ROR OPX_MATCH(OPX_ROR)
|
||||
#define OP_MATCH_SLL OPX_MATCH(OPX_SLL)
|
||||
#define OP_MATCH_SLLI OPX_MATCH(OPX_SLLI)
|
||||
#define OP_MATCH_SRA OPX_MATCH(OPX_SRA)
|
||||
#define OP_MATCH_SRAI OPX_MATCH(OPX_SRAI)
|
||||
#define OP_MATCH_SRL OPX_MATCH(OPX_SRL)
|
||||
#define OP_MATCH_SRLI OPX_MATCH(OPX_SRLI)
|
||||
#define OP_MATCH_SUB OPX_MATCH(OPX_SUB)
|
||||
#define OP_MATCH_SYNC OPX_MATCH(OPX_SYNC)
|
||||
#define OP_MATCH_TRAP ((0x1d << 17) | OPX_MATCH(OPX_TRAP))
|
||||
#define OP_MATCH_ERET (0xef800000 | OPX_MATCH(OPX_ERET))
|
||||
#define OP_MATCH_WRCTL OPX_MATCH(OPX_WRCTL)
|
||||
#define OP_MATCH_WRPRS OPX_MATCH(OPX_WRPRS)
|
||||
#define OP_MATCH_XOR OPX_MATCH(OPX_XOR)
|
||||
#define OP_MATCH_FLUSHI OPX_MATCH(OPX_FLUSHI)
|
||||
#define OP_MATCH_FLUSHP OPX_MATCH(OPX_FLUSHP)
|
||||
#define OP_MATCH_INITI OPX_MATCH(OPX_INITI)
|
||||
|
||||
/* Some unusual op masks. */
|
||||
#define OP_MASK_BREAK ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP) & 0xfffff03f)
|
||||
#define OP_MASK_CALLR ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP))
|
||||
#define OP_MASK_JMP ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP))
|
||||
#define OP_MASK_SYNC ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP))
|
||||
#define OP_MASK_TRAP ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP) & 0xfffff83f)
|
||||
#define OP_MASK_WRCTL ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP)) /*& 0xfffff83f */
|
||||
#define OP_MASK_NEXTPC ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
|
||||
#define OP_MASK_FLUSHI ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP))
|
||||
#define OP_MASK_INITI ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX | OP_MASK_OP))
|
||||
|
||||
#define OP_MASK_ROLI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
|
||||
#define OP_MASK_SLLI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
|
||||
#define OP_MASK_SRAI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
|
||||
#define OP_MASK_SRLI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
|
||||
#define OP_MASK_RDCTL ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP)) /*& 0xfffff83f */
|
||||
|
||||
#ifndef OP_MASK
|
||||
#define OP_MASK 0xffffffff
|
||||
#endif
|
||||
|
||||
/* These convenience macros to extract instruction fields are used by GDB. */
|
||||
#define GET_IW_A(Iw) \
|
||||
(((Iw) >> IW_A_LSB) & IW_A_MASK)
|
||||
#define GET_IW_B(Iw) \
|
||||
(((Iw) >> IW_B_LSB) & IW_B_MASK)
|
||||
#define GET_IW_C(Iw) \
|
||||
(((Iw) >> IW_C_LSB) & IW_C_MASK)
|
||||
#define GET_IW_CONTROL_REGNUM(Iw) \
|
||||
(((Iw) >> IW_CONTROL_REGNUM_LSB) & IW_CONTROL_REGNUM_MASK)
|
||||
#define GET_IW_IMM16(Iw) \
|
||||
(((Iw) >> IW_IMM16_LSB) & IW_IMM16_MASK)
|
||||
#define GET_IW_IMM26(Iw) \
|
||||
(((Iw) >> IW_IMM26_LSB) & IW_IMM26_MASK)
|
||||
#define GET_IW_OP(Iw) \
|
||||
(((Iw) >> IW_OP_LSB) & IW_OP_MASK)
|
||||
#define GET_IW_OPX(Iw) \
|
||||
(((Iw) >> IW_OPX_LSB) & IW_OPX_MASK)
|
||||
|
||||
/* These are the data structures we use to hold the instruction information. */
|
||||
extern const struct nios2_opcode nios2_builtin_opcodes[];
|
||||
extern const int bfd_nios2_num_builtin_opcodes;
|
||||
extern struct nios2_opcode *nios2_opcodes;
|
||||
extern int bfd_nios2_num_opcodes;
|
||||
|
||||
/* These are the data structures used to hold the register information. */
|
||||
extern const struct nios2_reg nios2_builtin_regs[];
|
||||
extern struct nios2_reg *nios2_regs;
|
||||
extern const int nios2_num_builtin_regs;
|
||||
extern int nios2_num_regs;
|
||||
|
||||
/* Machine-independent macro for number of opcodes. */
|
||||
#define NUMOPCODES bfd_nios2_num_opcodes
|
||||
#define NUMREGISTERS nios2_num_regs;
|
||||
|
||||
/* This is made extern so that the assembler can use it to find out
|
||||
what instruction caused an error. */
|
||||
extern const struct nios2_opcode *nios2_find_opcode_hash(unsigned long);
|
||||
|
||||
#endif /* _NIOS2_H */
|
||||
|
|
@ -1,431 +0,0 @@
|
|||
/* Altera Nios II disassemble routines
|
||||
Copyright (C) 2012, 2013 Free Software Foundation, Inc.
|
||||
Contributed by Nigel Gray (ngray@altera.com).
|
||||
Contributed by Mentor Graphics, Inc.
|
||||
|
||||
This file is part of the GNU opcodes library.
|
||||
|
||||
This library 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 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
It 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 file; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
#include <common_gnu/sysdep.h>
|
||||
#include <common_gnu/disas-asm.h>
|
||||
#include <common_gnu/opcode/nios2.h>
|
||||
#include <common_gnu/libiberty.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* No symbol table is available when this code runs out in an embedded
|
||||
system as when it is used for disassembler support in a monitor. */
|
||||
#if !defined(EMBEDDED_ENV)
|
||||
#define SYMTAB_AVAILABLE 1
|
||||
#include <common_gnu/elf-bfd.h>
|
||||
//#include "elf/nios2.h"
|
||||
#endif
|
||||
|
||||
/* Length of Nios II instruction in bytes. */
|
||||
#define INSNLEN 4
|
||||
|
||||
/* Data structures used by the opcode hash table. */
|
||||
typedef struct _nios2_opcode_hash
|
||||
{
|
||||
const struct nios2_opcode *opcode;
|
||||
struct _nios2_opcode_hash *next;
|
||||
} nios2_opcode_hash;
|
||||
|
||||
static bfd_boolean nios2_hash_init = 0;
|
||||
static nios2_opcode_hash *nios2_hash[(OP_MASK_OP) + 1];
|
||||
|
||||
/* Separate hash table for pseudo-ops. */
|
||||
static nios2_opcode_hash *nios2_ps_hash[(OP_MASK_OP) + 1];
|
||||
|
||||
/* Function to initialize the opcode hash table. */
|
||||
static void
|
||||
nios2_init_opcode_hash (void)
|
||||
{
|
||||
unsigned int i;
|
||||
register const struct nios2_opcode *op;
|
||||
|
||||
for (i = 0; i <= OP_MASK_OP; ++i) {
|
||||
nios2_hash[0] = NULL;
|
||||
}
|
||||
for (i = 0; i <= OP_MASK_OP; i++) {
|
||||
for (op = nios2_opcodes; op < &nios2_opcodes[NUMOPCODES]; op++) {
|
||||
nios2_opcode_hash *new_hash;
|
||||
nios2_opcode_hash **bucket = NULL;
|
||||
|
||||
if ((op->pinfo & NIOS2_INSN_MACRO) == NIOS2_INSN_MACRO) {
|
||||
if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP) && (op->pinfo & (NIOS2_INSN_MACRO_MOV | NIOS2_INSN_MACRO_MOVI) & 0x7fffffff)) {
|
||||
bucket = &(nios2_ps_hash[i]);
|
||||
}
|
||||
} else if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP)) {
|
||||
bucket = &(nios2_hash[i]);
|
||||
}
|
||||
|
||||
if (bucket) {
|
||||
new_hash =
|
||||
(nios2_opcode_hash *)malloc (sizeof (nios2_opcode_hash));
|
||||
if (!new_hash) {
|
||||
fprintf (stderr,
|
||||
"error allocating memory...broken disassembler\n");
|
||||
abort ();
|
||||
}
|
||||
new_hash->opcode = op;
|
||||
new_hash->next = NULL;
|
||||
while (*bucket) {
|
||||
bucket = &((*bucket)->next);
|
||||
}
|
||||
*bucket = new_hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
nios2_hash_init = 1;
|
||||
#ifdef DEBUG_HASHTABLE
|
||||
for (i = 0; i <= OP_MASK_OP; ++i)
|
||||
{
|
||||
nios2_opcode_hash *tmp_hash = nios2_hash[i];
|
||||
printf ("index: 0x%02X ops: ", i);
|
||||
while (tmp_hash != NULL)
|
||||
{
|
||||
printf ("%s ", tmp_hash->opcode->name);
|
||||
tmp_hash = tmp_hash->next;
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
for (i = 0; i <= OP_MASK_OP; ++i)
|
||||
{
|
||||
nios2_opcode_hash *tmp_hash = nios2_ps_hash[i];
|
||||
printf ("index: 0x%02X ops: ", i);
|
||||
while (tmp_hash != NULL)
|
||||
{
|
||||
printf ("%s ", tmp_hash->opcode->name);
|
||||
tmp_hash = tmp_hash->next;
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
#endif /* DEBUG_HASHTABLE */
|
||||
}
|
||||
|
||||
/* Return a pointer to an nios2_opcode struct for a given instruction
|
||||
opcode, or NULL if there is an error. */
|
||||
const struct nios2_opcode *
|
||||
nios2_find_opcode_hash (unsigned long opcode)
|
||||
{
|
||||
nios2_opcode_hash *entry;
|
||||
|
||||
/* Build a hash table to shorten the search time. */
|
||||
if (!nios2_hash_init) {
|
||||
nios2_init_opcode_hash ();
|
||||
}
|
||||
|
||||
/* First look in the pseudo-op hashtable. */
|
||||
for (entry = nios2_ps_hash[(opcode >> OP_SH_OP) & OP_MASK_OP];
|
||||
entry; entry = entry->next) {
|
||||
if (entry->opcode->match == (opcode & entry->opcode->mask)) {
|
||||
return entry->opcode;
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise look in the main hashtable. */
|
||||
for (entry = nios2_hash[(opcode >> OP_SH_OP) & OP_MASK_OP];
|
||||
entry; entry = entry->next) {
|
||||
if (entry->opcode->match == (opcode & entry->opcode->mask)) {
|
||||
return entry->opcode;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* There are 32 regular registers, 32 coprocessor registers,
|
||||
and 32 control registers. */
|
||||
#define NUMREGNAMES 32
|
||||
|
||||
/* Return a pointer to the base of the coprocessor register name array. */
|
||||
static struct nios2_reg *
|
||||
nios2_coprocessor_regs (void)
|
||||
{
|
||||
static struct nios2_reg *cached = NULL;
|
||||
|
||||
if (!cached)
|
||||
{
|
||||
int i;
|
||||
for (i = NUMREGNAMES; i < nios2_num_regs; i++) {
|
||||
if (!strcmp (nios2_regs[i].name, "c0")) {
|
||||
cached = nios2_regs + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert (cached);
|
||||
}
|
||||
return cached;
|
||||
}
|
||||
|
||||
/* Return a pointer to the base of the control register name array. */
|
||||
static struct nios2_reg *
|
||||
nios2_control_regs (void)
|
||||
{
|
||||
static struct nios2_reg *cached = NULL;
|
||||
|
||||
if (!cached)
|
||||
{
|
||||
int i;
|
||||
for (i = NUMREGNAMES; i < nios2_num_regs; i++) {
|
||||
if (!strcmp (nios2_regs[i].name, "status")) {
|
||||
cached = nios2_regs + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert (cached);
|
||||
}
|
||||
return cached;
|
||||
}
|
||||
|
||||
/* The function nios2_print_insn_arg uses the character pointed
|
||||
to by ARGPTR to determine how it print the next token or separator
|
||||
character in the arguments to an instruction. */
|
||||
static int
|
||||
nios2_print_insn_arg (const char *argptr,
|
||||
unsigned long opcode, bfd_vma address,
|
||||
disassemble_info *info)
|
||||
{
|
||||
unsigned long i = 0;
|
||||
struct nios2_reg *reg_base;
|
||||
|
||||
switch (*argptr)
|
||||
{
|
||||
case ',':
|
||||
case '(':
|
||||
case ')':
|
||||
(*info->fprintf_func) (info->stream, "%c", *argptr);
|
||||
break;
|
||||
case 'd':
|
||||
i = GET_INSN_FIELD (RRD, opcode);
|
||||
|
||||
if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM && GET_INSN_FIELD (CUSTOM_C, opcode) == 0) {
|
||||
reg_base = nios2_coprocessor_regs ();
|
||||
} else {
|
||||
reg_base = nios2_regs;
|
||||
}
|
||||
|
||||
if (i < NUMREGNAMES) {
|
||||
(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
|
||||
} else {
|
||||
(*info->fprintf_func) (info->stream, "unknown");
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
i = GET_INSN_FIELD (RRS, opcode);
|
||||
|
||||
if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM && GET_INSN_FIELD (CUSTOM_A, opcode) == 0) {
|
||||
reg_base = nios2_coprocessor_regs ();
|
||||
} else {
|
||||
reg_base = nios2_regs;
|
||||
}
|
||||
|
||||
if (i < NUMREGNAMES) {
|
||||
(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
|
||||
} else {
|
||||
(*info->fprintf_func) (info->stream, "unknown");
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
i = GET_INSN_FIELD (RRT, opcode);
|
||||
|
||||
if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM && GET_INSN_FIELD (CUSTOM_B, opcode) == 0) {
|
||||
reg_base = nios2_coprocessor_regs ();
|
||||
} else {
|
||||
reg_base = nios2_regs;
|
||||
}
|
||||
|
||||
if (i < NUMREGNAMES) {
|
||||
(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
|
||||
} else {
|
||||
(*info->fprintf_func) (info->stream, "unknown");
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
/* 16-bit signed immediate. */
|
||||
i = (int) (GET_INSN_FIELD (IMM16, opcode) << 16) >> 16;
|
||||
(*info->fprintf_func) (info->stream, "%ld", i);
|
||||
break;
|
||||
case 'u':
|
||||
/* 16-bit unsigned immediate. */
|
||||
i = GET_INSN_FIELD (IMM16, opcode);
|
||||
(*info->fprintf_func) (info->stream, "%ld", i);
|
||||
break;
|
||||
case 'o':
|
||||
/* 16-bit signed immediate address offset. */
|
||||
i = (int) (GET_INSN_FIELD (IMM16, opcode) << 16) >> 16;
|
||||
address = address + 4 + i;
|
||||
(*info->print_address_func) (address, info);
|
||||
break;
|
||||
case 'p':
|
||||
/* 5-bit unsigned immediate. */
|
||||
i = GET_INSN_FIELD (CACHE_OPX, opcode);
|
||||
(*info->fprintf_func) (info->stream, "%ld", i);
|
||||
break;
|
||||
case 'j':
|
||||
/* 5-bit unsigned immediate. */
|
||||
i = GET_INSN_FIELD (IMM5, opcode);
|
||||
(*info->fprintf_func) (info->stream, "%ld", i);
|
||||
break;
|
||||
case 'l':
|
||||
/* 8-bit unsigned immediate. */
|
||||
/* FIXME - not yet implemented */
|
||||
i = GET_INSN_FIELD (CUSTOM_N, opcode);
|
||||
(*info->fprintf_func) (info->stream, "%lu", i);
|
||||
break;
|
||||
case 'm':
|
||||
/* 26-bit unsigned immediate. */
|
||||
i = GET_INSN_FIELD (IMM26, opcode);
|
||||
/* This translates to an address because it's only used in call
|
||||
instructions. */
|
||||
address = (address & 0xf0000000) | (i << 2);
|
||||
(*info->print_address_func) (address, info);
|
||||
break;
|
||||
case 'c':
|
||||
/* Control register index. */
|
||||
i = GET_INSN_FIELD (IMM5, opcode);
|
||||
reg_base = nios2_control_regs ();
|
||||
(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
|
||||
break;
|
||||
case 'b':
|
||||
i = GET_INSN_FIELD (IMM5, opcode);
|
||||
(*info->fprintf_func) (info->stream, "%ld", i);
|
||||
break;
|
||||
default:
|
||||
(*info->fprintf_func) (info->stream, "unknown");
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* nios2_disassemble does all the work of disassembling a Nios II
|
||||
instruction opcode. */
|
||||
static int
|
||||
nios2_disassemble (bfd_vma address, unsigned long opcode,
|
||||
disassemble_info *info)
|
||||
{
|
||||
const struct nios2_opcode *op;
|
||||
|
||||
info->bytes_per_line = INSNLEN;
|
||||
info->bytes_per_chunk = INSNLEN;
|
||||
info->display_endian = info->endian;
|
||||
info->insn_info_valid = 1;
|
||||
info->branch_delay_insns = 0;
|
||||
info->data_size = 0;
|
||||
info->insn_type = dis_nonbranch;
|
||||
info->target = 0;
|
||||
info->target2 = 0;
|
||||
|
||||
/* Find the major opcode and use this to disassemble
|
||||
the instruction and its arguments. */
|
||||
op = nios2_find_opcode_hash (opcode);
|
||||
|
||||
if (op != NULL)
|
||||
{
|
||||
bfd_boolean is_nop = FALSE;
|
||||
if (op->pinfo == NIOS2_INSN_MACRO_MOV)
|
||||
{
|
||||
/* Check for mov r0, r0 and change to nop. */
|
||||
int dst, src;
|
||||
dst = GET_INSN_FIELD (RRD, opcode);
|
||||
src = GET_INSN_FIELD (RRS, opcode);
|
||||
if (dst == 0 && src == 0)
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, "nop");
|
||||
is_nop = TRUE;
|
||||
} else {
|
||||
(*info->fprintf_func) (info->stream, "%s", op->name);
|
||||
}
|
||||
} else {
|
||||
(*info->fprintf_func) (info->stream, "%s", op->name);
|
||||
}
|
||||
|
||||
if (!is_nop)
|
||||
{
|
||||
const char *argstr = op->args;
|
||||
if (argstr != NULL && *argstr != '\0')
|
||||
{
|
||||
(*info->fprintf_func) (info->stream, " ");
|
||||
while (*argstr != '\0')
|
||||
{
|
||||
nios2_print_insn_arg (argstr, opcode, address, info);
|
||||
++argstr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handle undefined instructions. */
|
||||
info->insn_type = dis_noninsn;
|
||||
(*info->fprintf_func) (info->stream, "0x%lx", opcode);
|
||||
}
|
||||
/* Tell the caller how far to advance the program counter. */
|
||||
return INSNLEN;
|
||||
}
|
||||
|
||||
|
||||
/* print_insn_nios2 is the main disassemble function for Nios II.
|
||||
The function diassembler(abfd) (source in disassemble.c) returns a
|
||||
pointer to this either print_insn_big_nios2 or
|
||||
print_insn_little_nios2, which in turn call this function when the
|
||||
bfd machine type is Nios II. print_insn_nios2 reads the
|
||||
instruction word at the address given, and prints the disassembled
|
||||
instruction on the stream info->stream using info->fprintf_func. */
|
||||
|
||||
static int
|
||||
print_insn_nios2 (bfd_vma address, disassemble_info *info,
|
||||
enum bfd_endian endianness)
|
||||
{
|
||||
bfd_byte buffer[INSNLEN];
|
||||
int status;
|
||||
|
||||
status = (*info->read_memory_func) (address, buffer, INSNLEN, info);
|
||||
if (status == 0)
|
||||
{
|
||||
unsigned long insn;
|
||||
if (endianness == BFD_ENDIAN_BIG) {
|
||||
insn = (unsigned long)bfd_getb32 (buffer);
|
||||
} else {
|
||||
insn = (unsigned long)bfd_getl32 (buffer);
|
||||
}
|
||||
status = nios2_disassemble (address, insn, info);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*info->memory_error_func) (status, address, info);
|
||||
status = -1;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/* These two functions are the main entry points, accessed from
|
||||
disassemble.c. */
|
||||
int
|
||||
print_insn_big_nios2 (bfd_vma address, disassemble_info *info)
|
||||
{
|
||||
return print_insn_nios2 (address, info, BFD_ENDIAN_BIG);
|
||||
}
|
||||
|
||||
int
|
||||
print_insn_little_nios2 (bfd_vma address, disassemble_info *info)
|
||||
{
|
||||
return print_insn_nios2 (address, info, BFD_ENDIAN_LITTLE);
|
||||
}
|
||||
|
|
@ -1,415 +0,0 @@
|
|||
/* Altera Nios II opcode list.
|
||||
Copyright (C) 2012, 2013 Free Software Foundation, Inc.
|
||||
Contributed by Nigel Gray (ngray@altera.com).
|
||||
Contributed by Mentor Graphics, Inc.
|
||||
|
||||
This file is part of the GNU opcodes library.
|
||||
|
||||
This library 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 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
It 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 file; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
#include <common_gnu/sysdep.h>
|
||||
#include <stdio.h>
|
||||
#include <common_gnu/opcode/nios2.h>
|
||||
|
||||
/* Register string table */
|
||||
|
||||
const struct nios2_reg nios2_builtin_regs[] = {
|
||||
/* Standard register names. */
|
||||
{"zero", 0},
|
||||
{"at", 1}, /* assembler temporary */
|
||||
{"r2", 2},
|
||||
{"r3", 3},
|
||||
{"r4", 4},
|
||||
{"r5", 5},
|
||||
{"r6", 6},
|
||||
{"r7", 7},
|
||||
{"r8", 8},
|
||||
{"r9", 9},
|
||||
{"r10", 10},
|
||||
{"r11", 11},
|
||||
{"r12", 12},
|
||||
{"r13", 13},
|
||||
{"r14", 14},
|
||||
{"r15", 15},
|
||||
{"r16", 16},
|
||||
{"r17", 17},
|
||||
{"r18", 18},
|
||||
{"r19", 19},
|
||||
{"r20", 20},
|
||||
{"r21", 21},
|
||||
{"r22", 22},
|
||||
{"r23", 23},
|
||||
{"et", 24},
|
||||
{"bt", 25},
|
||||
{"gp", 26}, /* global pointer */
|
||||
{"sp", 27}, /* stack pointer */
|
||||
{"fp", 28}, /* frame pointer */
|
||||
{"ea", 29}, /* exception return address */
|
||||
{"ba", 30}, /* breakpoint return address */
|
||||
{"ra", 31}, /* return address */
|
||||
|
||||
/* Alternative names for special registers. */
|
||||
{"r0", 0},
|
||||
{"r1", 1},
|
||||
{"r24", 24},
|
||||
{"r25", 25},
|
||||
{"r26", 26},
|
||||
{"r27", 27},
|
||||
{"r28", 28},
|
||||
{"r29", 29},
|
||||
{"r30", 30},
|
||||
{"sstatus", 30},
|
||||
{"r31", 31},
|
||||
|
||||
/* Control register names. */
|
||||
{"status", 0},
|
||||
{"estatus", 1},
|
||||
{"bstatus", 2},
|
||||
{"ienable", 3},
|
||||
{"ipending", 4},
|
||||
{"cpuid", 5},
|
||||
{"ctl6", 6},
|
||||
{"exception", 7},
|
||||
{"pteaddr", 8},
|
||||
{"tlbacc", 9},
|
||||
{"tlbmisc", 10},
|
||||
{"eccinj", 11},
|
||||
{"badaddr", 12},
|
||||
{"config", 13},
|
||||
{"mpubase", 14},
|
||||
{"mpuacc", 15},
|
||||
{"ctl16", 16},
|
||||
{"ctl17", 17},
|
||||
{"ctl18", 18},
|
||||
{"ctl19", 19},
|
||||
{"ctl20", 20},
|
||||
{"ctl21", 21},
|
||||
{"ctl22", 22},
|
||||
{"ctl23", 23},
|
||||
{"ctl24", 24},
|
||||
{"ctl25", 25},
|
||||
{"ctl26", 26},
|
||||
{"ctl27", 27},
|
||||
{"ctl28", 28},
|
||||
{"ctl29", 29},
|
||||
{"ctl30", 30},
|
||||
{"ctl31", 31},
|
||||
|
||||
/* Alternative names for special control registers. */
|
||||
{"ctl0", 0},
|
||||
{"ctl1", 1},
|
||||
{"ctl2", 2},
|
||||
{"ctl3", 3},
|
||||
{"ctl4", 4},
|
||||
{"ctl5", 5},
|
||||
{"ctl7", 7},
|
||||
{"ctl8", 8},
|
||||
{"ctl9", 9},
|
||||
{"ctl10", 10},
|
||||
{"ctl11", 11},
|
||||
{"ctl12", 12},
|
||||
{"ctl13", 13},
|
||||
{"ctl14", 14},
|
||||
{"ctl15", 15},
|
||||
|
||||
/* Coprocessor register names. */
|
||||
{"c0", 0},
|
||||
{"c1", 1},
|
||||
{"c2", 2},
|
||||
{"c3", 3},
|
||||
{"c4", 4},
|
||||
{"c5", 5},
|
||||
{"c6", 6},
|
||||
{"c7", 7},
|
||||
{"c8", 8},
|
||||
{"c9", 9},
|
||||
{"c10", 10},
|
||||
{"c11", 11},
|
||||
{"c12", 12},
|
||||
{"c13", 13},
|
||||
{"c14", 14},
|
||||
{"c15", 15},
|
||||
{"c16", 16},
|
||||
{"c17", 17},
|
||||
{"c18", 18},
|
||||
{"c19", 19},
|
||||
{"c20", 20},
|
||||
{"c21", 21},
|
||||
{"c22", 22},
|
||||
{"c23", 23},
|
||||
{"c24", 24},
|
||||
{"c25", 25},
|
||||
{"c26", 26},
|
||||
{"c27", 27},
|
||||
{"c28", 28},
|
||||
{"c29", 29},
|
||||
{"c30", 30},
|
||||
{"c31", 31},
|
||||
};
|
||||
|
||||
#define NIOS2_NUM_REGS \
|
||||
((sizeof nios2_builtin_regs) / (sizeof (nios2_builtin_regs[0])))
|
||||
const int nios2_num_builtin_regs = NIOS2_NUM_REGS;
|
||||
|
||||
/* This is not const in order to allow for dynamic extensions to the
|
||||
built-in instruction set. */
|
||||
struct nios2_reg *nios2_regs = (struct nios2_reg *) nios2_builtin_regs;
|
||||
int nios2_num_regs = NIOS2_NUM_REGS;
|
||||
#undef NIOS2_NUM_REGS
|
||||
|
||||
/* This is the opcode table used by the Nios II GNU as, disassembler
|
||||
and GDB. */
|
||||
const struct nios2_opcode nios2_builtin_opcodes[] =
|
||||
{
|
||||
/* { name, args, args_test, num_args,
|
||||
match, mask, pinfo, overflow_msg } */
|
||||
{"add", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_ADD, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"addi", "t,s,i", "t,s,i,E", 3,
|
||||
OP_MATCH_ADDI, OP_MASK_IOP, NIOS2_INSN_ADDI, signed_immed16_overflow},
|
||||
{"subi", "t,s,i", "t,s,i,E", 3,
|
||||
OP_MATCH_ADDI, OP_MASK_IOP, NIOS2_INSN_MACRO, signed_immed16_overflow},
|
||||
{"and", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_AND, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"andhi", "t,s,u", "t,s,u,E", 3,
|
||||
OP_MATCH_ANDHI, OP_MASK_IOP, 0, unsigned_immed16_overflow},
|
||||
{"andi", "t,s,u", "t,s,u,E", 3,
|
||||
OP_MATCH_ANDI, OP_MASK_IOP, NIOS2_INSN_ANDI, unsigned_immed16_overflow},
|
||||
{"beq", "s,t,o", "s,t,o,E", 3,
|
||||
OP_MATCH_BEQ, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow},
|
||||
{"bge", "s,t,o", "s,t,o,E", 3,
|
||||
OP_MATCH_BGE, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow},
|
||||
{"bgeu", "s,t,o", "s,t,o,E", 3,
|
||||
OP_MATCH_BGEU, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow},
|
||||
{"bgt", "s,t,o", "s,t,o,E", 3,
|
||||
OP_MATCH_BLT, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH,
|
||||
branch_target_overflow},
|
||||
{"bgtu", "s,t,o", "s,t,o,E", 3,
|
||||
OP_MATCH_BLTU, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH,
|
||||
branch_target_overflow},
|
||||
{"ble", "s,t,o", "s,t,o,E", 3,
|
||||
OP_MATCH_BGE, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH,
|
||||
branch_target_overflow},
|
||||
{"bleu", "s,t,o", "s,t,o,E", 3,
|
||||
OP_MATCH_BGEU, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH,
|
||||
branch_target_overflow},
|
||||
{"blt", "s,t,o", "s,t,o,E", 3,
|
||||
OP_MATCH_BLT, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow},
|
||||
{"bltu", "s,t,o", "s,t,o,E", 3,
|
||||
OP_MATCH_BLTU, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow},
|
||||
{"bne", "s,t,o", "s,t,o,E", 3,
|
||||
OP_MATCH_BNE, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow},
|
||||
{"br", "o", "o,E", 1,
|
||||
OP_MATCH_BR, OP_MASK_IOP, NIOS2_INSN_UBRANCH, branch_target_overflow},
|
||||
{"break", "b", "b,E", 1,
|
||||
OP_MATCH_BREAK, OP_MASK_BREAK, 0, no_overflow},
|
||||
{"bret", "", "E", 0,
|
||||
OP_MATCH_BRET, OP_MASK, 0, no_overflow},
|
||||
{"flushd", "i(s)", "i(s)E", 2,
|
||||
OP_MATCH_FLUSHD, OP_MASK_IOP, 0, signed_immed16_overflow},
|
||||
{"flushda", "i(s)", "i(s)E", 2,
|
||||
OP_MATCH_FLUSHDA, OP_MASK_IOP, 0, signed_immed16_overflow},
|
||||
{"flushi", "s", "s,E", 1,
|
||||
OP_MATCH_FLUSHI, OP_MASK_FLUSHI, 0, no_overflow},
|
||||
{"flushp", "", "E", 0,
|
||||
OP_MATCH_FLUSHP, OP_MASK, 0, no_overflow},
|
||||
{"initd", "i(s)", "i(s)E", 2,
|
||||
OP_MATCH_INITD, OP_MASK_IOP, 0, signed_immed16_overflow},
|
||||
{"initda", "i(s)", "i(s)E", 2,
|
||||
OP_MATCH_INITDA, OP_MASK_IOP, 0, signed_immed16_overflow},
|
||||
{"initi", "s", "s,E", 1,
|
||||
OP_MATCH_INITI, OP_MASK_INITI, 0, no_overflow},
|
||||
{"call", "m", "m,E", 1,
|
||||
OP_MATCH_CALL, OP_MASK_IOP, NIOS2_INSN_CALL, call_target_overflow},
|
||||
{"callr", "s", "s,E", 1,
|
||||
OP_MATCH_CALLR, OP_MASK_CALLR, 0, no_overflow},
|
||||
{"cmpeq", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_CMPEQ, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"cmpeqi", "t,s,i", "t,s,i,E", 3,
|
||||
OP_MATCH_CMPEQI, OP_MASK_IOP, 0, signed_immed16_overflow},
|
||||
{"cmpge", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_CMPGE, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"cmpgei", "t,s,i", "t,s,i,E", 3,
|
||||
OP_MATCH_CMPGEI, OP_MASK_IOP, 0, signed_immed16_overflow},
|
||||
{"cmpgeu", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_CMPGEU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"cmpgeui", "t,s,u", "t,s,u,E", 3,
|
||||
OP_MATCH_CMPGEUI, OP_MASK_IOP, 0, unsigned_immed16_overflow},
|
||||
{"cmpgt", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_CMPLT, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow},
|
||||
{"cmpgti", "t,s,i", "t,s,i,E", 3,
|
||||
OP_MATCH_CMPGEI, OP_MASK_IOP, NIOS2_INSN_MACRO, signed_immed16_overflow},
|
||||
{"cmpgtu", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_CMPLTU, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow},
|
||||
{"cmpgtui", "t,s,u", "t,s,u,E", 3,
|
||||
OP_MATCH_CMPGEUI, OP_MASK_IOP, NIOS2_INSN_MACRO, unsigned_immed16_overflow},
|
||||
{"cmple", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_CMPGE, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow},
|
||||
{"cmplei", "t,s,i", "t,s,i,E", 3,
|
||||
OP_MATCH_CMPLTI, OP_MASK_IOP, NIOS2_INSN_MACRO, signed_immed16_overflow},
|
||||
{"cmpleu", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_CMPGEU, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow},
|
||||
{"cmpleui", "t,s,u", "t,s,u,E", 3,
|
||||
OP_MATCH_CMPLTUI, OP_MASK_IOP, NIOS2_INSN_MACRO, unsigned_immed16_overflow},
|
||||
{"cmplt", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_CMPLT, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"cmplti", "t,s,i", "t,s,i,E", 3,
|
||||
OP_MATCH_CMPLTI, OP_MASK_IOP, 0, signed_immed16_overflow},
|
||||
{"cmpltu", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_CMPLTU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"cmpltui", "t,s,u", "t,s,u,E", 3,
|
||||
OP_MATCH_CMPLTUI, OP_MASK_IOP, 0, unsigned_immed16_overflow},
|
||||
{"cmpne", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_CMPNE, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"cmpnei", "t,s,i", "t,s,i,E", 3,
|
||||
OP_MATCH_CMPNEI, OP_MASK_IOP, 0, signed_immed16_overflow},
|
||||
{"div", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_DIV, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"divu", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_DIVU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"jmp", "s", "s,E", 1,
|
||||
OP_MATCH_JMP, OP_MASK_JMP, 0, no_overflow},
|
||||
{"jmpi", "m", "m,E", 1,
|
||||
OP_MATCH_JMPI, OP_MASK_IOP, 0, no_overflow},
|
||||
{"ldb", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_LDB, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"ldbio", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_LDBIO, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"ldbu", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_LDBU, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"ldbuio", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_LDBUIO, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"ldh", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_LDH, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"ldhio", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_LDHIO, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"ldhu", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_LDHU, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"ldhuio", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_LDHUIO, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"ldl", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_LDL, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"ldw", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_LDW, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"ldwio", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_LDWIO, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"mov", "d,s", "d,s,E", 2,
|
||||
OP_MATCH_ADD, OP_MASK_RRT|OP_MASK_ROPX|OP_MASK_ROP, NIOS2_INSN_MACRO_MOV,
|
||||
no_overflow},
|
||||
{"movhi", "t,u", "t,u,E", 2,
|
||||
OP_MATCH_ORHI, OP_MASK_IRS|OP_MASK_IOP, NIOS2_INSN_MACRO_MOVI,
|
||||
unsigned_immed16_overflow},
|
||||
{"movui", "t,u", "t,u,E", 2,
|
||||
OP_MATCH_ORI, OP_MASK_IRS|OP_MASK_IOP, NIOS2_INSN_MACRO_MOVI,
|
||||
unsigned_immed16_overflow},
|
||||
{"movi", "t,i", "t,i,E", 2,
|
||||
OP_MATCH_ADDI, OP_MASK_IRS|OP_MASK_IOP, NIOS2_INSN_MACRO_MOVI,
|
||||
signed_immed16_overflow},
|
||||
/* movia expands to two instructions so there is no mask or match */
|
||||
{"movia", "t,o", "t,o,E", 2,
|
||||
OP_MATCH_ORHI, OP_MASK_IOP, NIOS2_INSN_MACRO_MOVIA, no_overflow},
|
||||
{"mul", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_MUL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"muli", "t,s,i", "t,s,i,E", 3,
|
||||
OP_MATCH_MULI, OP_MASK_IOP, 0, signed_immed16_overflow},
|
||||
{"mulxss", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_MULXSS, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"mulxsu", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_MULXSU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"mulxuu", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_MULXUU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"nextpc", "d", "d,E", 1,
|
||||
OP_MATCH_NEXTPC, OP_MASK_NEXTPC, 0, no_overflow},
|
||||
{"nop", "", "E", 0,
|
||||
OP_MATCH_ADD, OP_MASK, NIOS2_INSN_MACRO_MOV, no_overflow},
|
||||
{"nor", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_NOR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"or", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_OR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"orhi", "t,s,u", "t,s,u,E", 3,
|
||||
OP_MATCH_ORHI, OP_MASK_IOP, 0, unsigned_immed16_overflow},
|
||||
{"ori", "t,s,u", "t,s,u,E", 3,
|
||||
OP_MATCH_ORI, OP_MASK_IOP, NIOS2_INSN_ORI, unsigned_immed16_overflow},
|
||||
{"rdctl", "d,c", "d,c,E", 2,
|
||||
OP_MATCH_RDCTL, OP_MASK_RDCTL, 0, no_overflow},
|
||||
{"rdprs", "t,s,i", "t,s,i,E", 3,
|
||||
OP_MATCH_RDPRS, OP_MASK_IOP, 0, unsigned_immed16_overflow},
|
||||
{"ret", "", "E", 0,
|
||||
OP_MATCH_RET, OP_MASK, 0, no_overflow},
|
||||
{"rol", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_ROL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"roli", "d,s,j", "d,s,j,E", 3,
|
||||
OP_MATCH_ROLI, OP_MASK_ROLI, 0, unsigned_immed5_overflow},
|
||||
{"ror", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_ROR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"sll", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_SLL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"slli", "d,s,j", "d,s,j,E", 3,
|
||||
OP_MATCH_SLLI, OP_MASK_SLLI, 0, unsigned_immed5_overflow},
|
||||
{"sra", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_SRA, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"srai", "d,s,j", "d,s,j,E", 3,
|
||||
OP_MATCH_SRAI, OP_MASK_SRAI, 0, unsigned_immed5_overflow},
|
||||
{"srl", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_SRL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"srli", "d,s,j", "d,s,j,E", 3,
|
||||
OP_MATCH_SRLI, OP_MASK_SRLI, 0, unsigned_immed5_overflow},
|
||||
{"stb", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_STB, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"stbio", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_STBIO, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"stc", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_STC, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"sth", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_STH, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"sthio", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_STHIO, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"stw", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_STW, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"stwio", "t,i(s)", "t,i(s)E", 3,
|
||||
OP_MATCH_STWIO, OP_MASK_IOP, 0, address_offset_overflow},
|
||||
{"sub", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_SUB, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"sync", "", "E", 0,
|
||||
OP_MATCH_SYNC, OP_MASK_SYNC, 0, no_overflow},
|
||||
{"trap", "b", "b,E", 1,
|
||||
OP_MATCH_TRAP, OP_MASK_TRAP, 0, no_overflow},
|
||||
{"eret", "", "E", 0,
|
||||
OP_MATCH_ERET, OP_MASK, 0, no_overflow},
|
||||
{"custom", "l,d,s,t", "l,d,s,t,E", 4,
|
||||
OP_MATCH_CUSTOM, OP_MASK_ROP, 0, custom_opcode_overflow},
|
||||
{"wrctl", "c,s", "c,s,E", 2,
|
||||
OP_MATCH_WRCTL, OP_MASK_WRCTL, 0, no_overflow},
|
||||
{"wrprs", "d,s", "d,s,E", 2,
|
||||
OP_MATCH_WRPRS, OP_MASK_RRT|OP_MASK_ROPX|OP_MASK_ROP, 0, no_overflow},
|
||||
{"xor", "d,s,t", "d,s,t,E", 3,
|
||||
OP_MATCH_XOR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
|
||||
{"xorhi", "t,s,u", "t,s,u,E", 3,
|
||||
OP_MATCH_XORHI, OP_MASK_IOP, 0, unsigned_immed16_overflow},
|
||||
{"xori", "t,s,u", "t,s,u,E", 3,
|
||||
OP_MATCH_XORI, OP_MASK_IOP, NIOS2_INSN_XORI, unsigned_immed16_overflow}
|
||||
};
|
||||
|
||||
#define NIOS2_NUM_OPCODES \
|
||||
((sizeof nios2_builtin_opcodes) / (sizeof (nios2_builtin_opcodes[0])))
|
||||
const int bfd_nios2_num_builtin_opcodes = NIOS2_NUM_OPCODES;
|
||||
|
||||
/* This is not const to allow for dynamic extensions to the
|
||||
built-in instruction set. */
|
||||
struct nios2_opcode *nios2_opcodes =
|
||||
(struct nios2_opcode *) nios2_builtin_opcodes;
|
||||
int bfd_nios2_num_opcodes = NIOS2_NUM_OPCODES;
|
||||
#undef NIOS2_NUM_OPCODES
|
||||
|
|
@ -326,7 +326,6 @@ if get_option('use_gpl')
|
|||
'hppa_gnu',
|
||||
'lanai_gnu',
|
||||
'mips_gnu',
|
||||
'nios2_gnu',
|
||||
'riscv_gnu',
|
||||
'sparc_gnu',
|
||||
'vax_gnu',
|
||||
|
|
@ -341,7 +340,6 @@ if get_option('use_gpl')
|
|||
'p_gnu/arch_hppa.c',
|
||||
'p_gnu/arch_lanai.c',
|
||||
'p_gnu/arch_mips.c',
|
||||
'p_gnu/arch_nios2.c',
|
||||
'p_gnu/arch_riscv.c',
|
||||
'p_gnu/arch_sparc.c',
|
||||
'p_gnu/arch_vax.c',
|
||||
|
|
@ -363,8 +361,6 @@ if get_option('use_gpl')
|
|||
'isa_gnu/mips/mips-dis.c',
|
||||
'isa_gnu/mips/mips-opc.c',
|
||||
'isa_gnu/mips/mips16-opc.c',
|
||||
'isa_gnu/nios/nios2-dis.c',
|
||||
'isa_gnu/nios/nios2-opc.c',
|
||||
# 'isa_gnu/riscv/riscv-opc.c',
|
||||
# 'isa_gnu/riscv/riscv.c',
|
||||
'isa_gnu/sparc/sparc-dis.c',
|
||||
|
|
|
|||
|
|
@ -1,93 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2014 pancake <pancake@nopcode.org>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <string.h>
|
||||
#include <rz_types.h>
|
||||
#include <rz_lib.h>
|
||||
#include <rz_asm.h>
|
||||
#include <rz_analysis.h>
|
||||
|
||||
static int nios2_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *b, int len, RzAnalysisOpMask mask) {
|
||||
if (!op) {
|
||||
return 1;
|
||||
}
|
||||
op->size = 4;
|
||||
|
||||
if ((b[0] & 0xff) == 0x3a) {
|
||||
// XXX
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_RET;
|
||||
} else if ((b[0] & 0xf) == 0xa) {
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_JMP;
|
||||
} else if ((b[0] & 0xf) == 4) {
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_ADD;
|
||||
} else if ((b[0] & 0xf) == 5) {
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_STORE;
|
||||
} else if ((b[0] & 0xf) == 6) {
|
||||
// blt, r19, r5, 0x8023480
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_CJMP;
|
||||
// TODO: address
|
||||
} else if ((b[0] & 0xf) == 7) {
|
||||
// blt, r19, r5, 0x8023480
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
|
||||
// TODO: address
|
||||
} else {
|
||||
switch (b[0]) {
|
||||
case 0x3a:
|
||||
if (b[1] >= 0xa0 && b[1] <= 0xaf && b[3] == 0x3d) {
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_TRAP;
|
||||
} else if ((b[1] >= 0xe0 && b[1] <= 0xe7) && b[2] == 0x3e && !b[3]) {
|
||||
// nextpc ra
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_RET;
|
||||
}
|
||||
break;
|
||||
case 0x01:
|
||||
// jmpi
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_JMP;
|
||||
break;
|
||||
case 0x00:
|
||||
case 0x20:
|
||||
case 0x40:
|
||||
case 0x80:
|
||||
case 0xc0:
|
||||
//
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_CALL;
|
||||
break;
|
||||
case 0x26:
|
||||
// beq
|
||||
break;
|
||||
case 0x07:
|
||||
case 0x47:
|
||||
case 0x87:
|
||||
case 0xc7:
|
||||
// ldb
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
|
||||
break;
|
||||
case 0x0d:
|
||||
case 0x2d:
|
||||
case 0x4d:
|
||||
case 0x8d:
|
||||
case 0xcd:
|
||||
// sth && sthio
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
|
||||
break;
|
||||
case 0x06:
|
||||
case 0x46:
|
||||
case 0x86:
|
||||
case 0xc6:
|
||||
// br
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_CALL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return op->size;
|
||||
}
|
||||
|
||||
RzAnalysisPlugin rz_analysis_plugin_nios2_gnu = {
|
||||
.name = "nios2",
|
||||
.desc = "NIOS II code analysis plugin",
|
||||
.license = "LGPL3",
|
||||
.arch = "nios2",
|
||||
.esil = false,
|
||||
.bits = 32,
|
||||
.op = &nios2_op,
|
||||
};
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2024 RizinOrg <info@rizin.re>
|
||||
// SPDX-FileCopyrightText: 2024 deroad <wargio@libero.it>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <deprecated_arch_helper.h>
|
||||
|
||||
#include "analysis/analysis_nios2_gnu.c"
|
||||
#include "asm/asm_nios2_gnu.c"
|
||||
|
||||
RZ_ARCH_PLUGIN_DEFINE_DEPRECATED(nios2_gnu);
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2014-2018 pancake <pancake@nopcode.org>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rz_types.h>
|
||||
#include <rz_lib.h>
|
||||
#include <rz_util.h>
|
||||
#include <rz_asm.h>
|
||||
|
||||
#include <common_gnu/disas-asm.h>
|
||||
|
||||
int print_insn_big_nios2(bfd_vma address, disassemble_info *info);
|
||||
int print_insn_little_nios2(bfd_vma address, disassemble_info *info);
|
||||
static unsigned long Offset = 0;
|
||||
static RzStrBuf *buf_global = NULL;
|
||||
static unsigned char bytes[4];
|
||||
|
||||
static int nios2_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) {
|
||||
//--
|
||||
}
|
||||
|
||||
DECLARE_GENERIC_PRINT_ADDRESS_FUNC()
|
||||
DECLARE_GENERIC_FPRINTF_FUNC()
|
||||
|
||||
static int disassemble(RzAsm *a, struct rz_asm_op_t *op, const ut8 *buf, int len) {
|
||||
struct disassemble_info disasm_obj;
|
||||
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 = "";
|
||||
disasm_obj.buffer = bytes;
|
||||
disasm_obj.read_memory_func = &nios2_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 = &generic_print_address_func;
|
||||
disasm_obj.endian = !a->big_endian;
|
||||
disasm_obj.fprintf_func = &generic_fprintf_func;
|
||||
disasm_obj.stream = stdout;
|
||||
|
||||
if (disasm_obj.endian == BFD_ENDIAN_BIG) {
|
||||
op->size = print_insn_big_nios2((bfd_vma)Offset, &disasm_obj);
|
||||
} else {
|
||||
op->size = print_insn_little_nios2((bfd_vma)Offset, &disasm_obj);
|
||||
}
|
||||
if (op->size == -1) {
|
||||
rz_asm_op_set_asm(op, "(data)");
|
||||
}
|
||||
return op->size;
|
||||
}
|
||||
|
||||
RzAsmPlugin rz_asm_plugin_nios2_gnu = {
|
||||
.name = "nios2",
|
||||
.arch = "nios2",
|
||||
.license = "GPL3",
|
||||
.bits = 32,
|
||||
.endian = RZ_SYS_ENDIAN_LITTLE | RZ_SYS_ENDIAN_BIG,
|
||||
.desc = "NIOS II Embedded Processor",
|
||||
.disassemble = &disassemble
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue