1/* mips16-opc.c.  Mips16 opcode table.
2   Copyright 1996, 1997, 1998, 2000, 2005, 2007 Free Software Foundation, Inc.
3   Contributed by Ian Lance Taylor, Cygnus Support
4
5   This file is part of the GNU opcodes library.
6
7   This library is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3, or (at your option)
10   any later version.
11
12   It is distributed in the hope that it will be useful, but WITHOUT
13   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15   License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this file; see the file COPYING.  If not, write to the
19   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
20   MA 02110-1301, USA.  */
21
22#include <stdio.h>
23#include "sysdep.h"
24#include "opcode/mips.h"
25
26/* This is the opcodes table for the mips16 processor.  The format of
27   this table is intentionally identical to the one in mips-opc.c.
28   However, the special letters that appear in the argument string are
29   different, and the table uses some different flags.  */
30
31/* Use some short hand macros to keep down the length of the lines in
32   the opcodes table.  */
33
34#define UBD     INSN_UNCOND_BRANCH_DELAY
35#define BR      MIPS16_INSN_BRANCH
36
37#define WR_x	MIPS16_INSN_WRITE_X
38#define WR_y	MIPS16_INSN_WRITE_Y
39#define WR_z	MIPS16_INSN_WRITE_Z
40#define WR_T	MIPS16_INSN_WRITE_T
41#define WR_SP	MIPS16_INSN_WRITE_SP
42#define WR_31	MIPS16_INSN_WRITE_31
43#define WR_Y	MIPS16_INSN_WRITE_GPR_Y
44
45#define RD_x	MIPS16_INSN_READ_X
46#define RD_y	MIPS16_INSN_READ_Y
47#define RD_Z	MIPS16_INSN_READ_Z
48#define RD_T	MIPS16_INSN_READ_T
49#define RD_SP	MIPS16_INSN_READ_SP
50#define RD_31	MIPS16_INSN_READ_31
51#define RD_PC	MIPS16_INSN_READ_PC
52#define RD_X	MIPS16_INSN_READ_GPR_X
53
54#define WR_HI	INSN_WRITE_HI
55#define WR_LO	INSN_WRITE_LO
56#define RD_HI	INSN_READ_HI
57#define RD_LO	INSN_READ_LO
58
59#define TRAP	INSN_TRAP
60
61#define I1	INSN_ISA1
62#define I3	INSN_ISA3
63#define I32	INSN_ISA32
64#define I64	INSN_ISA64
65#define T3	INSN_3900
66
67const struct mips_opcode mips16_opcodes[] =
68{
69/* name,    args,	match,	mask,	pinfo,         	pinfo2, membership */
70{"nop",	    "",		0x6500, 0xffff, RD_Z,		0,	I1 }, /* move $0,$Z */
71{"la",	    "x,A",	0x0800, 0xf800, WR_x|RD_PC,	0,	I1 },
72{"abs",	    "x,w",	0, (int) M_ABS, INSN_MACRO,	0,	I1 },
73{"addiu",   "y,x,4",	0x4000, 0xf810, WR_y|RD_x,	0,	I1 },
74{"addiu",   "x,k",	0x4800, 0xf800, WR_x|RD_x,	0,	I1 },
75{"addiu",   "S,K",	0x6300, 0xff00, WR_SP|RD_SP,	0,	I1 },
76{"addiu",   "S,S,K",	0x6300, 0xff00, WR_SP|RD_SP,	0,	I1 },
77{"addiu",   "x,P,V",	0x0800, 0xf800, WR_x|RD_PC,	0,	I1 },
78{"addiu",   "x,S,V",	0x0000, 0xf800, WR_x|RD_SP,	0,	I1 },
79{"addu",    "z,v,y",	0xe001, 0xf803, WR_z|RD_x|RD_y,	0,	I1 },
80{"addu",    "y,x,4",	0x4000, 0xf810, WR_y|RD_x,	0,	I1 },
81{"addu",    "x,k",	0x4800, 0xf800, WR_x|RD_x,	0,	I1 },
82{"addu",    "S,K",	0x6300, 0xff00, WR_SP|RD_SP,	0,	I1 },
83{"addu",    "S,S,K",	0x6300, 0xff00, WR_SP|RD_SP,	0,	I1 },
84{"addu",    "x,P,V",	0x0800, 0xf800, WR_x|RD_PC,	0,	I1 },
85{"addu",    "x,S,V",	0x0000, 0xf800, WR_x|RD_SP,	0,	I1 },
86{"and",	    "x,y",	0xe80c, 0xf81f, WR_x|RD_x|RD_y,	0,	I1 },
87{"b",	    "q",	0x1000, 0xf800, BR,		0,	I1 },
88{"beq",	    "x,y,p",	0, (int) M_BEQ, INSN_MACRO,	0,	I1 },
89{"beq",     "x,U,p",	0, (int) M_BEQ_I, INSN_MACRO,	0,	I1 },
90{"beqz",    "x,p",	0x2000, 0xf800, BR|RD_x,	0,	I1 },
91{"bge",	    "x,y,p",	0, (int) M_BGE, INSN_MACRO,	0,	I1 },
92{"bge",     "x,8,p",	0, (int) M_BGE_I, INSN_MACRO,	0,	I1 },
93{"bgeu",    "x,y,p",	0, (int) M_BGEU, INSN_MACRO,	0,	I1 },
94{"bgeu",    "x,8,p",	0, (int) M_BGEU_I, INSN_MACRO,	0,	I1 },
95{"bgt",	    "x,y,p",	0, (int) M_BGT, INSN_MACRO,	0,	I1 },
96{"bgt",     "x,8,p",	0, (int) M_BGT_I, INSN_MACRO,	0,	I1 },
97{"bgtu",    "x,y,p",	0, (int) M_BGTU, INSN_MACRO,	0,	I1 },
98{"bgtu",    "x,8,p",	0, (int) M_BGTU_I, INSN_MACRO,	0,	I1 },
99{"ble",	    "x,y,p",	0, (int) M_BLE, INSN_MACRO,	0,	I1 },
100{"ble",     "x,8,p",	0, (int) M_BLE_I, INSN_MACRO,	0,	I1 },
101{"bleu",    "x,y,p",	0, (int) M_BLEU, INSN_MACRO,	0,	I1 },
102{"bleu",    "x,8,p",	0, (int) M_BLEU_I, INSN_MACRO,	0,	I1 },
103{"blt",	    "x,y,p",	0, (int) M_BLT, INSN_MACRO,	0,	I1 },
104{"blt",     "x,8,p",	0, (int) M_BLT_I, INSN_MACRO,	0,	I1 },
105{"bltu",    "x,y,p",	0, (int) M_BLTU, INSN_MACRO,	0,	I1 },
106{"bltu",    "x,8,p",	0, (int) M_BLTU_I, INSN_MACRO,	0,	I1 },
107{"bne",	    "x,y,p",	0, (int) M_BNE, INSN_MACRO,	0,	I1 },
108{"bne",     "x,U,p",	0, (int) M_BNE_I, INSN_MACRO,	0,	I1 },
109{"bnez",    "x,p",	0x2800, 0xf800, BR|RD_x,	0,	I1 },
110{"break",   "6",	0xe805, 0xf81f, TRAP,		0,	I1 },
111{"bteqz",   "p",	0x6000, 0xff00, BR|RD_T,	0,	I1 },
112{"btnez",   "p",	0x6100, 0xff00, BR|RD_T,	0,	I1 },
113{"cmpi",    "x,U",	0x7000, 0xf800, WR_T|RD_x,	0,	I1 },
114{"cmp",	    "x,y",	0xe80a, 0xf81f, WR_T|RD_x|RD_y,	0,	I1 },
115{"cmp",     "x,U",	0x7000, 0xf800, WR_T|RD_x,	0,	I1 },
116{"dla",	    "y,E",	0xfe00, 0xff00, WR_y|RD_PC, 	0,	I3 },
117{"daddiu",  "y,x,4",	0x4010, 0xf810, WR_y|RD_x, 	0,	I3 },
118{"daddiu",  "y,j",	0xfd00, 0xff00, WR_y|RD_y, 	0,	I3 },
119{"daddiu",  "S,K",	0xfb00, 0xff00, WR_SP|RD_SP, 	0,	I3 },
120{"daddiu",  "S,S,K",	0xfb00, 0xff00, WR_SP|RD_SP, 	0,	I3 },
121{"daddiu",  "y,P,W",	0xfe00, 0xff00, WR_y|RD_PC, 	0,	I3 },
122{"daddiu",  "y,S,W",	0xff00, 0xff00, WR_y|RD_SP, 	0,	I3 },
123{"daddu",   "z,v,y",	0xe000, 0xf803, WR_z|RD_x|RD_y, 0,	I3 },
124{"daddu",   "y,x,4",	0x4010, 0xf810, WR_y|RD_x, 	0,	I3 },
125{"daddu",   "y,j",	0xfd00, 0xff00, WR_y|RD_y, 	0,	I3 },
126{"daddu",   "S,K",	0xfb00, 0xff00, WR_SP|RD_SP, 	0,	I3 },
127{"daddu",   "S,S,K",	0xfb00, 0xff00, WR_SP|RD_SP, 	0,	I3 },
128{"daddu",   "y,P,W",	0xfe00, 0xff00, WR_y|RD_PC, 	0,	I3 },
129{"daddu",   "y,S,W",	0xff00, 0xff00, WR_y|RD_SP, 	0,	I3 },
130{"ddiv",    "0,x,y",	0xe81e, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 	0,	I3 },
131{"ddiv",    "z,v,y",	0, (int) M_DDIV_3, INSN_MACRO,	0,	I1 },
132{"ddivu",   "0,x,y",	0xe81f, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0,	I3 },
133{"ddivu",   "z,v,y",	0, (int) M_DDIVU_3, INSN_MACRO,	0,	I1 },
134{"div",     "0,x,y",	0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	I1 },
135{"div",     "z,v,y",	0, (int) M_DIV_3, INSN_MACRO,	0,	I1 },
136{"divu",    "0,x,y",	0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	I1 },
137{"divu",    "z,v,y",	0, (int) M_DIVU_3, INSN_MACRO,	0,	I1 },
138{"dmul",    "z,v,y",	0, (int) M_DMUL, INSN_MACRO, 	0,	I3 },
139{"dmult",   "x,y",	0xe81c, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0,	I3 },
140{"dmultu",  "x,y",	0xe81d, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0,	I3 },
141{"drem",    "0,x,y",	0xe81e, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0,	I3 },
142{"drem",    "z,v,y",	0, (int) M_DREM_3, INSN_MACRO,	0,	I1 },
143{"dremu",   "0,x,y",	0xe81f, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0,	I3 },
144{"dremu",   "z,v,y",	0, (int) M_DREMU_3, INSN_MACRO,	0,	I1 },
145{"dsllv",   "y,x",	0xe814, 0xf81f, WR_y|RD_y|RD_x, 0,	I3 },
146{"dsll",    "x,w,[",	0x3001, 0xf803, WR_x|RD_y, 	0,	I3 },
147{"dsll",    "y,x",	0xe814, 0xf81f, WR_y|RD_y|RD_x, 0,	I3 },
148{"dsrav",   "y,x",	0xe817, 0xf81f, WR_y|RD_y|RD_x, 0,	I3 },
149{"dsra",    "y,]",	0xe813, 0xf81f, WR_y|RD_y, 	0,	I3 },
150{"dsra",    "y,x",	0xe817, 0xf81f, WR_y|RD_y|RD_x, 0,	I3 },
151{"dsrlv",   "y,x",	0xe816, 0xf81f, WR_y|RD_y|RD_x, 0,	I3 },
152{"dsrl",    "y,]",	0xe808, 0xf81f, WR_y|RD_y, 	0,	I3 },
153{"dsrl",    "y,x",	0xe816, 0xf81f, WR_y|RD_y|RD_x, 0,	I3 },
154{"dsubu",   "z,v,y",	0xe002, 0xf803, WR_z|RD_x|RD_y, 0,	I3 },
155{"dsubu",   "y,x,4",	0, (int) M_DSUBU_I, INSN_MACRO,	0,	I1 },
156{"dsubu",   "y,j",	0, (int) M_DSUBU_I_2, INSN_MACRO, 0,	I1 },
157{"exit",    "L",	0xed09, 0xff1f, TRAP,		0,	I1 },
158{"exit",    "L",	0xee09, 0xff1f, TRAP,		0,	I1 },
159{"exit",    "L",	0xef09, 0xff1f, TRAP,		0,	I1 },
160{"entry",   "l",	0xe809, 0xf81f, TRAP,		0,	I1 },
161{"extend",  "e",	0xf000, 0xf800, 0,		0,	I1 },
162{"jalr",    "x",	0xe840, 0xf8ff, UBD|WR_31|RD_x,	0,	I1 },
163{"jalr",    "R,x",	0xe840, 0xf8ff, UBD|WR_31|RD_x,	0,	I1 },
164{"jal",     "x",	0xe840, 0xf8ff, UBD|WR_31|RD_x,	0,	I1 },
165{"jal",     "R,x",	0xe840, 0xf8ff, UBD|WR_31|RD_x,	0,	I1 },
166{"jal",	    "a",	0x1800, 0xfc00, UBD|WR_31,	0,	I1 },
167{"jalx",    "a",	0x1c00, 0xfc00, UBD|WR_31,	0,	I1 },
168{"jr",	    "x",	0xe800, 0xf8ff, UBD|RD_x,	0,	I1 },
169{"jr",	    "R",	0xe820, 0xffff, UBD|RD_31,	0,	I1 },
170{"j",	    "x",	0xe800, 0xf8ff, UBD|RD_x,	0,	I1 },
171{"j",	    "R",	0xe820, 0xffff, UBD|RD_31,	0,	I1 },
172{"lb",	    "y,5(x)",	0x8000, 0xf800, WR_y|RD_x,	0,	I1 },
173{"lbu",	    "y,5(x)",	0xa000, 0xf800, WR_y|RD_x,	0,	I1 },
174{"ld",	    "y,D(x)",	0x3800, 0xf800, WR_y|RD_x, 	0,	I3 },
175{"ld",	    "y,B",	0xfc00, 0xff00, WR_y|RD_PC, 	0,	I3 },
176{"ld",	    "y,D(P)",	0xfc00, 0xff00, WR_y|RD_PC, 	0,	I3 },
177{"ld",	    "y,D(S)",	0xf800, 0xff00, WR_y|RD_SP, 	0,	I3 },
178{"lh",	    "y,H(x)",	0x8800, 0xf800, WR_y|RD_x,	0,	I1 },
179{"lhu",	    "y,H(x)",	0xa800, 0xf800, WR_y|RD_x,	0,	I1 },
180{"li",	    "x,U",	0x6800, 0xf800, WR_x,		0,	I1 },
181{"lw",	    "y,W(x)",	0x9800, 0xf800, WR_y|RD_x,	0,	I1 },
182{"lw",	    "x,A",	0xb000, 0xf800, WR_x|RD_PC,	0,	I1 },
183{"lw",	    "x,V(P)",	0xb000, 0xf800, WR_x|RD_PC,	0,	I1 },
184{"lw",	    "x,V(S)",	0x9000, 0xf800, WR_x|RD_SP,	0,	I1 },
185{"lwu",     "y,W(x)",	0xb800, 0xf800, WR_y|RD_x, 	0,	I3 },
186{"mfhi",    "x",	0xe810, 0xf8ff, WR_x|RD_HI,	0,	I1 },
187{"mflo",    "x",	0xe812, 0xf8ff, WR_x|RD_LO,	0,	I1 },
188{"move",    "y,X",	0x6700, 0xff00, WR_y|RD_X, 	0,	I1 },
189{"move",    "Y,Z",	0x6500, 0xff00, WR_Y|RD_Z,	0,	I1 },
190{"mul",     "z,v,y",	0, (int) M_MUL, INSN_MACRO,	0,	I1 },
191{"mult",    "x,y",	0xe818, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	I1 },
192{"multu",   "x,y",	0xe819, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	I1 },
193{"neg",	    "x,w",	0xe80b, 0xf81f, WR_x|RD_y,	0,	I1 },
194{"not",	    "x,w",	0xe80f, 0xf81f, WR_x|RD_y,	0,	I1 },
195{"or",	    "x,y",	0xe80d, 0xf81f, WR_x|RD_x|RD_y,	0,	I1 },
196{"rem",     "0,x,y",	0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	I1 },
197{"rem",     "z,v,y",	0, (int) M_REM_3, INSN_MACRO,	0,	I1 },
198{"remu",    "0,x,y",	0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO,	0,	I1 },
199{"remu",    "z,v,y",	0, (int) M_REMU_3, INSN_MACRO,	0,	I1 },
200{"sb",	    "y,5(x)",	0xc000, 0xf800, RD_y|RD_x,	0,	I1 },
201{"sd",	    "y,D(x)",	0x7800, 0xf800, RD_y|RD_x, 	0,	I3 },
202{"sd",	    "y,D(S)",	0xf900, 0xff00, RD_y|RD_PC, 	0,	I3 },
203{"sd",	    "R,C(S)",	0xfa00, 0xff00, RD_31|RD_PC,	0,	I1 },
204{"sh",	    "y,H(x)",	0xc800, 0xf800, RD_y|RD_x,	0,	I1 },
205{"sllv",    "y,x",	0xe804, 0xf81f, WR_y|RD_y|RD_x, 0,	I1 },
206{"sll",	    "x,w,<",	0x3000, 0xf803, WR_x|RD_y,	0,	I1 },
207{"sll",     "y,x",	0xe804, 0xf81f, WR_y|RD_y|RD_x,	0,	I1 },
208{"slti",    "x,8",	0x5000, 0xf800, WR_T|RD_x,	0,	I1 },
209{"slt",	    "x,y",	0xe802, 0xf81f, WR_T|RD_x|RD_y,	0,	I1 },
210{"slt",     "x,8",	0x5000, 0xf800, WR_T|RD_x,	0,	I1 },
211{"sltiu",   "x,8",	0x5800, 0xf800, WR_T|RD_x,	0,	I1 },
212{"sltu",    "x,y",	0xe803, 0xf81f, WR_T|RD_x|RD_y,	0,	I1 },
213{"sltu",    "x,8",	0x5800, 0xf800, WR_T|RD_x,	0,	I1 },
214{"srav",    "y,x",	0xe807, 0xf81f, WR_y|RD_y|RD_x,	0,	I1 },
215{"sra",	    "x,w,<",	0x3003, 0xf803, WR_x|RD_y,	0,	I1 },
216{"sra",     "y,x",	0xe807, 0xf81f, WR_y|RD_y|RD_x,	0,	I1 },
217{"srlv",    "y,x",	0xe806, 0xf81f, WR_y|RD_y|RD_x,	0,	I1 },
218{"srl",	    "x,w,<",	0x3002, 0xf803, WR_x|RD_y,	0,	I1 },
219{"srl",     "y,x",	0xe806, 0xf81f, WR_y|RD_y|RD_x,	0,	I1 },
220{"subu",    "z,v,y",	0xe003, 0xf803, WR_z|RD_x|RD_y,	0,	I1 },
221{"subu",    "y,x,4",	0, (int) M_SUBU_I, INSN_MACRO,	0,	I1 },
222{"subu",    "x,k",	0, (int) M_SUBU_I_2, INSN_MACRO,0,	I1 },
223{"sw",	    "y,W(x)",	0xd800, 0xf800, RD_y|RD_x,	0,	I1 },
224{"sw",	    "x,V(S)",	0xd000, 0xf800, RD_x|RD_SP,	0,	I1 },
225{"sw",	    "R,V(S)",	0x6200, 0xff00, RD_31|RD_SP,	0,	I1 },
226{"xor",	    "x,y",	0xe80e, 0xf81f, WR_x|RD_x|RD_y, 0,	I1 },
227  /* MIPS16e additions */
228{"jalrc",   "x",	0xe8c0, 0xf8ff, WR_31|RD_x|TRAP, 0,     I32 },
229{"jalrc",   "R,x",	0xe8c0, 0xf8ff, WR_31|RD_x|TRAP, 0,     I32 },
230{"jrc",     "x",	0xe880, 0xf8ff, RD_x|TRAP,	0,      I32 },
231{"jrc",     "R",	0xe8a0, 0xffff, RD_31|TRAP,	0,      I32 },
232{"restore", "M",	0x6400, 0xff80, WR_31|RD_SP|WR_SP|TRAP,	0,	I32 },
233{"save",    "m",	0x6480, 0xff80, RD_31|RD_SP|WR_SP|TRAP,	0,	I32 },
234{"sdbbp",   "6",	0xe801, 0xf81f, TRAP,		0,	I32 },
235{"seb",	    "x",	0xe891, 0xf8ff, WR_x|RD_x,	0,      I32 },
236{"seh",	    "x",	0xe8b1, 0xf8ff, WR_x|RD_x,	0,      I32 },
237{"sew",	    "x",	0xe8d1, 0xf8ff, WR_x|RD_x,	0,      I64 },
238{"zeb",	    "x",	0xe811, 0xf8ff, WR_x|RD_x,	0,      I32 },
239{"zeh",	    "x",	0xe831, 0xf8ff, WR_x|RD_x,	0,      I32 },
240{"zew",	    "x",	0xe851, 0xf8ff, WR_x|RD_x,	0,      I64 },
241};
242
243const int bfd_mips16_num_opcodes =
244  ((sizeof mips16_opcodes) / (sizeof (mips16_opcodes[0])));
245