1227825Stheraven/* SPU ELF support for BFD.
2227825Stheraven
3227825Stheraven   Copyright 2006, 2010 Free Software Foundation, Inc.
4227825Stheraven
5227825Stheraven   This file is part of GDB, GAS, and the GNU binutils.
6227825Stheraven
7227825Stheraven   This program is free software; you can redistribute it and/or modify
8227825Stheraven   it under the terms of the GNU General Public License as published by
9227825Stheraven   the Free Software Foundation; either version 3 of the License, or
10227825Stheraven   (at your option) any later version.
11227825Stheraven
12227825Stheraven   This program is distributed in the hope that it will be useful,
13227825Stheraven   but WITHOUT ANY WARRANTY; without even the implied warranty of
14227825Stheraven   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15227825Stheraven   GNU General Public License for more details.
16227825Stheraven
17227825Stheraven   You should have received a copy of the GNU General Public License
18227825Stheraven   along with this program; if not, write to the Free Software Foundation,
19227825Stheraven   Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
20227825Stheraven
21227825Stheraven/* These two enums are from rel_apu/common/spu_asm_format.h */
22227825Stheraven/* definition of instruction format */
23227825Stheraventypedef enum {
24227825Stheraven  RRR,
25227825Stheraven  RI18,
26227825Stheraven  RI16,
27227825Stheraven  RI10,
28227825Stheraven  RI8,
29227825Stheraven  RI7,
30227825Stheraven  RR,
31227825Stheraven  LBT,
32227825Stheraven  LBTI,
33227825Stheraven  IDATA,
34227825Stheraven  UNKNOWN_IFORMAT
35227825Stheraven} spu_iformat;
36227825Stheraven
37227825Stheraven/* These values describe assembly instruction arguments.  They indicate
38227825Stheraven * how to encode, range checking and which relocation to use. */
39227825Stheraventypedef enum {
40227825Stheraven  A_T,  /* register at pos 0 */
41227825Stheraven  A_A,  /* register at pos 7 */
42227825Stheraven  A_B,  /* register at pos 14 */
43227825Stheraven  A_C,  /* register at pos 21 */
44227825Stheraven  A_S,  /* special purpose register at pos 7 */
45227825Stheraven  A_H,  /* channel register at pos 7 */
46227825Stheraven  A_P,  /* parenthesis, this has to separate regs from immediates */
47227825Stheraven  A_S3,
48227825Stheraven  A_S6,
49227825Stheraven  A_S7N,
50227825Stheraven  A_S7,
51227825Stheraven  A_U7A,
52227825Stheraven  A_U7B,
53227825Stheraven  A_S10B,
54227825Stheraven  A_S10,
55227825Stheraven  A_S11,
56227825Stheraven  A_S11I,
57227825Stheraven  A_S14,
58227825Stheraven  A_S16,
59227825Stheraven  A_S18,
60227825Stheraven  A_R18,
61227825Stheraven  A_U3,
62227825Stheraven  A_U5,
63227825Stheraven  A_U6,
64227825Stheraven  A_U7,
65227825Stheraven  A_U14,
66227825Stheraven  A_X16,
67227825Stheraven  A_U18,
68227825Stheraven  A_MAX
69227825Stheraven} spu_aformat;
70227825Stheraven
71227825Stheravenenum spu_insns {
72227825Stheraven#define APUOP(TAG,MACFORMAT,OPCODE,MNEMONIC,ASMFORMAT,DEP,PIPE) \
73227825Stheraven	TAG,
74227825Stheraven#define APUOPFB(TAG,MACFORMAT,OPCODE,FB,MNEMONIC,ASMFORMAT,DEP,PIPE) \
75227825Stheraven	TAG,
76227825Stheraven#include "opcode/spu-insns.h"
77227825Stheraven#undef APUOP
78227825Stheraven#undef APUOPFB
79227825Stheraven        M_SPU_MAX
80227825Stheraven};
81227825Stheraven
82227825Stheravenstruct spu_opcode
83227825Stheraven{
84227825Stheraven   spu_iformat insn_type;
85227825Stheraven   unsigned int opcode;
86227825Stheraven   char *mnemonic;
87227825Stheraven   int arg[5];
88227825Stheraven};
89227825Stheraven
90227825Stheraven#define SIGNED_EXTRACT(insn,size,pos) (((int)((insn) << (32-size-pos))) >> (32-size))
91227825Stheraven#define UNSIGNED_EXTRACT(insn,size,pos) (((insn) >> pos) & ((1 << size)-1))
92227825Stheraven
93227825Stheraven#define DECODE_INSN_RT(insn) (insn & 0x7f)
94262801Sdim#define DECODE_INSN_RA(insn) ((insn >> 7) & 0x7f)
95227825Stheraven#define DECODE_INSN_RB(insn) ((insn >> 14) & 0x7f)
96227825Stheraven#define DECODE_INSN_RC(insn) ((insn >> 21) & 0x7f)
97241903Sdim
98227825Stheraven#define DECODE_INSN_I10(insn) SIGNED_EXTRACT(insn,10,14)
99227825Stheraven#define DECODE_INSN_U10(insn) UNSIGNED_EXTRACT(insn,10,14)
100227825Stheraven
101227825Stheraven/* For branching, immediate loads, hbr and  lqa/stqa. */
102241903Sdim#define DECODE_INSN_I16(insn) SIGNED_EXTRACT(insn,16,7)
103227825Stheraven#define DECODE_INSN_U16(insn) UNSIGNED_EXTRACT(insn,16,7)
104227825Stheraven
105227825Stheraven/* for stop */
106227825Stheraven#define DECODE_INSN_U14(insn) UNSIGNED_EXTRACT(insn,14,0)
107262801Sdim
108227825Stheraven/* For ila */
109227825Stheraven#define DECODE_INSN_I18(insn) SIGNED_EXTRACT(insn,18,7)
110227825Stheraven#define DECODE_INSN_U18(insn) UNSIGNED_EXTRACT(insn,18,7)
111227825Stheraven
112227825Stheraven/* For rotate and shift and generate control mask */
113227825Stheraven#define DECODE_INSN_I7(insn) SIGNED_EXTRACT(insn,7,14)
114227825Stheraven#define DECODE_INSN_U7(insn) UNSIGNED_EXTRACT(insn,7,14)
115227825Stheraven
116227825Stheraven/* For float <-> int conversion */
117227825Stheraven#define DECODE_INSN_I8(insn)  SIGNED_EXTRACT(insn,8,14)
118227825Stheraven#define DECODE_INSN_U8(insn) UNSIGNED_EXTRACT(insn,8,14)
119227825Stheraven
120227825Stheraven/* For hbr  */
121227825Stheraven#define DECODE_INSN_I9a(insn) ((SIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0))
122227825Stheraven#define DECODE_INSN_I9b(insn) ((SIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0))
123227825Stheraven#define DECODE_INSN_U9a(insn) ((UNSIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0))
124227825Stheraven#define DECODE_INSN_U9b(insn) ((UNSIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0))
125227825Stheraven
126227825Stheraven